diff options
Diffstat (limited to 'cli')
-rw-r--r-- | cli/compilers/ts.rs | 4 | ||||
-rw-r--r-- | cli/compilers/wasm.rs | 6 | ||||
-rw-r--r-- | cli/flags.rs | 342 | ||||
-rw-r--r-- | cli/global_state.rs | 11 | ||||
-rw-r--r-- | cli/js/runtime.ts | 11 | ||||
-rw-r--r-- | cli/js/runtime_main.ts | 7 | ||||
-rw-r--r-- | cli/lib.rs | 163 | ||||
-rw-r--r-- | cli/ops/runtime.rs | 12 | ||||
-rw-r--r-- | cli/ops/worker_host.rs | 24 | ||||
-rw-r--r-- | cli/state.rs | 25 | ||||
-rw-r--r-- | cli/tests/integration_tests.rs | 2 | ||||
-rw-r--r-- | cli/web_worker.rs | 5 | ||||
-rw-r--r-- | cli/worker.rs | 59 |
13 files changed, 331 insertions, 340 deletions
diff --git a/cli/compilers/ts.rs b/cli/compilers/ts.rs index 27203484f..8517c319b 100644 --- a/cli/compilers/ts.rs +++ b/cli/compilers/ts.rs @@ -241,8 +241,10 @@ impl TsCompiler { /// runtime. fn setup_worker(global_state: ThreadSafeGlobalState) -> CompilerWorker { let (int, ext) = ThreadSafeState::create_channels(); + let entry_point = + ModuleSpecifier::resolve_url_or_path("./__$deno$ts_compiler.ts").unwrap(); let worker_state = - ThreadSafeState::new(global_state.clone(), None, None, int) + ThreadSafeState::new(global_state.clone(), None, entry_point, int) .expect("Unable to create worker state"); // Count how many times we start the compiler worker. diff --git a/cli/compilers/wasm.rs b/cli/compilers/wasm.rs index f165654ff..0cba8118e 100644 --- a/cli/compilers/wasm.rs +++ b/cli/compilers/wasm.rs @@ -7,6 +7,7 @@ use crate::global_state::ThreadSafeGlobalState; use crate::startup_data; use crate::state::*; use deno_core::ErrBox; +use deno_core::ModuleSpecifier; use futures::FutureExt; use serde_derive::Deserialize; use serde_json; @@ -45,8 +46,11 @@ impl WasmCompiler { /// Create a new V8 worker with snapshot of WASM compiler and setup compiler's runtime. fn setup_worker(global_state: ThreadSafeGlobalState) -> CompilerWorker { let (int, ext) = ThreadSafeState::create_channels(); + let entry_point = + ModuleSpecifier::resolve_url_or_path("./__$deno$wasm_compiler.ts") + .unwrap(); let worker_state = - ThreadSafeState::new(global_state.clone(), None, None, int) + ThreadSafeState::new(global_state.clone(), None, entry_point, int) .expect("Unable to create worker state"); // Count how many times we start the compiler worker. diff --git a/cli/flags.rs b/cli/flags.rs index a0d322e56..4e314919e 100644 --- a/cli/flags.rs +++ b/cli/flags.rs @@ -33,16 +33,27 @@ const TEST_RUNNER_URL: &str = std_url!("testing/runner.ts"); #[derive(Clone, Debug, PartialEq)] pub enum DenoSubcommand { - Bundle, - Completions, - Eval, - Fetch, + Bundle { + source_file: String, + out_file: Option<String>, + }, + Completions { + buf: Box<[u8]>, + }, + Eval { + code: String, + }, + Fetch { + files: Vec<String>, + }, Format { check: bool, files: Option<Vec<String>>, }, Help, - Info, + Info { + file: Option<String>, + }, Install { dir: Option<String>, exe_name: String, @@ -50,13 +61,15 @@ pub enum DenoSubcommand { args: Vec<String>, }, Repl, - Run, + Run { + script: String, + }, Types, } impl Default for DenoSubcommand { fn default() -> DenoSubcommand { - DenoSubcommand::Run + DenoSubcommand::Repl } } @@ -89,8 +102,6 @@ pub struct DenoFlags { pub seed: Option<u64>, pub v8_flags: Option<Vec<String>>, - pub bundle_output: Option<String>, - pub lock: Option<String>, pub lock_write: bool, } @@ -202,15 +213,12 @@ pub fn flags_from_vec(args: Vec<String>) -> DenoFlags { /// 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), @@ -336,17 +344,22 @@ fn install_parse(flags: &mut DenoFlags, matches: &clap::ArgMatches) { } 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") { + let source_file = matches.value_of("source_file").unwrap().to_string(); + + let out_file = if let Some(out_file) = matches.value_of("out_file") { flags.allow_write = true; - flags.bundle_output = Some(out_file.to_string()); - } + Some(out_file.to_string()) + } else { + None + }; + + flags.subcommand = DenoSubcommand::Bundle { + source_file, + out_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; @@ -355,10 +368,10 @@ fn completions_parse(flags: &mut DenoFlags, matches: &clap::ArgMatches) { 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()); + + flags.subcommand = DenoSubcommand::Completions { + buf: buf.into_boxed_slice(), + }; } fn repl_parse(flags: &mut DenoFlags, matches: &clap::ArgMatches) { @@ -375,7 +388,6 @@ fn repl_parse(flags: &mut DenoFlags, matches: &clap::ArgMatches) { fn eval_parse(flags: &mut DenoFlags, matches: &clap::ArgMatches) { v8_flags_arg_parse(flags, matches); - flags.subcommand = DenoSubcommand::Eval; flags.allow_net = true; flags.allow_env = true; flags.allow_run = true; @@ -383,29 +395,28 @@ fn eval_parse(flags: &mut DenoFlags, matches: &clap::ArgMatches) { flags.allow_write = true; flags.allow_plugin = true; flags.allow_hrtime = true; - let code: &str = matches.value_of("code").unwrap(); - flags.argv.extend(vec![code.to_string()]); + let code = matches.value_of("code").unwrap().to_string(); + flags.subcommand = DenoSubcommand::Eval { code } } 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()); - } + flags.subcommand = DenoSubcommand::Info { + file: matches.value_of("file").map(|f| f.to_string()), + }; } 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); no_remote_arg_parse(flags, matches); - if let Some(files) = matches.values_of("file") { - for file in files { - flags.argv.push(file.into()); - } - } + let files = matches + .values_of("file") + .unwrap() + .map(String::from) + .collect(); + flags.subcommand = DenoSubcommand::Fetch { files }; } fn lock_args_parse(flags: &mut DenoFlags, matches: &clap::ArgMatches) { @@ -464,17 +475,29 @@ fn run_test_args_parse(flags: &mut DenoFlags, matches: &clap::ArgMatches) { } fn run_parse(flags: &mut DenoFlags, matches: &clap::ArgMatches) { - flags.subcommand = DenoSubcommand::Run; - script_arg_parse(flags, matches); run_test_args_parse(flags, matches); + + let mut script: Vec<String> = matches + .values_of("script_arg") + .unwrap() + .map(String::from) + .collect(); + assert!(!script.is_empty()); + let script_args = script.split_off(1); + let script = script[0].to_string(); + for v in script_args { + flags.argv.push(v); + } + + flags.subcommand = DenoSubcommand::Run { script }; } fn test_parse(flags: &mut DenoFlags, matches: &clap::ArgMatches) { - flags.subcommand = DenoSubcommand::Run; + flags.subcommand = DenoSubcommand::Run { + script: TEST_RUNNER_URL.to_string(), + }; flags.allow_read = true; - flags.argv.push(TEST_RUNNER_URL.to_string()); - run_test_args_parse(flags, matches); if matches.is_present("quiet") { @@ -849,18 +872,11 @@ _test.js and executes them. fn script_arg<'a, 'b>() -> Arg<'a, 'b> { Arg::with_name("script_arg") .multiple(true) + .required(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)); - } - } -} - fn lock_arg<'a, 'b>() -> Arg<'a, 'b> { Arg::with_name("lock") .long("lock") @@ -1172,8 +1188,9 @@ mod tests { assert_eq!( flags, DenoFlags { - subcommand: DenoSubcommand::Run, - argv: svec!["deno", "script.ts"], + subcommand: DenoSubcommand::Run { + script: "script.ts".to_string(), + }, reload: true, ..DenoFlags::default() } @@ -1193,8 +1210,9 @@ mod tests { r.unwrap(), DenoFlags { reload: true, - subcommand: DenoSubcommand::Run, - argv: svec!["deno", "script.ts"], + subcommand: DenoSubcommand::Run { + script: "script.ts".to_string(), + }, allow_write: true, ..DenoFlags::default() } @@ -1212,8 +1230,9 @@ mod tests { assert_eq!( r.unwrap(), DenoFlags { - subcommand: DenoSubcommand::Run, - argv: svec!["deno", "script.ts"], + subcommand: DenoSubcommand::Run { + script: "script.ts".to_string(), + }, v8_flags: Some(svec!["--help"]), ..DenoFlags::default() } @@ -1228,8 +1247,9 @@ mod tests { assert_eq!( r.unwrap(), DenoFlags { - subcommand: DenoSubcommand::Run, - argv: svec!["deno", "script.ts"], + subcommand: DenoSubcommand::Run { + script: "script.ts".to_string(), + }, v8_flags: Some(svec!["--expose-gc", "--gc-stats=1"]), ..DenoFlags::default() } @@ -1249,8 +1269,10 @@ mod tests { assert_eq!( r.unwrap(), DenoFlags { - subcommand: DenoSubcommand::Run, - argv: svec!["deno", "gist.ts", "--title", "X"], + subcommand: DenoSubcommand::Run { + script: "gist.ts".to_string(), + }, + argv: svec!["--title", "X"], allow_net: true, ..DenoFlags::default() } @@ -1263,8 +1285,9 @@ mod tests { assert_eq!( r.unwrap(), DenoFlags { - subcommand: DenoSubcommand::Run, - argv: svec!["deno", "gist.ts"], + subcommand: DenoSubcommand::Run { + script: "gist.ts".to_string(), + }, allow_net: true, allow_env: true, allow_run: true, @@ -1284,8 +1307,9 @@ mod tests { assert_eq!( r.unwrap(), DenoFlags { - subcommand: DenoSubcommand::Run, - argv: svec!["deno", "gist.ts"], + subcommand: DenoSubcommand::Run { + script: "gist.ts".to_string(), + }, allow_read: true, ..DenoFlags::default() } @@ -1299,8 +1323,9 @@ mod tests { assert_eq!( r.unwrap(), DenoFlags { - subcommand: DenoSubcommand::Run, - argv: svec!["deno", "gist.ts"], + subcommand: DenoSubcommand::Run { + script: "gist.ts".to_string(), + }, allow_hrtime: true, ..DenoFlags::default() } @@ -1324,8 +1349,10 @@ mod tests { assert_eq!( r.unwrap(), DenoFlags { - subcommand: DenoSubcommand::Run, - argv: svec!["deno", "script.ts", "--", "-D", "--allow-net"], + subcommand: DenoSubcommand::Run { + script: "script.ts".to_string(), + }, + argv: svec!["--", "-D", "--allow-net"], allow_write: true, ..DenoFlags::default() } @@ -1343,7 +1370,6 @@ mod tests { check: false, files: Some(svec!["script_1.ts", "script_2.ts"]) }, - argv: svec!["deno"], ..DenoFlags::default() } ); @@ -1356,7 +1382,6 @@ mod tests { check: true, files: None }, - argv: svec!["deno"], ..DenoFlags::default() } ); @@ -1369,7 +1394,6 @@ mod tests { r.unwrap(), DenoFlags { subcommand: DenoSubcommand::Types, - argv: svec!["deno"], ..DenoFlags::default() } ); @@ -1381,8 +1405,9 @@ mod tests { assert_eq!( r.unwrap(), DenoFlags { - subcommand: DenoSubcommand::Fetch, - argv: svec!["deno", "script.ts"], + subcommand: DenoSubcommand::Fetch { + files: svec!["script.ts"], + }, ..DenoFlags::default() } ); @@ -1394,10 +1419,9 @@ mod tests { 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"], + subcommand: DenoSubcommand::Info { + file: Some("script.ts".to_string()), + }, ..DenoFlags::default() } ); @@ -1406,8 +1430,7 @@ mod tests { assert_eq!( r.unwrap(), DenoFlags { - subcommand: DenoSubcommand::Info, - argv: svec!["deno"], // TODO(ry) Ditto argv unnecessary? + subcommand: DenoSubcommand::Info { file: None }, ..DenoFlags::default() } ); @@ -1425,8 +1448,9 @@ mod tests { assert_eq!( r.unwrap(), DenoFlags { - subcommand: DenoSubcommand::Run, - argv: svec!["deno", "script.ts"], + subcommand: DenoSubcommand::Run { + script: "script.ts".to_string(), + }, config_path: Some("tsconfig.json".to_owned()), ..DenoFlags::default() } @@ -1440,9 +1464,9 @@ mod tests { assert_eq!( r.unwrap(), DenoFlags { - subcommand: DenoSubcommand::Eval, - // TODO(ry) argv in this test seems odd and potentially not correct. - argv: svec!["deno", "'console.log(\"hello\")'"], + subcommand: DenoSubcommand::Eval { + code: "'console.log(\"hello\")'".to_string(), + }, allow_net: true, allow_env: true, allow_run: true, @@ -1462,8 +1486,9 @@ mod tests { assert_eq!( r.unwrap(), DenoFlags { - subcommand: DenoSubcommand::Eval, - argv: svec!["deno", "42"], + subcommand: DenoSubcommand::Eval { + code: "42".to_string(), + }, v8_flags: Some(svec!["--help"]), allow_net: true, allow_env: true, @@ -1484,7 +1509,6 @@ mod tests { r.unwrap(), DenoFlags { subcommand: DenoSubcommand::Repl, - argv: svec!["deno"], allow_net: true, allow_env: true, allow_run: true, @@ -1517,8 +1541,9 @@ mod tests { current_dir().unwrap().to_str().unwrap().to_owned(), &temp_dir_path ], - argv: svec!["deno", "script.ts"], - subcommand: DenoSubcommand::Run, + subcommand: DenoSubcommand::Run { + script: "script.ts".to_string(), + }, ..DenoFlags::default() } ); @@ -1544,8 +1569,9 @@ mod tests { current_dir().unwrap().to_str().unwrap().to_owned(), &temp_dir_path ], - argv: svec!["deno", "script.ts"], - subcommand: DenoSubcommand::Run, + subcommand: DenoSubcommand::Run { + script: "script.ts".to_string(), + }, ..DenoFlags::default() } ); @@ -1562,8 +1588,9 @@ mod tests { assert_eq!( r.unwrap(), DenoFlags { - subcommand: DenoSubcommand::Run, - argv: svec!["deno", "script.ts"], + subcommand: DenoSubcommand::Run { + script: "script.ts".to_string(), + }, allow_net: false, net_whitelist: svec!["127.0.0.1"], ..DenoFlags::default() @@ -1577,8 +1604,9 @@ mod tests { assert_eq!( r.unwrap(), DenoFlags { - subcommand: DenoSubcommand::Run, - argv: svec!["deno", "script.ts"], + subcommand: DenoSubcommand::Run { + script: "script.ts".to_string(), + }, ..DenoFlags::default() } ); @@ -1595,8 +1623,9 @@ mod tests { assert_eq!( r.unwrap(), DenoFlags { - subcommand: DenoSubcommand::Run, - argv: svec!["deno", "script.ts"], + subcommand: DenoSubcommand::Run { + script: "script.ts".to_string(), + }, allow_net: true, allow_read: true, ..DenoFlags::default() @@ -1610,9 +1639,10 @@ mod tests { assert_eq!( r.unwrap(), DenoFlags { - subcommand: DenoSubcommand::Bundle, - argv: svec!["deno", "source.ts"], - bundle_output: None, + subcommand: DenoSubcommand::Bundle { + source_file: "source.ts".to_string(), + out_file: None, + }, ..DenoFlags::default() } ); @@ -1625,9 +1655,10 @@ mod tests { assert_eq!( r.unwrap(), DenoFlags { - subcommand: DenoSubcommand::Bundle, - argv: svec!["deno", "source.ts"], - bundle_output: Some("bundle.js".to_string()), + subcommand: DenoSubcommand::Bundle { + source_file: "source.ts".to_string(), + out_file: Some("bundle.js".to_string()), + }, allow_write: true, ..DenoFlags::default() } @@ -1645,8 +1676,9 @@ mod tests { assert_eq!( r.unwrap(), DenoFlags { - subcommand: DenoSubcommand::Run, - argv: svec!["deno", "script.ts"], + subcommand: DenoSubcommand::Run { + script: "script.ts".to_string(), + }, import_map_path: Some("importmap.json".to_owned()), ..DenoFlags::default() } @@ -1663,8 +1695,9 @@ mod tests { assert_eq!( r.unwrap(), DenoFlags { - subcommand: DenoSubcommand::Run, - argv: svec!["deno", "script.ts"], + subcommand: DenoSubcommand::Run { + script: "script.ts".to_string(), + }, import_map_path: Some("importmap.json".to_owned()), ..DenoFlags::default() } @@ -1682,8 +1715,9 @@ mod tests { assert_eq!( r.unwrap(), DenoFlags { - subcommand: DenoSubcommand::Fetch, - argv: svec!["deno", "script.ts"], + subcommand: DenoSubcommand::Fetch { + files: svec!["script.ts"], + }, import_map_path: Some("importmap.json".to_owned()), ..DenoFlags::default() } @@ -1697,8 +1731,9 @@ mod tests { assert_eq!( r.unwrap(), DenoFlags { - subcommand: DenoSubcommand::Fetch, - argv: svec!["deno", "script.ts", "script_two.ts"], + subcommand: DenoSubcommand::Fetch { + files: svec!["script.ts", "script_two.ts"], + }, ..DenoFlags::default() } ); @@ -1711,8 +1746,9 @@ mod tests { assert_eq!( r.unwrap(), DenoFlags { - subcommand: DenoSubcommand::Run, - argv: svec!["deno", "script.ts"], + subcommand: DenoSubcommand::Run { + script: "script.ts".to_string(), + }, seed: Some(250 as u64), v8_flags: Some(svec!["--random-seed=250"]), ..DenoFlags::default() @@ -1733,8 +1769,9 @@ mod tests { assert_eq!( r.unwrap(), DenoFlags { - subcommand: DenoSubcommand::Run, - argv: svec!["deno", "script.ts"], + subcommand: DenoSubcommand::Run { + script: "script.ts".to_string(), + }, seed: Some(250 as u64), v8_flags: Some(svec!["--expose-gc", "--random-seed=250"]), ..DenoFlags::default() @@ -1759,7 +1796,6 @@ mod tests { module_url: "https://deno.land/std/examples/colors.ts".to_string(), args: vec![], }, - argv: svec!["deno"], ..DenoFlags::default() } ); @@ -1784,7 +1820,6 @@ mod tests { module_url: "https://deno.land/std/http/file_server.ts".to_string(), args: vec![], }, - argv: svec!["deno"], allow_net: true, allow_read: true, ..DenoFlags::default() @@ -1815,7 +1850,6 @@ mod tests { module_url: "https://deno.land/std/http/file_server.ts".to_string(), args: svec!["arg1", "arg2"], }, - argv: svec!["deno"], allow_net: true, allow_read: true, ..DenoFlags::default() @@ -1830,8 +1864,9 @@ mod tests { assert_eq!( r.unwrap(), DenoFlags { - subcommand: DenoSubcommand::Run, - argv: svec!["deno", "script.ts"], + subcommand: DenoSubcommand::Run { + script: "script.ts".to_string(), + }, log_level: Some(Level::Debug), ..DenoFlags::default() } @@ -1840,15 +1875,12 @@ mod tests { #[test] 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() - } - ); + let r = flags_from_vec_safe(svec!["deno", "completions", "bash"]).unwrap(); + + match r.subcommand { + DenoSubcommand::Completions { buf } => assert!(!buf.is_empty()), + _ => unreachable!(), + } } /* TODO(ry) Fix this test @@ -1865,7 +1897,7 @@ mod tests { } ); assert_eq!(subcommand, DenoSubcommand::Run); - assert_eq!(argv, svec!["deno", "script.ts"]); + assert_eq!(argv, svec!["script.ts"]); let (flags, subcommand, argv) = flags_from_vec_safe(svec![ "deno", @@ -1891,22 +1923,22 @@ mod tests { assert_eq!(argv, svec!["deno", "script.ts", "--help", "--foo", "bar"]); let (flags, subcommand, argv) = - flags_from_vec_safe(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"]); + assert_eq!(argv, svec!["script.ts", "foo", "bar"]); let (flags, subcommand, argv) = - flags_from_vec_safe(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", "-"]); + assert_eq!(argv, svec!["script.ts", "-"]); let (flags, subcommand, argv) = - flags_from_vec_safe(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"]); + assert_eq!(argv, svec!["script.ts", "-", "foo", "bar"]); } */ @@ -1916,8 +1948,9 @@ mod tests { assert_eq!( r.unwrap(), DenoFlags { - subcommand: DenoSubcommand::Run, - argv: svec!["deno", "script.ts"], + subcommand: DenoSubcommand::Run { + script: "script.ts".to_string(), + }, no_remote: true, ..DenoFlags::default() } @@ -1930,8 +1963,9 @@ mod tests { assert_eq!( r.unwrap(), DenoFlags { - subcommand: DenoSubcommand::Run, - argv: svec!["deno", "script.ts"], + subcommand: DenoSubcommand::Run { + script: "script.ts".to_string(), + }, cached_only: true, ..DenoFlags::default() } @@ -1948,8 +1982,9 @@ mod tests { assert_eq!( r.unwrap(), DenoFlags { - subcommand: DenoSubcommand::Run, - argv: svec!["deno", "script.ts"], + subcommand: DenoSubcommand::Run { + script: "script.ts".to_string(), + }, net_whitelist: svec![ "deno.land", "0.0.0.0:8000", @@ -1975,8 +2010,9 @@ mod tests { assert_eq!( r.unwrap(), DenoFlags { - subcommand: DenoSubcommand::Run, - argv: svec!["deno", "script.ts"], + subcommand: DenoSubcommand::Run { + script: "script.ts".to_string(), + }, lock_write: true, lock: Some("lock.json".to_string()), ..DenoFlags::default() @@ -1997,16 +2033,10 @@ mod tests { assert_eq!( r.unwrap(), DenoFlags { - subcommand: DenoSubcommand::Run, - argv: svec![ - "deno", - TEST_RUNNER_URL, - "--exclude", - "some_dir/", - "--", - "dir1/", - "dir2/" - ], + subcommand: DenoSubcommand::Run { + script: TEST_RUNNER_URL.to_string(), + }, + argv: svec!["--exclude", "some_dir/", "--", "dir1/", "dir2/"], allow_read: true, ..DenoFlags::default() } @@ -2025,8 +2055,10 @@ mod tests { assert_eq!( r.unwrap(), DenoFlags { - subcommand: DenoSubcommand::Run, - argv: svec!["deno", TEST_RUNNER_URL, "--", "dir1/", "dir2/"], + subcommand: DenoSubcommand::Run { + script: TEST_RUNNER_URL.to_string(), + }, + argv: svec!["--", "dir1/", "dir2/"], allow_read: true, allow_net: true, ..DenoFlags::default() diff --git a/cli/global_state.rs b/cli/global_state.rs index bd2a4f4c3..80f7d6e7a 100644 --- a/cli/global_state.rs +++ b/cli/global_state.rs @@ -34,8 +34,6 @@ pub struct ThreadSafeGlobalState(Arc<GlobalState>); pub struct GlobalState { /// Flags parsed from `argv` contents. pub flags: flags::DenoFlags, - /// Entry script parsed from CLI arguments. - pub main_module: Option<ModuleSpecifier>, /// Permissions parsed from `flags`. pub permissions: DenoPermissions, pub dir: deno_dir::DenoDir, @@ -86,13 +84,6 @@ impl ThreadSafeGlobalState { flags.config_path.clone(), )?; - let main_module: Option<ModuleSpecifier> = if flags.argv.len() <= 1 { - None - } else { - let root_specifier = flags.argv[1].clone(); - Some(ModuleSpecifier::resolve_url_or_path(&root_specifier)?) - }; - // Note: reads lazily from disk on first call to lockfile.check() let lockfile = if let Some(filename) = &flags.lock { Some(Mutex::new(Lockfile::new(filename.to_string()))) @@ -101,7 +92,6 @@ impl ThreadSafeGlobalState { }; let state = GlobalState { - main_module, dir, permissions: DenoPermissions::from_flags(&flags), flags, @@ -258,7 +248,6 @@ fn thread_safe() { fn import_map_given_for_repl() { let _result = ThreadSafeGlobalState::new( flags::DenoFlags { - argv: vec![String::from("./deno")], import_map_path: Some("import_map.json".to_string()), ..flags::DenoFlags::default() }, diff --git a/cli/js/runtime.ts b/cli/js/runtime.ts index 8cebf5dca..53ce5fcee 100644 --- a/cli/js/runtime.ts +++ b/cli/js/runtime.ts @@ -13,8 +13,9 @@ import { setPrepareStackTrace } from "./error_stack.ts"; interface Start { cwd: string; pid: number; - argv: string[]; - mainModule: string; // Absolute URL. + args: string[]; + location: string; // Absolute URL. + repl: boolean; debugFlag: boolean; depsFlag: boolean; typesFlag: boolean; @@ -57,10 +58,8 @@ export function start(preserveDenoNamespace = true, source?: string): Start { util.setLogDebug(s.debugFlag, source); // TODO(bartlomieju): this field should always be set - if (s.mainModule) { - assert(s.mainModule.length > 0); - setLocation(s.mainModule); - } + assert(s.location.length > 0); + setLocation(s.location); setPrepareStackTrace(Error); // TODO(bartlomieju): I don't like that it's mixed in here, when diff --git a/cli/js/runtime_main.ts b/cli/js/runtime_main.ts index 2ede2e20f..b5517cbcb 100644 --- a/cli/js/runtime_main.ts +++ b/cli/js/runtime_main.ts @@ -72,14 +72,13 @@ export function bootstrapMainRuntime(): void { setSignals(); log("cwd", s.cwd); - for (let i = 0; i < s.argv.length; i++) { - args.push(s.argv[i]); + for (let i = 0; i < s.args.length; i++) { + args.push(s.args[i]); } log("args", args); Object.freeze(args); - // TODO(bartlomieju): rename to s.repl - if (!s.mainModule) { + if (s.repl) { replLoop(); } } diff --git a/cli/lib.rs b/cli/lib.rs index f04db5c25..a7390b515 100644 --- a/cli/lib.rs +++ b/cli/lib.rs @@ -98,9 +98,7 @@ impl log::Log for Logger { fn flush(&self) {} } -fn create_worker_and_state( - flags: DenoFlags, -) -> (MainWorker, ThreadSafeGlobalState) { +fn create_global_state(flags: DenoFlags) -> ThreadSafeGlobalState { use crate::shell::Shell; use std::sync::Arc; use std::sync::Mutex; @@ -115,19 +113,19 @@ fn create_worker_and_state( } }); - let global_state = ThreadSafeGlobalState::new(flags, progress) + ThreadSafeGlobalState::new(flags, progress) .map_err(deno_error::print_err_and_exit) - .unwrap(); + .unwrap() +} +fn create_main_worker( + global_state: ThreadSafeGlobalState, + main_module: ModuleSpecifier, +) -> MainWorker { let (int, ext) = ThreadSafeState::create_channels(); - let state = ThreadSafeState::new( - global_state.clone(), - None, - global_state.main_module.clone(), - int, - ) - .map_err(deno_error::print_err_and_exit) - .unwrap(); + let state = ThreadSafeState::new(global_state, None, main_module, int) + .map_err(deno_error::print_err_and_exit) + .unwrap(); let state_ = state.clone(); { @@ -138,14 +136,12 @@ fn create_worker_and_state( resource_table.add("stderr", Box::new(stderr)); } - let worker = MainWorker::new( + MainWorker::new( "main".to_string(), startup_data::deno_isolate_init(), state, ext, - ); - - (worker, global_state) + ) } fn types_command() { @@ -157,9 +153,7 @@ fn types_command() { ); } -fn print_cache_info(worker: MainWorker) { - let state = &worker.state.global_state; - +fn print_cache_info(state: &ThreadSafeGlobalState) { println!( "{} {:?}", colors::bold("DENO_DIR location:".to_string()), @@ -257,20 +251,19 @@ async fn print_file_info( } } -async fn info_command(flags: DenoFlags) { - let argv_len = flags.argv.len(); - let (mut worker, state) = create_worker_and_state(flags); - +async fn info_command(flags: DenoFlags, file: Option<String>) { + let global_state = create_global_state(flags); // If it was just "deno info" print location of caches and exit - if argv_len == 1 { - return print_cache_info(worker); + if file.is_none() { + return print_cache_info(&global_state); } - - let main_module = state.main_module.as_ref().unwrap().clone(); - // Setup runtime. + let main_module = ModuleSpecifier::resolve_url_or_path(&file.unwrap()) + .expect("Bad specifier"); + let mut worker = create_main_worker(global_state, main_module.clone()); + + // TODO(bartlomieju): not needed? js_check(worker.execute("bootstrapMainRuntime()")); - debug!("main_module {}", main_module); let main_result = worker.execute_mod_async(&main_module, None, true).await; if let Err(e) = main_result { @@ -291,9 +284,8 @@ async fn install_command( // Firstly fetch and compile module, this // ensures the module exists. let mut fetch_flags = flags.clone(); - fetch_flags.argv.push(module_url.to_string()); fetch_flags.reload = true; - fetch_command(fetch_flags).await; + fetch_command(fetch_flags, vec![module_url.to_string()]).await; let install_result = installer::install(flags, dir, &exe_name, &module_url, args); @@ -302,33 +294,24 @@ async fn install_command( } } -async fn fetch_command(flags: DenoFlags) { - let args = flags.argv.clone(); - - let (mut worker, state) = create_worker_and_state(flags); - - let main_module = state.main_module.as_ref().unwrap().clone(); +async fn fetch_command(flags: DenoFlags, files: Vec<String>) { + let main_module = + ModuleSpecifier::resolve_url_or_path("./__$deno$fetch.ts").unwrap(); + let global_state = create_global_state(flags); + let mut worker = + create_main_worker(global_state.clone(), main_module.clone()); - // Setup runtime. + // TODO(bartlomieju): not needed? js_check(worker.execute("bootstrapMainRuntime()")); - debug!("main_module {}", main_module); - let result = worker.execute_mod_async(&main_module, None, true).await; - js_check(result); - - // resolve modules for rest of args if present - let files_len = args.len(); - if files_len > 2 { - for next_specifier in args.iter().take(files_len).skip(2) { - let next_module = - ModuleSpecifier::resolve_url_or_path(&next_specifier).unwrap(); - let result = worker.execute_mod_async(&next_module, None, true).await; - js_check(result); - } + for file in files { + let specifier = ModuleSpecifier::resolve_url_or_path(&file).unwrap(); + let result = worker.execute_mod_async(&specifier, None, true).await; + js_check(result); } - if state.flags.lock_write { - if let Some(ref lockfile) = state.lockfile { + if global_state.flags.lock_write { + if let Some(ref lockfile) = global_state.lockfile { let g = lockfile.lock().unwrap(); if let Err(e) = g.write() { print_err_and_exit(ErrBox::from(e)); @@ -340,18 +323,18 @@ async fn fetch_command(flags: DenoFlags) { } } -async fn eval_command(flags: DenoFlags) { - let ts_source = flags.argv[1].clone(); - let (mut worker, _state) = create_worker_and_state(flags); +async fn eval_command(flags: DenoFlags, code: String) { // Force TypeScript compile. let main_module = ModuleSpecifier::resolve_url_or_path("./__$deno$eval.ts").unwrap(); + let global_state = create_global_state(flags); + let mut worker = create_main_worker(global_state, main_module.clone()); js_check(worker.execute("bootstrapMainRuntime()")); debug!("main_module {}", &main_module); let exec_result = worker - .execute_mod_async(&main_module, Some(ts_source), false) + .execute_mod_async(&main_module, Some(code), false) .await; if let Err(e) = exec_result { print_err_and_exit(e); @@ -362,18 +345,28 @@ async fn eval_command(flags: DenoFlags) { js_check(worker.execute("window.dispatchEvent(new Event('unload'))")); } -async fn bundle_command(flags: DenoFlags) { - let out_file = flags.bundle_output.clone(); - let (mut worker, state) = create_worker_and_state(flags); - let main_module = state.main_module.as_ref().unwrap().clone(); - +async fn bundle_command( + flags: DenoFlags, + source_file: String, + out_file: Option<String>, +) { debug!(">>>>> bundle_async START"); + let source_file_specifier = + ModuleSpecifier::resolve_url_or_path(&source_file).expect("Bad specifier"); + let global_state = create_global_state(flags); + let mut worker = + create_main_worker(global_state.clone(), source_file_specifier.clone()); + // NOTE: we need to poll `worker` otherwise TS compiler worker won't run properly let result = (&mut *worker).await; js_check(result); - let bundle_result = state + let bundle_result = global_state .ts_compiler - .bundle_async(state.clone(), main_module.to_string(), out_file) + .bundle_async( + global_state.clone(), + source_file_specifier.to_string(), + out_file, + ) .await; if let Err(err) = bundle_result { debug!("diagnostics returned, exiting!"); @@ -384,7 +377,10 @@ async fn bundle_command(flags: DenoFlags) { } async fn run_repl(flags: DenoFlags) { - let (mut worker, _state) = create_worker_and_state(flags); + let main_module = + ModuleSpecifier::resolve_url_or_path("./__$deno$repl.ts").unwrap(); + let global_state = create_global_state(flags); + let mut worker = create_main_worker(global_state, main_module); js_check(worker.execute("bootstrapMainRuntime()")); loop { let result = (&mut *worker).await; @@ -394,15 +390,11 @@ async fn run_repl(flags: DenoFlags) { } } -async fn run_script(flags: DenoFlags) { - let (mut worker, state) = create_worker_and_state(flags); - - let maybe_main_module = state.main_module.as_ref(); - if maybe_main_module.is_none() { - print_msg_and_exit("Please provide a name to the main script to run."); - } - let main_module = maybe_main_module.unwrap().clone(); - // Normal situation of executing a module. +async fn run_script(flags: DenoFlags, script: String) { + let main_module = ModuleSpecifier::resolve_url_or_path(&script).unwrap(); + let global_state = create_global_state(flags); + let mut worker = + create_main_worker(global_state.clone(), main_module.clone()); // Setup runtime. js_check(worker.execute("bootstrapMainRuntime()")); @@ -412,8 +404,8 @@ async fn run_script(flags: DenoFlags) { if let Err(err) = mod_result { print_err_and_exit(err); } - if state.flags.lock_write { - if let Some(ref lockfile) = state.lockfile { + if global_state.flags.lock_write { + if let Some(ref lockfile) = global_state.lockfile { let g = lockfile.lock().unwrap(); if let Err(e) = g.write() { print_err_and_exit(ErrBox::from(e)); @@ -455,14 +447,19 @@ pub fn main() { let fut = async move { match flags.clone().subcommand { - DenoSubcommand::Bundle => bundle_command(flags).await, - DenoSubcommand::Completions => {} - DenoSubcommand::Eval => eval_command(flags).await, - DenoSubcommand::Fetch => fetch_command(flags).await, + DenoSubcommand::Bundle { + source_file, + out_file, + } => bundle_command(flags, source_file, out_file).await, + DenoSubcommand::Completions { buf } => { + print!("{}", std::str::from_utf8(&buf).unwrap()); + } + DenoSubcommand::Eval { code } => eval_command(flags, code).await, + DenoSubcommand::Fetch { files } => fetch_command(flags, files).await, DenoSubcommand::Format { check, files } => { fmt_command(files, check).await } - DenoSubcommand::Info => info_command(flags).await, + DenoSubcommand::Info { file } => info_command(flags, file).await, DenoSubcommand::Install { dir, exe_name, @@ -470,7 +467,7 @@ pub fn main() { args, } => install_command(flags, dir, exe_name, module_url, args).await, DenoSubcommand::Repl => run_repl(flags).await, - DenoSubcommand::Run => run_script(flags).await, + DenoSubcommand::Run { script } => run_script(flags, script).await, DenoSubcommand::Types => types_command(), _ => panic!("bad subcommand"), } diff --git a/cli/ops/runtime.rs b/cli/ops/runtime.rs index 886326146..210bbfcf6 100644 --- a/cli/ops/runtime.rs +++ b/cli/ops/runtime.rs @@ -5,6 +5,7 @@ use crate::fs as deno_fs; use crate::ops::json_op; use crate::state::ThreadSafeState; use crate::version; +use crate::DenoSubcommand; use deno_core::*; use std::env; @@ -28,16 +29,13 @@ fn op_start( _zero_copy: Option<ZeroCopyBuf>, ) -> Result<JsonOp, ErrBox> { let gs = &state.global_state; - let script_args = if gs.flags.argv.len() >= 2 { - gs.flags.argv.clone().split_off(2) - } else { - vec![] - }; + Ok(JsonOp::Sync(json!({ "cwd": deno_fs::normalize_path(&env::current_dir().unwrap()), "pid": std::process::id(), - "argv": script_args, - "mainModule": gs.main_module.as_ref().map(|x| x.to_string()), + "args": gs.flags.argv.clone(), + "repl": gs.flags.subcommand == DenoSubcommand::Repl, + "location": state.main_module.to_string(), "debugFlag": gs.flags.log_level.map_or(false, |l| l == log::Level::Debug), "versionFlag": gs.flags.version, "v8Version": version::v8(), diff --git a/cli/ops/worker_host.rs b/cli/ops/worker_host.rs index 519294314..b033b9ed9 100644 --- a/cli/ops/worker_host.rs +++ b/cli/ops/worker_host.rs @@ -86,24 +86,24 @@ fn op_create_worker( load_sender.send(Err(err.into())).unwrap(); return; } - let mut module_specifier = result.unwrap(); - if !has_source_code { - if let Some(referrer) = parent_state.main_module.as_ref() { - let referrer = referrer.clone().to_string(); - let result = ModuleSpecifier::resolve_import(&specifier, &referrer); - if let Err(err) = result { - load_sender.send(Err(err.into())).unwrap(); - return; - } - module_specifier = result.unwrap(); + + let module_specifier = if !has_source_code { + let referrer = parent_state.main_module.to_string(); + let result = ModuleSpecifier::resolve_import(&specifier, &referrer); + if let Err(err) = result { + load_sender.send(Err(err.into())).unwrap(); + return; } - } + result.unwrap() + } else { + result.unwrap() + }; let (int, ext) = ThreadSafeState::create_channels(); let result = ThreadSafeState::new_for_worker( parent_state.global_state.clone(), Some(parent_state.permissions.clone()), // by default share with parent - Some(module_specifier.clone()), + module_specifier.clone(), int, ); if let Err(err) = result { diff --git a/cli/state.rs b/cli/state.rs index 269264dbf..903c5871b 100644 --- a/cli/state.rs +++ b/cli/state.rs @@ -47,7 +47,7 @@ pub struct ThreadSafeState(Arc<State>); pub struct State { pub global_state: ThreadSafeGlobalState, pub permissions: Arc<Mutex<DenoPermissions>>, - pub main_module: Option<ModuleSpecifier>, + pub main_module: ModuleSpecifier, // TODO(ry) rename to worker_channels_internal pub worker_channels: WorkerChannels, /// When flags contains a `.import_map_path` option, the content of the @@ -240,7 +240,7 @@ impl ThreadSafeState { pub fn new( global_state: ThreadSafeGlobalState, shared_permissions: Option<Arc<Mutex<DenoPermissions>>>, - main_module: Option<ModuleSpecifier>, + main_module: ModuleSpecifier, internal_channels: WorkerChannels, ) -> Result<Self, ErrBox> { let import_map: Option<ImportMap> = @@ -285,7 +285,7 @@ impl ThreadSafeState { pub fn new_for_worker( global_state: ThreadSafeGlobalState, shared_permissions: Option<Arc<Mutex<DenoPermissions>>>, - main_module: Option<ModuleSpecifier>, + main_module: ModuleSpecifier, internal_channels: WorkerChannels, ) -> Result<Self, ErrBox> { let seeded_rng = match global_state.flags.seed { @@ -389,19 +389,13 @@ impl ThreadSafeState { #[cfg(test)] pub fn mock( - argv: Vec<String>, + main_module: &str, internal_channels: WorkerChannels, ) -> ThreadSafeState { - let module_specifier = if argv.is_empty() { - None - } else { - let module_specifier = ModuleSpecifier::resolve_url_or_path(&argv[0]) - .expect("Invalid entry module"); - Some(module_specifier) - }; - + let module_specifier = ModuleSpecifier::resolve_url_or_path(main_module) + .expect("Invalid entry module"); ThreadSafeState::new( - ThreadSafeGlobalState::mock(argv), + ThreadSafeGlobalState::mock(vec!["deno".to_string()]), None, module_specifier, internal_channels, @@ -438,8 +432,5 @@ impl ThreadSafeState { fn thread_safe() { fn f<S: Send + Sync>(_: S) {} let (int, _) = ThreadSafeState::create_channels(); - f(ThreadSafeState::mock( - vec![String::from("./deno"), String::from("hello.js")], - int, - )); + f(ThreadSafeState::mock("./hello.js", int)); } diff --git a/cli/tests/integration_tests.rs b/cli/tests/integration_tests.rs index 7d3eaf887..8fbe52dc7 100644 --- a/cli/tests/integration_tests.rs +++ b/cli/tests/integration_tests.rs @@ -794,7 +794,7 @@ itest!(run_v8_flags { }); itest!(run_v8_help { - args: "run --v8-flags=--help", + args: "--v8-flags=--help", output: "v8_help.out", }); diff --git a/cli/web_worker.rs b/cli/web_worker.rs index 575910cfa..d984c47b6 100644 --- a/cli/web_worker.rs +++ b/cli/web_worker.rs @@ -77,10 +77,7 @@ mod tests { fn create_test_worker() -> WebWorker { let (int, ext) = ThreadSafeState::create_channels(); - let state = ThreadSafeState::mock( - vec![String::from("./deno"), String::from("hello.js")], - int, - ); + let state = ThreadSafeState::mock("./hello.js", int); let mut worker = WebWorker::new( "TEST".to_string(), startup_data::deno_isolate_init(), diff --git a/cli/worker.rs b/cli/worker.rs index 07a96af16..b81a77a9e 100644 --- a/cli/worker.rs +++ b/cli/worker.rs @@ -230,22 +230,13 @@ mod tests { .join("cli/tests/esm_imports_a.js"); let module_specifier = ModuleSpecifier::resolve_url_or_path(&p.to_string_lossy()).unwrap(); - let global_state = ThreadSafeGlobalState::new( - flags::DenoFlags { - argv: vec![String::from("./deno"), module_specifier.to_string()], - ..flags::DenoFlags::default() - }, - Progress::new(), - ) - .unwrap(); + let global_state = + ThreadSafeGlobalState::new(flags::DenoFlags::default(), Progress::new()) + .unwrap(); let (int, ext) = ThreadSafeState::create_channels(); - let state = ThreadSafeState::new( - global_state, - None, - Some(module_specifier.clone()), - int, - ) - .unwrap(); + let state = + ThreadSafeState::new(global_state, None, module_specifier.clone(), int) + .unwrap(); let state_ = state.clone(); tokio_util::run_basic(async move { let mut worker = @@ -275,22 +266,13 @@ mod tests { .join("tests/circular1.ts"); let module_specifier = ModuleSpecifier::resolve_url_or_path(&p.to_string_lossy()).unwrap(); - let global_state = ThreadSafeGlobalState::new( - flags::DenoFlags { - argv: vec![String::from("deno"), module_specifier.to_string()], - ..flags::DenoFlags::default() - }, - Progress::new(), - ) - .unwrap(); + let global_state = + ThreadSafeGlobalState::new(flags::DenoFlags::default(), Progress::new()) + .unwrap(); let (int, ext) = ThreadSafeState::create_channels(); - let state = ThreadSafeState::new( - global_state, - None, - Some(module_specifier.clone()), - int, - ) - .unwrap(); + let state = + ThreadSafeState::new(global_state, None, module_specifier.clone(), int) + .unwrap(); let state_ = state.clone(); tokio_util::run_basic(async move { let mut worker = @@ -321,16 +303,20 @@ mod tests { .join("cli/tests/006_url_imports.ts"); let module_specifier = ModuleSpecifier::resolve_url_or_path(&p.to_string_lossy()).unwrap(); - let mut flags = flags::DenoFlags::default(); - flags.argv = vec![String::from("deno"), module_specifier.to_string()]; - flags.reload = true; + let flags = flags::DenoFlags { + subcommand: flags::DenoSubcommand::Run { + script: module_specifier.to_string(), + }, + reload: true, + ..flags::DenoFlags::default() + }; let global_state = ThreadSafeGlobalState::new(flags, Progress::new()).unwrap(); let (int, ext) = ThreadSafeState::create_channels(); let state = ThreadSafeState::new( global_state.clone(), None, - Some(module_specifier.clone()), + module_specifier.clone(), int, ) .unwrap(); @@ -361,10 +347,7 @@ mod tests { fn create_test_worker() -> MainWorker { let (int, ext) = ThreadSafeState::create_channels(); - let state = ThreadSafeState::mock( - vec![String::from("./deno"), String::from("hello.js")], - int, - ); + let state = ThreadSafeState::mock("./hello.js", int); let mut worker = MainWorker::new( "TEST".to_string(), startup_data::deno_isolate_init(), |