Add [positional-arguments] attribute (#2151)

This commit is contained in:
Casey Rodarmor 2024-06-13 12:35:14 -07:00 committed by GitHub
parent 637023e86f
commit 1ce7a05bef
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 65 additions and 5 deletions

View File

@ -996,6 +996,20 @@ $ just test foo "bar baz"
- bar baz - bar baz
``` ```
Positional arguments may also be turned on on a per-recipe basis with the
`[positional-arguments]` attribute<sup>master</sup>:
```just
[positional-arguments]
@foo bar:
echo $0
echo $1
```
Note that PowerShell does not handle positional arguments in the same way as
other shells, so turning on positional arguments will likely break recipes that
use PowerShell.
#### Shell #### Shell
The `shell` setting controls the command used to invoke recipe lines and The `shell` setting controls the command used to invoke recipe lines and
@ -1686,6 +1700,7 @@ Recipes may be annotated with attributes that change their behavior.
| `[no-cd]`<sup>1.9.0</sup> | Don't change directory before executing recipe. | | `[no-cd]`<sup>1.9.0</sup> | Don't change directory before executing recipe. |
| `[no-exit-message]`<sup>1.7.0</sup> | Don't print an error message if recipe fails. | | `[no-exit-message]`<sup>1.7.0</sup> | Don't print an error message if recipe fails. |
| `[no-quiet]`<sup>1.23.0</sup> | Override globally quiet recipes and always echo out the recipe. | | `[no-quiet]`<sup>1.23.0</sup> | Override globally quiet recipes and always echo out the recipe. |
| `[positional-arguments]`<sup>master</sup> | Turn on [positional arguments](#positional-arguments) for this recipe. |
| `[private]`<sup>1.10.0</sup> | See [Private Recipes](#private-recipes). | | `[private]`<sup>1.10.0</sup> | See [Private Recipes](#private-recipes). |
| `[unix]`<sup>1.8.0</sup> | Enable recipe on Unixes. (Includes MacOS). | | `[unix]`<sup>1.8.0</sup> | Enable recipe on Unixes. (Includes MacOS). |
| `[windows]`<sup>1.8.0</sup> | Enable recipe on Windows. | | `[windows]`<sup>1.8.0</sup> | Enable recipe on Windows. |
@ -3362,9 +3377,9 @@ foo argument:
touch "$1" touch "$1"
``` ```
This defeats `just`'s ability to catch typos, for example if you type `$2`, but This defeats `just`'s ability to catch typos, for example if you type `$2`
works for all possible values of `argument`, including those with double instead of `$1`, but works for all possible values of `argument`, including
quotes. those with double quotes.
#### Exported Arguments #### Exported Arguments

View File

@ -17,6 +17,7 @@ pub(crate) enum Attribute<'src> {
NoCd, NoCd,
NoExitMessage, NoExitMessage,
NoQuiet, NoQuiet,
PositionalArguments,
Private, Private,
Unix, Unix,
Windows, Windows,
@ -32,6 +33,7 @@ impl AttributeDiscriminant {
| Self::NoCd | Self::NoCd
| Self::NoExitMessage | Self::NoExitMessage
| Self::NoQuiet | Self::NoQuiet
| Self::PositionalArguments
| Self::Private | Self::Private
| Self::Unix | Self::Unix
| Self::Windows => 0..=0, | Self::Windows => 0..=0,
@ -78,6 +80,7 @@ impl<'src> Attribute<'src> {
NoCd => Self::NoCd, NoCd => Self::NoCd,
NoExitMessage => Self::NoExitMessage, NoExitMessage => Self::NoExitMessage,
NoQuiet => Self::NoQuiet, NoQuiet => Self::NoQuiet,
PositionalArguments => Self::PositionalArguments,
Private => Self::Private, Private => Self::Private,
Unix => Self::Unix, Unix => Self::Unix,
Windows => Self::Windows, Windows => Self::Windows,
@ -98,6 +101,7 @@ impl<'src> Attribute<'src> {
| Self::NoCd | Self::NoCd
| Self::NoExitMessage | Self::NoExitMessage
| Self::NoQuiet | Self::NoQuiet
| Self::PositionalArguments
| Self::Private | Self::Private
| Self::Unix | Self::Unix
| Self::Windows => None, | Self::Windows => None,

View File

@ -106,6 +106,10 @@ impl<'src, D> Recipe<'src, D> {
!self.private && !self.attributes.contains(&Attribute::Private) !self.private && !self.attributes.contains(&Attribute::Private)
} }
pub(crate) fn takes_positional_arguments(&self, settings: &Settings) -> bool {
settings.positional_arguments || self.attributes.contains(&Attribute::PositionalArguments)
}
pub(crate) fn change_directory(&self) -> bool { pub(crate) fn change_directory(&self) -> bool {
!self.attributes.contains(&Attribute::NoCd) !self.attributes.contains(&Attribute::NoCd)
} }
@ -263,7 +267,7 @@ impl<'src, D> Recipe<'src, D> {
cmd.arg(command); cmd.arg(command);
if context.settings.positional_arguments { if self.takes_positional_arguments(context.settings) {
cmd.arg(self.name.lexeme()); cmd.arg(self.name.lexeme());
cmd.args(positional); cmd.args(positional);
} }
@ -415,7 +419,7 @@ impl<'src, D> Recipe<'src, D> {
output_error, output_error,
})?; })?;
if context.settings.positional_arguments { if self.takes_positional_arguments(context.settings) {
command.args(positional); command.args(positional);
} }

View File

@ -24,6 +24,31 @@ test! {
"#, "#,
} }
test! {
name: linewise_with_attribute,
justfile: r#"
[positional-arguments]
foo bar baz:
echo $0
echo $1
echo $2
echo "$@"
"#,
args: ("foo", "hello", "goodbye"),
stdout: "
foo
hello
goodbye
hello goodbye
",
stderr: r#"
echo $0
echo $1
echo $2
echo "$@"
"#,
}
test! { test! {
name: variadic_linewise, name: variadic_linewise,
justfile: r#" justfile: r#"
@ -51,6 +76,18 @@ test! {
stdout: "hello\n", stdout: "hello\n",
} }
test! {
name: shebang_with_attribute,
justfile: "
[positional-arguments]
foo bar:
#!/bin/sh
echo $1
",
args: ("foo", "hello"),
stdout: "hello\n",
}
test! { test! {
name: variadic_shebang, name: variadic_shebang,
justfile: r#" justfile: r#"