1- use anyhow:: Result ;
2- use std:: env;
1+ use anyhow:: { Context as _ , Result , anyhow } ;
2+ use std:: { env, path :: PathBuf , process :: Command } ;
33
44fn main ( ) -> Result < ( ) > {
5+ println ! ( "cargo:rerun-if-changed=build.rs" ) ;
6+ println ! ( "cargo:rerun-if-env-changed=GIT_SHA" ) ;
57 read_git_version ( ) ?;
68 Ok ( ( ) )
79}
810
911fn read_git_version ( ) -> Result < ( ) > {
1012 if let Ok ( v) = env:: var ( "GIT_SHA" ) {
11- // first try to read an externally provided git SAH , e.g., from CI
13+ // first try to read an externally provided git SHA , e.g., from CI
1214 println ! ( "cargo:rustc-env=GIT_SHA={v}" ) ;
1315 } else {
16+ if let Some ( path) = git_head_ref_path ( ) . context ( "error trying to get git head ref path" ) ? {
17+ println ! ( "cargo:rerun-if-changed={}" , path. display( ) ) ;
18+ }
19+
1420 // then try to read the git repo.
15- let maybe_hash = get_git_hash ( ) ?;
21+ let maybe_hash = match git_output ( [ "rev-parse" , "--short" , "HEAD" ] ) {
22+ Ok ( hash) => Some ( hash) ,
23+ Err ( err) => {
24+ eprintln ! ( "error trying to get git head ref path: {:?}" , err) ;
25+ None
26+ }
27+ } ;
28+
1629 let git_hash = maybe_hash. as_deref ( ) . unwrap_or ( "???????" ) ;
1730 println ! ( "cargo:rustc-env=GIT_SHA={git_hash}" ) ;
1831 }
@@ -25,27 +38,29 @@ fn read_git_version() -> Result<()> {
2538 Ok ( ( ) )
2639}
2740
28- fn get_git_hash ( ) -> Result < Option < String > > {
29- use std:: process:: Command ;
30-
41+ fn git_head_ref_path ( ) -> Result < Option < PathBuf > > {
42+ let git_dir = git_output ( [ "rev-parse" , "--git-dir" ] ) ?;
3143 let output = Command :: new ( "git" )
32- . args ( [ "rev-parse" , "--short" , "HEAD" ] )
33- . output ( ) ;
44+ . args ( [ "symbolic-ref" , "-q" , "HEAD" ] )
45+ . output ( ) ?;
46+
47+ if output. status . success ( ) {
48+ let head_ref = String :: from_utf8_lossy ( & output. stdout ) . trim ( ) . to_string ( ) ;
49+ Ok ( Some ( PathBuf :: from ( git_dir) . join ( head_ref) ) )
50+ } else {
51+ Ok ( None )
52+ }
53+ }
3454
35- match output {
36- Ok ( output) if output. status . success ( ) => {
37- let hash = String :: from_utf8 ( output. stdout ) ?. trim ( ) . to_string ( ) ;
55+ fn git_output < const N : usize > ( args : [ & str ; N ] ) -> Result < String > {
56+ let output = Command :: new ( "git" ) . args ( args) . output ( ) ?;
3857
39- Ok ( Some ( hash) )
40- }
41- Ok ( output) => {
42- let err = String :: from_utf8_lossy ( & output. stderr ) ;
43- eprintln ! ( "failed to get git repo: {}" , err. trim( ) ) ;
44- Ok ( None )
45- }
46- Err ( err) => {
47- eprintln ! ( "failed to execute git: {err}" ) ;
48- Ok ( None )
49- }
58+ if output. status . success ( ) {
59+ Ok ( String :: from_utf8_lossy ( & output. stdout ) . trim ( ) . to_string ( ) )
60+ } else {
61+ Err (
62+ anyhow ! ( String :: from_utf8_lossy( & output. stderr) . trim( ) . to_string( ) )
63+ . context ( format ! ( "error running git command: {:?}" , args) ) ,
64+ )
5065 }
5166}
0 commit comments