Bug 1727276 [wpt PR 30149] - Update wpt metadata, a=testonly
[gecko.git] / testing / geckodriver / build.rs
blob2fca20dd231a50247cdfd05158165d2f4f218ef7
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:
7 //
8 // ```no_run
9 // const COMMIT_HASH: Option<&'static str> = Some("c31a366");
10 // const COMMIT_DATE: Option<&'static str> = Some("1988-05-10");
11 // ```
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.
16 use std::env;
17 use std::ffi::OsStr;
18 use std::fs::File;
19 use std::io;
20 use std::io::Write;
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"))?;
30     writeln!(
31         fh,
32         "const COMMIT_HASH: Option<&'static str> = {:?};",
33         build_info.hash()
34     )?;
35     writeln!(
36         fh,
37         "const COMMIT_DATE: Option<&'static str> = {:?};",
38         build_info.date()
39     )?;
41     Ok(())
44 fn get_build_info(dir: &Path) -> Box<dyn BuildInfo> {
45     if Path::exists(&dir.join(".hg")) {
46         Box::new(Hg {})
47     } else if Path::exists(&dir.join(".git")) {
48         Box::new(Git {})
49     } else if let Some(parent) = dir.parent() {
50         get_build_info(parent)
51     } else {
52         eprintln!("unable to detect vcs");
53         Box::new(Noop {})
54     }
57 trait BuildInfo {
58     fn hash(&self) -> Option<String>;
59     fn date(&self) -> Option<String>;
62 struct Hg;
64 impl Hg {
65     fn exec<I, S>(&self, args: I) -> Option<String>
66     where
67         I: IntoIterator<Item = S>,
68         S: AsRef<OsStr>,
69     {
70         Command::new("hg")
71             .env("HGPLAIN", "1")
72             .args(args)
73             .output()
74             .ok()
75             .and_then(|r| String::from_utf8(r.stdout).ok())
76             .map(|s| s.trim_end().into())
77     }
80 impl BuildInfo for Hg {
81     fn hash(&self) -> Option<String> {
82         self.exec(&["log", "-r.", "-T{node|short}"])
83     }
85     fn date(&self) -> Option<String> {
86         self.exec(&["log", "-r.", "-T{date|isodate}"])
87     }
90 struct Git;
92 impl Git {
93     fn exec<I, S>(&self, args: I) -> Option<String>
94     where
95         I: IntoIterator<Item = S>,
96         S: AsRef<OsStr>,
97     {
98         Command::new("git")
99             .env("GIT_CONFIG_NOSYSTEM", "1")
100             .args(args)
101             .output()
102             .ok()
103             .and_then(|r| String::from_utf8(r.stdout).ok())
104             .map(|s| s.trim_end().into())
105     }
107     fn to_hg_sha(&self, git_sha: String) -> Option<String> {
108         self.exec(&["cinnabar", "git2hg", &git_sha])
109     }
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))
116             .map(|mut s| {
117                 s.truncate(12);
118                 s
119             })
120     }
122     fn date(&self) -> Option<String> {
123         self.exec(&["log", "-1", "--date=short", "--pretty=format:%cd"])
124     }
127 struct Noop;
129 impl BuildInfo for Noop {
130     fn hash(&self) -> Option<String> {
131         None
132     }
133     fn date(&self) -> Option<String> {
134         None
135     }