From 4a968ad6793c289598cef41b515d24f1e61974ed Mon Sep 17 00:00:00 2001 From: Andreas Tolfsen Date: Thu, 22 Jun 2017 16:28:18 +0100 Subject: [PATCH] Bug 1375207 - Display hash from whence geckodriver came in --version; r=jgraham Because we no longer can tag geckodriver releases in mozilla-central, we need to include build information in the program itself. In the version information message displayed when passing the --version flag, we now include the current tip's SHA1 and build date following the version number. This patch could be made simpler by dumping this information correctly formatted into a text file in the output directory, but it was requested in https://bugzilla.mozilla.org/show_bug.cgi?id=1374977 to also include the version information in the log output, which means we need to access it differently and in different places. MozReview-Commit-ID: CbFQn7IV8ew --HG-- extra : rebase_source : dcc38ba7b5f209e9878755d5d75b611e22b5253d --- testing/geckodriver/build.rs | 73 +++++++++++++++++++++++++++++++++ testing/geckodriver/src/main.rs | 35 +++++++++++++++- 2 files changed, 106 insertions(+), 2 deletions(-) create mode 100644 testing/geckodriver/build.rs diff --git a/testing/geckodriver/build.rs b/testing/geckodriver/build.rs new file mode 100644 index 000000000000..a65d19d991e4 --- /dev/null +++ b/testing/geckodriver/build.rs @@ -0,0 +1,73 @@ +/// Writes build information to ${OUT_DIR}/build-info.rs which is included in +/// the program during compilation: +/// +/// ```no_run +/// const COMMIT_HASH: Option<&'static str> = Some("c31a366"); +/// const COMMIT_DATE: Option<&'static str> = Some("1988-05-10"); +/// ``` +/// +/// The values are `None` if running hg failed, e.g. if it is not installed or +/// if we are not in an hg repo. + +use std::env; +use std::ffi::OsStr; +use std::fs::File; +use std::io::Write; +use std::path::PathBuf; +use std::process::Command; + +fn main() { + let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap()); + let mut fh = File::create(out_dir.join("build-info.rs")).unwrap(); + writeln!( + fh, + "const COMMIT_HASH: Option<&'static str> = {:?};", + commit_hash() + ).unwrap(); + writeln!( + fh, + "const COMMIT_DATE: Option<&'static str> = {:?};", + commit_date() + ).unwrap(); +} + +fn commit_hash() -> Option { + exec(&"hg", &["log", "-r.", "-T '{node|short}'"]).or_else( + || { + exec(&"git", &["rev-parse", "HEAD"]).and_then(hg2git_sha) + }, + ) +} + +fn commit_date() -> Option { + exec(&"hg", &["log", "-r.", "-T '{date|isodate}'"]).or_else(|| { + exec( + &"git", + &["log", "-1", "--date=short", "--pretty=format:%cd"], + ) + }) +} + +fn exec(program: S, args: I) -> Option +where + S: AsRef, + I: IntoIterator, +{ + let mut cmd = Command::new(program); + for arg in args { + cmd.arg(arg.as_ref()); + } + cmd.output() + .ok() + .and_then(|r| if r.status.success() { + Some(r.stdout) + } else { + None + }) + .and_then(|o| String::from_utf8(o).ok()) + .map(|s| s.trim_right().into()) +} + +fn hg2git_sha(hg_sha: String) -> Option { + exec(&"git", &["cinnabar", "git2hg", &hg_sha]) +} diff --git a/testing/geckodriver/src/main.rs b/testing/geckodriver/src/main.rs index 518b50e151f3..296bc52c0f7e 100644 --- a/testing/geckodriver/src/main.rs +++ b/testing/geckodriver/src/main.rs @@ -21,8 +21,10 @@ extern crate webdriver; extern crate log; use std::borrow::ToOwned; +use std::fmt; +use std::fmt::Display; use std::io::Write; -use std::net::{SocketAddr, IpAddr}; +use std::net::{IpAddr, SocketAddr}; use std::path::PathBuf; use std::str::FromStr; @@ -45,6 +47,35 @@ mod capabilities; use logging::LogLevel; use marionette::{MarionetteHandler, MarionetteSettings, extension_routes}; +include!(concat!(env!("OUT_DIR"), "/build-info.rs")); + +struct BuildInfo; +impl BuildInfo { + pub fn version() -> &'static str { + crate_version!() + } + + pub fn hash() -> Option<&'static str> { + COMMIT_HASH + } + + pub fn date() -> Option<&'static str> { + COMMIT_DATE + } +} + +impl Display for BuildInfo { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", BuildInfo::version())?; + match (BuildInfo::hash(), BuildInfo::date()) { + (Some(hash), Some(date)) => write!(f, " ({} {})", hash, date)?, + (Some(hash), None) => write!(f, " ({})", hash)?, + _ => {}, + } + Ok(()) + } +} + type ProgramResult = std::result::Result<(), (ExitCode, String)>; enum ExitCode { @@ -104,7 +135,7 @@ fn run() -> ProgramResult { let matches = app().get_matches(); if matches.is_present("version") { - println!("geckodriver {}\n\n{}", crate_version!(), + println!("geckodriver {}\n\n{}", BuildInfo, "The source code of this program is available at https://github.com/mozilla/geckodriver.