diff options
| author | Sebastian Holmin <sebastian.holmin@mullvad.net> | 2024-05-03 10:07:44 +0200 |
|---|---|---|
| committer | Sebastian Holmin <sebastian.holmin@mullvad.net> | 2024-05-16 02:04:18 +0200 |
| commit | 57568b339518a1a8513a0e5dd8bfdf118dd4fb1e (patch) | |
| tree | c3ef4b6d5874aae3c1f147c6bfa61b961c1c4fba | |
| parent | 7cf5962c49cdca5f7bd5cac6aec2451d760f3814 (diff) | |
| download | mullvadvpn-57568b339518a1a8513a0e5dd8bfdf118dd4fb1e.tar.xz mullvadvpn-57568b339518a1a8513a0e5dd8bfdf118dd4fb1e.zip | |
Extract `rerun-if` logic to separate fn
| -rw-r--r-- | mullvad-version/build.rs | 100 |
1 files changed, 57 insertions, 43 deletions
diff --git a/mullvad-version/build.rs b/mullvad-version/build.rs index 008ec8d104..fc7eb9edbe 100644 --- a/mullvad-version/build.rs +++ b/mullvad-version/build.rs @@ -52,15 +52,26 @@ fn get_product_version(target: Target) -> String { Target::Desktop => DESKTOP_VERSION_FILE_PATH, }; println!("cargo:rerun-if-changed={version_file_path}"); - let version = fs::read_to_string(version_file_path) + let product_version = fs::read_to_string(version_file_path) .unwrap_or_else(|_| panic!("Failed to read {version_file_path}")) .trim() .to_owned(); - if let Some(dev_suffix) = get_dev_suffix(target, &version) { - format!("{version}{dev_suffix}") + // Compute the expected tag name for the release named `product_version` + let release_tag = match target { + Target::Android => format!("android/{product_version}"), + Target::Desktop => product_version.to_owned(), + }; + + // Rerun this build script on changes to the git ref that affects the build version. + // NOTE: This must be kept up to date with the behavior of `git_rev_parse_commit_hash`. + rerun_if_git_ref_changed(&release_tag) + .expect("Failed to set 'cargo:rerun-if-changed' on git ref changes"); + + if let Some(dev_suffix) = get_dev_suffix(&product_version) { + format!("{product_version}{dev_suffix}") } else { - version + product_version } } @@ -68,13 +79,26 @@ fn get_product_version(target: Target) -> String { /// suffix if the build is not done on a git tag named `product_version`. /// This also returns `None` if the `git` command can't run, or the code does /// not live in a git repository. -fn get_dev_suffix(target: Target, product_version: &str) -> Option<String> { - // Compute the expected tag name for the release named `product_version` - let release_tag = match target { - Target::Android => format!("android/{product_version}"), - Target::Desktop => product_version.to_owned(), - }; +fn get_dev_suffix(release_tag: &str) -> Option<String> { + // Get the git commit hashes for the latest release and current HEAD + // Return `None` if unable to find the hash for HEAD. + let head_commit_hash = git_rev_parse_commit_hash("HEAD")?; + let product_version_commit_hash = git_rev_parse_commit_hash(release_tag); + + // If we are currently building the release tag, there is no dev suffix + if Some(&head_commit_hash) == product_version_commit_hash.as_ref() { + return None; + } + Some(format!( + "-dev-{}", + &head_commit_hash[..GIT_HASH_DEV_SUFFIX_LEN] + )) +} +/// Trigger rebuild of `mullvad-version` on changing branch (`.git/HEAD`), on changes to the ref of +/// the current branch (`.git/refs/heads/$current_branch`) and on changes to the ref of the current +/// release tag (`.git/refs/tags/$current_release_tag`). +fn rerun_if_git_ref_changed(release_tag: &str) -> std::io::Result<()> { let git_dir = Path::new("..").join(".git"); // If we build our output on information about HEAD we need to re-run if HEAD moves @@ -83,45 +107,35 @@ fn get_dev_suffix(target: Target, product_version: &str) -> Option<String> { println!("cargo:rerun-if-changed={}", head_path.display()); } + // If we build our output on information about the ref of the current branch, we need to re-run + // on changes to it let output = Command::new("git") .arg("branch") .arg("--show-current") - .output() - .ok()?; - let current_branch = String::from_utf8(output.stdout).unwrap(); - // If we build our output on information about a git reference, we need to re-run - // if it moves. Instead of trying to be smart, just re-run if any git reference moves. - let git_current_branch_ref = git_dir - .join("refs") - .join("heads") - .join(current_branch.trim()); - if git_current_branch_ref.exists() { - println!( - "cargo:rerun-if-changed={}", - git_current_branch_ref.display() - ); - } - let git_current_branch_ref = git_dir.join("refs").join("tags").join(&release_tag); - if git_current_branch_ref.exists() { - println!( - "cargo:rerun-if-changed={}", - git_current_branch_ref.display() - ); - } + .output()?; - // Get the git commit hashes for the latest release and current HEAD - // Return `None` if unable to find the hash for HEAD. - let head_commit_hash = git_rev_parse_commit_hash("HEAD")?; - let product_version_commit_hash = git_rev_parse_commit_hash(&release_tag); + let current_branch = String::from_utf8(output.stdout).unwrap(); + let current_branch = current_branch.trim(); - // If we are currently building the release tag, there is no dev suffix - if Some(&head_commit_hash) == product_version_commit_hash.as_ref() { - return None; + // When in 'detached HEAD' state, the output will be empty. However, in that case we already get + // the ref from `.git/HEAD`, so we can safely skip this part. + if !current_branch.is_empty() { + let git_current_branch_ref = git_dir.join("refs").join("heads").join(current_branch); + if git_current_branch_ref.exists() { + println!( + "cargo:rerun-if-changed={}", + git_current_branch_ref.display() + ); + } } - Some(format!( - "-dev-{}", - &head_commit_hash[..GIT_HASH_DEV_SUFFIX_LEN] - )) + + // Since the product version depends on if the build is done on the commit with the + // corresponding release tag or not, we must track creation of/changes to said tag + let git_release_tag_ref = git_dir.join("refs").join("tags").join(release_tag); + if git_release_tag_ref.exists() { + println!("cargo:rerun-if-changed={}", git_release_tag_ref.display()); + }; + Some(()) } /// Returns the commit hash for the commit that `git_ref` is pointing to. |
