Skip to content

Commit 3bcafcd

Browse files
committed
feat(task): add --eval flag
1 parent 46b6037 commit 3bcafcd

File tree

7 files changed

+100
-4
lines changed

7 files changed

+100
-4
lines changed

cli/args/flags.rs

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,7 @@ pub struct TaskFlags {
380380
pub cwd: Option<String>,
381381
pub task: Option<String>,
382382
pub is_run: bool,
383+
pub eval: bool,
383384
}
384385

385386
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
@@ -1385,7 +1386,7 @@ pub fn flags_from_vec(args: Vec<OsString>) -> clap::error::Result<Flags> {
13851386
"repl" => repl_parse(&mut flags, &mut m)?,
13861387
"run" => run_parse(&mut flags, &mut m, app, false)?,
13871388
"serve" => serve_parse(&mut flags, &mut m, app)?,
1388-
"task" => task_parse(&mut flags, &mut m),
1389+
"task" => task_parse(&mut flags, &mut m, app)?,
13891390
"test" => test_parse(&mut flags, &mut m)?,
13901391
"types" => types_parse(&mut flags, &mut m),
13911392
"uninstall" => uninstall_parse(&mut flags, &mut m),
@@ -2930,7 +2931,10 @@ fn task_subcommand() -> Command {
29302931
<p(245)>deno task build</>
29312932
29322933
List all available tasks:
2933-
<p(245)>deno task</>"
2934+
<p(245)>deno task</>
2935+
2936+
Evaluate a task from string
2937+
<p(245)>deno task --eval \"echo $(pwd)\"</>"
29342938
),
29352939
UnstableArgsConfig::ResolutionAndRuntime,
29362940
)
@@ -2946,6 +2950,13 @@ List all available tasks:
29462950
.help("Specify the directory to run the task in")
29472951
.value_hint(ValueHint::DirPath),
29482952
)
2953+
.arg(
2954+
Arg::new("eval")
2955+
.long("eval")
2956+
.help(
2957+
"Evaluate the passed value as if, it was a task in a configuration file",
2958+
).action(ArgAction::SetTrue)
2959+
)
29492960
.arg(node_modules_dir_arg())
29502961
})
29512962
}
@@ -5056,7 +5067,11 @@ fn serve_parse(
50565067
Ok(())
50575068
}
50585069

5059-
fn task_parse(flags: &mut Flags, matches: &mut ArgMatches) {
5070+
fn task_parse(
5071+
flags: &mut Flags,
5072+
matches: &mut ArgMatches,
5073+
mut app: Command,
5074+
) -> clap::error::Result<()> {
50605075
flags.config_flag = matches
50615076
.remove_one::<String>("config")
50625077
.map(ConfigFlag::Path)
@@ -5069,6 +5084,7 @@ fn task_parse(flags: &mut Flags, matches: &mut ArgMatches) {
50695084
cwd: matches.remove_one::<String>("cwd"),
50705085
task: None,
50715086
is_run: false,
5087+
eval: matches.get_flag("eval"),
50725088
};
50735089

50745090
if let Some((task, mut matches)) = matches.remove_subcommand() {
@@ -5081,9 +5097,15 @@ fn task_parse(flags: &mut Flags, matches: &mut ArgMatches) {
50815097
.flatten()
50825098
.filter_map(|arg| arg.into_string().ok()),
50835099
);
5100+
} else if task_flags.eval {
5101+
return Err(app.find_subcommand_mut("task").unwrap().error(
5102+
clap::error::ErrorKind::MissingRequiredArgument,
5103+
"[TASK] must be specified when using --eval",
5104+
));
50845105
}
50855106

50865107
flags.subcommand = DenoSubcommand::Task(task_flags);
5108+
Ok(())
50875109
}
50885110

50895111
fn parallel_arg_parse(matches: &mut ArgMatches) -> Option<NonZeroUsize> {
@@ -10258,6 +10280,7 @@ mod tests {
1025810280
cwd: None,
1025910281
task: Some("build".to_string()),
1026010282
is_run: false,
10283+
eval: false,
1026110284
}),
1026210285
argv: svec!["hello", "world"],
1026310286
..Flags::default()
@@ -10272,6 +10295,7 @@ mod tests {
1027210295
cwd: None,
1027310296
task: Some("build".to_string()),
1027410297
is_run: false,
10298+
eval: false,
1027510299
}),
1027610300
..Flags::default()
1027710301
}
@@ -10285,10 +10309,28 @@ mod tests {
1028510309
cwd: Some("foo".to_string()),
1028610310
task: Some("build".to_string()),
1028710311
is_run: false,
10312+
eval: false,
1028810313
}),
1028910314
..Flags::default()
1029010315
}
1029110316
);
10317+
10318+
let r = flags_from_vec(svec!["deno", "task", "--eval", "echo 1"]);
10319+
assert_eq!(
10320+
r.unwrap(),
10321+
Flags {
10322+
subcommand: DenoSubcommand::Task(TaskFlags {
10323+
cwd: None,
10324+
task: Some("echo 1".to_string()),
10325+
is_run: false,
10326+
eval: true,
10327+
}),
10328+
..Flags::default()
10329+
}
10330+
);
10331+
10332+
let r = flags_from_vec(svec!["deno", "task", "--eval"]);
10333+
assert!(r.is_err());
1029210334
}
1029310335

1029410336
#[test]
@@ -10310,6 +10352,7 @@ mod tests {
1031010352
cwd: None,
1031110353
task: Some("build".to_string()),
1031210354
is_run: false,
10355+
eval: false,
1031310356
}),
1031410357
argv: svec!["--", "hello", "world"],
1031510358
config_flag: ConfigFlag::Path("deno.json".to_owned()),
@@ -10327,6 +10370,7 @@ mod tests {
1032710370
cwd: Some("foo".to_string()),
1032810371
task: Some("build".to_string()),
1032910372
is_run: false,
10373+
eval: false,
1033010374
}),
1033110375
argv: svec!["--", "hello", "world"],
1033210376
..Flags::default()
@@ -10345,6 +10389,7 @@ mod tests {
1034510389
cwd: None,
1034610390
task: Some("build".to_string()),
1034710391
is_run: false,
10392+
eval: false,
1034810393
}),
1034910394
argv: svec!["--"],
1035010395
..Flags::default()
@@ -10362,6 +10407,7 @@ mod tests {
1036210407
cwd: None,
1036310408
task: Some("build".to_string()),
1036410409
is_run: false,
10410+
eval: false,
1036510411
}),
1036610412
argv: svec!["-1", "--test"],
1036710413
..Flags::default()
@@ -10379,6 +10425,7 @@ mod tests {
1037910425
cwd: None,
1038010426
task: Some("build".to_string()),
1038110427
is_run: false,
10428+
eval: false,
1038210429
}),
1038310430
argv: svec!["--test"],
1038410431
..Flags::default()
@@ -10397,6 +10444,7 @@ mod tests {
1039710444
cwd: None,
1039810445
task: Some("build".to_string()),
1039910446
is_run: false,
10447+
eval: false,
1040010448
}),
1040110449
log_level: Some(log::Level::Error),
1040210450
..Flags::default()
@@ -10414,6 +10462,7 @@ mod tests {
1041410462
cwd: None,
1041510463
task: None,
1041610464
is_run: false,
10465+
eval: false,
1041710466
}),
1041810467
..Flags::default()
1041910468
}
@@ -10430,6 +10479,7 @@ mod tests {
1043010479
cwd: None,
1043110480
task: None,
1043210481
is_run: false,
10482+
eval: false,
1043310483
}),
1043410484
config_flag: ConfigFlag::Path("deno.jsonc".to_string()),
1043510485
..Flags::default()
@@ -10447,6 +10497,7 @@ mod tests {
1044710497
cwd: None,
1044810498
task: None,
1044910499
is_run: false,
10500+
eval: false,
1045010501
}),
1045110502
config_flag: ConfigFlag::Path("deno.jsonc".to_string()),
1045210503
..Flags::default()

cli/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@ async fn run_subcommand(flags: Arc<Flags>) -> Result<i32, AnyError> {
238238
cwd: None,
239239
task: Some(run_flags.script.clone()),
240240
is_run: true,
241+
eval: false,
241242
};
242243
new_flags.subcommand = DenoSubcommand::Task(task_flags.clone());
243244
let result = tools::task::execute_script(Arc::new(new_flags), task_flags.clone()).await;

cli/tools/task.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ pub async fn execute_script(
4242
let factory = CliFactory::from_flags(flags);
4343
let cli_options = factory.cli_options()?;
4444
let start_dir = &cli_options.start_dir;
45-
if !start_dir.has_deno_or_pkg_json() {
45+
if !start_dir.has_deno_or_pkg_json() && !task_flags.eval {
4646
bail!("deno task couldn't find deno.json(c). See https://docs.deno.com/go/config")
4747
}
4848
let force_use_pkg_json =
@@ -90,6 +90,19 @@ pub async fn execute_script(
9090
concurrency: no_of_concurrent_tasks.into(),
9191
};
9292

93+
if task_flags.eval {
94+
return task_runner
95+
.run_deno_task(
96+
&Url::from_directory_path(cli_options.initial_cwd()).unwrap(),
97+
&"".to_string(),
98+
&TaskDefinition {
99+
command: task_flags.task.as_ref().unwrap().to_string(),
100+
dependencies: vec![],
101+
description: None,
102+
},
103+
)
104+
.await;
105+
}
93106
task_runner.run_task(task_name).await
94107
}
95108

tests/specs/task/eval/__test__.jsonc

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"tempDir": true,
3+
"steps": [
4+
{
5+
"args": "task --eval",
6+
"output": "no_arg.out",
7+
"exitCode": 1
8+
},
9+
{
10+
"args": ["task", "--eval", "echo $(pwd)"],
11+
"output": "echo_pwd.out"
12+
},
13+
{
14+
"args": [
15+
"task",
16+
"--eval",
17+
"echo 12345 | (deno eval 'const b = new Uint8Array(1);Deno.stdin.readSync(b);console.log(b)' && deno eval 'const b = new Uint8Array(1);Deno.stdin.readSync(b);console.log(b)')"
18+
],
19+
"output": "piped.out"
20+
}
21+
]
22+
}

tests/specs/task/eval/echo_pwd.out

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Task echo $(pwd)
2+
[WILDCARD]

tests/specs/task/eval/no_arg.out

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
error: [TASK] must be specified when using --eval
2+
3+
Usage: deno task [OPTIONS] [TASK]
4+

tests/specs/task/eval/piped.out

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Task echo 12345 | (deno eval 'const b = new Uint8Array(1);Deno.stdin.readSync(b);console.log(b)' && deno eval 'const b = new Uint8Array(1);Deno.stdin.readSync(b);console.log(b)')
2+
Uint8Array(1) [ 49 ]
3+
Uint8Array(1) [ 50 ]

0 commit comments

Comments
 (0)