Bug 1396821 - [geckodriver] Apply rustfmt other geckodriver modules. r=ato
authorHenrik Skupin <mail@hskupin.info>
Wed, 22 Aug 2018 10:28:07 +0200
changeset 432809 559f9bc81c99d8421a6fa75788f2ac55bcf7e3fa
parent 432808 c1df1c2e46f6f3273bce2407fef907a779d491cd
child 432810 2cc9cac00814fa52f5a75d01f7883e11450ebf1e
push id34488
push usernerli@mozilla.com
push dateWed, 22 Aug 2018 16:28:54 +0000
treeherdermozilla-central@d6e4d3e69d4c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersato
bugs1396821
milestone63.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
Bug 1396821 - [geckodriver] Apply rustfmt other geckodriver modules. r=ato MozReview-Commit-ID: IW15TkjVeLT
testing/geckodriver/src/capabilities.rs
testing/geckodriver/src/logging.rs
testing/geckodriver/src/main.rs
--- a/testing/geckodriver/src/capabilities.rs
+++ b/testing/geckodriver/src/capabilities.rs
@@ -6,19 +6,19 @@ use mozprofile::profile::Profile;
 use mozrunner::runner::platform::firefox_default_path;
 use mozversion::{self, firefox_version, Version};
 use regex::bytes::Regex;
 use serde_json::{Map, Value};
 use std::collections::BTreeMap;
 use std::default::Default;
 use std::error::Error;
 use std::fs;
+use std::io;
 use std::io::BufWriter;
 use std::io::Cursor;
-use std::io;
 use std::path::{Path, PathBuf};
 use std::process::{Command, Stdio};
 use std::str::{self, FromStr};
 use webdriver::capabilities::{BrowserCapabilities, Capabilities};
 use webdriver::error::{ErrorStatus, WebDriverError, WebDriverResult};
 use zip;
 
 /// Provides matching of `moz:firefoxOptions` and resolution of which Firefox
@@ -29,17 +29,16 @@ use zip;
 /// system Firefox installation or an override, for example given to the
 /// `--binary` flag of geckodriver.
 pub struct FirefoxCapabilities<'a> {
     pub chosen_binary: Option<PathBuf>,
     fallback_binary: Option<&'a PathBuf>,
     version_cache: BTreeMap<PathBuf, String>,
 }
 
-
 impl<'a> FirefoxCapabilities<'a> {
     pub fn new(fallback_binary: Option<&'a PathBuf>) -> FirefoxCapabilities<'a> {
         FirefoxCapabilities {
             chosen_binary: None,
             fallback_binary: fallback_binary,
             version_cache: BTreeMap::new(),
         }
     }
@@ -64,52 +63,54 @@ impl<'a> FirefoxCapabilities<'a> {
                 .ok()
                 .and_then(|x| x.version_string)
                 .or_else(|| {
                     debug!("Trying to read firefox version from binary");
                     self.version_from_binary(binary)
                 });
             if let Some(ref version) = rv {
                 debug!("Found version {}", version);
-                self.version_cache
-                    .insert(binary.clone(), version.clone());
+                self.version_cache.insert(binary.clone(), version.clone());
             } else {
                 debug!("Failed to get binary version");
             }
             rv
         } else {
             None
         }
     }
 
     fn version_from_binary(&self, binary: &PathBuf) -> Option<String> {
-        let version_regexp = Regex::new(r#"\d+\.\d+(?:[a-z]\d+)?"#).expect("Error parsing version regexp");
+        let version_regexp =
+            Regex::new(r#"\d+\.\d+(?:[a-z]\d+)?"#).expect("Error parsing version regexp");
         let output = Command::new(binary)
             .args(&["-version"])
             .stdout(Stdio::piped())
             .spawn()
             .and_then(|child| child.wait_with_output())
             .ok();
 
         if let Some(x) = output {
-            version_regexp.captures(&*x.stdout)
+            version_regexp
+                .captures(&*x.stdout)
                 .and_then(|captures| captures.get(0))
                 .and_then(|m| str::from_utf8(m.as_bytes()).ok())
                 .map(|x| x.into())
         } else {
             None
         }
     }
 }
 
 // TODO: put this in webdriver-rust
 fn convert_version_error(err: mozversion::Error) -> WebDriverError {
     WebDriverError::new(
         ErrorStatus::SessionNotCreated,
-        err.description().to_string())
+        err.description().to_string(),
+    )
 }
 
 impl<'a> BrowserCapabilities for FirefoxCapabilities<'a> {
     fn init(&mut self, capabilities: &Capabilities) {
         self.set_binary(capabilities);
     }
 
     fn browser_name(&mut self, _: &Capabilities) -> WebDriverResult<Option<String>> {
@@ -117,18 +118,18 @@ impl<'a> BrowserCapabilities for Firefox
     }
 
     fn browser_version(&mut self, _: &Capabilities) -> WebDriverResult<Option<String>> {
         Ok(self.version())
     }
 
     fn platform_name(&mut self, _: &Capabilities) -> WebDriverResult<Option<String>> {
         Ok(if cfg!(target_os = "windows") {
-               Some("windows".into())
-           } else if cfg!(target_os = "macos") {
+            Some("windows".into())
+        } else if cfg!(target_os = "macos") {
             Some("mac".into())
         } else if cfg!(target_os = "linux") {
             Some("linux".into())
         } else {
             None
         })
     }
 
@@ -140,120 +141,149 @@ impl<'a> BrowserCapabilities for Firefox
             Ok(false)
         }
     }
 
     fn set_window_rect(&mut self, _: &Capabilities) -> WebDriverResult<bool> {
         Ok(true)
     }
 
-    fn compare_browser_version(&mut self,
-                               version: &str,
-                               comparison: &str)
-                               -> WebDriverResult<bool> {
+    fn compare_browser_version(
+        &mut self,
+        version: &str,
+        comparison: &str,
+    ) -> WebDriverResult<bool> {
         try!(Version::from_str(version).or_else(|x| Err(convert_version_error(x))))
             .matches(comparison)
             .or_else(|x| Err(convert_version_error(x)))
     }
 
     fn accept_proxy(&mut self, _: &Capabilities, _: &Capabilities) -> WebDriverResult<bool> {
         Ok(true)
     }
 
-    fn validate_custom(&self, name: &str,  value: &Value) -> WebDriverResult<()> {
+    fn validate_custom(&self, name: &str, value: &Value) -> WebDriverResult<()> {
         if !name.starts_with("moz:") {
-            return Ok(())
+            return Ok(());
         }
         match name {
             "moz:firefoxOptions" => {
-                let data = try_opt!(value.as_object(),
-                                    ErrorStatus::InvalidArgument,
-                                    "moz:firefoxOptions is not an object");
+                let data = try_opt!(
+                    value.as_object(),
+                    ErrorStatus::InvalidArgument,
+                    "moz:firefoxOptions is not an object"
+                );
                 for (key, value) in data.iter() {
                     match &**key {
                         "binary" => {
                             if !value.is_string() {
                                 return Err(WebDriverError::new(
                                     ErrorStatus::InvalidArgument,
-                                         "binary path is not a string"));
+                                    "binary path is not a string",
+                                ));
                             }
-                        },
+                        }
                         "args" => {
-                            if !try_opt!(value.as_array(),
-                                         ErrorStatus::InvalidArgument,
-                                         "args is not an array")
-                                .iter()
-                                .all(|value| value.is_string()) {
+                            if !try_opt!(
+                                value.as_array(),
+                                ErrorStatus::InvalidArgument,
+                                "args is not an array"
+                            ).iter()
+                                .all(|value| value.is_string())
+                            {
                                 return Err(WebDriverError::new(
                                     ErrorStatus::InvalidArgument,
-                                         "args entry is not a string"));
-                                }
-                        },
+                                    "args entry is not a string",
+                                ));
+                            }
+                        }
                         "profile" => {
                             if !value.is_string() {
                                 return Err(WebDriverError::new(
                                     ErrorStatus::InvalidArgument,
-                                         "profile is not a string"));
+                                    "profile is not a string",
+                                ));
                             }
-                        },
+                        }
                         "log" => {
-                            let log_data = try_opt!(value.as_object(),
-                                                    ErrorStatus::InvalidArgument,
-                                                    "log value is not an object");
+                            let log_data = try_opt!(
+                                value.as_object(),
+                                ErrorStatus::InvalidArgument,
+                                "log value is not an object"
+                            );
                             for (log_key, log_value) in log_data.iter() {
                                 match &**log_key {
                                     "level" => {
-                                        let level = try_opt!(log_value.as_str(),
-                                                             ErrorStatus::InvalidArgument,
-                                                             "log level is not a string");
+                                        let level = try_opt!(
+                                            log_value.as_str(),
+                                            ErrorStatus::InvalidArgument,
+                                            "log level is not a string"
+                                        );
                                         if Level::from_str(level).is_err() {
                                             return Err(WebDriverError::new(
                                                 ErrorStatus::InvalidArgument,
-                                                format!("Not a valid log level: {}", level)))
+                                                format!("Not a valid log level: {}", level),
+                                            ));
                                         }
                                     }
-                                    x => return Err(WebDriverError::new(
-                                        ErrorStatus::InvalidArgument,
-                                        format!("Invalid log field {}", x)))
+                                    x => {
+                                        return Err(WebDriverError::new(
+                                            ErrorStatus::InvalidArgument,
+                                            format!("Invalid log field {}", x),
+                                        ))
+                                    }
                                 }
                             }
-                        },
+                        }
                         "prefs" => {
-                            let prefs_data = try_opt!(value.as_object(),
-                                                    ErrorStatus::InvalidArgument,
-                                                    "prefs value is not an object");
-                            if !prefs_data.values()
-                                .all(|x| x.is_string() || x.is_i64() || x.is_u64() || x.is_boolean()) {
-                                    return Err(WebDriverError::new(
-                                        ErrorStatus::InvalidArgument,
-                                        "Preference values not all string or integer or boolean"));
-                                }
+                            let prefs_data = try_opt!(
+                                value.as_object(),
+                                ErrorStatus::InvalidArgument,
+                                "prefs value is not an object"
+                            );
+                            if !prefs_data.values().all(|x| {
+                                x.is_string() || x.is_i64() || x.is_u64() || x.is_boolean()
+                            }) {
+                                return Err(WebDriverError::new(
+                                    ErrorStatus::InvalidArgument,
+                                    "Preference values not all string or integer or boolean",
+                                ));
+                            }
                         }
-                        x => return Err(WebDriverError::new(
-                            ErrorStatus::InvalidArgument,
-                            format!("Invalid moz:firefoxOptions field {}", x)))
+                        x => {
+                            return Err(WebDriverError::new(
+                                ErrorStatus::InvalidArgument,
+                                format!("Invalid moz:firefoxOptions field {}", x),
+                            ))
+                        }
                     }
                 }
             }
             "moz:useNonSpecCompliantPointerOrigin" => {
                 if !value.is_boolean() {
                     return Err(WebDriverError::new(
                         ErrorStatus::InvalidArgument,
-                        "moz:useNonSpecCompliantPointerOrigin is not a boolean"));
+                        "moz:useNonSpecCompliantPointerOrigin is not a boolean",
+                    ));
                 }
             }
             "moz:webdriverClick" => {
                 if !value.is_boolean() {
                     return Err(WebDriverError::new(
                         ErrorStatus::InvalidArgument,
-                        "moz:webdriverClick is not a boolean"));
+                        "moz:webdriverClick is not a boolean",
+                    ));
                 }
             }
-            _ => return Err(WebDriverError::new(ErrorStatus::InvalidArgument,
-                                                format!("Unrecognised option {}", name)))
+            _ => {
+                return Err(WebDriverError::new(
+                    ErrorStatus::InvalidArgument,
+                    format!("Unrecognised option {}", name),
+                ))
+            }
         }
         Ok(())
     }
 
     fn accept_custom(&mut self, _: &str, _: &Value, _: &Capabilities) -> WebDriverResult<bool> {
         Ok(true)
     }
 }
@@ -273,75 +303,82 @@ pub struct FirefoxOptions {
     pub prefs: Vec<(String, Pref)>,
 }
 
 impl FirefoxOptions {
     pub fn new() -> FirefoxOptions {
         Default::default()
     }
 
-    pub fn from_capabilities(binary_path: Option<PathBuf>,
-                             matched: &mut Capabilities)
-                             -> WebDriverResult<FirefoxOptions> {
+    pub fn from_capabilities(
+        binary_path: Option<PathBuf>,
+        matched: &mut Capabilities,
+    ) -> WebDriverResult<FirefoxOptions> {
         let mut rv = FirefoxOptions::new();
         rv.binary = binary_path;
 
         if let Some(json) = matched.remove("moz:firefoxOptions") {
-            let options = try!(json.as_object()
-                                   .ok_or(WebDriverError::new(ErrorStatus::InvalidArgument,
-                                                              "'moz:firefoxOptions' \
-                                                               capability is not an object")));
+            let options = try!(json.as_object().ok_or(WebDriverError::new(
+                ErrorStatus::InvalidArgument,
+                "'moz:firefoxOptions' \
+                 capability is not an object"
+            )));
 
             rv.profile = try!(FirefoxOptions::load_profile(&options));
             rv.args = try!(FirefoxOptions::load_args(&options));
             rv.log = try!(FirefoxOptions::load_log(&options));
             rv.prefs = try!(FirefoxOptions::load_prefs(&options));
         }
 
         Ok(rv)
     }
 
     fn load_profile(options: &Capabilities) -> WebDriverResult<Option<Profile>> {
         if let Some(profile_json) = options.get("profile") {
-            let profile_base64 =
-                try!(profile_json
-                         .as_str()
-                         .ok_or(WebDriverError::new(ErrorStatus::UnknownError,
-                                                    "Profile is not a string")));
+            let profile_base64 = try!(profile_json.as_str().ok_or(WebDriverError::new(
+                ErrorStatus::UnknownError,
+                "Profile is not a string"
+            )));
             let profile_zip = &*try!(base64::decode(profile_base64));
 
             // Create an emtpy profile directory
             let profile = try!(Profile::new(None));
-            try!(unzip_buffer(profile_zip,
-                              profile
-                                  .temp_dir
-                                  .as_ref()
-                                  .expect("Profile doesn't have a path")
-                                  .path()));
+            try!(unzip_buffer(
+                profile_zip,
+                profile
+                    .temp_dir
+                    .as_ref()
+                    .expect("Profile doesn't have a path")
+                    .path()
+            ));
 
             Ok(Some(profile))
         } else {
             Ok(None)
         }
     }
 
     fn load_args(options: &Capabilities) -> WebDriverResult<Option<Vec<String>>> {
         if let Some(args_json) = options.get("args") {
-            let args_array = try!(args_json
-                                      .as_array()
-                                      .ok_or(WebDriverError::new(ErrorStatus::UnknownError,
-                                                                 "Arguments were not an \
-                                                                  array")));
-            let args = try!(args_array
-                                .iter()
-                                .map(|x| x.as_str().map(|x| x.to_owned()))
-                                .collect::<Option<Vec<String>>>()
-                                .ok_or(WebDriverError::new(ErrorStatus::UnknownError,
-                                                           "Arguments entries were not all \
-                                                            strings")));
+            let args_array = try!(args_json.as_array().ok_or(WebDriverError::new(
+                ErrorStatus::UnknownError,
+                "Arguments were not an \
+                 array"
+            )));
+            let args = try!(
+                args_array
+                    .iter()
+                    .map(|x| x.as_str().map(|x| x.to_owned()))
+                    .collect::<Option<Vec<String>>>()
+                    .ok_or(WebDriverError::new(
+                        ErrorStatus::UnknownError,
+                        "Arguments entries were not all \
+                         strings"
+                    ))
+            );
             Ok(Some(args))
         } else {
             Ok(None)
         }
     }
 
     fn load_log(options: &Capabilities) -> WebDriverResult<LogOptions> {
         if let Some(json) = options.get("log") {
@@ -367,51 +404,55 @@ impl FirefoxOptions {
             Ok(LogOptions { level })
         } else {
             Ok(Default::default())
         }
     }
 
     pub fn load_prefs(options: &Capabilities) -> WebDriverResult<Vec<(String, Pref)>> {
         if let Some(prefs_data) = options.get("prefs") {
-            let prefs = try!(prefs_data
-                                 .as_object()
-                                 .ok_or(WebDriverError::new(ErrorStatus::UnknownError,
-                                                            "Prefs were not an object")));
+            let prefs = try!(prefs_data.as_object().ok_or(WebDriverError::new(
+                ErrorStatus::UnknownError,
+                "Prefs were not an object"
+            )));
             let mut rv = Vec::with_capacity(prefs.len());
             for (key, value) in prefs.iter() {
                 rv.push((key.clone(), try!(pref_from_json(value))));
             }
             Ok(rv)
         } else {
             Ok(vec![])
         }
     }
 }
 
 fn pref_from_json(value: &Value) -> WebDriverResult<Pref> {
     match value {
         &Value::String(ref x) => Ok(Pref::new(x.clone())),
         &Value::Number(ref x) => Ok(Pref::new(x.as_i64().unwrap())),
         &Value::Bool(x) => Ok(Pref::new(x)),
-        _ => Err(WebDriverError::new(ErrorStatus::UnknownError,
-                                     "Could not convert pref value to string, boolean, or integer"))
+        _ => Err(WebDriverError::new(
+            ErrorStatus::UnknownError,
+            "Could not convert pref value to string, boolean, or integer",
+        )),
     }
 }
 
 fn unzip_buffer(buf: &[u8], dest_dir: &Path) -> WebDriverResult<()> {
     let reader = Cursor::new(buf);
-    let mut zip = try!(zip::ZipArchive::new(reader).map_err(|_| {
-        WebDriverError::new(ErrorStatus::UnknownError, "Failed to unzip profile")
-    }));
+    let mut zip = try!(
+        zip::ZipArchive::new(reader)
+            .map_err(|_| WebDriverError::new(ErrorStatus::UnknownError, "Failed to unzip profile"))
+    );
 
     for i in 0..zip.len() {
-        let mut file = try!(zip.by_index(i).map_err(|_| {
-            WebDriverError::new(ErrorStatus::UnknownError, "Processing profile zip file failed")
-        }));
+        let mut file = try!(zip.by_index(i).map_err(|_| WebDriverError::new(
+            ErrorStatus::UnknownError,
+            "Processing profile zip file failed"
+        )));
         let unzip_path = {
             let name = file.name();
             let is_dir = name.ends_with("/");
             let rel_path = Path::new(name);
             let dest_path = dest_dir.join(rel_path);
 
             {
                 let create_dir = if is_dir {
@@ -481,18 +522,20 @@ mod tests {
         firefox_opts.insert("profile".into(), encoded_profile);
 
         let opts = make_options(firefox_opts);
         let mut profile = opts.profile.unwrap();
         let prefs = profile.user_prefs().unwrap();
 
         println!("{:#?}", prefs.prefs);
 
-        assert_eq!(prefs.get("startup.homepage_welcome_url"),
-                   Some(&Pref::new("data:text/html,PASS")));
+        assert_eq!(
+            prefs.get("startup.homepage_welcome_url"),
+            Some(&Pref::new("data:text/html,PASS"))
+        );
     }
 
     #[test]
     fn test_prefs() {
         let encoded_profile = example_profile();
         let mut prefs: Map<String, Value> = Map::new();
         prefs.insert(
             "browser.display.background_color".into(),
--- a/testing/geckodriver/src/logging.rs
+++ b/testing/geckodriver/src/logging.rs
@@ -274,17 +274,20 @@ mod tests {
             (Level::Warn, "Warn"),
             (Level::Info, "Info"),
             (Level::Config, "Config"),
             (Level::Debug, "Debug"),
             (Level::Trace, "Trace"),
         ];
 
         for &(lvl, s) in tests.iter() {
-            let expected = Pref { value: PrefValue::String(s.to_string()), sticky: false };
+            let expected = Pref {
+                value: PrefValue::String(s.to_string()),
+                sticky: false,
+            };
             assert_eq!(Into::<Pref>::into(lvl), expected);
         }
     }
 
     #[test]
     fn test_level_from_str() {
         assert_eq!(Level::from_str("fatal"), Ok(Level::Fatal));
         assert_eq!(Level::from_str("error"), Ok(Level::Error));
--- a/testing/geckodriver/src/main.rs
+++ b/testing/geckodriver/src/main.rs
@@ -9,49 +9,49 @@ extern crate mozprofile;
 extern crate mozrunner;
 extern crate mozversion;
 extern crate regex;
 extern crate serde;
 #[macro_use]
 extern crate serde_derive;
 extern crate serde_json;
 extern crate uuid;
+extern crate webdriver;
 extern crate zip;
-extern crate webdriver;
 
 #[macro_use]
 extern crate log;
 
 use std::io::Write;
 use std::net::{IpAddr, SocketAddr};
 use std::path::PathBuf;
 use std::str::FromStr;
 
 use clap::{App, Arg};
 
 macro_rules! try_opt {
-    ($expr:expr, $err_type:expr, $err_msg:expr) => ({
+    ($expr:expr, $err_type:expr, $err_msg:expr) => {{
         match $expr {
             Some(x) => x,
-            None => return Err(WebDriverError::new($err_type, $err_msg))
+            None => return Err(WebDriverError::new($err_type, $err_msg)),
         }
-    })
+    }};
 }
 
 mod build;
+mod capabilities;
 mod logging;
+mod marionette;
 mod prefs;
-mod marionette;
-mod capabilities;
 
 #[cfg(test)]
 pub mod test;
 
 use build::BuildInfo;
-use marionette::{MarionetteHandler, MarionetteSettings, extension_routes};
+use marionette::{extension_routes, MarionetteHandler, MarionetteSettings};
 
 type ProgramResult = std::result::Result<(), (ExitCode, String)>;
 
 enum ExitCode {
     Ok = 0,
     Usage = 64,
     Unavailable = 69,
 }
@@ -64,62 +64,80 @@ fn print_version() {
     println!("");
     println!("This program is subject to the terms of the Mozilla Public License 2.0.");
     println!("You can obtain a copy of the license at https://mozilla.org/MPL/2.0/.");
 }
 
 fn app<'a, 'b>() -> App<'a, 'b> {
     App::new(format!("geckodriver {}", crate_version!()))
         .about("WebDriver implementation for Firefox.")
-        .arg(Arg::with_name("webdriver_host")
-            .long("host")
-            .value_name("HOST")
-            .help("Host ip to use for WebDriver server (default: 127.0.0.1)")
-            .takes_value(true))
-        .arg(Arg::with_name("webdriver_port")
-            .short("p")
-            .long("port")
-            .value_name("PORT")
-            .help("Port to use for WebDriver server (default: 4444)")
-            .takes_value(true)
-            .alias("webdriver-port"))
-        .arg(Arg::with_name("binary")
-            .short("b")
-            .long("binary")
-            .value_name("BINARY")
-            .help("Path to the Firefox binary")
-            .takes_value(true))
-        .arg(Arg::with_name("marionette_port")
-            .long("marionette-port")
-            .value_name("PORT")
-            .help("Port to use to connect to Gecko (default: random free port)")
-            .takes_value(true))
-        .arg(Arg::with_name("connect_existing")
-            .long("connect-existing")
-            .requires("marionette_port")
-            .help("Connect to an existing Firefox instance"))
-        .arg(Arg::with_name("jsdebugger")
-            .long("jsdebugger")
-            .takes_value(false)
-            .help("Attach browser toolbox debugger for Firefox"))
-        .arg(Arg::with_name("verbosity")
-            .short("v")
-            .multiple(true)
-            .conflicts_with("log_level")
-            .help("Log level verbosity (-v for debug and -vv for trace level)"))
-        .arg(Arg::with_name("log_level")
-            .long("log")
-            .takes_value(true)
-            .value_name("LEVEL")
-            .possible_values(&["fatal", "error", "warn", "info", "config", "debug", "trace"])
-            .help("Set Gecko log level"))
-        .arg(Arg::with_name("version")
-            .short("V")
-            .long("version")
-            .help("Prints version and copying information"))
+        .arg(
+            Arg::with_name("webdriver_host")
+                .long("host")
+                .value_name("HOST")
+                .help("Host ip to use for WebDriver server (default: 127.0.0.1)")
+                .takes_value(true),
+        )
+        .arg(
+            Arg::with_name("webdriver_port")
+                .short("p")
+                .long("port")
+                .value_name("PORT")
+                .help("Port to use for WebDriver server (default: 4444)")
+                .takes_value(true)
+                .alias("webdriver-port"),
+        )
+        .arg(
+            Arg::with_name("binary")
+                .short("b")
+                .long("binary")
+                .value_name("BINARY")
+                .help("Path to the Firefox binary")
+                .takes_value(true),
+        )
+        .arg(
+            Arg::with_name("marionette_port")
+                .long("marionette-port")
+                .value_name("PORT")
+                .help("Port to use to connect to Gecko (default: random free port)")
+                .takes_value(true),
+        )
+        .arg(
+            Arg::with_name("connect_existing")
+                .long("connect-existing")
+                .requires("marionette_port")
+                .help("Connect to an existing Firefox instance"),
+        )
+        .arg(
+            Arg::with_name("jsdebugger")
+                .long("jsdebugger")
+                .takes_value(false)
+                .help("Attach browser toolbox debugger for Firefox"),
+        )
+        .arg(
+            Arg::with_name("verbosity")
+                .short("v")
+                .multiple(true)
+                .conflicts_with("log_level")
+                .help("Log level verbosity (-v for debug and -vv for trace level)"),
+        )
+        .arg(
+            Arg::with_name("log_level")
+                .long("log")
+                .takes_value(true)
+                .value_name("LEVEL")
+                .possible_values(&["fatal", "error", "warn", "info", "config", "debug", "trace"])
+                .help("Set Gecko log level"),
+        )
+        .arg(
+            Arg::with_name("version")
+                .short("V")
+                .long("version")
+                .help("Prints version and copying information"),
+        )
 }
 
 fn run() -> ProgramResult {
     let matches = app().get_matches();
 
     if matches.is_present("version") {
         print_version();
         return Ok(());
@@ -138,22 +156,20 @@ fn run() -> ProgramResult {
     let addr = match IpAddr::from_str(host) {
         Ok(addr) => SocketAddr::new(addr, port),
         Err(_) => return Err((ExitCode::Usage, "invalid host address".into())),
     };
 
     let binary = matches.value_of("binary").map(|x| PathBuf::from(x));
 
     let marionette_port = match matches.value_of("marionette_port") {
-        Some(x) => {
-            match u16::from_str(x) {
-                Ok(x) => Some(x),
-                Err(_) => return Err((ExitCode::Usage, "invalid Marionette port".into())),
-            }
-        }
+        Some(x) => match u16::from_str(x) {
+            Ok(x) => Some(x),
+            Err(_) => return Err((ExitCode::Usage, "invalid Marionette port".into())),
+        },
         None => None,
     };
 
     let log_level = if matches.is_present("log_level") {
         logging::Level::from_str(matches.value_of("log_level").unwrap()).ok()
     } else {
         match matches.occurrences_of("verbosity") {
             0 => Some(logging::Level::Info),