1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-25 15:29:32 -05:00

Refactor CLI entry point (#2157)

Changes "deno --types" to "deno types"
and "deno --prefetch" to "deno prefetch"
This commit is contained in:
Bartek Iwańczuk 2019-04-21 17:34:18 +02:00 committed by Ryan Dahl
parent c08075053f
commit cd19da62d9
12 changed files with 425 additions and 404 deletions

View file

@ -1,6 +1,5 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
use clap::{App, AppSettings, Arg, ArgMatches, SubCommand}; use clap::{App, AppSettings, Arg, ArgMatches, SubCommand};
use deno::v8_set_flags;
// Creates vector of strings, Vec<String> // Creates vector of strings, Vec<String>
#[cfg(test)] #[cfg(test)]
@ -21,81 +20,15 @@ pub struct DenoFlags {
pub allow_run: bool, pub allow_run: bool,
pub allow_high_precision: bool, pub allow_high_precision: bool,
pub no_prompts: bool, pub no_prompts: bool,
pub types: bool, pub v8_help: bool,
pub prefetch: bool, pub v8_flags: Option<Vec<String>>,
pub info: bool,
pub fmt: bool,
pub eval: bool,
}
impl<'a> From<ArgMatches<'a>> for DenoFlags {
fn from(matches: ArgMatches) -> DenoFlags {
let mut flags = DenoFlags::default();
if matches.is_present("log-debug") {
flags.log_debug = true;
}
if matches.is_present("version") {
flags.version = true;
}
if matches.is_present("reload") {
flags.reload = true;
}
if matches.is_present("allow-read") {
flags.allow_read = true;
}
if matches.is_present("allow-write") {
flags.allow_write = true;
}
if matches.is_present("allow-net") {
flags.allow_net = true;
}
if matches.is_present("allow-env") {
flags.allow_env = true;
}
if matches.is_present("allow-run") {
flags.allow_run = true;
}
if matches.is_present("allow-high-precision") {
flags.allow_high_precision = 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_high_precision = true;
}
if matches.is_present("no-prompt") {
flags.no_prompts = true;
}
if matches.is_present("types") {
flags.types = true;
}
if matches.is_present("prefetch") {
flags.prefetch = true;
}
if matches.is_present("info") {
flags.info = true;
}
if matches.is_present("fmt") {
flags.fmt = true;
}
if matches.is_present("eval") {
flags.eval = true;
}
flags
}
} }
static ENV_VARIABLES_HELP: &str = "ENVIRONMENT VARIABLES: static ENV_VARIABLES_HELP: &str = "ENVIRONMENT VARIABLES:
DENO_DIR Set deno's base directory DENO_DIR Set deno's base directory
NO_COLOR Set to disable color"; NO_COLOR Set to disable color";
fn create_cli_app<'a, 'b>() -> App<'a, 'b> { pub fn create_cli_app<'a, 'b>() -> App<'a, 'b> {
App::new("deno") App::new("deno")
.bin_name("deno") .bin_name("deno")
.global_settings(&[AppSettings::ColorNever]) .global_settings(&[AppSettings::ColorNever])
@ -159,16 +92,18 @@ fn create_cli_app<'a, 'b>() -> App<'a, 'b> {
Arg::with_name("v8-flags") Arg::with_name("v8-flags")
.long("v8-flags") .long("v8-flags")
.takes_value(true) .takes_value(true)
.use_delimiter(true)
.require_equals(true) .require_equals(true)
.help("Set V8 command line options"), .help("Set V8 command line options"),
).arg( ).subcommand(
Arg::with_name("types") SubCommand::with_name("prefetch")
.long("types") .setting(AppSettings::DisableVersion)
.help("Print runtime TypeScript declarations"), .about("Prefetch the dependencies")
).arg( .arg(Arg::with_name("file").takes_value(true).required(true)),
Arg::with_name("prefetch") ).subcommand(
.long("prefetch") SubCommand::with_name("types")
.help("Prefetch the dependencies"), .setting(AppSettings::DisableVersion)
.about("Print runtime TypeScript declarations"),
).subcommand( ).subcommand(
SubCommand::with_name("info") SubCommand::with_name("info")
.setting(AppSettings::DisableVersion) .setting(AppSettings::DisableVersion)
@ -197,197 +132,226 @@ fn create_cli_app<'a, 'b>() -> App<'a, 'b> {
) )
} }
/// Parse ArgMatches into internal DenoFlags structure.
/// This method should not make any side effects.
#[cfg_attr(feature = "cargo-clippy", allow(stutter))] #[cfg_attr(feature = "cargo-clippy", allow(stutter))]
pub fn set_flags( pub fn parse_flags(matches: ArgMatches) -> DenoFlags {
args: Vec<String>, let mut flags = DenoFlags::default();
) -> Result<(DenoFlags, Vec<String>), String> {
let mut rest_argv: Vec<String> = vec!["deno".to_string()];
let cli_app = create_cli_app();
let matches = cli_app.get_matches_from(args);
match matches.subcommand() { if matches.is_present("log-debug") {
("eval", Some(info_match)) => { flags.log_debug = true;
let code: &str = info_match.value_of("code").unwrap(); }
rest_argv.extend(vec![code.to_string()]); if matches.is_present("version") {
} flags.version = true;
("info", Some(info_match)) => { }
let file: &str = info_match.value_of("file").unwrap(); if matches.is_present("reload") {
rest_argv.extend(vec![file.to_string()]); flags.reload = true;
} }
("fmt", Some(fmt_match)) => { if matches.is_present("allow-read") {
let files: Vec<String> = fmt_match flags.allow_read = true;
.values_of("files") }
.unwrap() if matches.is_present("allow-write") {
.map(String::from) flags.allow_write = true;
.collect(); }
rest_argv.extend(files); if matches.is_present("allow-net") {
} flags.allow_net = true;
(script, Some(script_match)) => { }
rest_argv.extend(vec![script.to_string()]); if matches.is_present("allow-env") {
// check if there are any extra arguments that should flags.allow_env = true;
// be passed to script }
if script_match.is_present("") { if matches.is_present("allow-run") {
let script_args: Vec<String> = script_match flags.allow_run = true;
.values_of("") }
.unwrap() if matches.is_present("allow-high-precision") {
.map(String::from) flags.allow_high_precision = true;
.collect(); }
rest_argv.extend(script_args); 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_high_precision = true;
}
if matches.is_present("no-prompt") {
flags.no_prompts = true;
} }
if matches.is_present("v8-options") { if matches.is_present("v8-options") {
// display v8 help and exit flags.v8_help = true;
// TODO(bartlomieju): this relies on `v8_set_flags` to swap `--v8-options` to help
v8_set_flags(vec!["deno".to_string(), "--v8-options".to_string()]);
} }
if matches.is_present("v8-flags") { if matches.is_present("v8-flags") {
let mut v8_flags: Vec<String> = matches let v8_flags: Vec<String> = matches
.values_of("v8-flags") .values_of("v8-flags")
.unwrap() .unwrap()
.map(String::from) .map(String::from)
.collect(); .collect();
v8_flags.insert(1, "deno".to_string()); flags.v8_flags = Some(v8_flags);
v8_set_flags(v8_flags);
} }
let flags = DenoFlags::from(matches); flags
Ok((flags, rest_argv))
} }
#[test] #[cfg(test)]
fn test_set_flags_1() { mod tests {
let (flags, rest) = set_flags(svec!["deno", "--version"]).unwrap(); use super::*;
assert_eq!(rest, svec!["deno"]);
assert_eq!(
flags,
DenoFlags {
version: true,
..DenoFlags::default()
}
);
}
#[test] fn flags_from_vec(args: Vec<String>) -> DenoFlags {
fn test_set_flags_2() { let cli_app = create_cli_app();
let (flags, rest) = let matches = cli_app.get_matches_from(args);
set_flags(svec!["deno", "-r", "-D", "script.ts"]).unwrap(); parse_flags(matches)
assert_eq!(rest, svec!["deno", "script.ts"]); }
assert_eq!(
flags,
DenoFlags {
log_debug: true,
reload: true,
..DenoFlags::default()
}
);
}
#[test] #[test]
fn test_set_flags_3() { fn test_set_flags_1() {
let (flags, rest) = let flags = flags_from_vec(svec!["deno", "--version"]);
set_flags(svec!["deno", "-r", "--allow-write", "script.ts"]).unwrap(); assert_eq!(
assert_eq!(rest, svec!["deno", "script.ts"]); flags,
assert_eq!( DenoFlags {
flags, version: true,
DenoFlags { ..DenoFlags::default()
reload: true, }
allow_write: true, );
..DenoFlags::default() }
}
);
}
#[test] #[test]
fn test_set_flags_4() { fn test_set_flags_2() {
let (flags, rest) = let flags = flags_from_vec(svec!["deno", "-r", "-D", "script.ts"]);
set_flags(svec!["deno", "-Dr", "--allow-write", "script.ts"]).unwrap(); assert_eq!(
assert_eq!(rest, svec!["deno", "script.ts"]); flags,
assert_eq!( DenoFlags {
flags, log_debug: true,
DenoFlags { reload: true,
log_debug: true, ..DenoFlags::default()
reload: true, }
allow_write: true, );
..DenoFlags::default() }
}
);
}
#[test] #[test]
fn test_set_flags_5() { fn test_set_flags_3() {
let (flags, rest) = set_flags(svec!["deno", "--types"]).unwrap(); let flags =
assert_eq!(rest, svec!["deno"]); flags_from_vec(svec!["deno", "-r", "--allow-write", "script.ts"]);
assert_eq!( assert_eq!(
flags, flags,
DenoFlags { DenoFlags {
types: true, reload: true,
..DenoFlags::default() allow_write: true,
} ..DenoFlags::default()
) }
} );
}
#[test] #[test]
fn test_set_flags_6() { fn test_set_flags_4() {
let (flags, rest) = let flags =
set_flags(svec!["deno", "--allow-net", "gist.ts", "--title", "X"]).unwrap(); flags_from_vec(svec!["deno", "-Dr", "--allow-write", "script.ts"]);
assert_eq!(rest, svec!["deno", "gist.ts", "--title", "X"]); assert_eq!(
assert_eq!( flags,
flags, DenoFlags {
DenoFlags { log_debug: true,
allow_net: true, reload: true,
..DenoFlags::default() allow_write: true,
} ..DenoFlags::default()
) }
} );
}
#[test] #[test]
fn test_set_flags_7() { fn test_set_flags_5() {
let (flags, rest) = let flags = flags_from_vec(svec!["deno", "--v8-options"]);
set_flags(svec!["deno", "--allow-all", "gist.ts"]).unwrap(); assert_eq!(
assert_eq!(rest, svec!["deno", "gist.ts"]); flags,
assert_eq!( DenoFlags {
flags, v8_help: true,
DenoFlags { ..DenoFlags::default()
allow_net: true, }
allow_env: true, );
allow_run: true,
allow_read: true,
allow_write: true,
allow_high_precision: true,
..DenoFlags::default()
}
)
}
#[test] let flags =
fn test_set_flags_8() { flags_from_vec(svec!["deno", "--v8-flags=--expose-gc,--gc-stats=1"]);
let (flags, rest) = assert_eq!(
set_flags(svec!["deno", "--allow-read", "gist.ts"]).unwrap(); flags,
assert_eq!(rest, svec!["deno", "gist.ts"]); DenoFlags {
assert_eq!( v8_flags: Some(svec!["--expose-gc", "--gc-stats=1"]),
flags, ..DenoFlags::default()
DenoFlags { }
allow_read: true, );
..DenoFlags::default() }
}
)
}
#[test] #[test]
fn test_set_flags_9() { fn test_set_flags_6() {
let (flags, rest) = let flags =
set_flags(svec!["deno", "--allow-high-precision", "script.ts"]).unwrap(); flags_from_vec(svec!["deno", "--allow-net", "gist.ts", "--title", "X"]);
assert_eq!(rest, svec!["deno", "script.ts"]); assert_eq!(
assert_eq!( flags,
flags, DenoFlags {
DenoFlags { allow_net: true,
allow_high_precision: true, ..DenoFlags::default()
..DenoFlags::default() }
} )
) }
#[test]
fn test_set_flags_7() {
let flags = flags_from_vec(svec!["deno", "--allow-all", "gist.ts"]);
assert_eq!(
flags,
DenoFlags {
allow_net: true,
allow_env: true,
allow_run: true,
allow_read: true,
allow_write: true,
allow_high_precision: true,
..DenoFlags::default()
}
)
}
#[test]
fn test_set_flags_8() {
let flags = flags_from_vec(svec!["deno", "--allow-read", "gist.ts"]);
assert_eq!(
flags,
DenoFlags {
allow_read: true,
..DenoFlags::default()
}
)
}
#[test]
fn test_set_flags_9() {
let flags =
flags_from_vec(svec!["deno", "--allow-high-precision", "script.ts"]);
assert_eq!(
flags,
DenoFlags {
allow_high_precision: true,
..DenoFlags::default()
}
)
}
#[test]
fn test_set_flags_10() {
// notice that flags passed after script name will not
// be parsed to DenoFlags but instead forwarded to
// script args as Deno.args
let flags = flags_from_vec(svec![
"deno",
"--allow-write",
"script.ts",
"-D",
"--allow-net"
]);
assert_eq!(
flags,
DenoFlags {
allow_write: true,
..DenoFlags::default()
}
)
}
} }

View file

@ -38,10 +38,13 @@ use crate::errors::RustOrJsError;
use crate::state::ThreadSafeState; use crate::state::ThreadSafeState;
use crate::worker::root_specifier_to_url; use crate::worker::root_specifier_to_url;
use crate::worker::Worker; use crate::worker::Worker;
use deno::v8_set_flags;
use flags::DenoFlags;
use futures::lazy; use futures::lazy;
use futures::Future; use futures::Future;
use log::{LevelFilter, Metadata, Record}; use log::{LevelFilter, Metadata, Record};
use std::env; use std::env;
use std::path::Path;
static LOGGER: Logger = Logger; static LOGGER: Logger = Logger;
@ -123,17 +126,157 @@ pub fn print_file_info(worker: &Worker, url: &str) {
} }
} }
fn create_worker_and_state(
flags: DenoFlags,
argv: Vec<String>,
) -> (Worker, ThreadSafeState) {
let state = ThreadSafeState::new(flags, argv, ops::op_selector_std);
let worker = Worker::new(
"main".to_string(),
startup_data::deno_isolate_init(),
state.clone(),
);
(worker, state)
}
fn types_command() {
let p = Path::new(concat!(
env!("GN_OUT_DIR"),
"/gen/cli/lib/lib.deno_runtime.d.ts"
));
let content_bytes = std::fs::read(p).unwrap();
let content = std::str::from_utf8(&content_bytes[..]).unwrap();
println!("{}", content);
}
fn prefetch_or_info_command(
flags: DenoFlags,
argv: Vec<String>,
print_info: bool,
) {
let (mut worker, state) = create_worker_and_state(flags, argv);
let main_module = state.main_module().unwrap();
let main_future = lazy(move || {
// Setup runtime.
js_check(worker.execute("denoMain()"));
debug!("main_module {}", main_module);
let main_url = root_specifier_to_url(&main_module).unwrap();
worker
.execute_mod_async(&main_url, true)
.and_then(move |worker| {
if print_info {
print_file_info(&worker, &main_module);
}
worker.then(|result| {
js_check(result);
Ok(())
})
}).map_err(|(err, _worker)| print_err_and_exit(err))
});
tokio_util::run(main_future);
}
fn eval_command(flags: DenoFlags, argv: Vec<String>) {
let (mut worker, state) = create_worker_and_state(flags, argv);
// Wrap provided script in async function so asynchronous methods
// work. This is required until top-level await is not supported.
let js_source = format!(
"async function _topLevelWrapper(){{
{}
}}
_topLevelWrapper();
",
&state.argv[1]
);
let main_future = lazy(move || {
js_check(worker.execute("denoMain()"));
// ATM imports in `deno eval` are not allowed
// TODO Support ES modules once Worker supports evaluating anonymous modules.
js_check(worker.execute(&js_source));
worker.then(|result| {
js_check(result);
Ok(())
})
});
tokio_util::run(main_future);
}
fn run_repl(flags: DenoFlags, argv: Vec<String>) {
let (mut worker, _state) = create_worker_and_state(flags, argv);
// REPL situation.
let main_future = lazy(move || {
// Setup runtime.
js_check(worker.execute("denoMain()"));
worker
.then(|result| {
js_check(result);
Ok(())
}).map_err(|(err, _worker): (RustOrJsError, Worker)| {
print_err_and_exit(err)
})
});
tokio_util::run(main_future);
}
fn run_script(flags: DenoFlags, argv: Vec<String>) {
let (mut worker, state) = create_worker_and_state(flags, argv);
let main_module = state.main_module().unwrap();
// Normal situation of executing a module.
let main_future = lazy(move || {
// Setup runtime.
js_check(worker.execute("denoMain()"));
debug!("main_module {}", main_module);
let main_url = root_specifier_to_url(&main_module).unwrap();
worker
.execute_mod_async(&main_url, false)
.and_then(move |worker| {
worker.then(|result| {
js_check(result);
Ok(())
})
}).map_err(|(err, _worker)| print_err_and_exit(err))
});
tokio_util::run(main_future);
}
fn fmt_command(mut flags: DenoFlags, mut argv: Vec<String>) {
argv.insert(1, "https://deno.land/std/prettier/main.ts".to_string());
flags.allow_read = true;
flags.allow_write = true;
run_script(flags, argv);
}
fn main() { fn main() {
#[cfg(windows)] #[cfg(windows)]
ansi_term::enable_ansi_support().ok(); // For Windows 10 ansi_term::enable_ansi_support().ok(); // For Windows 10
log::set_logger(&LOGGER).unwrap(); log::set_logger(&LOGGER).unwrap();
let args = env::args().collect(); let args: Vec<String> = env::args().collect();
let (mut flags, mut rest_argv) = let cli_app = flags::create_cli_app();
flags::set_flags(args).unwrap_or_else(|err| { let matches = cli_app.get_matches_from(args);
eprintln!("{}", err); let flags = flags::parse_flags(matches.clone());
std::process::exit(1) let mut argv: Vec<String> = vec!["deno".to_string()];
});
if flags.v8_help {
// show v8 help and exit
v8_set_flags(vec!["--help".to_string()]);
}
match &flags.v8_flags {
Some(v8_flags) => {
v8_set_flags(v8_flags.clone());
}
_ => {}
};
log::set_max_level(if flags.log_debug { log::set_max_level(if flags.log_debug {
LevelFilter::Debug LevelFilter::Debug
@ -141,85 +284,50 @@ fn main() {
LevelFilter::Warn LevelFilter::Warn
}); });
if flags.fmt { match matches.subcommand() {
rest_argv.insert(1, "https://deno.land/std/prettier/main.ts".to_string()); ("types", Some(_)) => {
flags.allow_read = true; types_command();
flags.allow_write = true; }
} ("eval", Some(eval_match)) => {
let code: &str = eval_match.value_of("code").unwrap();
let should_prefetch = flags.prefetch || flags.info; argv.extend(vec![code.to_string()]);
let should_display_info = flags.info; eval_command(flags, argv);
}
let state = ThreadSafeState::new(flags, rest_argv, ops::op_selector_std); ("info", Some(info_match)) => {
let mut worker = Worker::new( let file: &str = info_match.value_of("file").unwrap();
"main".to_string(), argv.extend(vec![file.to_string()]);
startup_data::deno_isolate_init(), prefetch_or_info_command(flags, argv, true);
state.clone(), }
); ("prefetch", Some(prefetch_match)) => {
let file: &str = prefetch_match.value_of("file").unwrap();
// TODO(ry) somehow combine the two branches below. They're very similar but argv.extend(vec![file.to_string()]);
// it's difficult to get the types to workout. prefetch_or_info_command(flags, argv, false);
}
if state.flags.eval { ("fmt", Some(fmt_match)) => {
let main_future = lazy(move || { let files: Vec<String> = fmt_match
js_check(worker.execute("denoMain()")); .values_of("files")
// Wrap provided script in async function so asynchronous methods .unwrap()
// work. This is required until top-level await is not supported. .map(String::from)
let js_source = format!( .collect();
"async function _topLevelWrapper(){{ argv.extend(files);
{} fmt_command(flags, argv);
}} }
_topLevelWrapper(); (script, Some(script_match)) => {
", argv.extend(vec![script.to_string()]);
&state.argv[1] // check if there are any extra arguments that should
); // be passed to script
// ATM imports in `deno eval` are not allowed if script_match.is_present("") {
// TODO Support ES modules once Worker supports evaluating anonymous modules. let script_args: Vec<String> = script_match
js_check(worker.execute(&js_source)); .values_of("")
worker.then(|result| { .unwrap()
js_check(result); .map(String::from)
Ok(()) .collect();
}) argv.extend(script_args);
}); }
tokio_util::run(main_future); run_script(flags, argv);
} else if let Some(main_module) = state.main_module() { }
// Normal situation of executing a module. _ => {
run_repl(flags, argv);
let main_future = lazy(move || { }
// Setup runtime.
js_check(worker.execute("denoMain()"));
debug!("main_module {}", main_module);
let main_url = root_specifier_to_url(&main_module).unwrap();
worker
.execute_mod_async(&main_url, should_prefetch)
.and_then(move |worker| {
if should_display_info {
// Display file info and exit. Do not run file
print_file_info(&worker, &main_module);
std::process::exit(0);
}
worker.then(|result| {
js_check(result);
Ok(())
})
}).map_err(|(err, _worker)| print_err_and_exit(err))
});
tokio_util::run(main_future);
} else {
// REPL situation.
let main_future = lazy(move || {
// Setup runtime.
js_check(worker.execute("denoMain()"));
worker
.then(|result| {
js_check(result);
Ok(())
}).map_err(|(err, _worker): (RustOrJsError, Worker)| {
print_err_and_exit(err)
})
});
tokio_util::run(main_future);
} }
} }

View file

@ -321,7 +321,6 @@ fn op_start(
argv: Some(argv_off), argv: Some(argv_off),
main_module, main_module,
debug_flag: state.flags.log_debug, debug_flag: state.flags.log_debug,
types_flag: state.flags.types,
version_flag: state.flags.version, version_flag: state.flags.version,
v8_version: Some(v8_version_off), v8_version: Some(v8_version_off),
deno_version: Some(deno_version_off), deno_version: Some(deno_version_off),

View file

@ -158,9 +158,11 @@ impl ThreadSafeState {
#[cfg(test)] #[cfg(test)]
pub fn mock() -> ThreadSafeState { pub fn mock() -> ThreadSafeState {
let argv = vec![String::from("./deno"), String::from("hello.js")]; let argv = vec![String::from("./deno"), String::from("hello.js")];
// For debugging: argv.push_back(String::from("-D")); ThreadSafeState::new(
let (flags, rest_argv) = flags::set_flags(argv).unwrap(); flags::DenoFlags::default(),
ThreadSafeState::new(flags, rest_argv, ops::op_selector_std) argv,
ops::op_selector_std,
)
} }
pub fn metrics_op_dispatched( pub fn metrics_op_dispatched(

View file

@ -267,9 +267,8 @@ mod tests {
let js_url = Url::from_file_path(filename).unwrap(); let js_url = Url::from_file_path(filename).unwrap();
let argv = vec![String::from("./deno"), js_url.to_string()]; let argv = vec![String::from("./deno"), js_url.to_string()];
let (flags, rest_argv) = flags::set_flags(argv).unwrap(); let state =
ThreadSafeState::new(flags::DenoFlags::default(), argv, op_selector_std);
let state = ThreadSafeState::new(flags, rest_argv, op_selector_std);
let state_ = state.clone(); let state_ = state.clone();
tokio_util::run(lazy(move || { tokio_util::run(lazy(move || {
let worker = Worker::new("TEST".to_string(), StartupData::None, state); let worker = Worker::new("TEST".to_string(), StartupData::None, state);
@ -294,9 +293,8 @@ mod tests {
let js_url = Url::from_file_path(filename).unwrap(); let js_url = Url::from_file_path(filename).unwrap();
let argv = vec![String::from("./deno"), js_url.to_string()]; let argv = vec![String::from("./deno"), js_url.to_string()];
let (flags, rest_argv) = flags::set_flags(argv).unwrap(); let state =
ThreadSafeState::new(flags::DenoFlags::default(), argv, op_selector_std);
let state = ThreadSafeState::new(flags, rest_argv, op_selector_std);
let state_ = state.clone(); let state_ = state.clone();
tokio_util::run(lazy(move || { tokio_util::run(lazy(move || {
let worker = Worker::new("TEST".to_string(), StartupData::None, state); let worker = Worker::new("TEST".to_string(), StartupData::None, state);

View file

@ -191,6 +191,7 @@ fn main() {
}); });
let args: Vec<String> = env::args().collect(); let args: Vec<String> = env::args().collect();
// NOTE: `--help` arg will display V8 help and exit
let args = deno::v8_set_flags(args); let args = deno::v8_set_flags(args);
log::set_logger(&LOGGER).unwrap(); log::set_logger(&LOGGER).unwrap();

View file

@ -5,17 +5,13 @@ use libc::c_char;
use libc::c_int; use libc::c_int;
use std::ffi::CStr; use std::ffi::CStr;
use std::ffi::CString; use std::ffi::CString;
use std::mem;
use std::vec::Vec; use std::vec::Vec;
/// Pass the command line arguments to v8. /// Pass the command line arguments to v8.
/// Returns a vector of command line arguments that V8 did not understand. /// Returns a vector of command line arguments that V8 did not understand.
/// Translates --v8-options into a --help flag for V8.
pub fn v8_set_flags(args: Vec<String>) -> Vec<String> { pub fn v8_set_flags(args: Vec<String>) -> Vec<String> {
// deno_set_v8_flags(int* argc, char** argv) mutates argc and argv to remove // deno_set_v8_flags(int* argc, char** argv) mutates argc and argv to remove
// flags that v8 understands. // flags that v8 understands.
// First parse core args, then convert to a vector of C strings.
let (args, rest) = v8_set_flags_preprocess(args);
// Make a new array, that can be modified by V8::SetFlagsFromCommandLine(), // Make a new array, that can be modified by V8::SetFlagsFromCommandLine(),
// containing mutable raw pointers to the individual command line args. // containing mutable raw pointers to the individual command line args.
@ -43,42 +39,5 @@ pub fn v8_set_flags(args: Vec<String>) -> Vec<String> {
let cstr = CStr::from_ptr(*ptr as *const c_char); let cstr = CStr::from_ptr(*ptr as *const c_char);
let slice = cstr.to_str().unwrap(); let slice = cstr.to_str().unwrap();
slice.to_string() slice.to_string()
}).chain(rest.into_iter()) }).collect()
.collect()
}
// Returns args passed to V8, followed by args passed to JS
fn v8_set_flags_preprocess(args: Vec<String>) -> (Vec<String>, Vec<String>) {
let (rest, mut v8_args) =
args.into_iter().partition(|ref a| a.as_str() == "--help");
// Replace args being sent to V8
for a in &mut v8_args {
if a == "--v8-options" {
mem::swap(a, &mut String::from("--help"));
}
}
(v8_args, rest)
}
#[test]
fn test_v8_set_flags_preprocess_1() {
let js_args = v8_set_flags_preprocess(vec![
"deno".to_string(),
"--v8-options".to_string(),
]);
assert_eq!(
js_args,
(vec!["deno".to_string(), "--help".to_string()], vec![])
);
}
#[test]
fn test_v8_set_flags_preprocess_2() {
let js_args =
v8_set_flags_preprocess(vec!["deno".to_string(), "--help".to_string()]);
assert_eq!(
js_args,
(vec!["deno".to_string()], vec!["--help".to_string()])
);
} }

View file

@ -15,9 +15,6 @@ import { setLocation } from "./location";
// builtin modules // builtin modules
import * as deno from "./deno"; import * as deno from "./deno";
// TODO(kitsonk) remove with `--types` below
import libDts from "gen/cli/lib/lib.deno_runtime.d.ts!string";
export default function denoMain(name?: string): void { export default function denoMain(name?: string): void {
const startResMsg = os.start(name); const startResMsg = os.start(name);
@ -31,13 +28,6 @@ export default function denoMain(name?: string): void {
os.exit(0); os.exit(0);
} }
// handle `--types`
// TODO(kitsonk) move to Rust fetching from compiler
if (startResMsg.typesFlag()) {
console.log(libDts);
os.exit(0);
}
const mainModule = startResMsg.mainModule(); const mainModule = startResMsg.mainModule();
if (mainModule) { if (mainModule) {
assert(mainModule.length > 0); assert(mainModule.length > 0);

View file

@ -1,2 +1,2 @@
args: --types args: types
output: tests/types.out output: tests/types.out

View file

@ -11,7 +11,7 @@ os.chdir(root_path)
# Builds into target/doc # Builds into target/doc
run(["cargo", "doc", "--all", "--no-deps", "-vv"]) run(["cargo", "doc", "--all", "--no-deps", "-vv"])
# 'deno --types' is stored in target/debug/gen/cli/lib/lib.deno_runtime.d.ts # 'deno types' is stored in target/debug/gen/cli/lib/lib.deno_runtime.d.ts
# We want to run typedoc on that declaration file only. # We want to run typedoc on that declaration file only.
os.chdir(os.path.join(target_path, "debug/gen/cli/lib/")) os.chdir(os.path.join(target_path, "debug/gen/cli/lib/"))

View file

@ -13,7 +13,7 @@ def prefetch_test(deno_exe):
deno_dir = mkdtemp() deno_dir = mkdtemp()
try: try:
t = os.path.join(tests_path, "006_url_imports.ts") t = os.path.join(tests_path, "006_url_imports.ts")
output = run_output([deno_exe, "--prefetch", t], output = run_output([deno_exe, "prefetch", t],
merge_env={"DENO_DIR": deno_dir}) merge_env={"DENO_DIR": deno_dir})
assert output == "" assert output == ""
# Check that we actually did the prefetch. # Check that we actually did the prefetch.

View file

@ -206,13 +206,13 @@ Environment variables: `DENO_BUILD_MODE`, `DENO_BUILD_PATH`, `DENO_BUILD_ARGS`,
## API reference ## API reference
### deno --types ### deno types
To get an exact reference of deno's runtime API, run the following in the To get an exact reference of deno's runtime API, run the following in the
command line: command line:
```shellsession ```shellsession
$ deno --types $ deno types
``` ```
[This is what the output looks like.](https://gist.github.com/ry/46da4724168cdefa763e13207d27ede5) [This is what the output looks like.](https://gist.github.com/ry/46da4724168cdefa763e13207d27ede5)
@ -551,9 +551,7 @@ FLAGS:
-h, --help Prints help information -h, --help Prints help information
-D, --log-debug Log debug output -D, --log-debug Log debug output
--no-prompt Do not use prompts --no-prompt Do not use prompts
--prefetch Prefetch the dependencies
-r, --reload Reload source code cache (recompile TypeScript) -r, --reload Reload source code cache (recompile TypeScript)
--types Print runtime TypeScript declarations
--v8-options Print V8 command line options --v8-options Print V8 command line options
-v, --version Print the version -v, --version Print the version
@ -565,6 +563,8 @@ SUBCOMMANDS:
eval Eval script eval Eval script
fmt Format files fmt Format files
info Show source file related info info Show source file related info
prefetch Prefetch the dependencies
types Print runtime TypeScript declarations
ENVIRONMENT VARIABLES: ENVIRONMENT VARIABLES:
DENO_DIR Set deno's base directory DENO_DIR Set deno's base directory
@ -606,7 +606,7 @@ Particularly useful ones:
| Scheduler | Tokio | | Scheduler | Tokio |
| Userland: libc++ / glib / boost | deno_std | | Userland: libc++ / glib / boost | deno_std |
| /proc/\$\$/stat | [Deno.metrics()](#metrics) | | /proc/\$\$/stat | [Deno.metrics()](#metrics) |
| man pages | deno --types | | man pages | deno types |
#### Resources #### Resources