diff options
author | Bartek IwaĆczuk <biwanczuk@gmail.com> | 2019-04-07 00:13:06 +0200 |
---|---|---|
committer | Ryan Dahl <ry@tinyclouds.org> | 2019-04-07 01:13:06 +0300 |
commit | 780e72ab6a092a6a7174c30bf4163857770d2ad0 (patch) | |
tree | 035bf5426c6c50f3cec4790700a29563c45db8b8 | |
parent | cb11bbd8396fc3f6607481d50a4c82db0bfeffb7 (diff) |
Refactor CLI flag parsing (#2025)
49 files changed, 328 insertions, 245 deletions
diff --git a/Cargo.lock b/Cargo.lock index 5b478ca8f..312915d70 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -215,7 +215,6 @@ dependencies = [ "dirs 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "flatbuffers 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "getopts 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "http 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.12.25 (registry+https://github.com/rust-lang/crates.io-index)", "hyper-rustls 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -318,14 +317,6 @@ dependencies = [ ] [[package]] -name = "getopts" -version = "0.2.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] name = "h2" version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1440,7 +1431,6 @@ dependencies = [ "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" "checksum futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)" = "49e7653e374fe0d0c12de4250f0bdb60680b8c80eed558c5c7538eec9c89e21b" "checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" -"checksum getopts 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "0a7292d30132fb5424b354f5dc02512a86e4c516fe544bb7a25e7f266951b797" "checksum h2 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "910a5e7be6283a9c91b3982fa5188368c8719cce2a3cf3b86048673bf9d9c36b" "checksum http 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "fe67e3678f2827030e89cc4b9e7ecd16d52f132c0b940ab5005f88e821500f6a" "checksum httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e8734b0cfd3bc3e101ec59100e101c2eecd19282202e87808b3037b442777a83" diff --git a/cli/BUILD.gn b/cli/BUILD.gn index ffc13891c..ee032a757 100644 --- a/cli/BUILD.gn +++ b/cli/BUILD.gn @@ -16,7 +16,6 @@ main_extern = [ "$rust_build:dirs", "$rust_build:flatbuffers", "$rust_build:futures", - "$rust_build:getopts", "$rust_build:http", "$rust_build:hyper", "$rust_build:hyper_rustls", diff --git a/cli/Cargo.toml b/cli/Cargo.toml index f1b70b7a6..9bebe84be 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -24,7 +24,6 @@ clap = "2.32.0" dirs = "1.0.5" flatbuffers = "0.5.0" futures = "0.1.25" -getopts = "0.2.18" http = "0.1.16" hyper = "0.12.25" hyper-rustls = "0.16.1" diff --git a/cli/flags.rs b/cli/flags.rs index 9d187ecac..cf1bb72bc 100644 --- a/cli/flags.rs +++ b/cli/flags.rs @@ -1,7 +1,6 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. +use clap::{App, AppSettings, Arg, ArgMatches, SubCommand}; use deno::v8_set_flags; -use getopts; -use getopts::Options; // Creates vector of strings, Vec<String> #[cfg(test)] @@ -12,7 +11,6 @@ macro_rules! svec { #[cfg_attr(feature = "cargo-clippy", allow(stutter))] #[derive(Clone, Debug, PartialEq, Default)] pub struct DenoFlags { - pub help: bool, pub log_debug: bool, pub version: bool, pub reload: bool, @@ -28,16 +26,6 @@ pub struct DenoFlags { pub fmt: bool, } -pub fn get_usage(opts: &Options) -> String { - format!( - "Usage: deno script.ts {} -Environment variables: - DENO_DIR Set deno's base directory - NO_COLOR Set to disable color", - opts.usage("") - ) -} - /// Checks provided arguments for known options and sets appropriate Deno flags /// for them. Unknown options are returned for further use. /// Note: @@ -51,129 +39,217 @@ Environment variables: /// not cause an error. I also think this is ok because missing any of the /// privileged flags is not destructive. Userland flag parsing would catch these /// errors. -fn set_recognized_flags( - opts: &Options, - flags: &mut DenoFlags, - args: Vec<String>, -) -> Result<Vec<String>, getopts::Fail> { - let mut rest = Vec::<String>::new(); - // getopts doesn't allow parsing unknown options so we check them - // one-by-one and handle unrecognized ones manually - // better solution welcome! - for arg in args { - let fake_args = vec![arg]; - match opts.parse(&fake_args) { - Err(getopts::Fail::UnrecognizedOption(_)) => { - rest.extend(fake_args); - } - Err(e) => { - return Err(e); - } - Ok(matches) => { - if matches.opt_present("help") { - flags.help = true; - } - if matches.opt_present("log-debug") { - flags.log_debug = true; - } - if matches.opt_present("version") { - flags.version = true; - } - if matches.opt_present("reload") { - flags.reload = true; - } - if matches.opt_present("allow-read") { - flags.allow_read = true; - } - if matches.opt_present("allow-write") { - flags.allow_write = true; - } - if matches.opt_present("allow-net") { - flags.allow_net = true; - } - if matches.opt_present("allow-env") { - flags.allow_env = true; - } - if matches.opt_present("allow-run") { - flags.allow_run = true; - } - if matches.opt_present("allow-all") { - flags.allow_read = true; - flags.allow_env = true; - flags.allow_net = true; - flags.allow_run = true; - flags.allow_read = true; - flags.allow_write = true; - } - if matches.opt_present("no-prompt") { - flags.no_prompts = true; - } - if matches.opt_present("types") { - flags.types = true; - } - if matches.opt_present("prefetch") { - flags.prefetch = true; - } - if matches.opt_present("info") { - flags.info = true; - } - if matches.opt_present("fmt") { - flags.fmt = true; - } - - if !matches.free.is_empty() { - rest.extend(matches.free); - } - } - } +fn set_recognized_flags(matches: ArgMatches, flags: &mut DenoFlags) { + if matches.is_present("log-debug") { + flags.log_debug = true; + } + if matches.is_present("version") { + flags.version = true; + } + if matches.is_present("reload") { + flags.reload = true; + } + if matches.is_present("allow-read") { + flags.allow_read = true; + } + if matches.is_present("allow-write") { + flags.allow_write = true; + } + if matches.is_present("allow-net") { + flags.allow_net = true; + } + if matches.is_present("allow-env") { + flags.allow_env = true; + } + if matches.is_present("allow-run") { + flags.allow_run = true; + } + if matches.is_present("allow-all") { + flags.allow_read = true; + flags.allow_env = true; + flags.allow_net = true; + flags.allow_run = true; + flags.allow_read = true; + flags.allow_write = true; + } + if matches.is_present("no-prompt") { + flags.no_prompts = true; + } + if matches.is_present("types") { + flags.types = true; + } + if matches.is_present("prefetch") { + flags.prefetch = true; + } + if matches.is_present("info") { + flags.info = true; + } + if matches.is_present("fmt") { + flags.fmt = true; } - Ok(rest) } #[cfg_attr(feature = "cargo-clippy", allow(stutter))] pub fn set_flags( args: Vec<String>, -) -> Result<(DenoFlags, Vec<String>, String), String> { - // TODO: all flags passed after "--" are swallowed by v8_set_flags - // eg. deno --allow-net ./test.ts -- --title foobar - // args === ["deno", "--allow-net" "./test.ts"] - let args = v8_set_flags(args); +) -> Result<(DenoFlags, Vec<String>), String> { + let app_settings: Vec<AppSettings> = vec![ + AppSettings::AllowExternalSubcommands, + AppSettings::DisableHelpSubcommand, + ]; - let mut opts = Options::new(); - // TODO(kevinkassimo): v8_set_flags intercepts '-help' with single '-' - // Resolve that and then uncomment line below (enabling Go style -long-flag) - // opts.long_only(true); - opts.optflag("", "allow-read", "Allow file system read access"); - opts.optflag("", "allow-write", "Allow file system write access"); - opts.optflag("", "allow-net", "Allow network access"); - opts.optflag("", "allow-env", "Allow environment access"); - opts.optflag("", "allow-run", "Allow running subprocesses"); - opts.optflag("A", "allow-all", "Allow all permissions"); - opts.optflag("", "no-prompt", "Do not use prompts"); - opts.optflag("h", "help", "Print this message"); - opts.optflag("D", "log-debug", "Log debug output"); - opts.optflag("v", "version", "Print the version"); - opts.optflag( - "r", - "reload", - "Reload source code cache (recompile TypeScript)", - ); - opts.optflag("", "v8-options", "Print V8 command line options"); - opts.optflag("", "types", "Print runtime TypeScript declarations"); - opts.optflag("", "prefetch", "Prefetch the dependencies"); - opts.optflag("", "info", "Show source file related info"); - opts.optflag("", "fmt", "Format code"); + let env_variables_help = "ENVIRONMENT VARIABLES: + DENO_DIR Set deno's base directory + NO_COLOR Set to disable color"; - let mut flags = DenoFlags::default(); + let clap_app = App::new("deno") + .global_settings(&vec![AppSettings::ColorNever]) + .settings(&app_settings[..]) + .after_help(env_variables_help) + .arg( + Arg::with_name("version") + .short("v") + .long("version") + .help("Print the version"), + ).arg( + Arg::with_name("allow-read") + .long("allow-read") + .help("Allow file system read access"), + ).arg( + Arg::with_name("allow-write") + .long("allow-write") + .help("Allow file system write access"), + ).arg( + Arg::with_name("allow-net") + .long("allow-net") + .help("Allow network access"), + ).arg( + Arg::with_name("allow-env") + .long("allow-env") + .help("Allow environment access"), + ).arg( + Arg::with_name("allow-run") + .long("allow-run") + .help("Allow running subprocesses"), + ).arg( + Arg::with_name("allow-all") + .short("A") + .long("allow-all") + .help("Allow all permissions"), + ).arg( + Arg::with_name("no-prompt") + .long("no-prompt") + .help("Do not use prompts"), + ).arg( + Arg::with_name("log-debug") + .short("D") + .long("log-debug") + .help("Log debug output"), + ).arg( + Arg::with_name("reload") + .short("r") + .long("reload") + .help("Reload source code cache (recompile TypeScript)"), + ).arg( + Arg::with_name("v8-options") + .long("v8-options") + .help("Print V8 command line options"), + ).arg( + Arg::with_name("v8-flags") + .long("v8-flags") + .takes_value(true) + .require_equals(true) + .help("Set V8 command line options"), + ).arg( + Arg::with_name("types") + .long("types") + .help("Print runtime TypeScript declarations"), + ).arg( + Arg::with_name("prefetch") + .long("prefetch") + .help("Prefetch the dependencies"), + ).subcommand( + // TODO(bartlomieju): version is not handled properly + SubCommand::with_name("info") + .about("Show source file related info") + .arg(Arg::with_name("file").takes_value(true).required(true)), + ).subcommand( + // TODO(bartlomieju): version is not handled properly + SubCommand::with_name("fmt").about("Format files").arg( + Arg::with_name("files") + .takes_value(true) + .multiple(true) + .required(true), + ), + ).subcommand( + // this is a fake subcommand - it's used in conjunction with + // AppSettings:AllowExternalSubcommand to treat it as an + // entry point script + SubCommand::with_name("<script>").about("Script to run"), + ); - let rest = - set_recognized_flags(&opts, &mut flags, args).map_err(|e| e.to_string())?; - Ok((flags, rest, get_usage(&opts))) + let matches = clap_app.get_matches_from(args); + + // TODO(bartomieju): compatibility with old "opts" approach - to be refactored + let mut rest: Vec<String> = vec![String::from("deno")]; + + match matches.subcommand() { + ("info", Some(info_match)) => { + // TODO(bartlomieju): it still relies on `is_present("info")` check + // in `set_recognized_flags` + let file: &str = info_match.value_of("file").unwrap(); + rest.extend(vec![file.to_string()]); + } + ("fmt", Some(fmt_match)) => { + // TODO(bartlomieju): it still relies on `is_present("fmt")` check + // in `set_recognized_flags` + let files: Vec<String> = fmt_match + .values_of("files") + .unwrap() + .map(String::from) + .collect(); + rest.extend(files); + } + (script, Some(script_match)) => { + rest.extend(vec![script.to_string()]); + // check if there are any extra arguments + if script_match.is_present("") { + let script_args: Vec<String> = script_match + .values_of("") + .unwrap() + .map(String::from) + .collect(); + rest.extend(script_args); + } + } + _ => {} + } + // TODO: end + + if matches.is_present("v8-options") { + // display v8 help and exit + v8_set_flags(vec!["deno".to_string(), "--help".to_string()]); + } + + if matches.is_present("v8-flags") { + let mut v8_flags: Vec<String> = matches + .values_of("v8-flags") + .unwrap() + .map(String::from) + .collect(); + + v8_flags.insert(1, "deno".to_string()); + v8_set_flags(v8_flags); + } + + let mut flags = DenoFlags::default(); + set_recognized_flags(matches, &mut flags); + Ok((flags, rest)) } #[test] fn test_set_flags_1() { - let (flags, rest, _) = set_flags(svec!["deno", "--version"]).unwrap(); + let (flags, rest) = set_flags(svec!["deno", "--version"]).unwrap(); assert_eq!(rest, svec!["deno"]); assert_eq!( flags, @@ -186,7 +262,7 @@ fn test_set_flags_1() { #[test] fn test_set_flags_2() { - let (flags, rest, _) = + let (flags, rest) = set_flags(svec!["deno", "-r", "-D", "script.ts"]).unwrap(); assert_eq!(rest, svec!["deno", "script.ts"]); assert_eq!( @@ -201,8 +277,8 @@ fn test_set_flags_2() { #[test] fn test_set_flags_3() { - let (flags, rest, _) = - set_flags(svec!["deno", "-r", "script.ts", "--allow-write"]).unwrap(); + let (flags, rest) = + set_flags(svec!["deno", "-r", "--allow-write", "script.ts"]).unwrap(); assert_eq!(rest, svec!["deno", "script.ts"]); assert_eq!( flags, @@ -216,8 +292,8 @@ fn test_set_flags_3() { #[test] fn test_set_flags_4() { - let (flags, rest, _) = - set_flags(svec!["deno", "-Dr", "script.ts", "--allow-write"]).unwrap(); + let (flags, rest) = + set_flags(svec!["deno", "-Dr", "--allow-write", "script.ts"]).unwrap(); assert_eq!(rest, svec!["deno", "script.ts"]); assert_eq!( flags, @@ -232,7 +308,7 @@ fn test_set_flags_4() { #[test] fn test_set_flags_5() { - let (flags, rest, _) = set_flags(svec!["deno", "--types"]).unwrap(); + let (flags, rest) = set_flags(svec!["deno", "--types"]).unwrap(); assert_eq!(rest, svec!["deno"]); assert_eq!( flags, @@ -245,8 +321,8 @@ fn test_set_flags_5() { #[test] fn test_set_flags_6() { - let (flags, rest, _) = - set_flags(svec!["deno", "gist.ts", "--title", "X", "--allow-net"]).unwrap(); + let (flags, rest) = + set_flags(svec!["deno", "--allow-net", "gist.ts", "--title", "X"]).unwrap(); assert_eq!(rest, svec!["deno", "gist.ts", "--title", "X"]); assert_eq!( flags, @@ -259,8 +335,8 @@ fn test_set_flags_6() { #[test] fn test_set_flags_7() { - let (flags, rest, _) = - set_flags(svec!["deno", "gist.ts", "--allow-all"]).unwrap(); + let (flags, rest) = + set_flags(svec!["deno", "--allow-all", "gist.ts"]).unwrap(); assert_eq!(rest, svec!["deno", "gist.ts"]); assert_eq!( flags, @@ -277,8 +353,8 @@ fn test_set_flags_7() { #[test] fn test_set_flags_8() { - let (flags, rest, _) = - set_flags(svec!["deno", "gist.ts", "--allow-read"]).unwrap(); + let (flags, rest) = + set_flags(svec!["deno", "--allow-read", "gist.ts"]).unwrap(); assert_eq!(rest, svec!["deno", "gist.ts"]); assert_eq!( flags, diff --git a/cli/isolate.rs b/cli/isolate.rs index 5fd3e98f9..1d7201074 100644 --- a/cli/isolate.rs +++ b/cli/isolate.rs @@ -265,7 +265,7 @@ mod tests { let filename = filename.to_str().unwrap().to_string(); let argv = vec![String::from("./deno"), filename.clone()]; - let (flags, rest_argv, _) = flags::set_flags(argv).unwrap(); + let (flags, rest_argv) = flags::set_flags(argv).unwrap(); let state = Arc::new(IsolateState::new(flags, rest_argv, None, false)); let state_ = state.clone(); @@ -288,7 +288,7 @@ mod tests { let filename = filename.to_str().unwrap().to_string(); let argv = vec![String::from("./deno"), filename.clone()]; - let (flags, rest_argv, _) = flags::set_flags(argv).unwrap(); + let (flags, rest_argv) = flags::set_flags(argv).unwrap(); let state = Arc::new(IsolateState::new(flags, rest_argv, None, false)); let state_ = state.clone(); diff --git a/cli/isolate_state.rs b/cli/isolate_state.rs index b0fb97f10..500cdd7d7 100644 --- a/cli/isolate_state.rs +++ b/cli/isolate_state.rs @@ -122,7 +122,7 @@ impl IsolateState { pub fn mock() -> IsolateState { let argv = vec![String::from("./deno"), String::from("hello.js")]; // For debugging: argv.push_back(String::from("-D")); - let (flags, rest_argv, _) = flags::set_flags(argv).unwrap(); + let (flags, rest_argv) = flags::set_flags(argv).unwrap(); IsolateState::new(flags, rest_argv, None, false) } diff --git a/cli/main.rs b/cli/main.rs index f9a88803e..4d0ceab5a 100644 --- a/cli/main.rs +++ b/cli/main.rs @@ -7,6 +7,8 @@ extern crate log; extern crate futures; #[macro_use] extern crate serde_json; +extern crate clap; +extern crate deno; mod ansi; pub mod cli_behavior; @@ -82,17 +84,12 @@ fn main() { log::set_logger(&LOGGER).unwrap(); let args = env::args().collect(); - let (mut flags, mut rest_argv, usage_string) = flags::set_flags(args) - .unwrap_or_else(|err| { + let (mut flags, mut rest_argv) = + flags::set_flags(args).unwrap_or_else(|err| { eprintln!("{}", err); std::process::exit(1) }); - if flags.help { - println!("{}", &usage_string); - std::process::exit(0); - } - log::set_max_level(if flags.log_debug { LevelFilter::Debug } else { diff --git a/tests/001_hello.test b/tests/001_hello.test index 1e37d024d..121dbb2ea 100644 --- a/tests/001_hello.test +++ b/tests/001_hello.test @@ -1,2 +1,2 @@ -args: tests/001_hello.js --reload +args: --reload tests/001_hello.js output: tests/001_hello.js.out diff --git a/tests/002_hello.test b/tests/002_hello.test index 881271a97..d889acd00 100644 --- a/tests/002_hello.test +++ b/tests/002_hello.test @@ -1,2 +1,2 @@ -args: tests/002_hello.ts --reload +args: --reload tests/002_hello.ts output: tests/002_hello.ts.out diff --git a/tests/003_relative_import.test b/tests/003_relative_import.test index 42336ba22..5206c1aaa 100644 --- a/tests/003_relative_import.test +++ b/tests/003_relative_import.test @@ -1,2 +1,2 @@ -args: tests/003_relative_import.ts --reload +args: --reload tests/003_relative_import.ts output: tests/003_relative_import.ts.out diff --git a/tests/004_set_timeout.test b/tests/004_set_timeout.test index ea47ef1f3..6fda34f25 100644 --- a/tests/004_set_timeout.test +++ b/tests/004_set_timeout.test @@ -1,2 +1,2 @@ -args: tests/004_set_timeout.ts --reload +args: --reload tests/004_set_timeout.ts output: tests/004_set_timeout.ts.out diff --git a/tests/005_more_imports.test b/tests/005_more_imports.test index 998047a7b..fde5276fe 100644 --- a/tests/005_more_imports.test +++ b/tests/005_more_imports.test @@ -1,2 +1,2 @@ -args: tests/005_more_imports.ts --reload +args: --reload tests/005_more_imports.ts output: tests/005_more_imports.ts.out diff --git a/tests/006_url_imports.test b/tests/006_url_imports.test index c7210c83c..13c04219a 100644 --- a/tests/006_url_imports.test +++ b/tests/006_url_imports.test @@ -1,2 +1,2 @@ -args: tests/006_url_imports.ts --reload +args: --reload tests/006_url_imports.ts output: tests/006_url_imports.ts.out diff --git a/tests/010_set_interval.test b/tests/010_set_interval.test index f7c7a1f00..08ef3d36c 100644 --- a/tests/010_set_interval.test +++ b/tests/010_set_interval.test @@ -1,2 +1,2 @@ -args: tests/010_set_interval.ts --reload +args: --reload tests/010_set_interval.ts output: tests/010_set_interval.ts.out diff --git a/tests/012_async.test b/tests/012_async.test index 7bfe0a3c5..3694d7362 100644 --- a/tests/012_async.test +++ b/tests/012_async.test @@ -1,2 +1,2 @@ -args: tests/012_async.ts --reload +args: --reload tests/012_async.ts output: tests/012_async.ts.out diff --git a/tests/016_double_await.test b/tests/016_double_await.test index 35c028810..842d167cc 100644 --- a/tests/016_double_await.test +++ b/tests/016_double_await.test @@ -1,2 +1,2 @@ -args: tests/016_double_await.ts --allow-read --reload +args: --allow-read --reload tests/016_double_await.ts output: tests/016_double_await.ts.out diff --git a/tests/017_import_redirect.test b/tests/017_import_redirect.test index 4550a2f76..db7439f05 100644 --- a/tests/017_import_redirect.test +++ b/tests/017_import_redirect.test @@ -1,2 +1,2 @@ -args: tests/017_import_redirect.ts --reload +args: --reload tests/017_import_redirect.ts output: tests/017_import_redirect.ts.out diff --git a/tests/018_async_catch.test b/tests/018_async_catch.test index 582ff2b35..08961916d 100644 --- a/tests/018_async_catch.test +++ b/tests/018_async_catch.test @@ -1,2 +1,2 @@ -args: tests/018_async_catch.ts --reload +args: --reload tests/018_async_catch.ts output: tests/018_async_catch.ts.out diff --git a/tests/019_media_types.test b/tests/019_media_types.test index 28b14e641..c0fea5bc6 100644 --- a/tests/019_media_types.test +++ b/tests/019_media_types.test @@ -1,2 +1,2 @@ -args: tests/019_media_types.ts --reload +args: --reload tests/019_media_types.ts output: tests/019_media_types.ts.out diff --git a/tests/020_json_modules.test b/tests/020_json_modules.test index d9e9467fa..cacd21da0 100644 --- a/tests/020_json_modules.test +++ b/tests/020_json_modules.test @@ -1,2 +1,2 @@ -args: tests/020_json_modules.ts --reload +args: --reload tests/020_json_modules.ts output: tests/020_json_modules.ts.out diff --git a/tests/022_info_flag.test b/tests/022_info_flag.test index 2de27bdfa..e58288ec5 100644 --- a/tests/022_info_flag.test +++ b/tests/022_info_flag.test @@ -1,4 +1,4 @@ # The output assumes 003_relative_import.ts has already been run earlier # and its output is cached to $DENO_DIR. -args: --info http://127.0.0.1:4545/tests/019_media_types.ts +args: info http://127.0.0.1:4545/tests/019_media_types.ts output: tests/022_info_flag.out diff --git a/tests/023_no_ext_with_headers.test b/tests/023_no_ext_with_headers.test index 5be189af0..b663f174c 100644 --- a/tests/023_no_ext_with_headers.test +++ b/tests/023_no_ext_with_headers.test @@ -1,2 +1,2 @@ -args: tests/023_no_ext_with_headers --reload +args: --reload tests/023_no_ext_with_headers output: tests/023_no_ext_with_headers.out diff --git a/tests/024_import_no_ext_with_headers.test b/tests/024_import_no_ext_with_headers.test index 572158f12..efaca96c3 100644 --- a/tests/024_import_no_ext_with_headers.test +++ b/tests/024_import_no_ext_with_headers.test @@ -1,2 +1,2 @@ -args: tests/024_import_no_ext_with_headers.ts --reload +args: --reload tests/024_import_no_ext_with_headers.ts output: tests/024_import_no_ext_with_headers.ts.out diff --git a/tests/025_reload_js_type_error.test b/tests/025_reload_js_type_error.test index de8c6e51d..a2cd214be 100644 --- a/tests/025_reload_js_type_error.test +++ b/tests/025_reload_js_type_error.test @@ -1,2 +1,2 @@ -args: tests/025_reload_js_type_error.js --reload +args: --reload tests/025_reload_js_type_error.js output: tests/025_reload_js_type_error.js.out diff --git a/tests/026_redirect_javascript.js.test b/tests/026_redirect_javascript.js.test index a66cb0ea0..81d0ad038 100644 --- a/tests/026_redirect_javascript.js.test +++ b/tests/026_redirect_javascript.js.test @@ -1,2 +1,2 @@ -args: tests/026_redirect_javascript.js --reload +args: --reload tests/026_redirect_javascript.js output: tests/026_redirect_javascript.js.out diff --git a/tests/026_workers.test b/tests/026_workers.test index 1c5b6f4e6..5019a9256 100644 --- a/tests/026_workers.test +++ b/tests/026_workers.test @@ -1,2 +1,2 @@ -args: tests/026_workers.ts --reload -output: tests/026_workers.ts.out
\ No newline at end of file +args: --reload tests/026_workers.ts +output: tests/026_workers.ts.out diff --git a/tests/027_redirect_typescript.ts.test b/tests/027_redirect_typescript.ts.test index 8abfbc616..8762e61f2 100644 --- a/tests/027_redirect_typescript.ts.test +++ b/tests/027_redirect_typescript.ts.test @@ -1,2 +1,2 @@ -args: tests/027_redirect_typescript.ts --reload -output: tests/027_redirect_typescript.ts.out
\ No newline at end of file +args: --reload tests/027_redirect_typescript.ts +output: tests/027_redirect_typescript.ts.out diff --git a/tests/028_args.test b/tests/028_args.test new file mode 100644 index 000000000..df3c56205 --- /dev/null +++ b/tests/028_args.test @@ -0,0 +1,2 @@ +args: --reload tests/028_args.ts --arg1 val1 --arg2=val2 -- arg3 arg4 +output: tests/028_args.ts.out diff --git a/tests/028_args.ts b/tests/028_args.ts new file mode 100644 index 000000000..15df61555 --- /dev/null +++ b/tests/028_args.ts @@ -0,0 +1,3 @@ +Deno.args.forEach(arg => { + console.log(arg); +}); diff --git a/tests/028_args.ts.out b/tests/028_args.ts.out new file mode 100644 index 000000000..003599c0d --- /dev/null +++ b/tests/028_args.ts.out @@ -0,0 +1,7 @@ +tests/028_args.ts +--arg1 +val1 +--arg2=val2 +-- +arg3 +arg4 diff --git a/tests/async_error.test b/tests/async_error.test index 4667f6e09..8ebbfb56c 100644 --- a/tests/async_error.test +++ b/tests/async_error.test @@ -1,4 +1,4 @@ exit_code: 1 -args: tests/async_error.ts --reload +args: --reload tests/async_error.ts check_stderr: true output: tests/async_error.ts.out diff --git a/tests/error_001.test b/tests/error_001.test index 354f536d5..ca0a2ef2e 100644 --- a/tests/error_001.test +++ b/tests/error_001.test @@ -1,4 +1,4 @@ -args: tests/error_001.ts --reload +args: --reload tests/error_001.ts check_stderr: true exit_code: 1 output: tests/error_001.ts.out diff --git a/tests/error_002.test b/tests/error_002.test index e8658ad96..12f6e3cec 100644 --- a/tests/error_002.test +++ b/tests/error_002.test @@ -1,4 +1,4 @@ -args: tests/error_002.ts --reload +args: --reload tests/error_002.ts check_stderr: true exit_code: 1 output: tests/error_002.ts.out diff --git a/tests/error_003_typescript.test b/tests/error_003_typescript.test index cacce54cc..7a9d4a8ea 100644 --- a/tests/error_003_typescript.test +++ b/tests/error_003_typescript.test @@ -1,3 +1,3 @@ -args: tests/error_003_typescript.ts --reload +args: --reload tests/error_003_typescript.ts exit_code: 1 output: tests/error_003_typescript.ts.out diff --git a/tests/error_007_any.test b/tests/error_007_any.test index 970049195..fc0480796 100644 --- a/tests/error_007_any.test +++ b/tests/error_007_any.test @@ -1,4 +1,4 @@ -args: tests/error_007_any.ts --reload +args: --reload tests/error_007_any.ts check_stderr: true exit_code: 1 output: tests/error_007_any.ts.out diff --git a/tests/error_008_checkjs.test b/tests/error_008_checkjs.test index 0e43421e4..1944f0bca 100644 --- a/tests/error_008_checkjs.test +++ b/tests/error_008_checkjs.test @@ -1,4 +1,4 @@ -args: tests/error_008_checkjs.js --reload +args: --reload tests/error_008_checkjs.js check_stderr: true exit_code: 1 output: tests/error_008_checkjs.js.out diff --git a/tests/error_syntax.test b/tests/error_syntax.test index 297711bfa..e83cd030f 100644 --- a/tests/error_syntax.test +++ b/tests/error_syntax.test @@ -1,4 +1,4 @@ -args: tests/error_syntax.js --reload +args: --reload tests/error_syntax.js check_stderr: true exit_code: 1 output: tests/error_syntax.js.out diff --git a/tests/exit_error42.test b/tests/exit_error42.test index 59e4cd3d2..21a339a5e 100644 --- a/tests/exit_error42.test +++ b/tests/exit_error42.test @@ -1,3 +1,3 @@ exit_code: 42 -args: tests/exit_error42.ts --reload +args: --reload tests/exit_error42.ts output: tests/exit_error42.ts.out diff --git a/tests/https_import.test b/tests/https_import.test index e308466be..6cfb53058 100644 --- a/tests/https_import.test +++ b/tests/https_import.test @@ -1,2 +1,2 @@ -args: tests/https_import.ts --reload +args: --reload tests/https_import.ts output: tests/https_import.ts.out diff --git a/tests/if_main.test b/tests/if_main.test index 5830d00f8..fe4f061a6 100644 --- a/tests/if_main.test +++ b/tests/if_main.test @@ -1,2 +1,2 @@ -args: tests/if_main.ts --reload +args: --reload tests/if_main.ts output: tests/if_main.ts.out diff --git a/tests/import_meta.test b/tests/import_meta.test index 6767cfbb2..bfef5cb56 100644 --- a/tests/import_meta.test +++ b/tests/import_meta.test @@ -1,2 +1,2 @@ -args: tests/import_meta.ts --reload +args: --reload tests/import_meta.ts output: tests/import_meta.ts.out diff --git a/tests/unbuffered_stderr.test b/tests/unbuffered_stderr.test index 0e4109c7f..b3909dc2d 100644 --- a/tests/unbuffered_stderr.test +++ b/tests/unbuffered_stderr.test @@ -1,3 +1,3 @@ -args: tests/unbuffered_stderr.ts --reload +args: --reload tests/unbuffered_stderr.ts check_stderr: true output: tests/unbuffered_stderr.ts.out diff --git a/tests/unbuffered_stdout.test b/tests/unbuffered_stdout.test index d0476b3ac..3ed399cb8 100644 --- a/tests/unbuffered_stdout.test +++ b/tests/unbuffered_stdout.test @@ -1,2 +1,2 @@ -args: tests/unbuffered_stdout.ts --reload +args: --reload tests/unbuffered_stdout.ts output: tests/unbuffered_stdout.ts.out diff --git a/tools/benchmark.py b/tools/benchmark.py index db2ef0fb2..2e3ac26e4 100755 --- a/tools/benchmark.py +++ b/tools/benchmark.py @@ -23,8 +23,8 @@ exec_time_benchmarks = [ ("hello", ["tests/002_hello.ts"]), ("relative_import", ["tests/003_relative_import.ts"]), ("error_001", ["tests/error_001.ts"]), - ("cold_hello", ["tests/002_hello.ts", "--reload"]), - ("cold_relative_import", ["tests/003_relative_import.ts", "--reload"]), + ("cold_hello", ["--reload", "tests/002_hello.ts"]), + ("cold_relative_import", ["--reload", "tests/003_relative_import.ts"]), ("workers_startup", ["tests/workers_startup_bench.ts"]), ("workers_round_robin", ["tests/workers_round_robin_bench.ts"]), ] @@ -127,10 +127,10 @@ def get_strace_summary(test_args): def run_thread_count_benchmark(deno_path): thread_count_map = {} thread_count_map["set_timeout"] = get_strace_summary([ - deno_path, "tests/004_set_timeout.ts", "--reload" + deno_path, "--reload", "tests/004_set_timeout.ts" ])["clone"]["calls"] + 1 thread_count_map["fetch_deps"] = get_strace_summary([ - deno_path, "tests/fetch_deps.ts", "--reload", "--allow-net" + deno_path, "--reload", "--allow-net", "tests/fetch_deps.ts" ])["clone"]["calls"] + 1 return thread_count_map @@ -147,10 +147,10 @@ def run_throughput(deno_exe): def run_syscall_count_benchmark(deno_path): syscall_count_map = {} syscall_count_map["hello"] = get_strace_summary( - [deno_path, "tests/002_hello.ts", "--reload"])["total"]["calls"] + [deno_path, "--reload", "tests/002_hello.ts"])["total"]["calls"] syscall_count_map["fetch_deps"] = get_strace_summary( - [deno_path, "tests/fetch_deps.ts", "--reload", - "--allow-net"])["total"]["calls"] + [deno_path, "--reload", "--allow-net", + "tests/fetch_deps.ts"])["total"]["calls"] return syscall_count_map diff --git a/tools/fmt_test.py b/tools/fmt_test.py index dd704485d..85b475015 100755 --- a/tools/fmt_test.py +++ b/tools/fmt_test.py @@ -19,7 +19,7 @@ def fmt_test(deno_exe): # Set DENO_DIR to //js/ so we don't have to rely on an intenet # connection to download https://deno.land/std/prettier/main.ts deno_dir = os.path.join(root_path, "js") - run([deno_exe, dst, "--fmt"], merge_env={"DENO_DIR": deno_dir}) + run([deno_exe, "fmt", dst], merge_env={"DENO_DIR": deno_dir}) with open(fixed_filename) as f: expected = f.read() with open(dst) as f: diff --git a/tools/permission_prompt_test.py b/tools/permission_prompt_test.py index 312af2cf2..6e8922640 100755 --- a/tools/permission_prompt_test.py +++ b/tools/permission_prompt_test.py @@ -69,14 +69,14 @@ class Prompt(object): self.deno_exe = deno_exe self.test_types = test_types - def run(self, args, bytes_input): + def run(self, flags, args, bytes_input): "Returns (return_code, stdout, stderr)." - cmd = [self.deno_exe, PERMISSIONS_PROMPT_TEST_TS] + args + cmd = [self.deno_exe] + flags + [PERMISSIONS_PROMPT_TEST_TS] + args return tty_capture(cmd, bytes_input) def warm_up(self): # ignore the ts compiling message - self.run('needsWrite', b'', ["--allow-write"]) + self.run(["--allow-write"], 'needsWrite', b'') def test(self): for test_type in self.test_types: @@ -99,14 +99,14 @@ class Prompt(object): def test_allow_flag(self, test_type): code, stdout, stderr = self.run( - ["needs" + test_type.capitalize(), "--allow-" + test_type], b'') + ["--allow-" + test_type], ["needs" + test_type.capitalize()], b'') assert code == 0 assert not PROMPT_PATTERN in stderr assert not FIRST_CHECK_FAILED_PATTERN in stdout assert not PERMISSION_DENIED_PATTERN in stderr def test_yes_yes(self, test_type): - code, stdout, stderr = self.run(["needs" + test_type.capitalize()], + code, stdout, stderr = self.run([], ["needs" + test_type.capitalize()], b'y\ny\n') assert code == 0 assert PROMPT_PATTERN in stderr @@ -114,7 +114,7 @@ class Prompt(object): assert not PERMISSION_DENIED_PATTERN in stderr def test_yes_no(self, test_type): - code, stdout, stderr = self.run(["needs" + test_type.capitalize()], + code, stdout, stderr = self.run([], ["needs" + test_type.capitalize()], b'y\nn\n') assert code == 1 assert PROMPT_PATTERN in stderr @@ -122,7 +122,7 @@ class Prompt(object): assert PERMISSION_DENIED_PATTERN in stderr def test_no_no(self, test_type): - code, stdout, stderr = self.run(["needs" + test_type.capitalize()], + code, stdout, stderr = self.run([], ["needs" + test_type.capitalize()], b'n\nn\n') assert code == 1 assert PROMPT_PATTERN in stderr @@ -130,7 +130,7 @@ class Prompt(object): assert PERMISSION_DENIED_PATTERN in stderr def test_no_yes(self, test_type): - code, stdout, stderr = self.run(["needs" + test_type.capitalize()], + code, stdout, stderr = self.run([], ["needs" + test_type.capitalize()], b'n\ny\n') assert code == 0 @@ -139,7 +139,7 @@ class Prompt(object): assert not PERMISSION_DENIED_PATTERN in stderr def test_allow(self, test_type): - code, stdout, stderr = self.run(["needs" + test_type.capitalize()], + code, stdout, stderr = self.run([], ["needs" + test_type.capitalize()], b'a\n') assert code == 0 assert PROMPT_PATTERN in stderr @@ -147,7 +147,7 @@ class Prompt(object): assert not PERMISSION_DENIED_PATTERN in stderr def test_deny(self, test_type): - code, stdout, stderr = self.run(["needs" + test_type.capitalize()], + code, stdout, stderr = self.run([], ["needs" + test_type.capitalize()], b'd\n') assert code == 1 assert PROMPT_PATTERN in stderr @@ -155,7 +155,7 @@ class Prompt(object): assert PERMISSION_DENIED_PATTERN in stderr def test_unrecognized_option(self, test_type): - code, stdout, stderr = self.run(["needs" + test_type.capitalize()], + code, stdout, stderr = self.run([], ["needs" + test_type.capitalize()], b'e\na\n') assert code == 0 assert PROMPT_PATTERN in stderr @@ -165,17 +165,16 @@ class Prompt(object): def test_no_prompt(self, test_type): code, stdout, stderr = self.run( - ["needs" + test_type.capitalize(), "--no-prompt"], b'') + ["--no-prompt"], ["needs" + test_type.capitalize()], b'') assert code == 1 assert not PROMPT_PATTERN in stderr assert FIRST_CHECK_FAILED_PATTERN in stdout assert PERMISSION_DENIED_PATTERN in stderr def test_no_prompt_allow(self, test_type): - code, stdout, stderr = self.run([ - "needs" + test_type.capitalize(), "--no-prompt", - "--allow-" + test_type - ], b'') + code, stdout, stderr = self.run( + ["--no-prompt", "--allow-" + test_type], + ["needs" + test_type.capitalize()], b'') assert code == 0 assert not PROMPT_PATTERN in stderr assert not FIRST_CHECK_FAILED_PATTERN in stdout diff --git a/tools/throughput_benchmark.py b/tools/throughput_benchmark.py index 9048d3582..712edfe43 100755 --- a/tools/throughput_benchmark.py +++ b/tools/throughput_benchmark.py @@ -19,7 +19,7 @@ ADDR = "127.0.0.1:4544" def cat(deno_exe, megs): size = megs * MB start = time.time() - cmd = deno_exe + " tests/cat.ts --allow-read /dev/zero | head -c %s " % size + cmd = deno_exe + " --allow-read tests/cat.ts /dev/zero | head -c %s " % size print cmd subprocess.check_output(cmd, shell=True) end = time.time() diff --git a/tools/unit_tests.py b/tools/unit_tests.py index 45b35b417..76ecefbde 100755 --- a/tools/unit_tests.py +++ b/tools/unit_tests.py @@ -32,7 +32,7 @@ def run_unit_test2(cmd): def run_unit_test(deno_exe, permStr, flags=None): if flags is None: flags = [] - cmd = [deno_exe, "js/unit_tests.ts", permStr] + flags + cmd = [deno_exe, "js/unit_tests.ts"] + flags + [permStr] run_unit_test2(cmd) diff --git a/website/manual.md b/website/manual.md index 7480e25ff..c9609741c 100644 --- a/website/manual.md +++ b/website/manual.md @@ -67,10 +67,12 @@ Deno provides <a href="https://github.com/denoland/deno_std">a set of reviewed - Be able to serve HTTP efficiently. ([Currently it is relatively slow.](https://deno.land/benchmarks.html#req-per-sec)) -- Provide useful tooling out of the box: Built-in command-line debugger - [not yet](https://github.com/denoland/deno/issues/1120), built-in lint - [not yet](https://github.com/denoland/deno/issues/1880), dependency inspector - (`deno --info`), built-in code formatter (`deno --fmt`), +- Provide useful tooling out of the box: + - command-line debugger + [not yet](https://github.com/denoland/deno/issues/1120) + - linter [not yet](https://github.com/denoland/deno/issues/1880) + - dependency inspector (`deno info`) + - code formatter (`deno fmt`), ### Non-goals @@ -533,29 +535,38 @@ if (import.meta.main) { ```shellsession $ deno -h -Usage: deno script.ts - -Options: - --allow-read Allow file system read access - --allow-write Allow file system write access - --allow-net Allow network access - --allow-env Allow environment access - --allow-run Allow running subprocesses - -A, --allow-all Allow all permissions - --no-prompt Do not use prompts - -h, --help Print this message - -D, --log-debug Log debug output - -v, --version Print the version - -r, --reload Reload source code cache (recompile TypeScript) - --v8-options Print V8 command line options - --types Print runtime TypeScript declarations - --prefetch Prefetch the dependencies - --info Show source file related info - --fmt Format code - -Environment variables: - DENO_DIR Set deno's base directory - NO_COLOR Set to disable color +deno + +USAGE: + deno_dev [FLAGS] [OPTIONS] [SUBCOMMAND] + +FLAGS: + -A, --allow-all Allow all permissions + --allow-env Allow environment access + --allow-net Allow network access + --allow-read Allow file system read access + --allow-run Allow running subprocesses + --allow-write Allow file system write access + -h, --help Prints help information + -D, --log-debug Log debug output + --no-prompt Do not use prompts + --prefetch Prefetch the dependencies + -r, --reload Reload source code cache (recompile TypeScript) + --types Print runtime TypeScript declarations + --v8-options Print V8 command line options + -v, --version Print the version + +OPTIONS: + --v8-flags=<v8-flags> Set V8 command line options + +SUBCOMMANDS: + <script> Script to run + fmt Format files + info Show source file related info + +ENVIRONMENT VARIABLES: + DENO_DIR Set deno's base directory + NO_COLOR Set to disable color ``` ### Environmental variables |