1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 // Writes build information to ${OUT_DIR}/build-info.rs which is included in
6 // the program during compilation:
9 // const COMMIT_HASH: Option<&'static str> = Some("c31a366");
10 // const COMMIT_DATE: Option<&'static str> = Some("1988-05-10");
13 // The values are `None` if running hg failed, e.g. if it is not installed or
14 // if we are not in an hg repo.
21 use std::path::{Path, PathBuf};
22 use std::process::Command;
24 fn main() -> io::Result<()> {
25 let cur_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
26 let build_info = get_build_info(&cur_dir);
28 let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
29 let mut fh = File::create(out_dir.join("build-info.rs"))?;
32 "const COMMIT_HASH: Option<&'static str> = {:?};",
37 "const COMMIT_DATE: Option<&'static str> = {:?};",
44 fn get_build_info(dir: &Path) -> Box<dyn BuildInfo> {
45 if Path::exists(&dir.join(".hg")) {
47 } else if Path::exists(&dir.join(".git")) {
49 } else if let Some(parent) = dir.parent() {
50 get_build_info(parent)
52 eprintln!("unable to detect vcs");
58 fn hash(&self) -> Option<String>;
59 fn date(&self) -> Option<String>;
65 fn exec<I, S>(&self, args: I) -> Option<String>
67 I: IntoIterator<Item = S>,
75 .and_then(|r| String::from_utf8(r.stdout).ok())
76 .map(|s| s.trim_end().into())
80 impl BuildInfo for Hg {
81 fn hash(&self) -> Option<String> {
82 self.exec(["log", "-r.", "-T{node|short}"])
85 fn date(&self) -> Option<String> {
86 self.exec(["log", "-r.", "-T{date|isodate}"])
93 fn exec<I, S>(&self, args: I) -> Option<String>
95 I: IntoIterator<Item = S>,
99 .env("GIT_CONFIG_NOSYSTEM", "1")
103 .and_then(|r| String::from_utf8(r.stdout).ok())
104 .map(|s| s.trim_end().into())
107 fn to_hg_sha(&self, git_sha: String) -> Option<String> {
108 self.exec(["cinnabar", "git2hg", &git_sha])
112 impl BuildInfo for Git {
113 fn hash(&self) -> Option<String> {
114 self.exec(["rev-parse", "HEAD"])
115 .and_then(|sha| self.to_hg_sha(sha))
122 fn date(&self) -> Option<String> {
123 self.exec(["log", "-1", "--date=short", "--pretty=format:%cd"])
129 impl BuildInfo for Noop {
130 fn hash(&self) -> Option<String> {
133 fn date(&self) -> Option<String> {