From d3877867461ab788524713c467b5cf34aa4d81c9 Mon Sep 17 00:00:00 2001 From: Casey Rodarmor Date: Sun, 19 May 2024 21:02:10 -0700 Subject: [PATCH 1/6] Pass the command being run as the first argument to `shell()` --- src/evaluator.rs | 2 +- src/function.rs | 6 +++++- tests/functions.rs | 7 ++++++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/evaluator.rs b/src/evaluator.rs index 1b0f9460ac..0ccafb987f 100644 --- a/src/evaluator.rs +++ b/src/evaluator.rs @@ -226,7 +226,7 @@ impl<'src, 'run> Evaluator<'src, 'run> { }) } - pub(crate) fn run_command(&self, command: &str, args: &[String]) -> Result { + pub(crate) fn run_command(&self, command: &str, args: &[&str]) -> Result { let mut cmd = self.settings.shell_command(self.config); cmd.arg(command); cmd.args(args); diff --git a/src/function.rs b/src/function.rs index 0133d9ef83..0321508ac8 100644 --- a/src/function.rs +++ b/src/function.rs @@ -460,8 +460,12 @@ fn sha256_file(evaluator: &Evaluator, path: &str) -> Result { } fn shell(evaluator: &Evaluator, command: &str, args: &[String]) -> Result { + let args = iter::once(command) + .chain(args.iter().map(String::as_str)) + .collect::>(); + evaluator - .run_command(command, args) + .run_command(command, &args) .map_err(|output_error| output_error.to_string()) } diff --git a/tests/functions.rs b/tests/functions.rs index c2d718c7cd..3cf6b2e14c 100644 --- a/tests/functions.rs +++ b/tests/functions.rs @@ -779,7 +779,12 @@ fn shell_no_argument() { #[test] fn shell_minimal() { - assert_eval_eq("shell('echo $0 $1', 'justice', 'legs')", "justice legs"); + assert_eval_eq("shell('echo $1 $2', 'justice', 'legs')", "justice legs"); +} + +#[test] +fn shell_args() { + assert_eval_eq("shell('echo $@', 'justice', 'legs')", "justice legs"); } #[test] From 3ca4a8fb5135891252f5f2a75cba3db82e6f0b5c Mon Sep 17 00:00:00 2001 From: Casey Rodarmor Date: Sun, 19 May 2024 21:06:23 -0700 Subject: [PATCH 2/6] Update readme --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index fd0e7db06a..aa573c5df1 100644 --- a/README.md +++ b/README.md @@ -1347,6 +1347,18 @@ file. interpret `command` is the same shell that is used to evaluate recipe lines, and can be changed with `set shell := […]`. + `command` is passes as the first argument, so if the command is `'echo $@'`, + the full command line, with the default shell command `shell -cu` and `args` + `'foo'` and `'bar'` will be: + + ``` + 'shell' '-cu' 'echo $@' 'echo $@' 'foo' 'bar' + ``` + + This is so that `$@` works as expected. `$@` does not include the first + positional argument, which is expected to be the name of the program being + run. + ```just # arguments can be variables file := '/sys/class/power_supply/BAT0/status' From 83c1b5fcc3b616e4abd7e482af1571d6a2d0698f Mon Sep 17 00:00:00 2001 From: Casey Rodarmor Date: Sun, 19 May 2024 21:08:44 -0700 Subject: [PATCH 3/6] Enhance --- README.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index aa573c5df1..9eec3152d0 100644 --- a/README.md +++ b/README.md @@ -1355,9 +1355,9 @@ file. 'shell' '-cu' 'echo $@' 'echo $@' 'foo' 'bar' ``` - This is so that `$@` works as expected. `$@` does not include the first - positional argument, which is expected to be the name of the program being - run. + This is so that `$@` works as expected, and `$1` refers to the first + argument. `$@` does not include the first positional argument, which is + expected to be the name of the program being run. ```just # arguments can be variables @@ -1374,9 +1374,10 @@ full := shell('echo $1', 'foo') ``` ```just -# using python as the shell +# using python as the shell. Since `python -c` sets `sys.argv[0]` to `'-c'`, +# the first "real" positional argument will be `sys.argv[2]` set shell := ["python3", "-c"] -olleh := shell('import sys; print(sys.argv[1][::-1]))', 'hello') +olleh := shell('import sys; print(sys.argv[2][::-1]))', 'hello') ``` #### Environment Variables From 99374c3be4509c05174920b5eab88f448db33230 Mon Sep 17 00:00:00 2001 From: Casey Rodarmor Date: Sun, 19 May 2024 21:09:13 -0700 Subject: [PATCH 4/6] Adapt --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9eec3152d0..6b622ded32 100644 --- a/README.md +++ b/README.md @@ -1347,7 +1347,7 @@ file. interpret `command` is the same shell that is used to evaluate recipe lines, and can be changed with `set shell := […]`. - `command` is passes as the first argument, so if the command is `'echo $@'`, + `command` is passed as the first argument, so if the command is `'echo $@'`, the full command line, with the default shell command `shell -cu` and `args` `'foo'` and `'bar'` will be: From 7c81e286ba0f051ad7826856b246dbaef2b3a8b6 Mon Sep 17 00:00:00 2001 From: Casey Rodarmor Date: Sun, 19 May 2024 21:09:45 -0700 Subject: [PATCH 5/6] Modify --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6b622ded32..d67efc5268 100644 --- a/README.md +++ b/README.md @@ -1374,8 +1374,8 @@ full := shell('echo $1', 'foo') ``` ```just -# using python as the shell. Since `python -c` sets `sys.argv[0]` to `'-c'`, -# the first "real" positional argument will be `sys.argv[2]` +# Using python as the shell. Since `python -c` sets `sys.argv[0]` to `'-c'`, +# the first "real" positional argument will be `sys.argv[2]`. set shell := ["python3", "-c"] olleh := shell('import sys; print(sys.argv[2][::-1]))', 'hello') ``` From 951b596f07f68522f382b039f459f14e38c5901e Mon Sep 17 00:00:00 2001 From: Casey Rodarmor Date: Sun, 19 May 2024 21:10:43 -0700 Subject: [PATCH 6/6] Revise --- tests/functions.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/functions.rs b/tests/functions.rs index 3cf6b2e14c..4631f55bfe 100644 --- a/tests/functions.rs +++ b/tests/functions.rs @@ -787,6 +787,11 @@ fn shell_args() { assert_eval_eq("shell('echo $@', 'justice', 'legs')", "justice legs"); } +#[test] +fn shell_first_arg() { + assert_eval_eq("shell('echo $0')", "echo $0"); +} + #[test] fn shell_error() { Test::new()