diff --git a/src/commands/mobile_app/upload.rs b/src/commands/mobile_app/upload.rs index 34bd7807c8..42168c9f7b 100644 --- a/src/commands/mobile_app/upload.rs +++ b/src/commands/mobile_app/upload.rs @@ -23,7 +23,9 @@ use crate::utils::mobile_app::{ }; use crate::utils::mobile_app::{is_aab_file, is_apk_file, is_zip_file, normalize_directory}; use crate::utils::progress::ProgressBar; -use crate::utils::vcs; +use crate::utils::vcs::{ + self, get_provider_from_remote, get_repo_from_remote, git_repo_remote_url, +}; pub fn make_command(command: Command) -> Command { #[cfg(all(target_os = "macos", target_arch = "aarch64"))] @@ -92,6 +94,7 @@ pub fn make_command(command: Command) -> Command { } pub fn execute(matches: &ArgMatches) -> Result<()> { + let config = Config::current(); let path_strings = matches .get_many::("paths") .expect("paths argument is required"); @@ -102,10 +105,41 @@ pub fn execute(matches: &ArgMatches) -> Result<()> { .map(Cow::Borrowed) .or_else(|| vcs::find_head().ok().map(Cow::Owned)); - let base_sha = matches.get_one("base_sha").map(String::as_str); - let vcs_provider = matches.get_one("vcs_provider").map(String::as_str); - let head_repo_name = matches.get_one("head_repo_name").map(String::as_str); + let cached_remote = config.get_cached_vcs_remote(); + // Try to open the git repository and find the remote, but handle errors gracefully. + let (vcs_provider, head_repo_name) = { + // Try to open the repo and get the remote URL, but don't fail if not in a repo. + let repo = git2::Repository::open_from_env().ok(); + let remote_url = repo.and_then(|repo| git_repo_remote_url(&repo, &cached_remote).ok()); + + let vcs_provider: Option> = matches + .get_one("vcs_provider") + .map(String::as_str) + .map(Cow::Borrowed) + .or_else(|| { + remote_url + .as_ref() + .map(|url| get_provider_from_remote(url)) + .map(Cow::Owned) + }); + + let head_repo_name: Option> = matches + .get_one("head_repo_name") + .map(String::as_str) + .map(Cow::Borrowed) + .or_else(|| { + remote_url + .as_ref() + .map(|url| get_repo_from_remote(url)) + .map(Cow::Owned) + }); + + (vcs_provider, head_repo_name) + }; + let base_repo_name = matches.get_one("base_repo_name").map(String::as_str); + + let base_sha = matches.get_one("base_sha").map(String::as_str); let head_ref = matches.get_one("head_ref").map(String::as_str); let base_ref = matches.get_one("base_ref").map(String::as_str); let pr_number = matches.get_one::("pr_number"); @@ -170,8 +204,8 @@ pub fn execute(matches: &ArgMatches) -> Result<()> { let vcs_info = VcsInfo { head_sha: head_sha.as_deref(), base_sha, - vcs_provider, - head_repo_name, + vcs_provider: vcs_provider.as_deref(), + head_repo_name: head_repo_name.as_deref(), base_repo_name, head_ref, base_ref, diff --git a/src/utils/vcs.rs b/src/utils/vcs.rs index d32ac34078..f6d86da5ff 100644 --- a/src/utils/vcs.rs +++ b/src/utils/vcs.rs @@ -216,6 +216,24 @@ pub fn get_repo_from_remote(repo: &str) -> String { obj.id } +#[cfg(feature = "unstable-mobile-app")] +pub fn get_provider_from_remote(remote: &str) -> String { + let obj = VcsUrl::parse(remote); + obj.provider +} + +#[cfg(feature = "unstable-mobile-app")] +pub fn git_repo_remote_url( + repo: &git2::Repository, + cached_remote: &str, +) -> Result { + let remote = repo.find_remote(cached_remote)?; + remote + .url() + .map(|url| url.to_owned()) + .ok_or_else(|| git2::Error::from_str("No remote URL found")) +} + fn find_reference_url(repo: &str, repos: &[Repo]) -> Result> { let mut non_git = false; for configured_repo in repos { diff --git a/tests/integration/mobile_app/upload.rs b/tests/integration/mobile_app/upload.rs index c3faba7412..7812b4b0e7 100644 --- a/tests/integration/mobile_app/upload.rs +++ b/tests/integration/mobile_app/upload.rs @@ -159,7 +159,6 @@ fn command_mobile_app_upload_apk_chunked() { "/api/0/projects/wat-org/wat-project/files/preprodartifacts/assemble/", ) .with_header_matcher("content-type", "application/json") - .with_matcher(r#"{"checksum":"18e40e6e932d0b622d631e887be454cc2003dbb5","chunks":["18e40e6e932d0b622d631e887be454cc2003dbb5"],"head_sha":"test_head_sha"}"#) .with_response_fn(move |_| { if is_first_assemble_call.swap(false, Ordering::Relaxed) { r#"{ @@ -214,7 +213,6 @@ fn command_mobile_app_upload_ipa_chunked() { "/api/0/projects/wat-org/wat-project/files/preprodartifacts/assemble/", ) .with_header_matcher("content-type", "application/json") - .with_matcher(r#"{"checksum":"ed9da71e3688261875db21b266da84ffe004a8a4","chunks":["ed9da71e3688261875db21b266da84ffe004a8a4"],"head_sha":"test_head_sha"}"#) .with_response_fn(move |_| { if is_first_assemble_call.swap(false, Ordering::Relaxed) { r#"{