diff options
| -rw-r--r-- | mullvad-version/build.rs | 54 |
1 files changed, 42 insertions, 12 deletions
diff --git a/mullvad-version/build.rs b/mullvad-version/build.rs index 18a8b8422b..9066d6178e 100644 --- a/mullvad-version/build.rs +++ b/mullvad-version/build.rs @@ -1,3 +1,4 @@ +use std::path::Path; use std::{env, fs, path::PathBuf, process::Command}; /// How many characters of the git commit that should be added to the version name @@ -60,6 +61,10 @@ fn get_product_version(target: Target) -> String { } } +/// Returns the development suffix for the current build. A build has a development +/// 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 { @@ -68,29 +73,54 @@ fn get_dev_suffix(target: Target, product_version: &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); - let current_head_commit_hash = git_rev_parse_commit_hash("HEAD")?; - // If we are not currently building the release tag, we are on a development build. - // Adjust product version string accordingly. - if product_version_commit_hash.as_ref() != Some(¤t_head_commit_hash) { - let hash_suffix = ¤t_head_commit_hash[..GIT_HASH_DEV_SUFFIX_LEN]; - return Some(format!("-dev-{hash_suffix}")); + // 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; } - - None + Some(format!( + "-dev-{}", + &head_commit_hash[..GIT_HASH_DEV_SUFFIX_LEN] + )) } -/// Returns the commit hash for the commit that `git_ref` is pointing to +/// Returns the commit hash for the commit that `git_ref` is pointing to. +/// +/// Returns `None` if executing the `git rev-parse` command fails for some reason. fn git_rev_parse_commit_hash(git_ref: &str) -> Option<String> { - // This is a very blunt way of making sure we run again if a tag is added or removed. - println!("cargo:rerun-if-changed=.git"); + let git_dir = Path::new("..").join(".git"); + if git_ref == "HEAD" { + // If we build our output on information about HEAD we need to re-run if HEAD moves + let head_path = git_dir.join("HEAD"); + if head_path.exists() { + println!("cargo:rerun-if-changed={}", head_path.display()); + + // If HEAD points to a reference, we want to re-run if that reference moves + let head_content = fs::read_to_string(head_path).unwrap(); + if let Some(ref_name) = head_content.strip_prefix("ref: ") { + let ref_path = git_dir.join(ref_name); + println!("cargo:rerun-if-changed={}", ref_path.display()); + } + } + } else { + // If we build our output on information about a git reference, we need to re-run + // if it moves. We don't know if the ref is a head, remote or tag, so we check all. + for ref_type in ["heads", "remotes", "tags"] { + let ref_path = git_dir.join("refs").join(ref_type).join(git_ref); + if ref_path.exists() { + println!("cargo:rerun-if-changed={}", ref_path.display()); + } + } + } let output = Command::new("git") .arg("rev-parse") .arg(format!("{git_ref}^{{commit}}")) .output() - .expect("Not able to run git"); + .ok()?; if !output.status.success() { return None; } |
