mirror of
https://github.com/denoland/deno.git
synced 2025-03-03 17:34:47 -05:00
feat(task): add --cwd
flag for configuring the working directory (#14823)
This commit is contained in:
parent
a0a13b3a1b
commit
94068b7109
7 changed files with 81 additions and 6 deletions
63
cli/flags.rs
63
cli/flags.rs
|
@ -163,6 +163,7 @@ pub struct RunFlags {
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
|
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
|
||||||
pub struct TaskFlags {
|
pub struct TaskFlags {
|
||||||
|
pub cwd: Option<String>,
|
||||||
pub task: String,
|
pub task: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1465,6 +1466,14 @@ fn task_subcommand<'a>() -> Command<'a> {
|
||||||
Command::new("task")
|
Command::new("task")
|
||||||
.trailing_var_arg(true)
|
.trailing_var_arg(true)
|
||||||
.args(config_args())
|
.args(config_args())
|
||||||
|
.arg(
|
||||||
|
Arg::new("cwd")
|
||||||
|
.long("cwd")
|
||||||
|
.value_name("DIR")
|
||||||
|
.help("Specify the directory to run the task in")
|
||||||
|
.takes_value(true)
|
||||||
|
.value_hint(ValueHint::DirPath)
|
||||||
|
)
|
||||||
// Ideally the task name and trailing arguments should be two separate clap
|
// Ideally the task name and trailing arguments should be two separate clap
|
||||||
// arguments, but there is a bug in clap that's preventing us from doing
|
// arguments, but there is a bug in clap that's preventing us from doing
|
||||||
// this (https://github.com/clap-rs/clap/issues/1538). Once that's fixed,
|
// this (https://github.com/clap-rs/clap/issues/1538). Once that's fixed,
|
||||||
|
@ -2567,7 +2576,15 @@ fn task_parse(
|
||||||
) {
|
) {
|
||||||
config_args_parse(flags, matches);
|
config_args_parse(flags, matches);
|
||||||
|
|
||||||
let mut task_name = "".to_string();
|
let mut task_flags = TaskFlags {
|
||||||
|
cwd: None,
|
||||||
|
task: String::new(),
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(cwd) = matches.value_of("cwd") {
|
||||||
|
task_flags.cwd = Some(cwd.to_string());
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(mut index) = matches.index_of("task_name_and_args") {
|
if let Some(mut index) = matches.index_of("task_name_and_args") {
|
||||||
index += 1; // skip `task`
|
index += 1; // skip `task`
|
||||||
|
|
||||||
|
@ -2578,6 +2595,10 @@ fn task_parse(
|
||||||
flags.config_flag = ConfigFlag::Path(raw_args[index + 1].to_string());
|
flags.config_flag = ConfigFlag::Path(raw_args[index + 1].to_string());
|
||||||
index += 2;
|
index += 2;
|
||||||
}
|
}
|
||||||
|
"--cwd" => {
|
||||||
|
task_flags.cwd = Some(raw_args[index + 1].to_string());
|
||||||
|
index += 2;
|
||||||
|
}
|
||||||
"--no-config" => {
|
"--no-config" => {
|
||||||
flags.config_flag = ConfigFlag::Disabled;
|
flags.config_flag = ConfigFlag::Disabled;
|
||||||
index += 1;
|
index += 1;
|
||||||
|
@ -2591,7 +2612,7 @@ fn task_parse(
|
||||||
}
|
}
|
||||||
|
|
||||||
if index < raw_args.len() {
|
if index < raw_args.len() {
|
||||||
task_name = raw_args[index].to_string();
|
task_flags.task = raw_args[index].to_string();
|
||||||
index += 1;
|
index += 1;
|
||||||
|
|
||||||
if index < raw_args.len() {
|
if index < raw_args.len() {
|
||||||
|
@ -2602,7 +2623,7 @@ fn task_parse(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
flags.subcommand = DenoSubcommand::Task(TaskFlags { task: task_name });
|
flags.subcommand = DenoSubcommand::Task(task_flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
|
fn test_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
|
||||||
|
@ -5597,6 +5618,7 @@ mod tests {
|
||||||
r.unwrap(),
|
r.unwrap(),
|
||||||
Flags {
|
Flags {
|
||||||
subcommand: DenoSubcommand::Task(TaskFlags {
|
subcommand: DenoSubcommand::Task(TaskFlags {
|
||||||
|
cwd: None,
|
||||||
task: "build".to_string(),
|
task: "build".to_string(),
|
||||||
}),
|
}),
|
||||||
argv: svec!["hello", "world"],
|
argv: svec!["hello", "world"],
|
||||||
|
@ -5609,6 +5631,19 @@ mod tests {
|
||||||
r.unwrap(),
|
r.unwrap(),
|
||||||
Flags {
|
Flags {
|
||||||
subcommand: DenoSubcommand::Task(TaskFlags {
|
subcommand: DenoSubcommand::Task(TaskFlags {
|
||||||
|
cwd: None,
|
||||||
|
task: "build".to_string(),
|
||||||
|
}),
|
||||||
|
..Flags::default()
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
let r = flags_from_vec(svec!["deno", "task", "--cwd", "foo", "build"]);
|
||||||
|
assert_eq!(
|
||||||
|
r.unwrap(),
|
||||||
|
Flags {
|
||||||
|
subcommand: DenoSubcommand::Task(TaskFlags {
|
||||||
|
cwd: Some("foo".to_string()),
|
||||||
task: "build".to_string(),
|
task: "build".to_string(),
|
||||||
}),
|
}),
|
||||||
..Flags::default()
|
..Flags::default()
|
||||||
|
@ -5632,6 +5667,7 @@ mod tests {
|
||||||
r.unwrap(),
|
r.unwrap(),
|
||||||
Flags {
|
Flags {
|
||||||
subcommand: DenoSubcommand::Task(TaskFlags {
|
subcommand: DenoSubcommand::Task(TaskFlags {
|
||||||
|
cwd: None,
|
||||||
task: "build".to_string(),
|
task: "build".to_string(),
|
||||||
}),
|
}),
|
||||||
argv: svec!["--", "hello", "world"],
|
argv: svec!["--", "hello", "world"],
|
||||||
|
@ -5639,6 +5675,21 @@ mod tests {
|
||||||
..Flags::default()
|
..Flags::default()
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let r = flags_from_vec(svec![
|
||||||
|
"deno", "task", "--cwd", "foo", "build", "--", "hello", "world"
|
||||||
|
]);
|
||||||
|
assert_eq!(
|
||||||
|
r.unwrap(),
|
||||||
|
Flags {
|
||||||
|
subcommand: DenoSubcommand::Task(TaskFlags {
|
||||||
|
cwd: Some("foo".to_string()),
|
||||||
|
task: "build".to_string(),
|
||||||
|
}),
|
||||||
|
argv: svec!["--", "hello", "world"],
|
||||||
|
..Flags::default()
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -5649,6 +5700,7 @@ mod tests {
|
||||||
r.unwrap(),
|
r.unwrap(),
|
||||||
Flags {
|
Flags {
|
||||||
subcommand: DenoSubcommand::Task(TaskFlags {
|
subcommand: DenoSubcommand::Task(TaskFlags {
|
||||||
|
cwd: None,
|
||||||
task: "build".to_string(),
|
task: "build".to_string(),
|
||||||
}),
|
}),
|
||||||
argv: svec!["--"],
|
argv: svec!["--"],
|
||||||
|
@ -5664,6 +5716,7 @@ mod tests {
|
||||||
r.unwrap(),
|
r.unwrap(),
|
||||||
Flags {
|
Flags {
|
||||||
subcommand: DenoSubcommand::Task(TaskFlags {
|
subcommand: DenoSubcommand::Task(TaskFlags {
|
||||||
|
cwd: None,
|
||||||
task: "build".to_string(),
|
task: "build".to_string(),
|
||||||
}),
|
}),
|
||||||
argv: svec!["-1", "--test"],
|
argv: svec!["-1", "--test"],
|
||||||
|
@ -5679,6 +5732,7 @@ mod tests {
|
||||||
r.unwrap(),
|
r.unwrap(),
|
||||||
Flags {
|
Flags {
|
||||||
subcommand: DenoSubcommand::Task(TaskFlags {
|
subcommand: DenoSubcommand::Task(TaskFlags {
|
||||||
|
cwd: None,
|
||||||
task: "build".to_string(),
|
task: "build".to_string(),
|
||||||
}),
|
}),
|
||||||
argv: svec!["--test"],
|
argv: svec!["--test"],
|
||||||
|
@ -5694,6 +5748,7 @@ mod tests {
|
||||||
r.unwrap(),
|
r.unwrap(),
|
||||||
Flags {
|
Flags {
|
||||||
subcommand: DenoSubcommand::Task(TaskFlags {
|
subcommand: DenoSubcommand::Task(TaskFlags {
|
||||||
|
cwd: None,
|
||||||
task: "".to_string(),
|
task: "".to_string(),
|
||||||
}),
|
}),
|
||||||
..Flags::default()
|
..Flags::default()
|
||||||
|
@ -5708,6 +5763,7 @@ mod tests {
|
||||||
r.unwrap(),
|
r.unwrap(),
|
||||||
Flags {
|
Flags {
|
||||||
subcommand: DenoSubcommand::Task(TaskFlags {
|
subcommand: DenoSubcommand::Task(TaskFlags {
|
||||||
|
cwd: None,
|
||||||
task: "".to_string(),
|
task: "".to_string(),
|
||||||
}),
|
}),
|
||||||
config_flag: ConfigFlag::Path("deno.jsonc".to_string()),
|
config_flag: ConfigFlag::Path("deno.jsonc".to_string()),
|
||||||
|
@ -5723,6 +5779,7 @@ mod tests {
|
||||||
r.unwrap(),
|
r.unwrap(),
|
||||||
Flags {
|
Flags {
|
||||||
subcommand: DenoSubcommand::Task(TaskFlags {
|
subcommand: DenoSubcommand::Task(TaskFlags {
|
||||||
|
cwd: None,
|
||||||
task: "".to_string(),
|
task: "".to_string(),
|
||||||
}),
|
}),
|
||||||
config_flag: ConfigFlag::Path("deno.jsonc".to_string()),
|
config_flag: ConfigFlag::Path("deno.jsonc".to_string()),
|
||||||
|
|
|
@ -12,6 +12,13 @@ itest!(task_no_args {
|
||||||
exit_code: 1,
|
exit_code: 1,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
itest!(task_cwd {
|
||||||
|
args: "task -q --config task/deno.json --cwd .. echo_cwd",
|
||||||
|
output: "task/task_cwd.out",
|
||||||
|
envs: vec![("NO_COLOR".to_string(), "1".to_string())],
|
||||||
|
exit_code: 0,
|
||||||
|
});
|
||||||
|
|
||||||
itest!(task_non_existent {
|
itest!(task_non_existent {
|
||||||
args: "task --config task/deno.json non_existent",
|
args: "task --config task/deno.json non_existent",
|
||||||
output: "task/task_non_existent.out",
|
output: "task/task_non_existent.out",
|
||||||
|
|
3
cli/tests/testdata/task/deno.json
vendored
3
cli/tests/testdata/task/deno.json
vendored
|
@ -5,6 +5,7 @@
|
||||||
"deno_echo": "deno eval 'console.log(5)'",
|
"deno_echo": "deno eval 'console.log(5)'",
|
||||||
"strings": "deno run main.ts && deno eval \"console.log(\\\"test\\\")\"",
|
"strings": "deno run main.ts && deno eval \"console.log(\\\"test\\\")\"",
|
||||||
"piped": "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)')",
|
"piped": "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)')",
|
||||||
"exit_code_5": "echo $(echo 10 ; exit 2) && exit 5"
|
"exit_code_5": "echo $(echo 10 ; exit 2) && exit 5",
|
||||||
|
"echo_cwd": "echo $(pwd)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
1
cli/tests/testdata/task/task_cwd.out
vendored
Normal file
1
cli/tests/testdata/task/task_cwd.out
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
[WILDCARD]tests
|
2
cli/tests/testdata/task/task_no_args.out
vendored
2
cli/tests/testdata/task/task_no_args.out
vendored
|
@ -5,6 +5,8 @@ Available tasks:
|
||||||
deno eval 'console.log(5)'
|
deno eval 'console.log(5)'
|
||||||
- echo
|
- echo
|
||||||
echo 1
|
echo 1
|
||||||
|
- echo_cwd
|
||||||
|
echo $(pwd)
|
||||||
- exit_code_5
|
- exit_code_5
|
||||||
echo $(echo 10 ; exit 2) && exit 5
|
echo $(echo 10 ; exit 2) && exit 5
|
||||||
- piped
|
- piped
|
||||||
|
|
|
@ -7,6 +7,8 @@ Available tasks:
|
||||||
deno eval 'console.log(5)'
|
deno eval 'console.log(5)'
|
||||||
- echo
|
- echo
|
||||||
echo 1
|
echo 1
|
||||||
|
- echo_cwd
|
||||||
|
echo $(pwd)
|
||||||
- exit_code_5
|
- exit_code_5
|
||||||
echo $(echo 10 ; exit 2) && exit 5
|
echo $(echo 10 ; exit 2) && exit 5
|
||||||
- piped
|
- piped
|
||||||
|
|
|
@ -4,12 +4,14 @@ use crate::colors;
|
||||||
use crate::config_file::ConfigFile;
|
use crate::config_file::ConfigFile;
|
||||||
use crate::flags::Flags;
|
use crate::flags::Flags;
|
||||||
use crate::flags::TaskFlags;
|
use crate::flags::TaskFlags;
|
||||||
|
use crate::fs_util;
|
||||||
use crate::proc_state::ProcState;
|
use crate::proc_state::ProcState;
|
||||||
use deno_core::anyhow::bail;
|
use deno_core::anyhow::bail;
|
||||||
use deno_core::anyhow::Context;
|
use deno_core::anyhow::Context;
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::path::PathBuf;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
fn get_tasks_config(
|
fn get_tasks_config(
|
||||||
|
@ -71,7 +73,10 @@ pub async fn execute_script(
|
||||||
return Ok(1);
|
return Ok(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
let cwd = config_file_path.parent().unwrap();
|
let cwd = match task_flags.cwd {
|
||||||
|
Some(path) => fs_util::canonicalize_path(&PathBuf::from(path))?,
|
||||||
|
None => config_file_path.parent().unwrap().to_owned(),
|
||||||
|
};
|
||||||
let task_name = task_flags.task;
|
let task_name = task_flags.task;
|
||||||
let maybe_script = tasks_config.get(&task_name);
|
let maybe_script = tasks_config.get(&task_name);
|
||||||
|
|
||||||
|
@ -95,7 +100,7 @@ pub async fn execute_script(
|
||||||
let seq_list = deno_task_shell::parser::parse(script)
|
let seq_list = deno_task_shell::parser::parse(script)
|
||||||
.with_context(|| format!("Error parsing script '{}'.", task_name))?;
|
.with_context(|| format!("Error parsing script '{}'.", task_name))?;
|
||||||
let env_vars = std::env::vars().collect::<HashMap<String, String>>();
|
let env_vars = std::env::vars().collect::<HashMap<String, String>>();
|
||||||
let exit_code = deno_task_shell::execute(seq_list, env_vars, cwd).await;
|
let exit_code = deno_task_shell::execute(seq_list, env_vars, &cwd).await;
|
||||||
Ok(exit_code)
|
Ok(exit_code)
|
||||||
} else {
|
} else {
|
||||||
eprintln!("Task not found: {}", task_name);
|
eprintln!("Task not found: {}", task_name);
|
||||||
|
|
Loading…
Add table
Reference in a new issue