-
Notifications
You must be signed in to change notification settings - Fork 13
/
build.rs
90 lines (83 loc) · 2.55 KB
/
build.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
use regex::Regex;
use std::env;
use std::process::Command;
struct LastGitCommit {
hash: String,
timestamp: String,
}
impl LastGitCommit {
fn short_hash(&self) -> &str {
&self.hash[..9]
}
fn date(&self) -> &str {
&self.timestamp[..10]
}
}
fn last_git_commit() -> LastGitCommit {
let output = Command::new("git")
.args(["log", "-1", "--format=%H %cd", "--date=format-local:%Y-%m-%dT%H:%M:%SZ"])
.env("TZ", "UTC")
.output().unwrap();
let parts: Vec<_> = std::str::from_utf8(&output.stdout).unwrap().trim()
.split(' ')
.collect();
assert_eq!(parts.len(), 2, "{:?}", parts);
LastGitCommit {
hash: parts[0].into(),
timestamp: parts[1].into(),
}
}
#[derive(Debug)]
enum GitVersionStatus {
Stable,
Dev,
Dirty,
}
// Stable:
// 1.2.3
//
// Dev:
// 1.2.3-1-g70e989d
// 0c6cf14
//
// Dirty:
// 1.2.3-dirty
// 1.2.3-broken
// 0c6cf14-dirty
// 0c6cf14-broken
fn git_version_status() -> GitVersionStatus {
let o = Command::new("git")
.args(["describe", "--always", "--dirty", "--broken", "--exclude", "snapshot-*"])
.output()
.unwrap();
let o = std::str::from_utf8(&o.stdout).unwrap().trim();
assert!(!o.is_empty());
let re = Regex::new(r#"((?P<ver>^\d+\.\d+\.\d+)|g?[a-zA-Z0-9]{7})(-(?P<dirty>dirty|broken))?$"#).unwrap();
if let Some(caps) = re.captures(o) {
let has_ver = caps.name("ver").is_some();
let dirty = caps.name("dirty").is_some();
match (has_ver, dirty) {
(true, false) => {
assert_eq!(&caps["ver"], env!("CARGO_PKG_VERSION"),
"version in Cargo.toml doesn't match version in Git tag");
GitVersionStatus::Stable
}
(false, false) => GitVersionStatus::Dev,
(_, true) => GitVersionStatus::Dirty,
}
} else {
panic!("couldn't parse git output: {}", o);
}
}
fn main() {
let last_git_commit = last_git_commit();
let git_version_status = git_version_status();
println!("cargo:rustc-env=GIT_HASH={}", last_git_commit.hash);
println!("cargo:rustc-env=GIT_SHORT_HASH={}", last_git_commit.short_hash());
println!("cargo:rustc-env=GIT_TIMESTAMP={}", last_git_commit.timestamp);
println!("cargo:rustc-env=GIT_DATE={}", last_git_commit.date());
println!("cargo:rustc-env=GIT_VERSION_STATUS={:?}", git_version_status);
println!("cargo:rustc-env=BUILD_TARGET={}-{}",
env::var("CARGO_CFG_TARGET_OS").unwrap(),
env::var("CARGO_CFG_TARGET_ARCH").unwrap());
}