summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorSebastian Holmin <sebastian.holmin@mullvad.net>2024-05-03 10:07:44 +0200
committerSebastian Holmin <sebastian.holmin@mullvad.net>2024-05-16 02:04:18 +0200
commit57568b339518a1a8513a0e5dd8bfdf118dd4fb1e (patch)
treec3ef4b6d5874aae3c1f147c6bfa61b961c1c4fba
parent7cf5962c49cdca5f7bd5cac6aec2451d760f3814 (diff)
downloadmullvadvpn-57568b339518a1a8513a0e5dd8bfdf118dd4fb1e.tar.xz
mullvadvpn-57568b339518a1a8513a0e5dd8bfdf118dd4fb1e.zip
Extract `rerun-if` logic to separate fn
-rw-r--r--mullvad-version/build.rs100
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.