|
| 1 | +use std::path::PathBuf; |
| 2 | +use std::process::Command; |
1 | 3 | use std::str; |
2 | 4 |
|
3 | 5 | /// This macro creates the version string during compilation from the |
@@ -32,6 +34,7 @@ macro_rules! get_version_info { |
32 | 34 | #[macro_export] |
33 | 35 | macro_rules! setup_version_info { |
34 | 36 | () => {{ |
| 37 | + $crate::rerun_if_git_changes(); |
35 | 38 | println!( |
36 | 39 | "cargo:rustc-env=GIT_HASH={}", |
37 | 40 | $crate::get_commit_hash().unwrap_or_default() |
@@ -99,20 +102,35 @@ impl std::fmt::Debug for VersionInfo { |
99 | 102 | } |
100 | 103 | } |
101 | 104 |
|
| 105 | +pub fn rerun_if_git_changes() -> Option<()> { |
| 106 | + // Make sure we get rerun when the git commit changes. |
| 107 | + // First, find the `HEAD` file. This should work even with worktrees. |
| 108 | + let output = Command::new("git").args(["rev-parse", "--git-dir"]).output().ok()?; |
| 109 | + let stdout = output.status.success().then_some(output.stdout)?; |
| 110 | + let git_dir = PathBuf::from(String::from_utf8(stdout).ok()?.trim()); |
| 111 | + // Read the HEAD file to determine the name of the current ref. |
| 112 | + let git_head_file = git_dir.join("HEAD"); |
| 113 | + let git_head_ref = String::from_utf8(std::fs::read(&git_head_file).ok()?).ok()?; |
| 114 | + let git_head_ref = git_head_ref.strip_prefix("ref:")?.trim(); |
| 115 | + // Determine the file where the target of that ref is stored. |
| 116 | + let git_head_ref_file = git_dir.join(git_head_ref); |
| 117 | + |
| 118 | + println!("cargo::rerun-if-changed={}", git_head_file.display()); |
| 119 | + println!("cargo::rerun-if-changed={}", git_head_ref_file.display()); |
| 120 | + Some(()) |
| 121 | +} |
| 122 | + |
102 | 123 | #[must_use] |
103 | 124 | pub fn get_commit_hash() -> Option<String> { |
104 | | - let output = std::process::Command::new("git") |
105 | | - .args(["rev-parse", "HEAD"]) |
106 | | - .output() |
107 | | - .ok()?; |
| 125 | + let output = Command::new("git").args(["rev-parse", "HEAD"]).output().ok()?; |
108 | 126 | let mut stdout = output.status.success().then_some(output.stdout)?; |
109 | 127 | stdout.truncate(10); |
110 | 128 | String::from_utf8(stdout).ok() |
111 | 129 | } |
112 | 130 |
|
113 | 131 | #[must_use] |
114 | 132 | pub fn get_commit_date() -> Option<String> { |
115 | | - let output = std::process::Command::new("git") |
| 133 | + let output = Command::new("git") |
116 | 134 | .args(["log", "-1", "--date=short", "--pretty=format:%cd"]) |
117 | 135 | .output() |
118 | 136 | .ok()?; |
|
0 commit comments