summaryrefslogtreecommitdiff
path: root/cli
diff options
context:
space:
mode:
Diffstat (limited to 'cli')
-rw-r--r--cli/BUILD.gn1
-rw-r--r--cli/flags.rs64
-rw-r--r--cli/main.rs26
-rw-r--r--cli/msg.fbs1
-rw-r--r--cli/ops.rs7
5 files changed, 99 insertions, 0 deletions
diff --git a/cli/BUILD.gn b/cli/BUILD.gn
index 0b5fadc68..195bdfd60 100644
--- a/cli/BUILD.gn
+++ b/cli/BUILD.gn
@@ -115,6 +115,7 @@ ts_sources = [
"../js/write_file.ts",
"../js/performance.ts",
"../js/version.ts",
+ "../js/xeval.ts",
"../tsconfig.json",
# Listing package.json and yarn.lock as sources ensures the bundle is rebuilt
diff --git a/cli/flags.rs b/cli/flags.rs
index 380c87b90..f60c1a3fa 100644
--- a/cli/flags.rs
+++ b/cli/flags.rs
@@ -24,6 +24,8 @@ pub struct DenoFlags {
pub no_prompts: bool,
pub no_fetch: bool,
pub v8_flags: Option<Vec<String>>,
+ pub xeval_replvar: Option<String>,
+ pub xeval_delim: Option<String>,
}
static ENV_VARIABLES_HELP: &str = "ENVIRONMENT VARIABLES:
@@ -194,6 +196,37 @@ Prettier dependencies on first run.
.required(true),
),
).subcommand(
+ SubCommand::with_name("xeval")
+ .setting(AppSettings::DisableVersion)
+ .about("Eval a script on text segments from stdin")
+ .long_about(
+ "
+Eval a script on lines (or chunks split under delimiter) from stdin.
+
+Read from standard input and eval code on each whitespace-delimited
+string chunks.
+
+-I/--replvar optionally set variable name for input to be used in eval.
+Otherwise '$' will be used as default variable name.
+
+ cat /etc/passwd | deno xeval \"a = $.split(':'); if (a) console.log(a[0])\"
+ git branch | deno xeval -I 'line' \"if (line.startsWith('*')) console.log(line.slice(2))\"
+ cat LICENSE | deno xeval -d ' ' \"if ($ === 'MIT') console.log('MIT licensed')\"
+",
+ ).arg(
+ Arg::with_name("replvar")
+ .long("replvar")
+ .short("I")
+ .help("Set variable name to be used in eval, defaults to $")
+ .takes_value(true),
+ ).arg(
+ Arg::with_name("delim")
+ .long("delim")
+ .short("d")
+ .help("Set delimiter, defaults to newline")
+ .takes_value(true),
+ ).arg(Arg::with_name("code").takes_value(true).required(true)),
+ ).subcommand(
// this is a fake subcommand - it's used in conjunction with
// AppSettings:AllowExternalSubcommand to treat it as an
// entry point script
@@ -281,6 +314,7 @@ pub enum DenoSubcommand {
Repl,
Run,
Types,
+ Xeval,
}
pub fn flags_from_vec(
@@ -322,6 +356,17 @@ pub fn flags_from_vec(
DenoSubcommand::Info
}
("types", Some(_)) => DenoSubcommand::Types,
+ ("xeval", Some(eval_match)) => {
+ let code: &str = eval_match.value_of("code").unwrap();
+ flags.xeval_replvar =
+ Some(eval_match.value_of("replvar").unwrap_or("$").to_owned());
+ // Currently clap never escapes string,
+ // So -d "\n" won't expand to newline.
+ // Instead, do -d $'\n'
+ flags.xeval_delim = eval_match.value_of("delim").map(String::from);
+ argv.extend(vec![code.to_string()]);
+ DenoSubcommand::Xeval
+ }
(script, Some(script_match)) => {
argv.extend(vec![script.to_string()]);
// check if there are any extra arguments that should
@@ -570,6 +615,25 @@ mod tests {
}
#[test]
+ fn test_flags_from_vec_15() {
+ let (flags, subcommand, argv) = flags_from_vec(svec![
+ "deno",
+ "xeval",
+ "-I",
+ "val",
+ "-d",
+ " ",
+ "console.log(val)"
+ ]);
+ let mut expected_flags = DenoFlags::default();
+ expected_flags.xeval_replvar = Some("val".to_owned());
+ expected_flags.xeval_delim = Some(" ".to_owned());
+ assert_eq!(flags, expected_flags);
+ assert_eq!(subcommand, DenoSubcommand::Xeval);
+ assert_eq!(argv, svec!["deno", "console.log(val)"]);
+ }
+
+ #[test]
fn test_set_flags_11() {
let (flags, _, _) =
flags_from_vec(svec!["deno", "-c", "tsconfig.json", "script.ts"]);
diff --git a/cli/main.rs b/cli/main.rs
index cff42f5a0..5a6efa073 100644
--- a/cli/main.rs
+++ b/cli/main.rs
@@ -208,6 +208,31 @@ fn eval_command(flags: DenoFlags, argv: Vec<String>) {
tokio_util::run(main_future);
}
+fn xeval_command(flags: DenoFlags, argv: Vec<String>) {
+ let xeval_replvar = flags.xeval_replvar.clone().unwrap();
+ let (mut worker, state) = create_worker_and_state(flags, argv);
+ let xeval_source = format!(
+ "window._xevalWrapper = async function ({}){{
+ {}
+ }}",
+ &xeval_replvar, &state.argv[1]
+ );
+
+ let main_future = lazy(move || {
+ // Setup runtime.
+ js_check(worker.execute(&xeval_source));
+ 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_repl(flags: DenoFlags, argv: Vec<String>) {
let (mut worker, _state) = create_worker_and_state(flags, argv);
@@ -275,5 +300,6 @@ fn main() {
DenoSubcommand::Repl => run_repl(flags, argv),
DenoSubcommand::Run => run_script(flags, argv),
DenoSubcommand::Types => types_command(),
+ DenoSubcommand::Xeval => xeval_command(flags, argv),
}
}
diff --git a/cli/msg.fbs b/cli/msg.fbs
index b93fb68a7..fb8fd9c22 100644
--- a/cli/msg.fbs
+++ b/cli/msg.fbs
@@ -175,6 +175,7 @@ table StartRes {
deno_version: string;
v8_version: string;
no_color: bool;
+ xeval_delim: string;
}
table CompilerConfig {
diff --git a/cli/ops.rs b/cli/ops.rs
index b2b9b4245..ab2284110 100644
--- a/cli/ops.rs
+++ b/cli/ops.rs
@@ -341,6 +341,12 @@ fn op_start(
let main_module = state.main_module().map(|m| builder.create_string(&m));
+ let xeval_delim = state
+ .flags
+ .xeval_delim
+ .clone()
+ .map(|m| builder.create_string(&m));
+
let inner = msg::StartRes::create(
&mut builder,
&msg::StartResArgs {
@@ -354,6 +360,7 @@ fn op_start(
deno_version: Some(deno_version_off),
no_color: !ansi::use_color(),
exec_path: Some(exec_path),
+ xeval_delim,
..Default::default()
},
);