diff --git a/cli/build.rs b/cli/build.rs index 35f1694353..dae2338f35 100644 --- a/cli/build.rs +++ b/cli/build.rs @@ -22,17 +22,20 @@ const JJ_OP_HEADS_PATH: &str = "../.jj/repo/op_heads/heads"; fn main() { let version = std::env::var("CARGO_PKG_VERSION").unwrap(); - if Path::new(GIT_HEAD_PATH).exists() { - // In colocated repo, .git/HEAD should reflect the working-copy parent. - println!("cargo:rerun-if-changed={GIT_HEAD_PATH}"); - } else if Path::new(JJ_OP_HEADS_PATH).exists() { - // op_heads changes when working-copy files are mutated, which is way more - // frequent than .git/HEAD. - println!("cargo:rerun-if-changed={JJ_OP_HEADS_PATH}"); - } println!("cargo:rerun-if-env-changed=NIX_JJ_GIT_HASH"); + let git_hash = get_git_hash_from_nix().or_else(|| { + if Path::new(GIT_HEAD_PATH).exists() { + // In colocated repo, .git/HEAD should reflect the working-copy parent. + println!("cargo:rerun-if-changed={GIT_HEAD_PATH}"); + } else if Path::new(JJ_OP_HEADS_PATH).exists() { + // op_heads changes when working-copy files are mutated, which is way more + // frequent than .git/HEAD. + println!("cargo:rerun-if-changed={JJ_OP_HEADS_PATH}"); + } + get_git_hash_from_jj().or_else(get_git_hash_from_git) + }); - if let Some(git_hash) = get_git_hash() { + if let Some(git_hash) = git_hash { println!("cargo:rustc-env=JJ_VERSION={version}-{git_hash}"); } else { println!("cargo:rustc-env=JJ_VERSION={version}"); @@ -47,14 +50,14 @@ fn main() { } } -fn get_git_hash() -> Option { - if let Some(nix_hash) = std::env::var("NIX_JJ_GIT_HASH") +fn get_git_hash_from_nix() -> Option { + std::env::var("NIX_JJ_GIT_HASH") .ok() .filter(|s| !s.is_empty()) - { - return Some(nix_hash); - } - if let Ok(output) = Command::new("jj") +} + +fn get_git_hash_from_jj() -> Option { + Command::new("jj") .args([ "--ignore-working-copy", "--color=never", @@ -64,21 +67,27 @@ fn get_git_hash() -> Option { "-T=commit_id ++ '-'", ]) .output() - && output.status.success() - { - let mut parent_commits = String::from_utf8(output.stdout).unwrap(); - // If a development version of `jj` is compiled at a merge commit, this will - // result in several commit ids separated by `-`s. - parent_commits.truncate(parent_commits.trim_end_matches('-').len()); - return Some(parent_commits); - } - - if let Ok(output) = Command::new("git").args(["rev-parse", "HEAD"]).output() - && output.status.success() - { - let line = str::from_utf8(&output.stdout).unwrap(); - return Some(line.trim_end().to_owned()); - } + .ok() + .filter(|output| output.status.success()) + .map(|output| { + let mut parent_commits = String::from_utf8(output.stdout).unwrap(); + // If a development version of `jj` is compiled at a merge commit, this will + // result in several commit ids separated by `-`s. + parent_commits.truncate(parent_commits.trim_end_matches('-').len()); + parent_commits + }) +} - None +fn get_git_hash_from_git() -> Option { + Command::new("git") + .args(["rev-parse", "HEAD"]) + .output() + .ok() + .filter(|output| output.status.success()) + .map(|output| { + str::from_utf8(&output.stdout) + .unwrap() + .trim_end() + .to_owned() + }) }