Skip to content

Commit ec77894

Browse files
committed
rustc_tools_util: rerun when git commit changes
1 parent a81f1c8 commit ec77894

File tree

1 file changed

+29
-5
lines changed

1 file changed

+29
-5
lines changed

rustc_tools_util/src/lib.rs

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::path::PathBuf;
2+
use std::process::Command;
13
use std::str;
24

35
/// This macro creates the version string during compilation from the
@@ -32,6 +34,7 @@ macro_rules! get_version_info {
3234
#[macro_export]
3335
macro_rules! setup_version_info {
3436
() => {{
37+
let _ = $crate::rerun_if_git_changes();
3538
println!(
3639
"cargo:rustc-env=GIT_HASH={}",
3740
$crate::get_commit_hash().unwrap_or_default()
@@ -41,6 +44,7 @@ macro_rules! setup_version_info {
4144
$crate::get_commit_date().unwrap_or_default()
4245
);
4346
println!("cargo:rustc-env=RUSTC_RELEASE_CHANNEL={}", $crate::get_channel());
47+
panic!()
4448
}};
4549
}
4650

@@ -99,20 +103,40 @@ impl std::fmt::Debug for VersionInfo {
99103
}
100104
}
101105

106+
#[must_use]
107+
pub fn rerun_if_git_changes() -> Option<()> {
108+
// Make sure we get rerun when the git commit changes.
109+
// First, find the `HEAD` file. This should work even with worktrees.
110+
let output = Command::new("git").args(["rev-parse", "--git-dir"]).output().ok()?;
111+
let stdout = output.status.success().then_some(output.stdout)?;
112+
let git_dir = PathBuf::from(String::from_utf8(stdout).ok()?.trim());
113+
// Read the HEAD file to determine the name of the current ref.
114+
let git_head_file = git_dir.join("HEAD");
115+
let git_head_ref = String::from_utf8(std::fs::read(&git_head_file).ok()?).ok()?;
116+
let git_head_ref = git_head_ref.strip_prefix("ref:")?.trim();
117+
// Find the directory that stores the ref files.
118+
let output = Command::new("git").args(["rev-parse", "--git-common-dir"]).output().ok()?;
119+
let stdout = output.status.success().then_some(output.stdout)?;
120+
let git_common_dir = PathBuf::from(String::from_utf8(stdout).ok()?.trim());
121+
// Determine the file where the target of that ref is stored.
122+
let git_head_ref_file = git_common_dir.join(git_head_ref);
123+
124+
println!("cargo::rerun-if-changed={}", git_head_file.display());
125+
println!("cargo::rerun-if-changed={}", git_head_ref_file.display());
126+
Some(())
127+
}
128+
102129
#[must_use]
103130
pub fn get_commit_hash() -> Option<String> {
104-
let output = std::process::Command::new("git")
105-
.args(["rev-parse", "HEAD"])
106-
.output()
107-
.ok()?;
131+
let output = Command::new("git").args(["rev-parse", "HEAD"]).output().ok()?;
108132
let mut stdout = output.status.success().then_some(output.stdout)?;
109133
stdout.truncate(10);
110134
String::from_utf8(stdout).ok()
111135
}
112136

113137
#[must_use]
114138
pub fn get_commit_date() -> Option<String> {
115-
let output = std::process::Command::new("git")
139+
let output = Command::new("git")
116140
.args(["log", "-1", "--date=short", "--pretty=format:%cd"])
117141
.output()
118142
.ok()?;

0 commit comments

Comments
 (0)