just icon indicating copy to clipboard operation
just copied to clipboard

Add support for flags and options (issue #476)

Open chmp opened this issue 7 months ago • 5 comments

Implementation for #476. See below for the design decisions I took in the implementation.

Example

# excerpt from `examples/kitchen-sink.just`

flags --flag --option="foo" positional:
  @echo "flag:      " {{ flag }}
  @echo "option:    " {{ option }}
  @echo "positional:" {{ positional}}

Invocations

$ cargo run -q -- --justfile ./examples/kitchen-sink.just flags bar
flag:
option:     foo
positional: bar

$ cargo run -q -- --justfile ./examples/kitchen-sink.just flags --option 42 bar
flag:
option:     42
positional: bar

cargo run -q -- --justfile ./examples/kitchen-sink.just flags --flag bar
flag:       flag
option:     foo
positional: bar

$ cargo run -q -- --justfile ./examples/kitchen-sink.just flags --option 42 --flag bar
flag:       flag
option:     42
positional: bar

# out of order
$ cargo run -q -- --justfile ./examples/kitchen-sink.just flags bar --option test --flag
flag:       flag
option:     test
positional: bar

# special cases
$ cargo run -q -- --justfile ./examples/kitchen-sink.just flags -- --flag
flag:
option:     foo
positional: --flag

$ cargo run -q -- --justfile ./examples/kitchen-sink.just flags --option --flag  bar
flag:
option:     --flag
positional: bar

Design

  • Flags are defined by ---parameter without default value
  • Options are defined by --parameter=default
  • Flags and options must be defined before positional parameters. Positional arguments are handled as before (including * and + modifiers)
  • Flags evaluate to their name when passed. When not passed, they evaluate to the empty string . This way flag != "" checks for the flag
  • Options consume the next parameter and evaluate to it when passed. When not passed, they evaluate to their default value
  • Options and flags can be passed in any order and mixed with positional arguments
  • -- forces all following arguments to interpreted as positional for the given recipe. When specifying multiple recipes, the parser resets for each new recipe
  • Recipes without flag parameters accept flags or options as positional arguments. This behavior ensure backwards compatibility (see for example the trailing_flags test)
  • --$flag or --$option=default defining environment variables

Open questions:

  • Support --options-with-hyphens? At the moment underscores must be used as in --options_with_underscores
  • How to update the Chinese readme?

chmp avatar Jul 07 '25 21:07 chmp

Merge casey:master to keep PR up to date

chmp avatar Jul 20 '25 07:07 chmp

Need this a lot

chosroes avatar Jul 23 '25 14:07 chosroes

Small observation from my own use of this feature: the definition of flags plays quite nicely with the unstable && operator.

For example, this justfile

set unstable 

test --full:
    cargo test {{ full && "--all-targets --all-features" }}

allows to use

  • just test to run cargo test, and
  • just test --full to run cargo test "--all-targets --all-features"

Related example:

set unstable 

run --port="" path="example":
    RUST_LOG="debug" cargo run -p server -- {{ port && ("--port " + port) }} {{ path }}

chmp avatar Jul 26 '25 14:07 chmp

hey @casey I just tipped you $20 via GitHub sponsors. Could you please take a look quick at this PR?

I suggest other folks in this thread to tip, too.

Flags are an essential features for CLIs but they are not currently available in Just :(

PaulRBerg avatar Nov 28 '25 06:11 PaulRBerg

Merged master to keep the PR up to date

chmp avatar Nov 28 '25 08:11 chmp