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
+ let _ = $crate:: rerun_if_git_changes( ) ;
35
38
println!(
36
39
"cargo:rustc-env=GIT_HASH={}" ,
37
40
$crate:: get_commit_hash( ) . unwrap_or_default( )
@@ -41,6 +44,7 @@ macro_rules! setup_version_info {
41
44
$crate:: get_commit_date( ) . unwrap_or_default( )
42
45
) ;
43
46
println!( "cargo:rustc-env=RUSTC_RELEASE_CHANNEL={}" , $crate:: get_channel( ) ) ;
47
+ panic!( )
44
48
} } ;
45
49
}
46
50
@@ -99,20 +103,40 @@ impl std::fmt::Debug for VersionInfo {
99
103
}
100
104
}
101
105
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
+
102
129
#[ must_use]
103
130
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 ( ) ?;
108
132
let mut stdout = output. status . success ( ) . then_some ( output. stdout ) ?;
109
133
stdout. truncate ( 10 ) ;
110
134
String :: from_utf8 ( stdout) . ok ( )
111
135
}
112
136
113
137
#[ must_use]
114
138
pub fn get_commit_date ( ) -> Option < String > {
115
- let output = std :: process :: Command :: new ( "git" )
139
+ let output = Command :: new ( "git" )
116
140
. args ( [ "log" , "-1" , "--date=short" , "--pretty=format:%cd" ] )
117
141
. output ( )
118
142
. ok ( ) ?;
0 commit comments