Skip to content

Commit c96586d

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

File tree

1 file changed

+31
-4
lines changed

1 file changed

+31
-4
lines changed

rustc_tools_util/src/lib.rs

Lines changed: 31 additions & 4 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

@@ -100,19 +104,42 @@ impl std::fmt::Debug for VersionInfo {
100104
}
101105

102106
#[must_use]
103-
pub fn get_commit_hash() -> Option<String> {
104-
let output = std::process::Command::new("git")
105-
.args(["rev-parse", "HEAD"])
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")
119+
.args(["rev-parse", "--git-common-dir"])
106120
.output()
107121
.ok()?;
122+
let stdout = output.status.success().then_some(output.stdout)?;
123+
let git_common_dir = PathBuf::from(String::from_utf8(stdout).ok()?.trim());
124+
// Determine the file where the target of that ref is stored.
125+
let git_head_ref_file = git_common_dir.join(git_head_ref);
126+
127+
println!("cargo::rerun-if-changed={}", git_head_file.display());
128+
println!("cargo::rerun-if-changed={}", git_head_ref_file.display());
129+
Some(())
130+
}
131+
132+
#[must_use]
133+
pub fn get_commit_hash() -> Option<String> {
134+
let output = Command::new("git").args(["rev-parse", "HEAD"]).output().ok()?;
108135
let mut stdout = output.status.success().then_some(output.stdout)?;
109136
stdout.truncate(10);
110137
String::from_utf8(stdout).ok()
111138
}
112139

113140
#[must_use]
114141
pub fn get_commit_date() -> Option<String> {
115-
let output = std::process::Command::new("git")
142+
let output = Command::new("git")
116143
.args(["log", "-1", "--date=short", "--pretty=format:%cd"])
117144
.output()
118145
.ok()?;

0 commit comments

Comments
 (0)