summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRy Dahl <ry@tinyclouds.org>2019-11-26 08:06:32 -0800
committerGitHub <noreply@github.com>2019-11-26 08:06:32 -0800
commitc016684653df45c3c3bc88d79dfc295ea5c6426f (patch)
tree3cced64c9bace85163f5b4b0f4882a6548fa2905
parentf88dc4e197f36842b13843dd88da3d74d67578e5 (diff)
refactor: reorganize flags (#3389)
- Remove ability to specify run arguments like `--allow-net` after the script argument. It's too hacky to make work with clap. - Remove `--v8-options`, instead use `--v8-flags=--help` - Give more descriptive names to unit tests in flags.rs - Assume argv and subcommand into DenoFlags struct so the output of flags module is only DenoFlags rather than the tuple (subcommand, flags, argv). - Improve CLI help text - Make `deno run` specific args like `--allow-net` only show up in 'deno help run' instead of as global flags in `deno help`. - Removes `deno version` to simplify our implementation and be closer to clap defaults. `deno -V` now only shows Deno's version and not V8's nor TypeScript. `Deno.versions` can be used to see that information. - Prevent clap from auto-detecting terminal width and attempting to wrap text.
-rw-r--r--cli/flags.rs2535
-rw-r--r--cli/lib.rs66
-rw-r--r--cli/tests/integration_tests.rs27
-rw-r--r--cli/tests/version.out3
-rw-r--r--std/http/server_test.ts6
-rw-r--r--std/manual.md55
6 files changed, 1345 insertions, 1347 deletions
diff --git a/cli/flags.rs b/cli/flags.rs
index 5a95d39e8..5ab2e4eff 100644
--- a/cli/flags.rs
+++ b/cli/flags.rs
@@ -1,16 +1,15 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-use crate::fs as deno_fs;
use clap::App;
use clap::AppSettings;
use clap::Arg;
use clap::ArgMatches;
-use clap::Shell;
use clap::SubCommand;
use log::Level;
-use std;
-use std::str;
-use std::str::FromStr;
-use url::Url;
+
+/// Creates vector of strings, Vec<String>
+macro_rules! svec {
+ ($($x:expr),*) => (vec![$($x.to_string()),*]);
+}
macro_rules! std_url {
($x:expr) => {
@@ -27,13 +26,32 @@ const TEST_RUNNER_URL: &str = std_url!("testing/runner.ts");
/// Used for `deno xeval...` subcommand
const XEVAL_URL: &str = std_url!("xeval/mod.ts");
-// Creates vector of strings, Vec<String>
-macro_rules! svec {
- ($($x:expr),*) => (vec![$($x.to_string()),*]);
+#[derive(Clone, Debug, PartialEq)]
+pub enum DenoSubcommand {
+ Bundle,
+ Completions,
+ Eval,
+ Fetch,
+ Help,
+ Info,
+ Install,
+ Repl,
+ Run,
+ Types,
+ Xeval,
+}
+
+impl Default for DenoSubcommand {
+ fn default() -> DenoSubcommand {
+ DenoSubcommand::Run
+ }
}
#[derive(Clone, Debug, PartialEq, Default)]
pub struct DenoFlags {
+ pub argv: Vec<String>,
+ pub subcommand: DenoSubcommand,
+
pub log_level: Option<Level>,
pub version: bool,
pub reload: bool,
@@ -56,106 +74,114 @@ pub struct DenoFlags {
// Use tokio::runtime::current_thread
pub current_thread: bool,
+ pub bundle_output: Option<String>,
+
pub lock: Option<String>,
pub lock_write: bool,
}
static ENV_VARIABLES_HELP: &str = "ENVIRONMENT VARIABLES:
- DENO_DIR Set deno's base directory
- NO_COLOR Set to disable color
- HTTP_PROXY Set proxy address for HTTP requests (module downloads, fetch)
- HTTPS_PROXY Set proxy address for HTTPS requests (module downloads, fetch)";
-
-fn add_run_args<'a, 'b>(app: App<'a, 'b>) -> App<'a, 'b> {
- app
- .arg(
- Arg::with_name("allow-read")
- .long("allow-read")
- .min_values(0)
- .takes_value(true)
- .use_delimiter(true)
- .require_equals(true)
- .help("Allow file system read access"),
- )
- .arg(
- Arg::with_name("allow-write")
- .long("allow-write")
- .min_values(0)
- .takes_value(true)
- .use_delimiter(true)
- .require_equals(true)
- .help("Allow file system write access"),
- )
- .arg(
- Arg::with_name("allow-net")
- .long("allow-net")
- .min_values(0)
- .takes_value(true)
- .use_delimiter(true)
- .require_equals(true)
- .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-hrtime")
- .long("allow-hrtime")
- .help("Allow high resolution time measurement"),
- )
- .arg(
- Arg::with_name("allow-all")
- .short("A")
- .long("allow-all")
- .help("Allow all permissions"),
- )
- .arg(
- Arg::with_name("no-fetch")
- .long("no-fetch")
- .help("Do not download remote modules"),
- )
-}
+ DENO_DIR Set deno's base directory
+ NO_COLOR Set to disable color
+ HTTP_PROXY Proxy address for HTTP requests (module downloads, fetch)
+ HTTPS_PROXY Same but for HTTPS";
-pub fn create_cli_app<'a, 'b>() -> App<'a, 'b> {
- add_run_args(App::new("deno"))
- .bin_name("deno")
- .global_settings(&[AppSettings::ColorNever, AppSettings::UnifiedHelpMessage, AppSettings::DisableVersion])
- .settings(&[AppSettings::AllowExternalSubcommands])
- .after_help(ENV_VARIABLES_HELP)
- .long_about("A secure JavaScript and TypeScript runtime
+static DENO_HELP: &str = "A secure JavaScript and TypeScript runtime
-Docs: https://deno.land/manual.html
+Docs: https://deno.land/std/manual.md
Modules: https://deno.land/x/
Bugs: https://github.com/denoland/deno/issues
-To run the REPL:
+To run the REPL supply no arguments:
deno
-To execute a sandboxed script:
+To evaluate code from the command line:
+
+ deno eval \"console.log(30933 + 404)\"
+
+To execute a script:
deno https://deno.land/std/examples/welcome.ts
-To evaluate code from the command line:
+The default subcommand is 'run'. The above is equivalent to
- deno eval \"console.log(30933 + 404)\"
+ deno run https://deno.land/std/examples/welcome.ts
-To get help on the another subcommands (run in this case):
+See 'deno help run' for run specific flags.";
- deno help run")
- .arg(
- Arg::with_name("version")
- .short("v")
- .long("version")
- .help("Print the version"),
- )
+/// Main entry point for parsing deno's command line flags.
+/// Exits the process on error.
+pub fn flags_from_vec(args: Vec<String>) -> DenoFlags {
+ match flags_from_vec_safe(args) {
+ Ok(flags) => flags,
+ Err(err) => err.exit(),
+ }
+}
+
+/// Same as flags_from_vec but does not exit on error.
+pub fn flags_from_vec_safe(args: Vec<String>) -> clap::Result<DenoFlags> {
+ let args0 = args[0].clone();
+ let args = arg_hacks(args);
+ let app = clap_root();
+ let matches = app.get_matches_from_safe(args)?;
+
+ let mut flags = DenoFlags::default();
+
+ flags.argv.push(args0);
+
+ if matches.is_present("log-level") {
+ flags.log_level = match matches.value_of("log-level").unwrap() {
+ "debug" => Some(Level::Debug),
+ "info" => Some(Level::Info),
+ _ => unreachable!(),
+ };
+ }
+
+ if let Some(m) = matches.subcommand_matches("run") {
+ run_parse(&mut flags, m);
+ } else if let Some(m) = matches.subcommand_matches("fmt") {
+ fmt_parse(&mut flags, m);
+ } else if let Some(m) = matches.subcommand_matches("types") {
+ types_parse(&mut flags, m);
+ } else if let Some(m) = matches.subcommand_matches("fetch") {
+ fetch_parse(&mut flags, m);
+ } else if let Some(m) = matches.subcommand_matches("info") {
+ info_parse(&mut flags, m);
+ } else if let Some(m) = matches.subcommand_matches("eval") {
+ eval_parse(&mut flags, m);
+ } else if let Some(m) = matches.subcommand_matches("repl") {
+ repl_parse(&mut flags, m);
+ } else if let Some(m) = matches.subcommand_matches("xeval") {
+ xeval_parse(&mut flags, m);
+ } else if let Some(m) = matches.subcommand_matches("bundle") {
+ bundle_parse(&mut flags, m);
+ } else if let Some(m) = matches.subcommand_matches("install") {
+ install_parse(&mut flags, m);
+ } else if let Some(m) = matches.subcommand_matches("completions") {
+ completions_parse(&mut flags, m);
+ } else if let Some(m) = matches.subcommand_matches("test") {
+ test_parse(&mut flags, m);
+ } else {
+ unimplemented!();
+ }
+
+ Ok(flags)
+}
+
+fn clap_root<'a, 'b>() -> App<'a, 'b> {
+ clap::App::new("deno")
+ .bin_name("deno")
+ .global_settings(&[
+ AppSettings::UnifiedHelpMessage,
+ AppSettings::ColorNever,
+ AppSettings::VersionlessSubcommands,
+ ])
+ // Disable clap's auto-detection of terminal width
+ .set_term_width(0)
+ // Disable each subcommand having its own version.
+ // TODO(ry) use long_version here instead to display TS/V8 versions too.
+ .version(crate::version::DENO)
.arg(
Arg::with_name("log-level")
.short("L")
@@ -164,174 +190,360 @@ To get help on the another subcommands (run in this case):
.takes_value(true)
.possible_values(&["debug", "info"])
.global(true),
- ).arg(
- Arg::with_name("reload")
- .short("r")
- .min_values(0)
- .takes_value(true)
- .use_delimiter(true)
- .require_equals(true)
- .long("reload")
- .help("Reload source code cache (recompile TypeScript)")
- .value_name("CACHE_BLACKLIST")
- .long_help("Reload source code cache (recompile TypeScript)
- --reload
- Reload everything
- --reload=https://deno.land/std
- Reload all standard modules
- --reload=https://deno.land/std/fs/utils.ts,https://deno.land/std/fmt/colors.ts
- Reloads specific modules")
- .global(true),
- ).arg(
- Arg::with_name("config")
- .short("c")
- .long("config")
- .value_name("FILE")
- .help("Load tsconfig.json configuration file")
- .takes_value(true)
- .global(true),
)
- .arg(
- Arg::with_name("current-thread")
- .long("current-thread")
- .global(true)
- .help("Use tokio::runtime::current_thread"),
- ).arg(
- Arg::with_name("importmap")
- .long("importmap")
- .value_name("FILE")
- .help("Load import map file")
- .long_help(
- "Load import map file
-Specification: https://wicg.github.io/import-maps/
-Examples: https://github.com/WICG/import-maps#the-import-map",
- )
- .takes_value(true)
- .global(true),
- ).arg(
- Arg::with_name("seed")
- .long("seed")
- .value_name("NUMBER")
- .help("Seed Math.random()")
- .takes_value(true)
- .validator(|val: String| {
- match val.parse::<u64>() {
- Ok(_) => Ok(()),
- Err(_) => Err("Seed should be a number".to_string())
- }
- })
- .global(true),
- ).arg(
- Arg::with_name("lock")
- .long("lock")
- .value_name("FILE")
- .help("Check the specified lock file")
- .takes_value(true)
- .global(true),
- ).arg(
- Arg::with_name("lock-write")
- .long("lock-write")
- .help("Write lock file. Use with --lock.")
- .global(true),
- ).arg(
- Arg::with_name("v8-options")
- .long("v8-options")
- .help("Print V8 command line options")
- .global(true),
- ).arg(
- Arg::with_name("v8-flags")
- .long("v8-flags")
- .takes_value(true)
- .use_delimiter(true)
- .require_equals(true)
- .help("Set V8 command line options")
- .global(true),
- ).subcommand(
- SubCommand::with_name("version")
- .about("Print the version")
- .long_about("Print current version of Deno.
-
-Includes versions of Deno, V8 JavaScript Engine, and the TypeScript
-compiler.",
- ),
- ).subcommand(
- SubCommand::with_name("bundle")
- .about("Bundle module and dependencies into single file")
- .long_about(
- "Output a single JavaScript file with all dependencies.
+ .subcommand(bundle_subcommand())
+ .subcommand(completions_subcommand())
+ .subcommand(eval_subcommand())
+ .subcommand(fetch_subcommand())
+ .subcommand(fmt_subcommand())
+ .subcommand(info_subcommand())
+ .subcommand(install_subcommand())
+ .subcommand(repl_subcommand())
+ .subcommand(run_subcommand())
+ .subcommand(test_subcommand())
+ .subcommand(types_subcommand())
+ .subcommand(xeval_subcommand())
+ .long_about(DENO_HELP)
+ .after_help(ENV_VARIABLES_HELP)
+}
-If a out_file argument is omitted, the output of the bundle will be sent to
-standard out.
+fn types_parse(flags: &mut DenoFlags, _matches: &clap::ArgMatches) {
+ flags.subcommand = DenoSubcommand::Types;
+}
-Example:
+fn fmt_parse(flags: &mut DenoFlags, matches: &clap::ArgMatches) {
+ flags.subcommand = DenoSubcommand::Run;
+ flags.allow_read = true;
+ flags.allow_write = true;
+ flags.argv.push(PRETTIER_URL.to_string());
+
+ let files: Vec<String> = matches
+ .values_of("files")
+ .unwrap()
+ .map(String::from)
+ .collect();
+ flags.argv.extend(files);
+
+ if !matches.is_present("stdout") {
+ // `deno fmt` writes to the files by default
+ flags.argv.push("--write".to_string());
+ }
- deno bundle https://deno.land/std/examples/colors.ts
-
- deno bundle https://deno.land/std/examples/colors.ts colors.bundle.js"
- )
- .arg(Arg::with_name("source_file").takes_value(true).required(true))
- .arg(Arg::with_name("out_file").takes_value(true).required(false)),
- ).subcommand(
- SubCommand::with_name("fetch")
- .about("Fetch the dependencies")
- .long_about(
- "Fetch and compile remote dependencies recursively.
+ let prettier_flags = [
+ ["0", "check"],
+ ["1", "prettierrc"],
+ ["1", "ignore-path"],
+ ["1", "print-width"],
+ ["1", "tab-width"],
+ ["0", "use-tabs"],
+ ["0", "no-semi"],
+ ["0", "single-quote"],
+ ["1", "quote-props"],
+ ["0", "jsx-single-quote"],
+ ["0", "jsx-bracket-same-line"],
+ ["0", "trailing-comma"],
+ ["0", "no-bracket-spacing"],
+ ["1", "arrow-parens"],
+ ["1", "prose-wrap"],
+ ["1", "end-of-line"],
+ ];
+
+ for opt in &prettier_flags {
+ let t = opt[0];
+ let keyword = opt[1];
+
+ if matches.is_present(&keyword) {
+ if t == "0" {
+ flags.argv.push(format!("--{}", keyword));
+ } else {
+ if keyword == "prettierrc" {
+ flags.argv.push("--config".to_string());
+ } else {
+ flags.argv.push(format!("--{}", keyword));
+ }
+ flags
+ .argv
+ .push(matches.value_of(keyword).unwrap().to_string());
+ }
+ }
+ }
+}
-Downloads all statically imported scripts and save them in local
-cache, without running the code. No future import network requests
-would be made unless --reload is specified.
+fn install_parse(flags: &mut DenoFlags, matches: &clap::ArgMatches) {
+ flags.subcommand = DenoSubcommand::Run;
+ flags.allow_read = true;
+ flags.allow_write = true;
+ flags.allow_net = true;
+ flags.allow_env = true;
+ flags.allow_run = true;
+ flags.argv.push(INSTALLER_URL.to_string());
+
+ if matches.is_present("dir") {
+ let install_dir = matches.value_of("dir").unwrap();
+ flags.argv.push("--dir".to_string());
+ println!("dir {}", install_dir);
+ flags.argv.push(install_dir.to_string());
+ } else {
+ println!("no dir");
+ }
- # Downloads all dependencies
- deno fetch https://deno.land/std/http/file_server.ts
+ let exe_name = matches.value_of("exe_name").unwrap();
+ flags.argv.push(String::from(exe_name));
- # Once cached, static imports no longer send network requests
- deno run -A https://deno.land/std/http/file_server.ts",
- ).arg(Arg::with_name("file").takes_value(true).required(true)),
- ).subcommand(
- SubCommand::with_name("types")
- .about("Print runtime TypeScript declarations")
- .long_about("Print runtime TypeScript declarations.
+ let cmd = matches.values_of("cmd").unwrap();
+ for arg in cmd {
+ flags.argv.push(String::from(arg));
+ }
+}
- deno types > lib.deno_runtime.d.ts
+fn bundle_parse(flags: &mut DenoFlags, matches: &clap::ArgMatches) {
+ flags.subcommand = DenoSubcommand::Bundle;
+ let source_file: &str = matches.value_of("source_file").unwrap();
+ flags.argv.push(source_file.into());
+ if let Some(out_file) = matches.value_of("out_file") {
+ flags.allow_write = true;
+ flags.bundle_output = Some(out_file.to_string());
+ }
+}
-The declaration file could be saved and used for typing information.",
- ),
- ).subcommand(
- SubCommand::with_name("info")
- .about("Show info about cache or info related to source file")
- .long_about("Show info about cache or info related to source file.
+fn completions_parse(flags: &mut DenoFlags, matches: &clap::ArgMatches) {
+ flags.subcommand = DenoSubcommand::Completions;
+ let shell: &str = matches.value_of("shell").unwrap();
+ let mut buf: Vec<u8> = vec![];
+ use std::str::FromStr;
+ clap_root().gen_completions_to(
+ "deno",
+ clap::Shell::from_str(shell).unwrap(),
+ &mut buf,
+ );
+ // TODO(ry) This flags module should only be for parsing flags, not actually
+ // acting upon the flags. Although this print is innocent, it breaks the
+ // model. The print should be moved out.
+ print!("{}", std::str::from_utf8(&buf).unwrap());
+}
- deno info
+fn xeval_parse(flags: &mut DenoFlags, matches: &clap::ArgMatches) {
+ flags.subcommand = DenoSubcommand::Run;
+ flags.allow_net = true;
+ flags.allow_env = true;
+ flags.allow_run = true;
+ flags.allow_read = true;
+ flags.allow_write = true;
+ flags.allow_hrtime = true;
+ flags.argv.push(XEVAL_URL.to_string());
+
+ if matches.is_present("delim") {
+ let delim = matches.value_of("delim").unwrap();
+ flags.argv.push("--delim".to_string());
+ flags.argv.push(delim.to_string());
+ }
-The following information is shown:
+ if matches.is_present("replvar") {
+ let replvar = matches.value_of("replvar").unwrap();
+ flags.argv.push("--replvar".to_string());
+ flags.argv.push(replvar.to_string());
+ }
- DENO_DIR: location of directory containing Deno-related files
- Remote modules cache: location of directory containing remote modules
- TypeScript compiler cache: location of directory containing TS compiler output
+ let code: &str = matches.value_of("code").unwrap();
+ flags.argv.push(code.to_string());
+}
+fn repl_parse(flags: &mut DenoFlags, _matches: &clap::ArgMatches) {
+ flags.subcommand = DenoSubcommand::Repl;
+ flags.allow_net = true;
+ flags.allow_env = true;
+ flags.allow_run = true;
+ flags.allow_read = true;
+ flags.allow_write = true;
+ flags.allow_hrtime = true;
+}
- deno info https://deno.land/std@v0.11/http/file_server.ts
+fn eval_parse(flags: &mut DenoFlags, matches: &clap::ArgMatches) {
+ flags.subcommand = DenoSubcommand::Eval;
+ flags.allow_net = true;
+ flags.allow_env = true;
+ flags.allow_run = true;
+ flags.allow_read = true;
+ flags.allow_write = true;
+ flags.allow_hrtime = true;
+ let code: &str = matches.value_of("code").unwrap();
+ flags.argv.extend(vec![code.to_string()]);
+}
-The following information is shown:
+fn info_parse(flags: &mut DenoFlags, matches: &clap::ArgMatches) {
+ flags.subcommand = DenoSubcommand::Info;
+ if let Some(file) = matches.value_of("file") {
+ flags.argv.push(file.into());
+ }
+}
- local: Local path of the file.
- type: JavaScript, TypeScript, or JSON.
- compiled: TypeScript only. shown local path of compiled source code.
- map: TypeScript only. shown local path of source map.
- deps: Dependency tree of the source file.",
- ).arg(Arg::with_name("file").takes_value(true).required(false)),
- ).subcommand(
- SubCommand::with_name("eval")
- .about("Eval script")
- .long_about(
- "Evaluate provided script.
+fn fetch_parse(flags: &mut DenoFlags, matches: &clap::ArgMatches) {
+ flags.subcommand = DenoSubcommand::Fetch;
+ reload_arg_parse(flags, matches);
+ lock_args_parse(flags, matches);
+ importmap_arg_parse(flags, matches);
+ config_arg_parse(flags, matches);
+ if let Some(file) = matches.value_of("file") {
+ flags.argv.push(file.into());
+ }
+}
-This command has implicit access to all permissions (equivalent to deno run --allow-all)
+fn lock_args_parse(flags: &mut DenoFlags, matches: &clap::ArgMatches) {
+ if matches.is_present("lock") {
+ let lockfile = matches.value_of("lock").unwrap();
+ flags.lock = Some(lockfile.to_string());
+ }
+ if matches.is_present("lock-write") {
+ flags.lock_write = true;
+ }
+}
- deno eval \"console.log('hello world')\"",
- ).arg(Arg::with_name("code").takes_value(true).required(true)),
- ).subcommand(
- SubCommand::with_name("fmt")
+// Shared between the run and test subcommands. They both take similar options.
+fn run_test_args_parse(flags: &mut DenoFlags, matches: &clap::ArgMatches) {
+ reload_arg_parse(flags, matches);
+ lock_args_parse(flags, matches);
+ importmap_arg_parse(flags, matches);
+ config_arg_parse(flags, matches);
+
+ if matches.is_present("allow-read") {
+ if matches.value_of("allow-read").is_some() {
+ let read_wl = matches.values_of("allow-read").unwrap();
+ let raw_read_whitelist: Vec<String> =
+ read_wl.map(std::string::ToString::to_string).collect();
+ flags.read_whitelist = raw_read_whitelist;
+ debug!("read whitelist: {:#?}", &flags.read_whitelist);
+ } else {
+ flags.allow_read = true;
+ }
+ }
+ if matches.is_present("allow-write") {
+ if matches.value_of("allow-write").is_some() {
+ let write_wl = matches.values_of("allow-write").unwrap();
+ let raw_write_whitelist =
+ write_wl.map(std::string::ToString::to_string).collect();
+ flags.write_whitelist = raw_write_whitelist;
+ debug!("write whitelist: {:#?}", &flags.write_whitelist);
+ } else {
+ flags.allow_write = true;
+ }
+ }
+ if matches.is_present("allow-net") {
+ if matches.value_of("allow-net").is_some() {
+ let net_wl = matches.values_of("allow-net").unwrap();
+ let raw_net_whitelist =
+ net_wl.map(std::string::ToString::to_string).collect();
+ flags.net_whitelist = resolve_hosts(raw_net_whitelist);
+ debug!("net whitelist: {:#?}", &flags.net_whitelist);
+ } else {
+ 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-hrtime") {
+ flags.allow_hrtime = 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;
+ flags.allow_hrtime = true;
+ }
+ if matches.is_present("no-fetch") {
+ flags.no_fetch = true;
+ }
+
+ if matches.is_present("current-thread") {
+ flags.current_thread = true;
+ }
+
+ if let Some(v8_flags) = matches.values_of("v8-flags") {
+ let s: Vec<String> = v8_flags.map(String::from).collect();
+ flags.v8_flags = Some(s);
+ }
+
+ if matches.is_present("seed") {
+ let seed_string = matches.value_of("seed").unwrap();
+ let seed = seed_string.parse::<u64>().unwrap();
+ flags.seed = Some(seed);
+
+ let v8_seed_flag = format!("--random-seed={}", seed);
+
+ match flags.v8_flags {
+ Some(ref mut v8_flags) => {
+ v8_flags.push(v8_seed_flag);
+ }
+ None => {
+ flags.v8_flags = Some(svec![v8_seed_flag]);
+ }
+ }
+ }
+}
+
+fn run_parse(flags: &mut DenoFlags, matches: &clap::ArgMatches) {
+ flags.subcommand = DenoSubcommand::Run;
+ script_arg_parse(flags, matches);
+ run_test_args_parse(flags, matches);
+}
+
+fn test_parse(flags: &mut DenoFlags, matches: &clap::ArgMatches) {
+ flags.subcommand = DenoSubcommand::Run;
+ flags.allow_read = true;
+
+ flags.argv.push(TEST_RUNNER_URL.to_string());
+
+ run_test_args_parse(flags, matches);
+
+ if matches.is_present("quiet") {
+ flags.argv.push("--quiet".to_string());
+ }
+
+ if matches.is_present("failfast") {
+ flags.argv.push("--failfast".to_string());
+ }
+
+ if matches.is_present("exclude") {
+ flags.argv.push("--exclude".to_string());
+ let exclude: Vec<String> = matches
+ .values_of("exclude")
+ .unwrap()
+ .map(String::from)
+ .collect();
+ flags.argv.extend(exclude);
+ }
+
+ if matches.is_present("files") {
+ flags.argv.push("--".to_string());
+ let files: Vec<String> = matches
+ .values_of("files")
+ .unwrap()
+ .map(String::from)
+ .collect();
+ flags.argv.extend(files);
+ }
+}
+
+fn types_subcommand<'a, 'b>() -> App<'a, 'b> {
+ SubCommand::with_name("types")
+ .about("Print runtime TypeScript declarations")
+ .long_about(
+ "Print runtime TypeScript declarations.
+
+ deno types > lib.deno_runtime.d.ts
+
+The declaration file could be saved and used for typing information.",
+ )
+}
+
+fn fmt_subcommand<'a, 'b>() -> App<'a, 'b> {
+ SubCommand::with_name("fmt")
.about("Format files")
.long_about(
"Auto-format JavaScript/TypeScript source code using Prettier
@@ -480,72 +692,89 @@ instead of being alone on the next line (does not apply to self closing elements
.takes_value(true)
.multiple(true)
.required(true),
- ),
- ).subcommand(
- add_run_args(SubCommand::with_name("test"))
- .about("Run tests")
- .long_about(
-"Run tests using test runner
+ )
+}
-Automatically downloads test runner on first run.
+fn repl_subcommand<'a, 'b>() -> App<'a, 'b> {
+ SubCommand::with_name("repl").about("Read Eval Print Loop")
+}
- deno test **/*_test.ts **/test.ts",
- ).arg(
- Arg::with_name("failfast")
- .short("f")
- .long("failfast")
- .help("Stop on first error")
- .takes_value(false),
- ).arg(
- Arg::with_name("quiet")
- .short("q")
- .long("quiet")
- .help("Don't show output from test cases")
- .takes_value(false)
- ).arg(
- Arg::with_name("exclude")
- .short("e")
- .long("exclude")
- .help("List of file names to exclude from run")
- .takes_value(true)
- .multiple(true)
- ).arg(
- Arg::with_name("files")
- .help("List of file names to run")
+fn install_subcommand<'a, 'b>() -> App<'a, 'b> {
+ SubCommand::with_name("install")
+ .setting(AppSettings::TrailingVarArg)
+ .arg(
+ Arg::with_name("dir")
+ .long("dir")
+ .short("d")
+ .help("Installation directory (defaults to $HOME/.deno/bin)")
.takes_value(true)
+ .multiple(false))
+ .arg(
+ Arg::with_name("exe_name")
+ .required(true)
+ )
+ .arg(
+ Arg::with_name("cmd")
+ .required(true)
.multiple(true)
- ),
- ).subcommand(
- add_run_args(SubCommand::with_name("run"))
- .settings(&[
- AppSettings::AllowExternalSubcommands,
- AppSettings::DisableHelpSubcommand,
- AppSettings::SubcommandRequired,
- ]).about("Run a program given a filename or url to the source code")
+ .allow_hyphen_values(true)
+ )
+ .about("Install script as executable")
.long_about(
- "Run a program given a filename or url to the source code.
+"Installs a script as executable. The default installation directory is
+$HOME/.deno/bin and it must be added to the path manually.
-By default all programs are run in sandbox without access to disk, network or
-ability to spawn subprocesses.
+ deno install file_server https://deno.land/std/http/file_server.ts --allow-net --allow-read
- deno run https://deno.land/welcome.ts
+ deno install colors https://deno.land/std/examples/colors.ts
- # run program with permission to read from disk and listen to network
- deno run --allow-net --allow-read https://deno.land/std/http/file_server.ts
+To change installation directory use -d/--dir flag
- # run program with permission to read whitelist files from disk and listen to network
- deno run --allow-net --allow-read=$(pwd) https://deno.land/std/http/file_server.ts
+ deno install -d /usr/local/bin file_server https://deno.land/std/http/file_server.ts --allow-net --allow-read")
+}
- # run program with all permissions
- deno run -A https://deno.land/std/http/file_server.ts",
- ).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"),
- ),
- ).subcommand(
- SubCommand::with_name("xeval")
+fn bundle_subcommand<'a, 'b>() -> App<'a, 'b> {
+ SubCommand::with_name("bundle")
+ .arg(
+ Arg::with_name("source_file")
+ .takes_value(true)
+ .required(true),
+ )
+ .arg(Arg::with_name("out_file").takes_value(true).required(false))
+ .about("Bundle module and dependencies into single file")
+ .long_about(
+ "Output a single JavaScript file with all dependencies.
+
+If a out_file argument is omitted, the output of the bundle will be sent to
+standard out. Examples:
+
+ deno bundle https://deno.land/std/examples/colors.ts
+
+ deno bundle https://deno.land/std/examples/colors.ts colors.bundle.js",
+ )
+}
+
+fn completions_subcommand<'a, 'b>() -> App<'a, 'b> {
+ SubCommand::with_name("completions")
+ .setting(AppSettings::DisableHelpSubcommand)
+ .arg(
+ Arg::with_name("shell")
+ .possible_values(&clap::Shell::variants())
+ .required(true),
+ )
+ .about("Generate shell completions")
+ .long_about(
+ "Output shell completion script to standard output.
+
+Example:
+
+ deno completions bash > /usr/local/etc/bash_completion.d/deno.bash
+ source /usr/local/etc/bash_completion.d/deno.bash",
+ )
+}
+
+fn xeval_subcommand<'a, 'b>() -> App<'a, 'b> {
+ SubCommand::with_name("xeval")
.about("Eval a script on text segments from stdin")
.long_about(
"Eval a script on lines from stdin
@@ -581,92 +810,329 @@ Demonstrates breaking the input up by space delimiter instead of by lines:
.short("d")
.help("Set delimiter, defaults to newline")
.takes_value(true),
- ).arg(Arg::with_name("code").takes_value(true).required(true)),
- ).subcommand(
- SubCommand::with_name("install")
- .settings(&[
- AppSettings::DisableHelpSubcommand,
- AppSettings::AllowExternalSubcommands,
- AppSettings::SubcommandRequired,
- ])
- .about("Install script as executable")
- .long_about(
-"Automatically downloads deno_installer dependencies on first run.
+ ).arg(Arg::with_name("code").takes_value(true).required(true))
+}
-Default installation directory is $HOME/.deno/bin and it must be added to the path manually.
+fn eval_subcommand<'a, 'b>() -> App<'a, 'b> {
+ SubCommand::with_name("eval")
+ .about("Eval script")
+ .long_about(
+ "Evaluate JavaScript from command-line
- deno install file_server https://deno.land/std/http/file_server.ts --allow-net --allow-read
+This command has implicit access to all permissions (--allow-all)
- deno install colors https://deno.land/std/examples/colors.ts
+ deno eval \"console.log('hello world')\"",
+ )
+ .arg(Arg::with_name("code").takes_value(true).required(true))
+}
-To change installation directory use -d/--dir flag
+fn info_subcommand<'a, 'b>() -> App<'a, 'b> {
+ SubCommand::with_name("info")
+ .about("Show info about cache or info related to source file")
+ .long_about(
+ "Information about source file and cache
- deno install -d /usr/local/bin file_server https://deno.land/std/http/file_server.ts --allow-net --allow-read",
- ).arg(
- Arg::with_name("dir")
- .long("dir")
- .short("d")
- .help("Installation directory (defaults to $HOME/.deno/bin)")
- .takes_value(true)
- ).arg(
- Arg::with_name("exe_name")
- .help("Executable name")
- .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 URL"),
- ),
- ).subcommand(
- SubCommand::with_name("completions")
- .settings(&[
- AppSettings::DisableHelpSubcommand,
- ]).about("Generate shell completions")
- .long_about(
-"Output shell completion script to standard output.
+Example: deno info https://deno.land/std/http/file_server.ts
-Example:
+The following information is shown:
- deno completions bash > /usr/local/etc/bash_completion.d/deno.bash
- source /usr/local/etc/bash_completion.d/deno.bash")
- .arg(
- Arg::with_name("shell")
- .possible_values(&Shell::variants())
- .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"),
+local: Local path of the file.
+type: JavaScript, TypeScript, or JSON.
+compiled: Local path of compiled source code (TypeScript only)
+map: Local path of source map (TypeScript only)
+deps: Dependency tree of the source file.
+
+Without any additional arguments 'deno info' shows:
+
+DENO_DIR: directory containing Deno-related files
+Remote modules cache: directory containing remote modules
+TypeScript compiler cache: directory containing TS compiler output",
)
+ .arg(Arg::with_name("file").takes_value(true).required(false))
}
-/// Convert paths supplied into full path.
-/// If a path is invalid, we print out a warning
-/// and ignore this path in the output.
-fn resolve_paths(paths: Vec<String>) -> Vec<String> {
- let mut out: Vec<String> = vec![];
- for pathstr in paths.iter() {
- let result = deno_fs::resolve_from_cwd(pathstr);
- if result.is_err() {
- eprintln!("Unrecognized path to whitelist: {}", pathstr);
- continue;
+fn fetch_subcommand<'a, 'b>() -> App<'a, 'b> {
+ SubCommand::with_name("fetch")
+ .arg(reload_arg())
+ .arg(lock_arg())
+ .arg(lock_write_arg())
+ .arg(importmap_arg())
+ .arg(config_arg())
+ .arg(Arg::with_name("file").takes_value(true).required(true))
+ .about("Fetch the dependencies")
+ .long_about(
+ "Fetch and compile remote dependencies recursively.
+
+Downloads all statically imported scripts and save them in local
+cache, without running the code. No future import network requests
+would be made unless --reload is specified.
+
+Downloads all dependencies
+
+ deno fetch https://deno.land/std/http/file_server.ts
+
+Once cached, static imports no longer send network requests
+
+ deno run -A https://deno.land/std/http/file_server.ts",
+ )
+}
+
+fn run_test_args<'a, 'b>(app: App<'a, 'b>) -> App<'a, 'b> {
+ app
+ .arg(importmap_arg())
+ .arg(reload_arg())
+ .arg(config_arg())
+ .arg(lock_arg())
+ .arg(lock_write_arg())
+ .arg(
+ Arg::with_name("allow-read")
+ .long("allow-read")
+ .min_values(0)
+ .takes_value(true)
+ .use_delimiter(true)
+ .require_equals(true)
+ .help("Allow file system read access"),
+ )
+ .arg(
+ Arg::with_name("allow-write")
+ .long("allow-write")
+ .min_values(0)
+ .takes_value(true)
+ .use_delimiter(true)
+ .require_equals(true)
+ .help("Allow file system write access"),
+ )
+ .arg(
+ Arg::with_name("allow-net")
+ .long("allow-net")
+ .min_values(0)
+ .takes_value(true)
+ .use_delimiter(true)
+ .require_equals(true)
+ .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-hrtime")
+ .long("allow-hrtime")
+ .help("Allow high resolution time measurement"),
+ )
+ .arg(
+ Arg::with_name("allow-all")
+ .short("A")
+ .long("allow-all")
+ .help("Allow all permissions"),
+ )
+ .arg(
+ Arg::with_name("no-fetch")
+ .long("no-fetch")
+ .help("Do not download remote modules"),
+ )
+ .arg(
+ Arg::with_name("current-thread")
+ .long("current-thread")
+ .help("Use tokio::runtime::current_thread"),
+ )
+ .arg(
+ Arg::with_name("seed")
+ .long("seed")
+ .value_name("NUMBER")
+ .help("Seed Math.random()")
+ .takes_value(true)
+ .validator(|val: String| match val.parse::<u64>() {
+ Ok(_) => Ok(()),
+ Err(_) => Err("Seed should be a number".to_string()),
+ }),
+ )
+ .arg(
+ Arg::with_name("v8-flags")
+ .long("v8-flags")
+ .takes_value(true)
+ .use_delimiter(true)
+ .require_equals(true)
+ .help("Set V8 command line options. For help: --v8-flags=--help"),
+ )
+}
+
+fn run_subcommand<'a, 'b>() -> App<'a, 'b> {
+ run_test_args(SubCommand::with_name("run"))
+ .setting(AppSettings::TrailingVarArg)
+ .arg(script_arg())
+ .about("Run a program given a filename or url to the source code")
+ .long_about(
+ "Run a program given a filename or url to the source code.
+
+By default all programs are run in sandbox without access to disk, network or
+ability to spawn subprocesses.
+
+ deno run https://deno.land/std/examples/welcome.ts
+
+With all permissions
+
+ deno run -A https://deno.land/std/http/file_server.ts
+
+With only permission to read from disk and listen to network
+
+ deno run --allow-net --allow-read https://deno.land/std/http/file_server.ts
+
+With only permission to read whitelist files from disk
+
+ deno run --allow-read=/etc https://deno.land/std/http/file_server.ts",
+ )
+}
+
+fn test_subcommand<'a, 'b>() -> App<'a, 'b> {
+ run_test_args(SubCommand::with_name("test"))
+ .arg(
+ Arg::with_name("failfast")
+ .short("f")
+ .long("failfast")
+ .help("Stop on first error")
+ .takes_value(false),
+ )
+ .arg(
+ Arg::with_name("quiet")
+ .short("q")
+ .long("quiet")
+ .help("Don't show output from test cases")
+ .takes_value(false),
+ )
+ .arg(
+ Arg::with_name("exclude")
+ .short("e")
+ .long("exclude")
+ .help("List of file names to exclude from run")
+ .takes_value(true),
+ )
+ .arg(
+ Arg::with_name("files")
+ .help("List of file names to run")
+ .takes_value(true)
+ .multiple(true),
+ )
+ .about("Run tests")
+ .long_about(
+ "Run tests using test runner
+
+Searches the specified directories for all files that end in _test.ts or
+_test.js and executes them.
+
+ deno test src/",
+ )
+}
+
+fn script_arg<'a, 'b>() -> Arg<'a, 'b> {
+ Arg::with_name("script_arg")
+ .multiple(true)
+ .help("script args")
+ .value_name("SCRIPT_ARG")
+}
+
+fn script_arg_parse(flags: &mut DenoFlags, matches: &ArgMatches) {
+ if let Some(script_values) = matches.values_of("script_arg") {
+ for v in script_values {
+ flags.argv.push(String::from(v));
}
- let mut full_path = result.unwrap().1;
- // Remove trailing slash.
- if full_path.len() > 1 && full_path.ends_with('/') {
- full_path.pop();
+ }
+}
+
+fn lock_arg<'a, 'b>() -> Arg<'a, 'b> {
+ Arg::with_name("lock")
+ .long("lock")
+ .value_name("FILE")
+ .help("Check the specified lock file")
+ .takes_value(true)
+}
+
+fn lock_write_arg<'a, 'b>() -> Arg<'a, 'b> {
+ Arg::with_name("lock-write")
+ .long("lock-write")
+ .help("Write lock file. Use with --lock.")
+}
+
+fn config_arg<'a, 'b>() -> Arg<'a, 'b> {
+ Arg::with_name("config")
+ .short("c")
+ .long("config")
+ .value_name("FILE")
+ .help("Load tsconfig.json configuration file")
+ .takes_value(true)
+}
+
+fn config_arg_parse(flags: &mut DenoFlags, matches: &ArgMatches) {
+ flags.config_path = matches.value_of("config").map(ToOwned::to_owned);
+}
+
+fn reload_arg<'a, 'b>() -> Arg<'a, 'b> {
+ Arg::with_name("reload")
+ .short("r")
+ .min_values(0)
+ .takes_value(true)
+ .use_delimiter(true)
+ .require_equals(true)
+ .long("reload")
+ .help("Reload source code cache (recompile TypeScript)")
+ .value_name("CACHE_BLACKLIST")
+ .long_help(
+ "Reload source code cache (recompile TypeScript)
+--reload
+ Reload everything
+--reload=https://deno.land/std
+ Reload only standard modules
+--reload=https://deno.land/std/fs/utils.ts,https://deno.land/std/fmt/colors.ts
+ Reloads specific modules",
+ )
+}
+
+fn reload_arg_parse(flags: &mut DenoFlags, matches: &ArgMatches) {
+ if matches.is_present("reload") {
+ if matches.value_of("reload").is_some() {
+ let cache_bl = matches.values_of("reload").unwrap();
+ let raw_cache_blacklist: Vec<String> =
+ cache_bl.map(std::string::ToString::to_string).collect();
+ flags.cache_blacklist = resolve_urls(raw_cache_blacklist);
+ debug!("cache blacklist: {:#?}", &flags.cache_blacklist);
+ flags.reload = false;
+ } else {
+ flags.reload = true;
}
- out.push(full_path);
}
- out
}
+fn importmap_arg<'a, 'b>() -> Arg<'a, 'b> {
+ Arg::with_name("importmap")
+ .long("importmap")
+ .value_name("FILE")
+ .help("Load import map file")
+ .long_help(
+ "Load import map file
+Docs: https://deno.land/std/manual.md#import-maps
+Specification: https://wicg.github.io/import-maps/
+Examples: https://github.com/WICG/import-maps#the-import-map",
+ )
+ .takes_value(true)
+}
+
+fn importmap_arg_parse(flags: &mut DenoFlags, matches: &clap::ArgMatches) {
+ flags.import_map_path = matches.value_of("importmap").map(ToOwned::to_owned);
+}
+
+// TODO(ry) move this to utility module and add test.
+/// Strips fragment part of URL. Panics on bad URL.
pub fn resolve_urls(urls: Vec<String>) -> Vec<String> {
+ use url::Url;
let mut out: Vec<String> = vec![];
for urlstr in urls.iter() {
+ use std::str::FromStr;
let result = Url::from_str(urlstr);
if result.is_err() {
panic!("Bad Url: {}", urlstr);
@@ -681,9 +1147,10 @@ pub fn resolve_urls(urls: Vec<String>) -> Vec<String> {
}
out
}
-/// This function expands "bare port" paths (eg. ":8080")
-/// into full paths with hosts. It expands to such paths
-/// into 3 paths with following hosts: `0.0.0.0:port`, `127.0.0.1:port` and `localhost:port`.
+
+/// Expands "bare port" paths (eg. ":8080") into full paths with hosts. It
+/// expands to such paths into 3 paths with following hosts: `0.0.0.0:port`,
+/// `127.0.0.1:port` and `localhost:port`.
fn resolve_hosts(paths: Vec<String>) -> Vec<String> {
let mut out: Vec<String> = vec![];
for host_and_port in paths.iter() {
@@ -716,477 +1183,41 @@ fn resolve_hosts(paths: Vec<String>) -> Vec<String> {
out
}
-/// Parse ArgMatches into internal DenoFlags structure.
-/// This method should not make any side effects.
-pub fn parse_flags(
- matches: &ArgMatches,
- maybe_flags: Option<DenoFlags>,
-) -> DenoFlags {
- let mut flags = maybe_flags.unwrap_or_default();
-
- if matches.is_present("current-thread") {
- flags.current_thread = true;
- }
- if matches.is_present("log-level") {
- flags.log_level = match matches.value_of("log-level").unwrap() {
- "debug" => Some(Level::Debug),
- "info" => Some(Level::Info),
- _ => unreachable!(),
- };
- }
- if matches.is_present("version") {
- flags.version = true;
- }
- if matches.is_present("reload") {
- if matches.value_of("reload").is_some() {
- let cache_bl = matches.values_of("reload").unwrap();
- let raw_cache_blacklist: Vec<String> =
- cache_bl.map(std::string::ToString::to_string).collect();
- flags.cache_blacklist = resolve_urls(raw_cache_blacklist);
- debug!("cache blacklist: {:#?}", &flags.cache_blacklist);
- flags.reload = false;
- } else {
- flags.reload = true;
- }
- }
- flags.config_path = matches.value_of("config").map(ToOwned::to_owned);
- if matches.is_present("v8-options") {
- let v8_flags = svec!["deno", "--help"];
- flags.v8_flags = Some(v8_flags);
- }
- 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(0, "deno".to_string());
- flags.v8_flags = Some(v8_flags);
- }
- if matches.is_present("seed") {
- let seed_string = matches.value_of("seed").unwrap();
- let seed = seed_string.parse::<u64>().unwrap();
- flags.seed = Some(seed);
-
- let v8_seed_flag = format!("--random-seed={}", seed);
-
- match flags.v8_flags {
- Some(ref mut v8_flags) => {
- v8_flags.push(v8_seed_flag);
- }
- None => {
- flags.v8_flags = Some(svec!["deno", v8_seed_flag]);
- }
+fn arg_hacks(mut args: Vec<String>) -> Vec<String> {
+ // Hack #1 We want to default the subcommand to "run"
+ // Clap does not let us have a default sub-command. But we want to allow users
+ // to do "deno script.js" instead of "deno run script.js".
+ // This function insert the "run" into the second position of the args.
+ assert!(!args.is_empty());
+ if args.len() == 1 {
+ // Default to Repl subcommand.
+ args.insert(1, "repl".to_string());
+ } else {
+ // TODO don't have another list of subcommands here to maintain....
+ if args[1] != "bundle"
+ && args[1] != "completions"
+ && args[1] != "eval"
+ && args[1] != "fetch"
+ && args[1] != "fmt"
+ && args[1] != "test"
+ && args[1] != "info"
+ && args[1] != "repl"
+ && args[1] != "run"
+ && args[1] != "types"
+ && args[1] != "install"
+ && args[1] != "help"
+ && args[1] != "version"
+ && args[1] != "xeval"
+ && args[1] != "-h"
+ && args[1] != "--help"
+ && args[1] != "-V"
+ && args[1] != "--version"
+ {
+ args.insert(1, "run".to_string());
}
}
- if matches.is_present("lock") {
- let lockfile = matches.value_of("lock").unwrap();
- flags.lock = Some(lockfile.to_string());
- }
- if matches.is_present("lock-write") {
- flags.lock_write = true;
- }
-
- flags = parse_run_args(flags, matches);
- // flags specific to "run" subcommand
- if let Some(run_matches) = matches.subcommand_matches("run") {
- flags = parse_run_args(flags.clone(), run_matches);
- }
- // flags specific to "test" subcommand
- if let Some(test_matches) = matches.subcommand_matches("test") {
- flags = parse_run_args(flags.clone(), test_matches);
- }
- flags
-}
-
-/// Parse permission specific matches Args and assign to DenoFlags.
-/// This method is required because multiple subcommands use permission args.
-fn parse_run_args(mut flags: DenoFlags, matches: &ArgMatches) -> DenoFlags {
- if matches.is_present("allow-read") {
- if matches.value_of("allow-read").is_some() {
- let read_wl = matches.values_of("allow-read").unwrap();
- let raw_read_whitelist: Vec<String> =
- read_wl.map(std::string::ToString::to_string).collect();
- flags.read_whitelist = resolve_paths(raw_read_whitelist);
- debug!("read whitelist: {:#?}", &flags.read_whitelist);
- } else {
- flags.allow_read = true;
- }
- }
- if matches.is_present("allow-write") {
- if matches.value_of("allow-write").is_some() {
- let write_wl = matches.values_of("allow-write").unwrap();
- let raw_write_whitelist =
- write_wl.map(std::string::ToString::to_string).collect();
- flags.write_whitelist = resolve_paths(raw_write_whitelist);
- debug!("write whitelist: {:#?}", &flags.write_whitelist);
- } else {
- flags.allow_write = true;
- }
- }
- if matches.is_present("allow-net") {
- if matches.value_of("allow-net").is_some() {
- let net_wl = matches.values_of("allow-net").unwrap();
- let raw_net_whitelist =
- net_wl.map(std::string::ToString::to_string).collect();
- flags.net_whitelist = resolve_hosts(raw_net_whitelist);
- debug!("net whitelist: {:#?}", &flags.net_whitelist);
- } else {
- 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-hrtime") {
- flags.allow_hrtime = 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;
- flags.allow_hrtime = true;
- }
- if matches.is_present("no-fetch") {
- flags.no_fetch = true;
- }
- flags.import_map_path = matches.value_of("importmap").map(ToOwned::to_owned);
-
- flags
-}
-
-/// Parse vector or arguments as DenoFlags.
-///
-/// This is very specialized utility that parses arguments passed after script URL.
-///
-/// Only dash (eg. `-r`) and double dash (eg. `--reload`) arguments are supported.
-/// Arguments recognized as DenoFlags will be eaten.
-/// Parsing stops after double dash `--` argument.
-///
-/// NOTE: this method ignores `-h/--help` and `-v/--version` flags.
-fn parse_script_args(
- args: Vec<String>,
- mut flags: DenoFlags,
-) -> (Vec<String>, DenoFlags) {
- let mut argv = vec![];
- let mut seen_double_dash = false;
-
- // we have to iterate and parse argument one by one because clap returns error on any
- // unrecognized argument
- for arg in args.iter() {
- if seen_double_dash {
- argv.push(arg.to_string());
- continue;
- }
-
- if arg == "--" {
- seen_double_dash = true;
- argv.push(arg.to_string());
- continue;
- }
-
- if !arg.starts_with('-') || arg == "-" {
- argv.push(arg.to_string());
- continue;
- }
-
- let cli_app = create_cli_app();
- // `get_matches_from_safe` returns error for `-h/-v` flags
- let matches =
- cli_app.get_matches_from_safe(vec!["deno".to_string(), arg.to_string()]);
-
- if let Ok(m) = matches {
- flags = parse_flags(&m, Some(flags));
- } else {
- argv.push(arg.to_string());
- }
- }
-
- (argv, flags)
-}
-
-/// These are currently handled subcommands.
-/// There is no "Help" subcommand because it's handled by `clap::App` itself.
-#[derive(Debug, PartialEq)]
-pub enum DenoSubcommand {
- Bundle,
- Completions,
- Eval,
- Fetch,
- Info,
- Repl,
- Run,
- Types,
- Version,
-}
-
-pub fn flags_from_vec(
- args: Vec<String>,
-) -> (DenoFlags, DenoSubcommand, Vec<String>) {
- let cli_app = create_cli_app();
- let matches = cli_app.get_matches_from(args);
- let mut argv: Vec<String> = vec!["deno".to_string()];
- let mut flags = parse_flags(&matches.clone(), None);
-
- if flags.version {
- return (flags, DenoSubcommand::Version, argv);
- }
-
- let subcommand = match matches.subcommand() {
- ("bundle", Some(bundle_match)) => {
- flags.allow_write = true;
- let source_file: &str = bundle_match.value_of("source_file").unwrap();
- let out_file = bundle_match.value_of("out_file").map(String::from);
- match out_file {
- Some(out_file) => {
- argv.extend(vec![source_file.to_string(), out_file.to_string()])
- }
- _ => argv.extend(vec![source_file.to_string()]),
- }
- DenoSubcommand::Bundle
- }
- ("completions", Some(completions_match)) => {
- let shell: &str = completions_match.value_of("shell").unwrap();
- let mut buf: Vec<u8> = vec![];
- create_cli_app().gen_completions_to(
- "deno",
- Shell::from_str(shell).unwrap(),
- &mut buf,
- );
- print!("{}", std::str::from_utf8(&buf).unwrap());
- DenoSubcommand::Completions
- }
- ("eval", Some(eval_match)) => {
- flags.allow_net = true;
- flags.allow_env = true;
- flags.allow_run = true;
- flags.allow_read = true;
- flags.allow_write = true;
- flags.allow_hrtime = true;
- let code: &str = eval_match.value_of("code").unwrap();
- argv.extend(vec![code.to_string()]);
- DenoSubcommand::Eval
- }
- ("fetch", Some(fetch_match)) => {
- let file: &str = fetch_match.value_of("file").unwrap();
- argv.extend(vec![file.to_string()]);
- DenoSubcommand::Fetch
- }
- ("fmt", Some(fmt_match)) => {
- flags.allow_read = true;
- flags.allow_write = true;
- argv.push(PRETTIER_URL.to_string());
-
- let files: Vec<String> = fmt_match
- .values_of("files")
- .unwrap()
- .map(String::from)
- .collect();
- argv.extend(files);
-
- if !fmt_match.is_present("stdout") {
- // `deno fmt` writes to the files by default
- argv.push("--write".to_string());
- }
-
- let prettier_flags = [
- ["0", "check"],
- ["1", "prettierrc"],
- ["1", "ignore-path"],
- ["1", "print-width"],
- ["1", "tab-width"],
- ["0", "use-tabs"],
- ["0", "no-semi"],
- ["0", "single-quote"],
- ["1", "quote-props"],
- ["0", "jsx-single-quote"],
- ["0", "jsx-bracket-same-line"],
- ["0", "trailing-comma"],
- ["0", "no-bracket-spacing"],
- ["1", "arrow-parens"],
- ["1", "prose-wrap"],
- ["1", "end-of-line"],
- ];
-
- for opt in &prettier_flags {
- let t = opt[0];
- let keyword = opt[1];
-
- if fmt_match.is_present(&keyword) {
- if t == "0" {
- argv.push(format!("--{}", keyword));
- } else {
- if keyword == "prettierrc" {
- argv.push("--config".to_string());
- } else {
- argv.push(format!("--{}", keyword));
- }
- argv.push(fmt_match.value_of(keyword).unwrap().to_string());
- }
- }
- }
-
- DenoSubcommand::Run
- }
- ("info", Some(info_match)) => {
- if info_match.is_present("file") {
- argv.push(info_match.value_of("file").unwrap().to_string());
- }
- DenoSubcommand::Info
- }
- ("install", Some(install_match)) => {
- flags.allow_read = true;
- flags.allow_write = true;
- flags.allow_net = true;
- flags.allow_env = true;
- flags.allow_run = true;
- argv.push(INSTALLER_URL.to_string());
-
- if install_match.is_present("dir") {
- let install_dir = install_match.value_of("dir").unwrap();
- argv.push("--dir".to_string());
- argv.push(install_dir.to_string());
- }
-
- let exe_name: &str = install_match.value_of("exe_name").unwrap();
- argv.push(exe_name.to_string());
-
- match install_match.subcommand() {
- (script_url, Some(script_match)) => {
- argv.push(script_url.to_string());
- if script_match.is_present("") {
- let flags: Vec<String> = script_match
- .values_of("")
- .unwrap()
- .map(String::from)
- .collect();
- argv.extend(flags);
- }
- DenoSubcommand::Run
- }
- _ => unreachable!(),
- }
- }
- ("test", Some(test_match)) => {
- flags.allow_read = true;
- argv.push(TEST_RUNNER_URL.to_string());
-
- if test_match.is_present("quiet") {
- argv.push("--quiet".to_string());
- }
-
- if test_match.is_present("failfast") {
- argv.push("--failfast".to_string());
- }
-
- if test_match.is_present("exclude") {
- argv.push("--exclude".to_string());
- let exclude: Vec<String> = test_match
- .values_of("exclude")
- .unwrap()
- .map(String::from)
- .collect();
- argv.extend(exclude);
- }
-
- if test_match.is_present("files") {
- argv.push("--".to_string());
- let files: Vec<String> = test_match
- .values_of("files")
- .unwrap()
- .map(String::from)
- .collect();
- argv.extend(files);
- }
-
- DenoSubcommand::Run
- }
- ("types", Some(_)) => DenoSubcommand::Types,
- ("run", Some(run_match)) => {
- match run_match.subcommand() {
- (script, Some(script_match)) => {
- argv.extend(vec![script.to_string()]);
- // check if there are any extra arguments that should
- // be passed to script
- if script_match.is_present("") {
- let script_args: Vec<String> = script_match
- .values_of("")
- .unwrap()
- .map(String::from)
- .collect();
-
- let (script_args, flags_) = parse_script_args(script_args, flags);
- flags = flags_;
- argv.extend(script_args);
- }
- DenoSubcommand::Run
- }
- _ => unreachable!(),
- }
- }
- ("xeval", Some(xeval_match)) => {
- flags.allow_net = true;
- flags.allow_env = true;
- flags.allow_run = true;
- flags.allow_read = true;
- flags.allow_write = true;
- flags.allow_hrtime = true;
- argv.push(XEVAL_URL.to_string());
-
- if xeval_match.is_present("delim") {
- let delim = xeval_match.value_of("delim").unwrap();
- argv.push("--delim".to_string());
- argv.push(delim.to_string());
- }
-
- if xeval_match.is_present("replvar") {
- let replvar = xeval_match.value_of("replvar").unwrap();
- argv.push("--replvar".to_string());
- argv.push(replvar.to_string());
- }
-
- let code: &str = xeval_match.value_of("code").unwrap();
- argv.push(code.to_string());
-
- DenoSubcommand::Run
- }
- (script, Some(script_match)) => {
- argv.extend(vec![script.to_string()]);
- // check if there are any extra arguments that should
- // be passed to script
- if script_match.is_present("") {
- let script_args: Vec<String> = script_match
- .values_of("")
- .unwrap()
- .map(String::from)
- .collect();
-
- let (script_args, flags_) = parse_script_args(script_args, flags);
- flags = flags_;
- argv.extend(script_args);
- }
- DenoSubcommand::Run
- }
- _ => {
- flags.allow_net = true;
- flags.allow_env = true;
- flags.allow_run = true;
- flags.allow_read = true;
- flags.allow_write = true;
- flags.allow_hrtime = true;
- DenoSubcommand::Repl
- }
- };
-
- (flags, subcommand, argv)
+ args
}
#[cfg(test)]
@@ -1194,122 +1225,87 @@ mod tests {
use super::*;
#[test]
- fn test_flags_from_vec_1() {
- let (flags, subcommand, argv) = flags_from_vec(svec!["deno", "version"]);
- assert_eq!(
- flags,
- DenoFlags {
- version: true,
- ..DenoFlags::default()
- }
- );
- assert_eq!(subcommand, DenoSubcommand::Version);
- assert_eq!(argv, svec!["deno"]);
-
- let (flags, subcommand, argv) = flags_from_vec(svec!["deno", "--version"]);
- assert_eq!(
- flags,
- DenoFlags {
- version: true,
- ..DenoFlags::default()
- }
- );
- assert_eq!(subcommand, DenoSubcommand::Version);
- assert_eq!(argv, svec!["deno"]);
-
- let (flags, subcommand, argv) = flags_from_vec(svec!["deno", "-v"]);
- assert_eq!(
- flags,
- DenoFlags {
- version: true,
- ..DenoFlags::default()
- }
- );
- assert_eq!(subcommand, DenoSubcommand::Version);
- assert_eq!(argv, svec!["deno"]);
- }
-
- #[test]
- fn test_flags_from_vec_2() {
- let (flags, subcommand, argv) =
- flags_from_vec(svec!["deno", "-r", "run", "script.ts"]);
- assert_eq!(
- flags,
- DenoFlags {
- reload: true,
- ..DenoFlags::default()
- }
- );
- assert_eq!(subcommand, DenoSubcommand::Run);
- assert_eq!(argv, svec!["deno", "script.ts"]);
+ fn version() {
+ let r = flags_from_vec_safe(svec!["deno", "--version"]);
+ assert_eq!(r.unwrap_err().kind, clap::ErrorKind::VersionDisplayed);
+ let r = flags_from_vec_safe(svec!["deno", "-V"]);
+ assert_eq!(r.unwrap_err().kind, clap::ErrorKind::VersionDisplayed);
}
#[test]
- fn test_flags_from_vec_3() {
- let (flags, subcommand, argv) =
- flags_from_vec(svec!["deno", "run", "-r", "--allow-write", "script.ts"]);
+ fn run_reload() {
+ let r = flags_from_vec_safe(svec!["deno", "run", "-r", "script.ts"]);
+ let flags = r.unwrap();
assert_eq!(
flags,
DenoFlags {
+ subcommand: DenoSubcommand::Run,
+ argv: svec!["deno", "script.ts"],
reload: true,
- allow_write: true,
..DenoFlags::default()
}
);
- assert_eq!(subcommand, DenoSubcommand::Run);
- assert_eq!(argv, svec!["deno", "script.ts"]);
}
#[test]
- fn test_flags_from_vec_4() {
- let (flags, subcommand, argv) =
- flags_from_vec(svec!["deno", "-r", "run", "--allow-write", "script.ts"]);
+ fn run_reload_allow_write() {
+ let r = flags_from_vec_safe(svec![
+ "deno",
+ "run",
+ "-r",
+ "--allow-write",
+ "script.ts"
+ ]);
assert_eq!(
- flags,
+ r.unwrap(),
DenoFlags {
reload: true,
+ subcommand: DenoSubcommand::Run,
+ argv: svec!["deno", "script.ts"],
allow_write: true,
..DenoFlags::default()
}
);
- assert_eq!(subcommand, DenoSubcommand::Run);
- assert_eq!(argv, svec!["deno", "script.ts"]);
}
#[test]
- fn test_flags_from_vec_5() {
- let (flags, subcommand, argv) =
- flags_from_vec(svec!["deno", "--v8-options", "run", "script.ts"]);
+ fn run_v8_flags() {
+ let r = flags_from_vec_safe(svec![
+ "deno",
+ "run",
+ "--v8-flags=--help",
+ "script.ts"
+ ]);
assert_eq!(
- flags,
+ r.unwrap(),
DenoFlags {
- v8_flags: Some(svec!["deno", "--help"]),
+ subcommand: DenoSubcommand::Run,
+ argv: svec!["deno", "script.ts"],
+ v8_flags: Some(svec!["--help"]),
..DenoFlags::default()
}
);
- assert_eq!(subcommand, DenoSubcommand::Run);
- assert_eq!(argv, svec!["deno", "script.ts"]);
- let (flags, subcommand, argv) = flags_from_vec(svec![
+ let r = flags_from_vec_safe(svec![
"deno",
- "--v8-flags=--expose-gc,--gc-stats=1",
"run",
+ "--v8-flags=--expose-gc,--gc-stats=1",
"script.ts"
]);
assert_eq!(
- flags,
+ r.unwrap(),
DenoFlags {
- v8_flags: Some(svec!["deno", "--expose-gc", "--gc-stats=1"]),
+ subcommand: DenoSubcommand::Run,
+ argv: svec!["deno", "script.ts"],
+ v8_flags: Some(svec!["--expose-gc", "--gc-stats=1"]),
..DenoFlags::default()
}
);
- assert_eq!(subcommand, DenoSubcommand::Run);
- assert_eq!(argv, svec!["deno", "script.ts"]);
}
#[test]
- fn test_flags_from_vec_6() {
- let (flags, subcommand, argv) = flags_from_vec(svec![
+ fn script_args() {
+ let r = flags_from_vec_safe(svec![
"deno",
"run",
"--allow-net",
@@ -1318,23 +1314,24 @@ mod tests {
"X"
]);
assert_eq!(
- flags,
+ r.unwrap(),
DenoFlags {
+ subcommand: DenoSubcommand::Run,
+ argv: svec!["deno", "gist.ts", "--title", "X"],
allow_net: true,
..DenoFlags::default()
}
);
- assert_eq!(subcommand, DenoSubcommand::Run);
- assert_eq!(argv, svec!["deno", "gist.ts", "--title", "X"]);
}
#[test]
- fn test_flags_from_vec_7() {
- let (flags, subcommand, argv) =
- flags_from_vec(svec!["deno", "run", "--allow-all", "gist.ts"]);
+ fn allow_all() {
+ let r = flags_from_vec_safe(svec!["deno", "run", "--allow-all", "gist.ts"]);
assert_eq!(
- flags,
+ r.unwrap(),
DenoFlags {
+ subcommand: DenoSubcommand::Run,
+ argv: svec!["deno", "gist.ts"],
allow_net: true,
allow_env: true,
allow_run: true,
@@ -1344,46 +1341,44 @@ mod tests {
..DenoFlags::default()
}
);
- assert_eq!(subcommand, DenoSubcommand::Run);
- assert_eq!(argv, svec!["deno", "gist.ts"]);
}
#[test]
- fn test_flags_from_vec_8() {
- let (flags, subcommand, argv) =
- flags_from_vec(svec!["deno", "run", "--allow-read", "gist.ts"]);
+ fn allow_read() {
+ let r =
+ flags_from_vec_safe(svec!["deno", "run", "--allow-read", "gist.ts"]);
assert_eq!(
- flags,
+ r.unwrap(),
DenoFlags {
+ subcommand: DenoSubcommand::Run,
+ argv: svec!["deno", "gist.ts"],
allow_read: true,
..DenoFlags::default()
}
);
- assert_eq!(subcommand, DenoSubcommand::Run);
- assert_eq!(argv, svec!["deno", "gist.ts"]);
}
#[test]
- fn test_flags_from_vec_9() {
- let (flags, subcommand, argv) =
- flags_from_vec(svec!["deno", "run", "--allow-hrtime", "script.ts"]);
+ fn allow_hrtime() {
+ let r =
+ flags_from_vec_safe(svec!["deno", "run", "--allow-hrtime", "gist.ts"]);
assert_eq!(
- flags,
+ r.unwrap(),
DenoFlags {
+ subcommand: DenoSubcommand::Run,
+ argv: svec!["deno", "gist.ts"],
allow_hrtime: true,
..DenoFlags::default()
}
);
- assert_eq!(subcommand, DenoSubcommand::Run);
- assert_eq!(argv, svec!["deno", "script.ts"]);
}
#[test]
- fn test_flags_from_vec_10() {
+ fn double_hyphen() {
// notice that flags passed after double dash will not
// be parsed to DenoFlags but instead forwarded to
// script args as Deno.args
- let (flags, subcommand, argv) = flags_from_vec(svec![
+ let r = flags_from_vec_safe(svec![
"deno",
"run",
"--allow-write",
@@ -1393,98 +1388,123 @@ mod tests {
"--allow-net"
]);
assert_eq!(
- flags,
+ r.unwrap(),
DenoFlags {
+ subcommand: DenoSubcommand::Run,
+ argv: svec!["deno", "script.ts", "--", "-D", "--allow-net"],
allow_write: true,
..DenoFlags::default()
}
);
- assert_eq!(subcommand, DenoSubcommand::Run);
- assert_eq!(argv, svec!["deno", "script.ts", "--", "-D", "--allow-net"]);
}
#[test]
- fn test_flags_from_vec_11() {
- let (flags, subcommand, argv) =
- flags_from_vec(svec!["deno", "fmt", "script_1.ts", "script_2.ts"]);
+ fn fmt() {
+ let r =
+ flags_from_vec_safe(svec!["deno", "fmt", "script_1.ts", "script_2.ts"]);
assert_eq!(
- flags,
+ r.unwrap(),
DenoFlags {
+ subcommand: DenoSubcommand::Run,
allow_write: true,
allow_read: true,
+ argv: svec![
+ "deno",
+ PRETTIER_URL,
+ "script_1.ts",
+ "script_2.ts",
+ "--write",
+ "--config",
+ "auto",
+ "--ignore-path",
+ "auto"
+ ],
..DenoFlags::default()
}
);
- assert_eq!(subcommand, DenoSubcommand::Run);
- assert_eq!(
- argv,
- svec![
- "deno",
- PRETTIER_URL,
- "script_1.ts",
- "script_2.ts",
- "--write",
- "--config",
- "auto",
- "--ignore-path",
- "auto"
- ]
- );
}
#[test]
- fn test_flags_from_vec_12() {
- let (flags, subcommand, argv) = flags_from_vec(svec!["deno", "types"]);
- assert_eq!(flags, DenoFlags::default());
- assert_eq!(subcommand, DenoSubcommand::Types);
- assert_eq!(argv, svec!["deno"]);
+ fn types() {
+ let r = flags_from_vec_safe(svec!["deno", "types"]);
+ assert_eq!(
+ r.unwrap(),
+ DenoFlags {
+ subcommand: DenoSubcommand::Types,
+ argv: svec!["deno"],
+ ..DenoFlags::default()
+ }
+ );
}
#[test]
- fn test_flags_from_vec_13() {
- let (flags, subcommand, argv) =
- flags_from_vec(svec!["deno", "fetch", "script.ts"]);
- assert_eq!(flags, DenoFlags::default());
- assert_eq!(subcommand, DenoSubcommand::Fetch);
- assert_eq!(argv, svec!["deno", "script.ts"]);
+ fn fetch() {
+ let r = flags_from_vec_safe(svec!["deno", "fetch", "script.ts"]);
+ assert_eq!(
+ r.unwrap(),
+ DenoFlags {
+ subcommand: DenoSubcommand::Fetch,
+ argv: svec!["deno", "script.ts"],
+ ..DenoFlags::default()
+ }
+ );
}
#[test]
- fn test_flags_from_vec_14() {
- let (flags, subcommand, argv) =
- flags_from_vec(svec!["deno", "info", "script.ts"]);
- assert_eq!(flags, DenoFlags::default());
- assert_eq!(subcommand, DenoSubcommand::Info);
- assert_eq!(argv, svec!["deno", "script.ts"]);
+ fn info() {
+ let r = flags_from_vec_safe(svec!["deno", "info", "script.ts"]);
+ assert_eq!(
+ r.unwrap(),
+ DenoFlags {
+ subcommand: DenoSubcommand::Info,
+ // TODO(ry) I'm not sure the argv values in this case make sense.
+ // Nothing is being executed. Shouldn't argv be empty?
+ argv: svec!["deno", "script.ts"],
+ ..DenoFlags::default()
+ }
+ );
- let (flags, subcommand, argv) = flags_from_vec(svec!["deno", "info"]);
- assert_eq!(flags, DenoFlags::default());
- assert_eq!(subcommand, DenoSubcommand::Info);
- assert_eq!(argv, svec!["deno"]);
+ let r = flags_from_vec_safe(svec!["deno", "info"]);
+ assert_eq!(
+ r.unwrap(),
+ DenoFlags {
+ subcommand: DenoSubcommand::Info,
+ argv: svec!["deno"], // TODO(ry) Ditto argv unnessary?
+ ..DenoFlags::default()
+ }
+ );
}
#[test]
- fn test_flags_from_vec_15() {
- let (flags, subcommand, argv) =
- flags_from_vec(svec!["deno", "run", "-c", "tsconfig.json", "script.ts"]);
+ fn tsconfig() {
+ let r = flags_from_vec_safe(svec![
+ "deno",
+ "run",
+ "-c",
+ "tsconfig.json",
+ "script.ts"
+ ]);
assert_eq!(
- flags,
+ r.unwrap(),
DenoFlags {
+ subcommand: DenoSubcommand::Run,
+ argv: svec!["deno", "script.ts"],
config_path: Some("tsconfig.json".to_owned()),
..DenoFlags::default()
}
);
- assert_eq!(subcommand, DenoSubcommand::Run);
- assert_eq!(argv, svec!["deno", "script.ts"]);
}
#[test]
- fn test_flags_from_vec_16() {
- let (flags, subcommand, argv) =
- flags_from_vec(svec!["deno", "eval", "'console.log(\"hello\")'"]);
+ fn eval() {
+ let r =
+ flags_from_vec_safe(svec!["deno", "eval", "'console.log(\"hello\")'"]);
assert_eq!(
- flags,
+ r.unwrap(),
DenoFlags {
+ subcommand: DenoSubcommand::Eval,
+ // TODO(ry) argv in this test seems odd and potentially not correct.
+ argv: svec!["deno", "'console.log(\"hello\")'"],
allow_net: true,
allow_env: true,
allow_run: true,
@@ -1494,16 +1514,16 @@ mod tests {
..DenoFlags::default()
}
);
- assert_eq!(subcommand, DenoSubcommand::Eval);
- assert_eq!(argv, svec!["deno", "'console.log(\"hello\")'"]);
}
#[test]
- fn test_flags_from_vec_17() {
- let (flags, subcommand, argv) = flags_from_vec(svec!["deno"]);
+ fn repl() {
+ let r = flags_from_vec_safe(svec!["deno"]);
assert_eq!(
- flags,
+ r.unwrap(),
DenoFlags {
+ subcommand: DenoSubcommand::Repl,
+ argv: svec!["deno"],
allow_net: true,
allow_env: true,
allow_run: true,
@@ -1513,13 +1533,11 @@ mod tests {
..DenoFlags::default()
}
);
- assert_eq!(subcommand, DenoSubcommand::Repl);
- assert_eq!(argv, svec!["deno"]);
}
#[test]
- fn test_flags_from_vec_18() {
- let (flags, subcommand, argv) = flags_from_vec(svec![
+ fn xeval() {
+ let r = flags_from_vec_safe(svec![
"deno",
"xeval",
"-I",
@@ -1529,8 +1547,18 @@ mod tests {
"console.log(val)"
]);
assert_eq!(
- flags,
+ r.unwrap(),
DenoFlags {
+ subcommand: DenoSubcommand::Run,
+ argv: svec![
+ "deno",
+ XEVAL_URL,
+ "--delim",
+ " ",
+ "--replvar",
+ "val",
+ "console.log(val)"
+ ],
allow_net: true,
allow_env: true,
allow_run: true,
@@ -1540,94 +1568,79 @@ mod tests {
..DenoFlags::default()
}
);
- assert_eq!(subcommand, DenoSubcommand::Run);
- assert_eq!(
- argv,
- svec![
- "deno",
- XEVAL_URL,
- "--delim",
- " ",
- "--replvar",
- "val",
- "console.log(val)"
- ]
- );
}
#[test]
- fn test_flags_from_vec_19() {
+ fn allow_read_whitelist() {
use tempfile::TempDir;
let temp_dir = TempDir::new().expect("tempdir fail");
- let (_, temp_dir_path) =
- deno_fs::resolve_from_cwd(temp_dir.path().to_str().unwrap()).unwrap();
+ let temp_dir_path = temp_dir.path().to_str().unwrap();
- let (flags, subcommand, argv) = flags_from_vec(svec![
+ let r = flags_from_vec_safe(svec![
"deno",
"run",
format!("--allow-read={}", &temp_dir_path),
"script.ts"
]);
assert_eq!(
- flags,
+ r.unwrap(),
DenoFlags {
allow_read: false,
read_whitelist: svec![&temp_dir_path],
+ argv: svec!["deno", "script.ts"],
+ subcommand: DenoSubcommand::Run,
..DenoFlags::default()
}
);
- assert_eq!(subcommand, DenoSubcommand::Run);
- assert_eq!(argv, svec!["deno", "script.ts"]);
}
#[test]
- fn test_flags_from_vec_20() {
+ fn allow_write_whitelist() {
use tempfile::TempDir;
let temp_dir = TempDir::new().expect("tempdir fail");
- let (_, temp_dir_path) =
- deno_fs::resolve_from_cwd(temp_dir.path().to_str().unwrap()).unwrap();
+ let temp_dir_path = temp_dir.path().to_str().unwrap();
- let (flags, subcommand, argv) = flags_from_vec(svec![
+ let r = flags_from_vec_safe(svec![
"deno",
"run",
format!("--allow-write={}", &temp_dir_path),
"script.ts"
]);
assert_eq!(
- flags,
+ r.unwrap(),
DenoFlags {
allow_write: false,
write_whitelist: svec![&temp_dir_path],
+ argv: svec!["deno", "script.ts"],
+ subcommand: DenoSubcommand::Run,
..DenoFlags::default()
}
);
- assert_eq!(subcommand, DenoSubcommand::Run);
- assert_eq!(argv, svec!["deno", "script.ts"]);
}
#[test]
- fn test_flags_from_vec_21() {
- let (flags, subcommand, argv) = flags_from_vec(svec![
+ fn allow_net_whitelist() {
+ let r = flags_from_vec_safe(svec![
"deno",
"run",
"--allow-net=127.0.0.1",
"script.ts"
]);
assert_eq!(
- flags,
+ r.unwrap(),
DenoFlags {
+ subcommand: DenoSubcommand::Run,
+ argv: svec!["deno", "script.ts"],
allow_net: false,
net_whitelist: svec!["127.0.0.1"],
..DenoFlags::default()
}
);
- assert_eq!(subcommand, DenoSubcommand::Run);
- assert_eq!(argv, svec!["deno", "script.ts"]);
}
#[test]
- fn test_flags_from_vec_22() {
- let (flags, subcommand, argv) = flags_from_vec(svec![
+ fn fmt_stdout() {
+ let r = flags_from_vec_safe(svec![
"deno",
"fmt",
"--stdout",
@@ -1635,187 +1648,201 @@ mod tests {
"script_2.ts"
]);
assert_eq!(
- flags,
+ r.unwrap(),
DenoFlags {
+ subcommand: DenoSubcommand::Run,
+ argv: svec![
+ "deno",
+ PRETTIER_URL,
+ "script_1.ts",
+ "script_2.ts",
+ "--config",
+ "auto",
+ "--ignore-path",
+ "auto"
+ ],
allow_write: true,
allow_read: true,
..DenoFlags::default()
}
);
- assert_eq!(subcommand, DenoSubcommand::Run);
- assert_eq!(
- argv,
- svec![
- "deno",
- PRETTIER_URL,
- "script_1.ts",
- "script_2.ts",
- "--config",
- "auto",
- "--ignore-path",
- "auto"
- ]
- );
}
#[test]
- fn test_flags_from_vec_23() {
- let (flags, subcommand, argv) = flags_from_vec(svec!["deno", "script.ts"]);
- assert_eq!(flags, DenoFlags::default());
- assert_eq!(subcommand, DenoSubcommand::Run);
- assert_eq!(argv, svec!["deno", "script.ts"]);
- }
-
- #[test]
- fn test_flags_from_vec_24() {
- let (flags, subcommand, argv) =
- flags_from_vec(svec!["deno", "--allow-net", "--allow-read", "script.ts"]);
+ fn default_to_run() {
+ let r = flags_from_vec_safe(svec!["deno", "script.ts"]);
assert_eq!(
- flags,
+ r.unwrap(),
DenoFlags {
- allow_net: true,
- allow_read: true,
+ subcommand: DenoSubcommand::Run,
+ argv: svec!["deno", "script.ts"],
..DenoFlags::default()
}
);
- assert_eq!(subcommand, DenoSubcommand::Run);
- assert_eq!(argv, svec!["deno", "script.ts"]);
}
#[test]
- fn test_flags_from_vec_25() {
- let (flags, subcommand, argv) = flags_from_vec(svec![
+ fn default_to_run_with_permissions() {
+ let r = flags_from_vec_safe(svec![
"deno",
- "-r",
"--allow-net",
- "run",
"--allow-read",
"script.ts"
]);
assert_eq!(
- flags,
+ r.unwrap(),
DenoFlags {
- reload: true,
+ subcommand: DenoSubcommand::Run,
+ argv: svec!["deno", "script.ts"],
allow_net: true,
allow_read: true,
..DenoFlags::default()
}
);
- assert_eq!(subcommand, DenoSubcommand::Run);
- assert_eq!(argv, svec!["deno", "script.ts"]);
}
#[test]
- fn test_flags_from_vec_26() {
- let (flags, subcommand, argv) =
- flags_from_vec(svec!["deno", "bundle", "source.ts", "bundle.js"]);
+ fn bundle() {
+ let r = flags_from_vec_safe(svec!["deno", "bundle", "source.ts"]);
assert_eq!(
- flags,
+ r.unwrap(),
+ DenoFlags {
+ subcommand: DenoSubcommand::Bundle,
+ argv: svec!["deno", "source.ts"],
+ bundle_output: None,
+ ..DenoFlags::default()
+ }
+ );
+ }
+
+ #[test]
+ fn bundle_with_output() {
+ let r =
+ flags_from_vec_safe(svec!["deno", "bundle", "source.ts", "bundle.js"]);
+ assert_eq!(
+ r.unwrap(),
DenoFlags {
+ subcommand: DenoSubcommand::Bundle,
+ argv: svec!["deno", "source.ts"],
+ bundle_output: Some("bundle.js".to_string()),
allow_write: true,
..DenoFlags::default()
}
);
- assert_eq!(subcommand, DenoSubcommand::Bundle);
- assert_eq!(argv, svec!["deno", "source.ts", "bundle.js"])
}
#[test]
- fn test_flags_from_vec_27() {
- let (flags, subcommand, argv) = flags_from_vec(svec![
+ fn run_importmap() {
+ let r = flags_from_vec_safe(svec![
"deno",
"run",
"--importmap=importmap.json",
"script.ts"
]);
assert_eq!(
- flags,
+ r.unwrap(),
DenoFlags {
+ subcommand: DenoSubcommand::Run,
+ argv: svec!["deno", "script.ts"],
import_map_path: Some("importmap.json".to_owned()),
..DenoFlags::default()
}
);
- assert_eq!(subcommand, DenoSubcommand::Run);
- assert_eq!(argv, svec!["deno", "script.ts"]);
+ }
- let (flags, subcommand, argv) =
- flags_from_vec(svec!["deno", "--importmap=importmap.json", "script.ts"]);
+ #[test]
+ fn default_to_run_importmap() {
+ let r = flags_from_vec_safe(svec![
+ "deno",
+ "--importmap=importmap.json",
+ "script.ts"
+ ]);
assert_eq!(
- flags,
+ r.unwrap(),
DenoFlags {
+ subcommand: DenoSubcommand::Run,
+ argv: svec!["deno", "script.ts"],
import_map_path: Some("importmap.json".to_owned()),
..DenoFlags::default()
}
);
- assert_eq!(subcommand, DenoSubcommand::Run);
- assert_eq!(argv, svec!["deno", "script.ts"]);
+ }
- let (flags, subcommand, argv) = flags_from_vec(svec![
+ #[test]
+ fn fetch_importmap() {
+ let r = flags_from_vec_safe(svec![
"deno",
"fetch",
"--importmap=importmap.json",
"script.ts"
]);
assert_eq!(
- flags,
+ r.unwrap(),
DenoFlags {
+ subcommand: DenoSubcommand::Fetch,
+ argv: svec!["deno", "script.ts"],
import_map_path: Some("importmap.json".to_owned()),
..DenoFlags::default()
}
);
- assert_eq!(subcommand, DenoSubcommand::Fetch);
- assert_eq!(argv, svec!["deno", "script.ts"]);
}
#[test]
- fn test_flags_from_vec_28() {
- let (flags, subcommand, argv) =
- flags_from_vec(svec!["deno", "--seed", "250", "run", "script.ts"]);
+ fn run_seed() {
+ let r =
+ flags_from_vec_safe(svec!["deno", "run", "--seed", "250", "script.ts"]);
assert_eq!(
- flags,
+ r.unwrap(),
DenoFlags {
+ subcommand: DenoSubcommand::Run,
+ argv: svec!["deno", "script.ts"],
seed: Some(250 as u64),
- v8_flags: Some(svec!["deno", "--random-seed=250"]),
+ v8_flags: Some(svec!["--random-seed=250"]),
..DenoFlags::default()
}
);
- assert_eq!(subcommand, DenoSubcommand::Run);
- assert_eq!(argv, svec!["deno", "script.ts"]);
}
#[test]
- fn test_flags_from_vec_29() {
- let (flags, subcommand, argv) = flags_from_vec(svec![
+ fn run_seed_with_v8_flags() {
+ let r = flags_from_vec_safe(svec![
"deno",
+ "run",
"--seed",
"250",
"--v8-flags=--expose-gc",
- "run",
"script.ts"
]);
assert_eq!(
- flags,
+ r.unwrap(),
DenoFlags {
+ subcommand: DenoSubcommand::Run,
+ argv: svec!["deno", "script.ts"],
seed: Some(250 as u64),
- v8_flags: Some(svec!["deno", "--expose-gc", "--random-seed=250"]),
+ v8_flags: Some(svec!["--expose-gc", "--random-seed=250"]),
..DenoFlags::default()
}
);
- assert_eq!(subcommand, DenoSubcommand::Run);
- assert_eq!(argv, svec!["deno", "script.ts"]);
}
#[test]
- fn test_flags_from_vec_30() {
- let (flags, subcommand, argv) = flags_from_vec(svec![
+ fn install() {
+ let r = flags_from_vec_safe(svec![
"deno",
"install",
"deno_colors",
"https://deno.land/std/examples/colors.ts"
]);
assert_eq!(
- flags,
+ r.unwrap(),
DenoFlags {
+ subcommand: DenoSubcommand::Run,
+ argv: svec![
+ "deno",
+ INSTALLER_URL,
+ "deno_colors",
+ "https://deno.land/std/examples/colors.ts"
+ ],
allow_write: true,
allow_net: true,
allow_read: true,
@@ -1824,18 +1851,11 @@ mod tests {
..DenoFlags::default()
}
);
- assert_eq!(subcommand, DenoSubcommand::Run);
- assert_eq!(
- argv,
- svec![
- "deno",
- INSTALLER_URL,
- "deno_colors",
- "https://deno.land/std/examples/colors.ts"
- ]
- );
+ }
- let (flags, subcommand, argv) = flags_from_vec(svec![
+ #[test]
+ fn install_with_args() {
+ let r = flags_from_vec_safe(svec![
"deno",
"install",
"file_server",
@@ -1844,8 +1864,17 @@ mod tests {
"--allow-read"
]);
assert_eq!(
- flags,
+ r.unwrap(),
DenoFlags {
+ subcommand: DenoSubcommand::Run,
+ argv: svec![
+ "deno",
+ INSTALLER_URL,
+ "file_server",
+ "https://deno.land/std/http/file_server.ts",
+ "--allow-net",
+ "--allow-read"
+ ],
allow_write: true,
allow_net: true,
allow_read: true,
@@ -1854,20 +1883,11 @@ mod tests {
..DenoFlags::default()
}
);
- assert_eq!(subcommand, DenoSubcommand::Run);
- assert_eq!(
- argv,
- svec![
- "deno",
- INSTALLER_URL,
- "file_server",
- "https://deno.land/std/http/file_server.ts",
- "--allow-net",
- "--allow-read"
- ]
- );
+ }
- let (flags, subcommand, argv) = flags_from_vec(svec![
+ #[test]
+ fn install_with_args_and_dir() {
+ let r = flags_from_vec_safe(svec![
"deno",
"install",
"-d",
@@ -1878,8 +1898,19 @@ mod tests {
"--allow-read"
]);
assert_eq!(
- flags,
+ r.unwrap(),
DenoFlags {
+ subcommand: DenoSubcommand::Run,
+ argv: svec![
+ "deno",
+ INSTALLER_URL,
+ "--dir",
+ "/usr/local/bin",
+ "file_server",
+ "https://deno.land/std/http/file_server.ts",
+ "--allow-net",
+ "--allow-read"
+ ],
allow_write: true,
allow_net: true,
allow_read: true,
@@ -1888,50 +1919,41 @@ mod tests {
..DenoFlags::default()
}
);
- assert_eq!(subcommand, DenoSubcommand::Run);
- assert_eq!(
- argv,
- svec![
- "deno",
- INSTALLER_URL,
- "--dir",
- "/usr/local/bin",
- "file_server",
- "https://deno.land/std/http/file_server.ts",
- "--allow-net",
- "--allow-read"
- ]
- );
}
#[test]
- fn test_flags_from_vec_31() {
- let (flags, subcommand, argv) =
- flags_from_vec(svec!["deno", "--log-level=debug", "script.ts"]);
+ fn log_level() {
+ let r =
+ flags_from_vec_safe(svec!["deno", "--log-level=debug", "script.ts"]);
assert_eq!(
- flags,
+ r.unwrap(),
DenoFlags {
+ subcommand: DenoSubcommand::Run,
+ argv: svec!["deno", "script.ts"],
log_level: Some(Level::Debug),
..DenoFlags::default()
}
);
- assert_eq!(subcommand, DenoSubcommand::Run);
- assert_eq!(argv, svec!["deno", "script.ts"])
}
#[test]
- fn test_flags_from_vec_32() {
- let (flags, subcommand, argv) =
- flags_from_vec(svec!["deno", "completions", "bash"]);
- assert_eq!(flags, DenoFlags::default());
- assert_eq!(subcommand, DenoSubcommand::Completions);
- assert_eq!(argv, svec!["deno"])
+ fn completions() {
+ let r = flags_from_vec_safe(svec!["deno", "completions", "bash"]);
+ assert_eq!(
+ r.unwrap(),
+ DenoFlags {
+ subcommand: DenoSubcommand::Completions,
+ argv: svec!["deno"], // TODO(ry) argv doesn't make sense here. Make it Option.
+ ..DenoFlags::default()
+ }
+ );
}
+ /* TODO(ry) Fix this test
#[test]
fn test_flags_from_vec_33() {
let (flags, subcommand, argv) =
- flags_from_vec(svec!["deno", "script.ts", "--allow-read", "--allow-net"]);
+ flags_from_vec_safe(svec!["deno", "script.ts", "--allow-read", "--allow-net"]);
assert_eq!(
flags,
DenoFlags {
@@ -1943,10 +1965,10 @@ mod tests {
assert_eq!(subcommand, DenoSubcommand::Run);
assert_eq!(argv, svec!["deno", "script.ts"]);
- let (flags, subcommand, argv) = flags_from_vec(svec![
+ let (flags, subcommand, argv) = flags_from_vec_safe(svec![
"deno",
- "--allow-read",
"run",
+ "--allow-read",
"script.ts",
"--allow-net",
"-r",
@@ -1967,93 +1989,65 @@ mod tests {
assert_eq!(argv, svec!["deno", "script.ts", "--help", "--foo", "bar"]);
let (flags, subcommand, argv) =
- flags_from_vec(svec!["deno", "script.ts", "foo", "bar"]);
+ flags_from_vec_safe(svec!["deno", "script.ts", "foo", "bar"]);
assert_eq!(flags, DenoFlags::default());
assert_eq!(subcommand, DenoSubcommand::Run);
assert_eq!(argv, svec!["deno", "script.ts", "foo", "bar"]);
let (flags, subcommand, argv) =
- flags_from_vec(svec!["deno", "script.ts", "-"]);
+ flags_from_vec_safe(svec!["deno", "script.ts", "-"]);
assert_eq!(flags, DenoFlags::default());
assert_eq!(subcommand, DenoSubcommand::Run);
assert_eq!(argv, svec!["deno", "script.ts", "-"]);
let (flags, subcommand, argv) =
- flags_from_vec(svec!["deno", "script.ts", "-", "foo", "bar"]);
+ flags_from_vec_safe(svec!["deno", "script.ts", "-", "foo", "bar"]);
assert_eq!(flags, DenoFlags::default());
assert_eq!(subcommand, DenoSubcommand::Run);
assert_eq!(argv, svec!["deno", "script.ts", "-", "foo", "bar"]);
}
+ */
#[test]
- fn test_flags_from_vec_34() {
- let (flags, subcommand, argv) =
- flags_from_vec(svec!["deno", "--no-fetch", "script.ts"]);
+ fn no_fetch() {
+ let r = flags_from_vec_safe(svec!["deno", "--no-fetch", "script.ts"]);
assert_eq!(
- flags,
+ r.unwrap(),
DenoFlags {
+ subcommand: DenoSubcommand::Run,
+ argv: svec!["deno", "script.ts"],
no_fetch: true,
..DenoFlags::default()
}
);
- assert_eq!(subcommand, DenoSubcommand::Run);
- assert_eq!(argv, svec!["deno", "script.ts"])
}
#[test]
- fn test_flags_from_vec_35() {
- let (flags, subcommand, argv) =
- flags_from_vec(svec!["deno", "--current-thread", "script.ts"]);
+ fn current_thread() {
+ let r = flags_from_vec_safe(svec!["deno", "--current-thread", "script.ts"]);
assert_eq!(
- flags,
+ r.unwrap(),
DenoFlags {
+ subcommand: DenoSubcommand::Run,
+ argv: svec!["deno", "script.ts"],
current_thread: true,
..DenoFlags::default()
}
);
- assert_eq!(subcommand, DenoSubcommand::Run);
- assert_eq!(argv, svec!["deno", "script.ts"])
}
#[test]
- fn test_flags_from_vec_36() {
- let (flags, subcommand, argv) = flags_from_vec(svec![
- "deno",
- "test",
- "--exclude",
- "some_dir/",
- "**/*_test.ts"
- ]);
- assert_eq!(
- flags,
- DenoFlags {
- allow_read: true,
- ..DenoFlags::default()
- }
- );
- assert_eq!(subcommand, DenoSubcommand::Run);
- assert_eq!(
- argv,
- svec![
- "deno",
- TEST_RUNNER_URL,
- "--exclude",
- "some_dir/",
- "**/*_test.ts"
- ]
- )
- }
-
- #[test]
- fn test_flags_from_vec_37() {
- let (flags, subcommand, argv) = flags_from_vec(svec![
+ fn allow_net_whitelist_with_ports() {
+ let r = flags_from_vec_safe(svec![
"deno",
"--allow-net=deno.land,:8000,:4545",
"script.ts"
]);
assert_eq!(
- flags,
+ r.unwrap(),
DenoFlags {
+ subcommand: DenoSubcommand::Run,
+ argv: svec!["deno", "script.ts"],
net_whitelist: svec![
"deno.land",
"0.0.0.0:8000",
@@ -2066,33 +2060,31 @@ mod tests {
..DenoFlags::default()
}
);
- assert_eq!(subcommand, DenoSubcommand::Run);
- assert_eq!(argv, svec!["deno", "script.ts"])
}
#[test]
- fn test_flags_from_vec_38() {
- let (flags, subcommand, argv) = flags_from_vec(svec![
+ fn lock_write() {
+ let r = flags_from_vec_safe(svec![
"deno",
"--lock-write",
"--lock=lock.json",
"script.ts"
]);
assert_eq!(
- flags,
+ r.unwrap(),
DenoFlags {
+ subcommand: DenoSubcommand::Run,
+ argv: svec!["deno", "script.ts"],
lock_write: true,
lock: Some("lock.json".to_string()),
..DenoFlags::default()
}
);
- assert_eq!(subcommand, DenoSubcommand::Run);
- assert_eq!(argv, svec!["deno", "script.ts"])
}
#[test]
- fn test_flags_from_vec_39() {
- let (flags, subcommand, argv) = flags_from_vec(svec![
+ fn fmt_args() {
+ let r = flags_from_vec_safe(svec![
"deno",
"fmt",
"--check",
@@ -2112,44 +2104,91 @@ mod tests {
"script.ts"
]);
assert_eq!(
- flags,
+ r.unwrap(),
DenoFlags {
+ subcommand: DenoSubcommand::Run,
+ argv: svec![
+ "deno",
+ PRETTIER_URL,
+ "script.ts",
+ "--write",
+ "--check",
+ "--config",
+ "auto",
+ "--ignore-path",
+ ".prettier-ignore",
+ "--print-width",
+ "100",
+ "--tab-width",
+ "4",
+ "--use-tabs",
+ "--no-semi",
+ "--single-quote",
+ "--quote-props",
+ "preserve",
+ "--jsx-single-quote",
+ "--jsx-bracket-same-line",
+ "--arrow-parens",
+ "always",
+ "--prose-wrap",
+ "preserve",
+ "--end-of-line",
+ "crlf"
+ ],
allow_write: true,
allow_read: true,
..DenoFlags::default()
}
);
- assert_eq!(subcommand, DenoSubcommand::Run);
+ }
+
+ #[test]
+ fn test_with_exclude() {
+ let r = flags_from_vec_safe(svec![
+ "deno",
+ "test",
+ "--exclude",
+ "some_dir/",
+ "dir1/",
+ "dir2/"
+ ]);
assert_eq!(
- argv,
- svec![
- "deno",
- PRETTIER_URL,
- "script.ts",
- "--write",
- "--check",
- "--config",
- "auto",
- "--ignore-path",
- ".prettier-ignore",
- "--print-width",
- "100",
- "--tab-width",
- "4",
- "--use-tabs",
- "--no-semi",
- "--single-quote",
- "--quote-props",
- "preserve",
- "--jsx-single-quote",
- "--jsx-bracket-same-line",
- "--arrow-parens",
- "always",
- "--prose-wrap",
- "preserve",
- "--end-of-line",
- "crlf"
- ]
+ r.unwrap(),
+ DenoFlags {
+ subcommand: DenoSubcommand::Run,
+ argv: svec![
+ "deno",
+ TEST_RUNNER_URL,
+ "--exclude",
+ "some_dir/",
+ "--",
+ "dir1/",
+ "dir2/"
+ ],
+ allow_read: true,
+ ..DenoFlags::default()
+ }
+ );
+ }
+
+ #[test]
+ fn test_with_allow_net() {
+ let r = flags_from_vec_safe(svec![
+ "deno",
+ "test",
+ "--allow-net",
+ "dir1/",
+ "dir2/"
+ ]);
+ assert_eq!(
+ r.unwrap(),
+ DenoFlags {
+ subcommand: DenoSubcommand::Run,
+ argv: svec!["deno", TEST_RUNNER_URL, "--", "dir1/", "dir2/"],
+ allow_read: true,
+ allow_net: true,
+ ..DenoFlags::default()
+ }
);
}
}
diff --git a/cli/lib.rs b/cli/lib.rs
index 416147422..7328d9d26 100644
--- a/cli/lib.rs
+++ b/cli/lib.rs
@@ -95,7 +95,6 @@ impl log::Log for Logger {
fn create_worker_and_state(
flags: DenoFlags,
- argv: Vec<String>,
) -> (Worker, ThreadSafeGlobalState) {
use crate::shell::Shell;
use std::sync::Arc;
@@ -111,6 +110,8 @@ fn create_worker_and_state(
}
});
+ // TODO(ry) Remove argv param from ThreadSafeGlobalState::new.
+ let argv = flags.argv.clone();
let global_state = ThreadSafeGlobalState::new(flags, argv, progress)
.map_err(deno_error::print_err_and_exit)
.unwrap();
@@ -248,11 +249,12 @@ async fn print_file_info(worker: Worker, module_specifier: ModuleSpecifier) {
}
}
-fn info_command(flags: DenoFlags, argv: Vec<String>) {
- let (mut worker, state) = create_worker_and_state(flags, argv.clone());
+fn info_command(flags: DenoFlags) {
+ let argv_len = flags.argv.len();
+ let (mut worker, state) = create_worker_and_state(flags);
// If it was just "deno info" print location of caches and exit
- if argv.len() == 1 {
+ if argv_len == 1 {
return print_cache_info(worker);
}
@@ -276,8 +278,8 @@ fn info_command(flags: DenoFlags, argv: Vec<String>) {
tokio_util::run(main_future);
}
-fn fetch_command(flags: DenoFlags, argv: Vec<String>) {
- let (mut worker, state) = create_worker_and_state(flags, argv.clone());
+fn fetch_command(flags: DenoFlags) {
+ let (mut worker, state) = create_worker_and_state(flags);
let main_module = state.main_module.as_ref().unwrap().clone();
@@ -294,8 +296,8 @@ fn fetch_command(flags: DenoFlags, argv: Vec<String>) {
tokio_util::run(main_future);
}
-fn eval_command(flags: DenoFlags, argv: Vec<String>) {
- let (mut worker, state) = create_worker_and_state(flags, argv);
+fn eval_command(flags: DenoFlags) {
+ let (mut worker, state) = create_worker_and_state(flags);
let ts_source = state.argv[1].clone();
// Force TypeScript compile.
let main_module =
@@ -322,15 +324,11 @@ fn eval_command(flags: DenoFlags, argv: Vec<String>) {
tokio_util::run(main_future);
}
-fn bundle_command(flags: DenoFlags, argv: Vec<String>) {
- let (worker, state) = create_worker_and_state(flags, argv);
-
+fn bundle_command(flags: DenoFlags) {
+ let out_file = flags.bundle_output.clone();
+ let (worker, state) = create_worker_and_state(flags);
let main_module = state.main_module.as_ref().unwrap().clone();
- assert!(state.argv.len() >= 2);
- let out_file = match state.argv.len() {
- 3 => Some(state.argv[2].clone()),
- _ => None,
- };
+
debug!(">>>>> bundle_async START");
// NOTE: we need to poll `worker` otherwise TS compiler worker won't run properly
let main_future = async move {
@@ -351,8 +349,8 @@ fn bundle_command(flags: DenoFlags, argv: Vec<String>) {
tokio_util::run(main_future);
}
-fn run_repl(flags: DenoFlags, argv: Vec<String>) {
- let (mut worker, _state) = create_worker_and_state(flags, argv);
+fn run_repl(flags: DenoFlags) {
+ let (mut worker, _state) = create_worker_and_state(flags);
// Setup runtime.
js_check(worker.execute("denoMain()"));
let main_future = async move {
@@ -363,9 +361,9 @@ fn run_repl(flags: DenoFlags, argv: Vec<String>) {
tokio_util::run(main_future);
}
-fn run_script(flags: DenoFlags, argv: Vec<String>) {
+fn run_script(flags: DenoFlags) {
let use_current_thread = flags.current_thread;
- let (mut worker, state) = create_worker_and_state(flags, argv);
+ let (mut worker, state) = create_worker_and_state(flags);
let main_module = state.main_module.as_ref().unwrap().clone();
// Normal situation of executing a module.
@@ -406,22 +404,18 @@ fn run_script(flags: DenoFlags, argv: Vec<String>) {
}
}
-fn version_command() {
- println!("deno: {}", version::DENO);
- println!("v8: {}", version::v8());
- println!("typescript: {}", version::TYPESCRIPT);
-}
-
pub fn main() {
#[cfg(windows)]
ansi_term::enable_ansi_support().ok(); // For Windows 10
log::set_logger(&LOGGER).unwrap();
let args: Vec<String> = env::args().collect();
- let (flags, subcommand, argv) = flags::flags_from_vec(args);
+ let flags = flags::flags_from_vec(args);
if let Some(ref v8_flags) = flags.v8_flags {
- v8_set_flags(v8_flags.clone());
+ let mut v8_flags_ = v8_flags.clone();
+ v8_flags_.insert(0, "UNUSED_BUT_NECESSARY_ARG0".to_string());
+ v8_set_flags(v8_flags_);
}
let log_level = match flags.log_level {
@@ -430,15 +424,15 @@ pub fn main() {
};
log::set_max_level(log_level.to_level_filter());
- match subcommand {
- DenoSubcommand::Bundle => bundle_command(flags, argv),
+ match flags.subcommand {
+ DenoSubcommand::Bundle => bundle_command(flags),
DenoSubcommand::Completions => {}
- DenoSubcommand::Eval => eval_command(flags, argv),
- DenoSubcommand::Fetch => fetch_command(flags, argv),
- DenoSubcommand::Info => info_command(flags, argv),
- DenoSubcommand::Repl => run_repl(flags, argv),
- DenoSubcommand::Run => run_script(flags, argv),
+ DenoSubcommand::Eval => eval_command(flags),
+ DenoSubcommand::Fetch => fetch_command(flags),
+ DenoSubcommand::Info => info_command(flags),
+ DenoSubcommand::Repl => run_repl(flags),
+ DenoSubcommand::Run => run_script(flags),
DenoSubcommand::Types => types_command(),
- DenoSubcommand::Version => version_command(),
+ _ => panic!("bad subcommand"),
}
}
diff --git a/cli/tests/integration_tests.rs b/cli/tests/integration_tests.rs
index 7fd7a396b..3cc8039db 100644
--- a/cli/tests/integration_tests.rs
+++ b/cli/tests/integration_tests.rs
@@ -168,17 +168,17 @@ itest!(_012_async {
});
itest!(_013_dynamic_import {
- args: "013_dynamic_import.ts --reload --allow-read",
+ args: "run --reload --allow-read 013_dynamic_import.ts",
output: "013_dynamic_import.ts.out",
});
itest!(_014_duplicate_import {
- args: "014_duplicate_import.ts --reload --allow-read",
+ args: "run --reload --allow-read 014_duplicate_import.ts ",
output: "014_duplicate_import.ts.out",
});
itest!(_015_duplicate_parallel_import {
- args: "015_duplicate_parallel_import.js --reload --allow-read",
+ args: "run --reload --allow-read 015_duplicate_parallel_import.js",
output: "015_duplicate_parallel_import.js.out",
});
@@ -418,7 +418,7 @@ itest!(lock_check_err {
});
itest!(lock_check_err2 {
- args: "run 019_media_types.ts --lock=lock_check_err2.json",
+ args: "run --lock=lock_check_err2.json 019_media_types.ts",
output: "lock_check_err2.out",
check_stderr: true,
exit_code: 10,
@@ -538,7 +538,7 @@ itest!(error_013_missing_script {
});
itest!(error_014_catch_dynamic_import_error {
- args: "error_014_catch_dynamic_import_error.js --reload --allow-read",
+ args: "run --reload --allow-read error_014_catch_dynamic_import_error.js",
output: "error_014_catch_dynamic_import_error.js.out",
exit_code: 1,
});
@@ -641,25 +641,10 @@ itest!(v8_flags {
});
itest!(v8_help {
- args: "--v8-options",
+ args: "run --v8-flags=--help",
output: "v8_help.out",
});
-itest!(version {
- args: "version",
- output: "version.out",
-});
-
-itest!(version_long_flag {
- args: "--version",
- output: "version.out",
-});
-
-itest!(version_short_flag {
- args: "-v",
- output: "version.out",
-});
-
itest!(wasm {
args: "run wasm.ts",
output: "wasm.ts.out",
diff --git a/cli/tests/version.out b/cli/tests/version.out
deleted file mode 100644
index de13d769f..000000000
--- a/cli/tests/version.out
+++ /dev/null
@@ -1,3 +0,0 @@
-deno:[WILDCARD]
-v8:[WILDCARD]
-typescript:[WILDCARD] \ No newline at end of file
diff --git a/std/http/server_test.ts b/std/http/server_test.ts
index b9ca14630..30070b272 100644
--- a/std/http/server_test.ts
+++ b/std/http/server_test.ts
@@ -494,7 +494,7 @@ test({
async fn(): Promise<void> {
// Runs a simple server as another process
const p = Deno.run({
- args: [Deno.execPath(), "http/testdata/simple_server.ts", "--allow-net"],
+ args: [Deno.execPath(), "--allow-net", "http/testdata/simple_server.ts"],
stdout: "piped"
});
@@ -535,9 +535,9 @@ test({
const p = Deno.run({
args: [
Deno.execPath(),
- "http/testdata/simple_https_server.ts",
"--allow-net",
- "--allow-read"
+ "--allow-read",
+ "http/testdata/simple_https_server.ts"
],
stdout: "piped"
});
diff --git a/std/manual.md b/std/manual.md
index 434d2d17b..2582184ed 100644
--- a/std/manual.md
+++ b/std/manual.md
@@ -676,56 +676,39 @@ if (import.meta.main) {
Use `deno help` to see the help text.
```
-deno
A secure JavaScript and TypeScript runtime
-Docs: https://deno.land/manual.html
+Docs: https://deno.land/std/manual.md
Modules: https://deno.land/x/
Bugs: https://github.com/denoland/deno/issues
-To run the REPL:
+To run the REPL supply no arguments:
deno
-To execute a sandboxed script:
-
- deno https://deno.land/std/examples/welcome.ts
-
To evaluate code from the command line:
deno eval "console.log(30933 + 404)"
-To get help on the another subcommands (run in this case):
+To execute a script:
+
+ deno https://deno.land/std/examples/welcome.ts
+
+The default subcommand is 'run'. The above is equivalent to
+
+ deno run https://deno.land/std/examples/welcome.ts
- deno help run
+See 'deno help run' for run specific flags.
USAGE:
- deno [OPTIONS] [SUBCOMMAND]
+ deno [SUBCOMMAND]
OPTIONS:
- -A, --allow-all Allow all permissions
- --allow-env Allow environment access
- --allow-hrtime Allow high resolution time measurement
- --allow-net=<allow-net> Allow network access
- --allow-read=<allow-read> Allow file system read access
- --allow-run Allow running subprocesses
- --allow-write=<allow-write> Allow file system write access
- -c, --config <FILE> Load compiler configuration file
- --current-thread Use tokio::runtime::current_thread
- -h, --help Prints help information
- --importmap <FILE> Load import map file
- --lock <FILE> Check the specified lock file
- --lock-write Write lock file. Use with --lock.
- -L, --log-level <log-level> Set log level [possible values: debug, info]
- --no-fetch Do not download remote modules
- -r, --reload=<CACHE_BLACKLIST> Reload source code cache (recompile TypeScript)
- --seed <NUMBER> Seed Math.random()
- --v8-flags=<v8-flags> Set V8 command line options
- --v8-options Print V8 command line options
- -v, --version Print the version
+ -h, --help Prints help information
+ -L, --log-level <log-level> Set log level [possible values: debug, info]
+ -V, --version Prints version information
SUBCOMMANDS:
- [SCRIPT] Script to run
bundle Bundle module and dependencies into single file
completions Generate shell completions
eval Eval script
@@ -734,17 +717,17 @@ SUBCOMMANDS:
help Prints this message or the help of the given subcommand(s)
info Show info about cache or info related to source file
install Install script as executable
+ repl Read Eval Print Loop
run Run a program given a filename or url to the source code
test Run tests
types Print runtime TypeScript declarations
- version Print the version
xeval Eval a script on text segments from stdin
ENVIRONMENT VARIABLES:
- DENO_DIR Set deno's base directory
- NO_COLOR Set to disable color
- HTTP_PROXY Set proxy address for HTTP requests (module downloads, fetch)
- HTTPS_PROXY Set proxy address for HTTPS requests (module downloads, fetch)
+ DENO_DIR Set deno's base directory
+ NO_COLOR Set to disable color
+ HTTP_PROXY Proxy address for HTTP requests (module downloads, fetch)
+ HTTPS_PROXY Same but for HTTPS
```
### Environmental variables