diff --git a/README.md b/README.md
index 040639f..27e0ba5 100644
--- a/README.md
+++ b/README.md
@@ -996,6 +996,20 @@ $ just test foo "bar baz"
- bar baz
```
+Positional arguments may also be turned on on a per-recipe basis with the
+`[positional-arguments]` attributemaster:
+
+```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
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]`1.9.0 | Don't change directory before executing recipe. |
| `[no-exit-message]`1.7.0 | Don't print an error message if recipe fails. |
| `[no-quiet]`1.23.0 | Override globally quiet recipes and always echo out the recipe. |
+| `[positional-arguments]`master | Turn on [positional arguments](#positional-arguments) for this recipe. |
| `[private]`1.10.0 | See [Private Recipes](#private-recipes). |
| `[unix]`1.8.0 | Enable recipe on Unixes. (Includes MacOS). |
| `[windows]`1.8.0 | Enable recipe on Windows. |
@@ -3362,9 +3377,9 @@ foo argument:
touch "$1"
```
-This defeats `just`'s ability to catch typos, for example if you type `$2`, but
-works for all possible values of `argument`, including those with double
-quotes.
+This defeats `just`'s ability to catch typos, for example if you type `$2`
+instead of `$1`, but works for all possible values of `argument`, including
+those with double quotes.
#### Exported Arguments
diff --git a/src/attribute.rs b/src/attribute.rs
index f9c5bfc..5e83891 100644
--- a/src/attribute.rs
+++ b/src/attribute.rs
@@ -17,6 +17,7 @@ pub(crate) enum Attribute<'src> {
NoCd,
NoExitMessage,
NoQuiet,
+ PositionalArguments,
Private,
Unix,
Windows,
@@ -32,6 +33,7 @@ impl AttributeDiscriminant {
| Self::NoCd
| Self::NoExitMessage
| Self::NoQuiet
+ | Self::PositionalArguments
| Self::Private
| Self::Unix
| Self::Windows => 0..=0,
@@ -78,6 +80,7 @@ impl<'src> Attribute<'src> {
NoCd => Self::NoCd,
NoExitMessage => Self::NoExitMessage,
NoQuiet => Self::NoQuiet,
+ PositionalArguments => Self::PositionalArguments,
Private => Self::Private,
Unix => Self::Unix,
Windows => Self::Windows,
@@ -98,6 +101,7 @@ impl<'src> Attribute<'src> {
| Self::NoCd
| Self::NoExitMessage
| Self::NoQuiet
+ | Self::PositionalArguments
| Self::Private
| Self::Unix
| Self::Windows => None,
diff --git a/src/recipe.rs b/src/recipe.rs
index 13b3bb9..e27cc2e 100644
--- a/src/recipe.rs
+++ b/src/recipe.rs
@@ -106,6 +106,10 @@ impl<'src, D> Recipe<'src, D> {
!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 {
!self.attributes.contains(&Attribute::NoCd)
}
@@ -263,7 +267,7 @@ impl<'src, D> Recipe<'src, D> {
cmd.arg(command);
- if context.settings.positional_arguments {
+ if self.takes_positional_arguments(context.settings) {
cmd.arg(self.name.lexeme());
cmd.args(positional);
}
@@ -415,7 +419,7 @@ impl<'src, D> Recipe<'src, D> {
output_error,
})?;
- if context.settings.positional_arguments {
+ if self.takes_positional_arguments(context.settings) {
command.args(positional);
}
diff --git a/tests/positional_arguments.rs b/tests/positional_arguments.rs
index f412f0c..86e4da1 100644
--- a/tests/positional_arguments.rs
+++ b/tests/positional_arguments.rs
@@ -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! {
name: variadic_linewise,
justfile: r#"
@@ -51,6 +76,18 @@ test! {
stdout: "hello\n",
}
+test! {
+ name: shebang_with_attribute,
+ justfile: "
+ [positional-arguments]
+ foo bar:
+ #!/bin/sh
+ echo $1
+ ",
+ args: ("foo", "hello"),
+ stdout: "hello\n",
+}
+
test! {
name: variadic_shebang,
justfile: r#"