geckodriver: new --version flag showing copying info and link to repo (#109)
authorAndreas Tolfsen <ato@mozilla.com>
Thu, 23 Jun 2016 15:52:12 +0100
changeset 359519 794ae7db6d94d760cfaca2ec94485e8f0cffe522
parent 359518 4f82a43ead39600bea1bfd39fe87670d328a10cf
child 359520 9e9c22a94cfe1bda204492ed67c6f74e19900737
push id31854
push userarchaeopteryx@coole-files.de
push dateSat, 20 May 2017 16:46:00 +0000
treeherdermozilla-central@51736db67723 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone55.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
geckodriver: new --version flag showing copying info and link to repo (#109) Fixes #107. Source-Repo: https://github.com/mozilla/geckodriver Source-Revision: d70da21e3c69f73b877df1b7fd0f818890218799 committer: jgraham <james@hoppipolla.co.uk>
testing/geckodriver/Makefile
testing/geckodriver/rust-version
testing/geckodriver/src/main.rs
deleted file mode 100644
--- a/testing/geckodriver/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-all: .version
-
-.version: Cargo.lock
-	grep -E -m1 '^version\s*=\s*"[^"]*"$$' Cargo.lock | grep -Eo '[0-9\.]+' | tr -d '\n' > $@
-
-.PHONY = clean
-clean:
-	rm -f .version
deleted file mode 100644
--- a/testing/geckodriver/rust-version
+++ /dev/null
@@ -1,1 +0,0 @@
-rustc 1.0.0-alpha (44a287e6e 2015-01-08 17:03:40 -0800)
--- a/testing/geckodriver/src/main.rs
+++ b/testing/geckodriver/src/main.rs
@@ -9,81 +9,73 @@ extern crate mozprofile;
 extern crate mozrunner;
 extern crate regex;
 extern crate rustc_serialize;
 #[macro_use]
 extern crate webdriver;
 extern crate zip;
 
 use std::borrow::ToOwned;
-use std::env;
 use std::io::Write;
 use std::net::{SocketAddr, IpAddr};
 use std::path::Path;
-use std::process;
 use std::str::FromStr;
 
 use argparse::{ArgumentParser, IncrBy, StoreTrue, Store};
 use webdriver::server::start;
 
 use marionette::{MarionetteHandler, BrowserLauncher, LogLevel, MarionetteSettings, extension_routes};
 
 macro_rules! try_opt {
     ($expr:expr, $err_type:expr, $err_msg:expr) => ({
         match $expr {
             Some(x) => x,
             None => return Err(WebDriverError::new($err_type, $err_msg))
         }
     })
 }
 
-macro_rules! println_stderr {
-    ($($arg:tt)*) => { {
-        let r = writeln!(&mut ::std::io::stderr(), $($arg)*);
-        r.expect("failed printing to stderr");
-    } }
-}
+mod marionette;
+
+type ProgramResult = std::result::Result<(), (ExitCode, String)>;
 
-macro_rules! err {
-    ($($arg:tt)*) => { {
-        let prog = env::args().next().unwrap();
-        println_stderr!("{}: error: {}", prog, format_args!($($arg)*));
-        process::exit(64);
-    } }
+enum ExitCode {
+    Ok = 0,
+    Usage = 64,
 }
 
-mod marionette;
-
 struct Options {
     binary: String,
     webdriver_host: String,
     webdriver_port: u16,
     marionette_port: u16,
     connect_existing: bool,
     e10s: bool,
     log_level: String,
     verbosity: u8,
+    version: bool,
 }
 
-
 fn parse_args() -> Options {
     let mut opts = Options {
         binary: "".to_owned(),
         webdriver_host: "127.0.0.1".to_owned(),
         webdriver_port: 4444u16,
         marionette_port: 2828u16,
         connect_existing: false,
         e10s: false,
         log_level: "".to_owned(),
         verbosity: 0,
+        version: false,
     };
 
     {
         let mut parser = ArgumentParser::new();
         parser.set_description("WebDriver to Marionette proxy.");
+
         parser.refer(&mut opts.binary)
             .add_option(&["-b", "--binary"], Store,
                         "Path to the Firefox binary");
         parser.refer(&mut opts.webdriver_host)
             .add_option(&["--webdriver-host"], Store,
                         "Host to run webdriver server on");
         parser.refer(&mut opts.webdriver_port)
             .add_option(&["--webdriver-port"], Store,
@@ -102,45 +94,69 @@ fn parse_args() -> Options {
             "Desired verbosity level of Gecko \
             (fatal, error, warn, info, config, debug, trace)")
             .metavar("LEVEL");
         parser.refer(&mut opts.verbosity)
             .add_option(&["-v"], IncrBy(1),
             "Shorthand to increase verbosity of output \
             to include debug messages with -v, \
             and trace messages with -vv");
-        parser.parse_args_or_exit();
-    }
+        parser.refer(&mut opts.version)
+            .add_option(&["--version"], StoreTrue,
+            "Show version and copying information.");
 
-    if opts.binary == "" && !opts.connect_existing {
-        err!("path to browser binary required unless --connect-existing");
+        parser.parse_args_or_exit();
     }
 
     opts
 }
 
-fn main() {
-    env_logger::init().unwrap();
+fn print_version() {
+    let version = option_env!("CARGO_PKG_VERSION").unwrap_or("unknown");
+
+    println!(r#"geckodriver v{}
+https://github.com/mozilla/geckodriver
+
+This program is subject to the terms of the Mozilla Public License 2.0.
+You can obtain a copy of the license at https://mozilla.org/MPL/2.0/."#,
+             version);
+}
+
+fn print_usage(reason: &str) {
+    let prog = std::env::args().next().unwrap();
+    let _ = writeln!(&mut ::std::io::stderr(), "{}: error: {}", prog, reason);
+}
+
+fn run() -> ProgramResult {
     let opts = parse_args();
 
+    if opts.version {
+        print_version();
+        return Ok(())
+    }
+    if opts.binary == "" && !opts.connect_existing {
+        return Err((ExitCode::Usage, "path to browser binary required unless --connect-existing".to_owned()))
+    }
+
     let host = &opts.webdriver_host[..];
     let port = opts.webdriver_port;
-    let addr = IpAddr::from_str(host).map(
-        |x| SocketAddr::new(x, port)).unwrap_or_else(
-        |_| { err!("invalid host address"); });
+    let addr = match IpAddr::from_str(host) {
+        Ok(addr) => SocketAddr::new(addr, port),
+        Err(_) => return Err((ExitCode::Usage, "invalid host address".to_owned())),
+    };
 
     // overrides defaults in Gecko
     // which are info for optimised builds
     // and debug for debug builds
     let log_level = if opts.log_level.len() > 0 && opts.verbosity > 0 {
-        err!("conflicting logging- and verbosity arguments");
+        return Err((ExitCode::Usage, "conflicting logging- and verbosity arguments".to_owned()))
     } else if opts.log_level.len() > 0 {
         match LogLevel::from_str(&opts.log_level) {
             Ok(level) => Some(level),
-            Err(_) => { err!("unknown log level: {}", opts.log_level); },
+            Err(_) => return Err((ExitCode::Usage, format!("unknown log level: {}", opts.log_level))),
         }
     } else {
         match opts.verbosity {
             0 => None,
             1 => Some(LogLevel::Debug),
             _ => Some(LogLevel::Trace),
         }
     };
@@ -154,16 +170,33 @@ fn main() {
 
     let settings = MarionetteSettings {
         port: opts.marionette_port,
         launcher: launcher,
         e10s: opts.e10s,
         log_level: log_level,
     };
     start(addr, MarionetteHandler::new(settings), extension_routes());
+
+    Ok(())
+}
+
+fn main() {
+    let _ = env_logger::init();
+
+    let exit_code = match run() {
+        Ok(_) => ExitCode::Ok,
+        Err((exit_code, reason)) => {
+            print_usage(&reason.to_string());
+            exit_code
+        },
+    };
+
+    std::io::stdout().flush().unwrap();
+    std::process::exit(exit_code as i32);
 }
 
 #[cfg(test)]
 mod tests {
     use std::collections::BTreeMap;
     use marionette::{MarionetteSettings, MarionetteHandler, BrowserLauncher};
     use webdriver::command::NewSessionParameters;
     use rustc_serialize::json::Json;