1
1
use std:: path:: Path ;
2
+ use std:: process:: Command ;
2
3
use std:: { env, fs} ;
3
4
4
5
use toml:: Value ;
5
6
7
+ /// Given a [Command], run it and return the output as a string,
8
+ /// returning `None` if the command fails.
9
+ fn run_git_command ( command : & mut Command ) -> Option < String > {
10
+ command
11
+ . output ( )
12
+ . map ( |output| String :: from_utf8 ( output. stdout ) . ok ( ) )
13
+ . unwrap_or ( None )
14
+ . map ( |s| s. trim ( ) . to_string ( ) )
15
+ }
16
+
17
+ fn current_git_hash ( ) -> Option < String > {
18
+ option_env ! ( "GIT_COMMIT" ) . map ( String :: from) . or_else ( || {
19
+ run_git_command (
20
+ Command :: new ( "git" )
21
+ . arg ( "log" )
22
+ . arg ( "-1" )
23
+ . arg ( "--pretty=format:%h" )
24
+ . current_dir ( env ! ( "CARGO_MANIFEST_DIR" ) ) ,
25
+ )
26
+ } )
27
+ }
28
+
29
+ fn current_git_branch ( ) -> Option < String > {
30
+ option_env ! ( "GIT_BRANCH" ) . map ( String :: from) . or_else ( || {
31
+ run_git_command (
32
+ Command :: new ( "git" )
33
+ . arg ( "rev-parse" )
34
+ . arg ( "--abbrev-ref" )
35
+ . arg ( "HEAD" ) ,
36
+ )
37
+ } )
38
+ }
39
+
40
+ fn is_working_tree_clean ( ) -> bool {
41
+ Command :: new ( "git" )
42
+ . arg ( "diff" )
43
+ . arg ( "--quiet" )
44
+ . arg ( "--exit-code" )
45
+ . current_dir ( env ! ( "CARGO_MANIFEST_DIR" ) )
46
+ . status ( )
47
+ . map ( |status| status. code ( ) == Some ( 0 ) )
48
+ . unwrap_or ( true )
49
+ }
50
+
6
51
fn main ( ) {
7
52
let toml_file = "../versions.toml" ;
8
53
let toml_content = fs:: read_to_string ( toml_file) . expect ( "Failed to read versions.toml" ) ;
@@ -24,6 +69,29 @@ fn main() {
24
69
) ) ;
25
70
}
26
71
72
+ let git_commit = current_git_hash ( ) ;
73
+ rust_code. push_str ( & format ! (
74
+ "pub const GIT_COMMIT: Option<&'static str> = {git_commit:?};\n " ,
75
+ ) ) ;
76
+ if let Some ( git_commit) = git_commit {
77
+ println ! ( "cargo:rustc-env=GIT_COMMIT={}" , git_commit) ;
78
+ }
79
+
80
+ let git_branch = current_git_branch ( ) ;
81
+ rust_code. push_str ( & format ! (
82
+ "pub const GIT_BRANCH: Option<&'static str> = {git_branch:?};\n " ,
83
+ ) ) ;
84
+ if let Some ( git_branch) = git_branch {
85
+ println ! ( "cargo:rustc-env=GIT_BRANCH={}" , git_branch) ;
86
+ }
87
+
88
+ let is_clean = if is_working_tree_clean ( ) { "" } else { "+" } ;
89
+ rust_code. push_str ( & format ! (
90
+ "pub const GIT_TREE_CLEAN: Option<&'static str> = Some(\" {}\" );\n " ,
91
+ is_clean
92
+ ) ) ;
93
+ println ! ( "cargo:rustc-env=GIT_TREE_CLEAN={}" , is_clean) ;
94
+
27
95
let out_dir = env:: var_os ( "OUT_DIR" ) . unwrap ( ) ;
28
96
let dest_path = Path :: new ( & out_dir) . join ( "versions.rs" ) ;
29
97
fs:: write ( & dest_path, rust_code) . expect ( "Failed to write generated code" ) ;
0 commit comments