mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 19:04:45 +00:00
Bug 1396821 - [geckodriver] Apply rustfmt other geckodriver modules. r=ato
MozReview-Commit-ID: IW15TkjVeLT --HG-- extra : rebase_source : 12f26d848d34f979a696191eb2fe1eeb8835019b
This commit is contained in:
parent
35d04474d0
commit
1fc0887dc1
@ -11,9 +11,9 @@ 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};
|
||||
@ -34,7 +34,6 @@ pub struct FirefoxCapabilities<'a> {
|
||||
version_cache: BTreeMap<PathBuf, String>,
|
||||
}
|
||||
|
||||
|
||||
impl<'a> FirefoxCapabilities<'a> {
|
||||
pub fn new(fallback_binary: Option<&'a PathBuf>) -> FirefoxCapabilities<'a> {
|
||||
FirefoxCapabilities {
|
||||
@ -69,8 +68,7 @@ impl<'a> FirefoxCapabilities<'a> {
|
||||
});
|
||||
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");
|
||||
}
|
||||
@ -81,7 +79,8 @@ impl<'a> FirefoxCapabilities<'a> {
|
||||
}
|
||||
|
||||
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())
|
||||
@ -90,7 +89,8 @@ impl<'a> FirefoxCapabilities<'a> {
|
||||
.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())
|
||||
@ -104,7 +104,8 @@ impl<'a> FirefoxCapabilities<'a> {
|
||||
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> {
|
||||
@ -122,8 +123,8 @@ impl<'a> BrowserCapabilities for FirefoxCapabilities<'a> {
|
||||
|
||||
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())
|
||||
@ -145,10 +146,11 @@ impl<'a> BrowserCapabilities for FirefoxCapabilities<'a> {
|
||||
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)))
|
||||
@ -158,78 +160,100 @@ impl<'a> BrowserCapabilities for FirefoxCapabilities<'a> {
|
||||
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"));
|
||||
}
|
||||
}
|
||||
x => return Err(WebDriverError::new(
|
||||
ErrorStatus::InvalidArgument,
|
||||
format!("Invalid moz:firefoxOptions 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",
|
||||
));
|
||||
}
|
||||
}
|
||||
x => {
|
||||
return Err(WebDriverError::new(
|
||||
ErrorStatus::InvalidArgument,
|
||||
format!("Invalid moz:firefoxOptions field {}", x),
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -237,18 +261,24 @@ impl<'a> BrowserCapabilities for FirefoxCapabilities<'a> {
|
||||
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(())
|
||||
}
|
||||
@ -278,17 +308,19 @@ impl 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));
|
||||
@ -301,21 +333,22 @@ impl FirefoxOptions {
|
||||
|
||||
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 {
|
||||
@ -325,18 +358,22 @@ impl FirefoxOptions {
|
||||
|
||||
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)
|
||||
@ -372,10 +409,10 @@ impl FirefoxOptions {
|
||||
|
||||
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))));
|
||||
@ -392,21 +429,25 @@ fn pref_from_json(value: &Value) -> WebDriverResult<Pref> {
|
||||
&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("/");
|
||||
@ -486,8 +527,10 @@ mod tests {
|
||||
|
||||
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]
|
||||
|
@ -279,7 +279,10 @@ mod tests {
|
||||
];
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -14,8 +14,8 @@ extern crate serde;
|
||||
extern crate serde_derive;
|
||||
extern crate serde_json;
|
||||
extern crate uuid;
|
||||
extern crate zip;
|
||||
extern crate webdriver;
|
||||
extern crate zip;
|
||||
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
@ -28,25 +28,25 @@ 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 logging;
|
||||
mod prefs;
|
||||
mod marionette;
|
||||
mod capabilities;
|
||||
mod logging;
|
||||
mod marionette;
|
||||
mod prefs;
|
||||
|
||||
#[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)>;
|
||||
|
||||
@ -69,52 +69,70 @@ fn print_version() {
|
||||
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 {
|
||||
@ -143,12 +161,10 @@ fn run() -> ProgramResult {
|
||||
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,
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user