From 1ce7a05befa8e2c0e3b05f52934087f57a439220 Mon Sep 17 00:00:00 2001 From: Casey Rodarmor Date: Thu, 13 Jun 2024 12:35:14 -0700 Subject: [PATCH] Add [positional-arguments] attribute (#2151) --- README.md | 21 +++++++++++++++++--- src/attribute.rs | 4 ++++ src/recipe.rs | 8 ++++++-- tests/positional_arguments.rs | 37 +++++++++++++++++++++++++++++++++++ 4 files changed, 65 insertions(+), 5 deletions(-) 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#"