mirror of
https://github.com/casey/just.git
synced 2024-09-11 05:55:31 +03:00
Update clap to version 4 (#1924)
This commit is contained in:
parent
b85540007e
commit
caace0a115
62
Cargo.lock
generated
62
Cargo.lock
generated
@ -172,13 +172,49 @@ dependencies = [
|
||||
"ansi_term",
|
||||
"atty",
|
||||
"bitflags 1.3.2",
|
||||
"strsim",
|
||||
"term_size",
|
||||
"strsim 0.8.0",
|
||||
"textwrap",
|
||||
"unicode-width",
|
||||
"vec_map",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0"
|
||||
dependencies = [
|
||||
"clap_builder",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_builder"
|
||||
version = "4.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
"clap_lex",
|
||||
"strsim 0.11.1",
|
||||
"terminal_size",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_complete"
|
||||
version = "4.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd79504325bf38b10165b02e89b4347300f855f273c4cb30c4a3209e6583275e"
|
||||
dependencies = [
|
||||
"clap 4.5.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_lex"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce"
|
||||
|
||||
[[package]]
|
||||
name = "colorchoice"
|
||||
version = "1.0.1"
|
||||
@ -474,7 +510,8 @@ dependencies = [
|
||||
"atty",
|
||||
"blake3",
|
||||
"camino",
|
||||
"clap",
|
||||
"clap 4.5.4",
|
||||
"clap_complete",
|
||||
"cradle",
|
||||
"ctrlc",
|
||||
"derivative",
|
||||
@ -847,13 +884,19 @@ version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
||||
|
||||
[[package]]
|
||||
name = "structopt"
|
||||
version = "0.3.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c6b5c64445ba8094a6ab0c3cd2ad323e07171012d9c98b0b15651daf1787a10"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"clap 2.34.0",
|
||||
"lazy_static",
|
||||
"structopt-derive",
|
||||
]
|
||||
@ -943,13 +986,13 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "term_size"
|
||||
version = "0.3.2"
|
||||
name = "terminal_size"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e4129646ca0ed8f45d09b929036bafad5377103edd06e50bf574b353d2b08d9"
|
||||
checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"winapi",
|
||||
"rustix",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -958,7 +1001,6 @@ version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
|
||||
dependencies = [
|
||||
"term_size",
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
|
@ -22,7 +22,8 @@ ansi_term = "0.12.0"
|
||||
atty = "0.2.0"
|
||||
blake3 = { version = "1.5.0", features = ["rayon", "mmap"] }
|
||||
camino = "1.0.4"
|
||||
clap = { version = "2.33.0", features = ["wrap_help"] }
|
||||
clap = { version = "4.0.0", features = ["env", "wrap_help"] }
|
||||
clap_complete = "4.0.0"
|
||||
ctrlc = { version = "3.1.1", features = ["termination"] }
|
||||
derivative = "2.0.0"
|
||||
dirs = "5.0.1"
|
||||
|
@ -1,5 +1,5 @@
|
||||
_just() {
|
||||
local i cur prev words cword opts cmds
|
||||
local i cur prev words cword opts cmd
|
||||
COMPREPLY=()
|
||||
|
||||
# Modules use "::" as the separator, which is considered a wordbreak character in bash.
|
||||
@ -19,19 +19,18 @@ _just() {
|
||||
|
||||
for i in ${words[@]}
|
||||
do
|
||||
case "${i}" in
|
||||
"$1")
|
||||
case "${cmd},${i}" in
|
||||
",$1")
|
||||
cmd="just"
|
||||
;;
|
||||
|
||||
*)
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
case "${cmd}" in
|
||||
just)
|
||||
opts=" -n -q -u -v -e -l -h -V -f -d -c -s -E --check --yes --dry-run --highlight --no-aliases --no-deps --no-dotenv --no-highlight --quiet --shell-command --clear-shell-args --unsorted --unstable --verbose --changelog --choose --dump --edit --evaluate --fmt --init --list --summary --variables --help --version --chooser --color --command-color --dump-format --list-heading --list-prefix --justfile --set --shell --shell-arg --working-directory --command --completions --show --dotenv-filename --dotenv-path <ARGUMENTS>... "
|
||||
"$1")
|
||||
opts="-n -f -q -u -v -d -c -e -l -s -E -h -V --check --chooser --color --command-color --yes --dry-run --dump-format --highlight --list-heading --list-prefix --no-aliases --no-deps --no-dotenv --no-highlight --justfile --quiet --set --shell --shell-arg --shell-command --clear-shell-args --unsorted --unstable --verbose --working-directory --changelog --choose --command --completions --dump --edit --evaluate --fmt --init --list --show --summary --variables --dotenv-filename --dotenv-path --help --version [ARGUMENTS]..."
|
||||
if [[ ${cur} == -* ]] ; then
|
||||
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
|
||||
return 0
|
||||
@ -53,7 +52,6 @@ _just() {
|
||||
fi
|
||||
fi
|
||||
case "${prev}" in
|
||||
|
||||
--chooser)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
@ -82,7 +80,7 @@ _just() {
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
-f)
|
||||
-f)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
@ -102,7 +100,7 @@ _just() {
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
-d)
|
||||
-d)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
@ -110,19 +108,19 @@ _just() {
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
-c)
|
||||
-c)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--completions)
|
||||
COMPREPLY=($(compgen -W "zsh bash fish powershell elvish" -- "${cur}"))
|
||||
COMPREPLY=($(compgen -W "bash elvish fish powershell zsh" -- "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--show)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
-s)
|
||||
-s)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
@ -134,7 +132,7 @@ _just() {
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
-E)
|
||||
-E)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
@ -145,8 +143,11 @@ _just() {
|
||||
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
|
||||
return 0
|
||||
;;
|
||||
|
||||
esac
|
||||
}
|
||||
|
||||
complete -F _just -o bashdefault -o default just
|
||||
if [[ "${BASH_VERSINFO[0]}" -eq 4 && "${BASH_VERSINFO[1]}" -ge 4 || "${BASH_VERSINFO[0]}" -gt 4 ]]; then
|
||||
complete -F _just -o nosort -o bashdefault -o default just
|
||||
else
|
||||
complete -F _just -o bashdefault -o default just
|
||||
fi
|
||||
|
@ -1,18 +1,21 @@
|
||||
edit:completion:arg-completer[just] = [@words]{
|
||||
fn spaces [n]{
|
||||
repeat $n ' ' | joins ''
|
||||
use builtin;
|
||||
use str;
|
||||
|
||||
set edit:completion:arg-completer[just] = {|@words|
|
||||
fn spaces {|n|
|
||||
builtin:repeat $n ' ' | str:join ''
|
||||
}
|
||||
fn cand [text desc]{
|
||||
edit:complex-candidate $text &display-suffix=' '(spaces (- 14 (wcswidth $text)))$desc
|
||||
fn cand {|text desc|
|
||||
edit:complex-candidate $text &display=$text' '(spaces (- 14 (wcswidth $text)))$desc
|
||||
}
|
||||
command = 'just'
|
||||
for word $words[1:-1] {
|
||||
if (has-prefix $word '-') {
|
||||
var command = 'just'
|
||||
for word $words[1..-1] {
|
||||
if (str:has-prefix $word '-') {
|
||||
break
|
||||
}
|
||||
command = $command';'$word
|
||||
set command = $command';'$word
|
||||
}
|
||||
completions = [
|
||||
var completions = [
|
||||
&'just'= {
|
||||
cand --chooser 'Override binary invoked by `--choose`'
|
||||
cand --color 'Print colorful output'
|
||||
@ -65,10 +68,10 @@ edit:completion:arg-completer[just] = [@words]{
|
||||
cand --list 'List available recipes and their arguments'
|
||||
cand --summary 'List names of available recipes'
|
||||
cand --variables 'List names of variables'
|
||||
cand -h 'Print help information'
|
||||
cand --help 'Print help information'
|
||||
cand -V 'Print version information'
|
||||
cand --version 'Print version information'
|
||||
cand -h 'Print help'
|
||||
cand --help 'Print help'
|
||||
cand -V 'Print version'
|
||||
cand --version 'Print version'
|
||||
}
|
||||
]
|
||||
$completions[$command]
|
||||
|
@ -35,45 +35,45 @@ complete -c just -n "__fish_is_first_arg" --no-files
|
||||
complete -c just -a '(__fish_just_complete_recipes)'
|
||||
|
||||
# autogenerated completions
|
||||
complete -c just -n "__fish_use_subcommand" -l chooser -d 'Override binary invoked by `--choose`'
|
||||
complete -c just -n "__fish_use_subcommand" -l color -d 'Print colorful output' -r -f -a "auto always never"
|
||||
complete -c just -n "__fish_use_subcommand" -l command-color -d 'Echo recipe lines in <COMMAND-COLOR>' -r -f -a "black blue cyan green purple red yellow"
|
||||
complete -c just -n "__fish_use_subcommand" -l dump-format -d 'Dump justfile as <FORMAT>' -r -f -a "just json"
|
||||
complete -c just -n "__fish_use_subcommand" -l list-heading -d 'Print <TEXT> before list'
|
||||
complete -c just -n "__fish_use_subcommand" -l list-prefix -d 'Print <TEXT> before each list item'
|
||||
complete -c just -n "__fish_use_subcommand" -s f -l justfile -d 'Use <JUSTFILE> as justfile'
|
||||
complete -c just -n "__fish_use_subcommand" -l set -d 'Override <VARIABLE> with <VALUE>'
|
||||
complete -c just -n "__fish_use_subcommand" -l shell -d 'Invoke <SHELL> to run recipes'
|
||||
complete -c just -n "__fish_use_subcommand" -l shell-arg -d 'Invoke shell with <SHELL-ARG> as an argument'
|
||||
complete -c just -n "__fish_use_subcommand" -s d -l working-directory -d 'Use <WORKING-DIRECTORY> as working directory. --justfile must also be set'
|
||||
complete -c just -n "__fish_use_subcommand" -s c -l command -d 'Run an arbitrary command with the working directory, `.env`, overrides, and exports set'
|
||||
complete -c just -n "__fish_use_subcommand" -l completions -d 'Print shell completion script for <SHELL>' -r -f -a "zsh bash fish powershell elvish"
|
||||
complete -c just -n "__fish_use_subcommand" -s s -l show -d 'Show information about <RECIPE>'
|
||||
complete -c just -n "__fish_use_subcommand" -l dotenv-filename -d 'Search for environment file named <DOTENV-FILENAME> instead of `.env`'
|
||||
complete -c just -n "__fish_use_subcommand" -s E -l dotenv-path -d 'Load <DOTENV-PATH> as environment file instead of searching for one'
|
||||
complete -c just -n "__fish_use_subcommand" -l check -d 'Run `--fmt` in \'check\' mode. Exits with 0 if justfile is formatted correctly. Exits with 1 and prints a diff if formatting is required.'
|
||||
complete -c just -n "__fish_use_subcommand" -l yes -d 'Automatically confirm all recipes.'
|
||||
complete -c just -n "__fish_use_subcommand" -s n -l dry-run -d 'Print what just would do without doing it'
|
||||
complete -c just -n "__fish_use_subcommand" -l highlight -d 'Highlight echoed recipe lines in bold'
|
||||
complete -c just -n "__fish_use_subcommand" -l no-aliases -d 'Don\'t show aliases in list'
|
||||
complete -c just -n "__fish_use_subcommand" -l no-deps -d 'Don\'t run recipe dependencies'
|
||||
complete -c just -n "__fish_use_subcommand" -l no-dotenv -d 'Don\'t load `.env` file'
|
||||
complete -c just -n "__fish_use_subcommand" -l no-highlight -d 'Don\'t highlight echoed recipe lines in bold'
|
||||
complete -c just -n "__fish_use_subcommand" -s q -l quiet -d 'Suppress all output'
|
||||
complete -c just -n "__fish_use_subcommand" -l shell-command -d 'Invoke <COMMAND> with the shell used to run recipe lines and backticks'
|
||||
complete -c just -n "__fish_use_subcommand" -l clear-shell-args -d 'Clear shell arguments'
|
||||
complete -c just -n "__fish_use_subcommand" -s u -l unsorted -d 'Return list and summary entries in source order'
|
||||
complete -c just -n "__fish_use_subcommand" -l unstable -d 'Enable unstable features'
|
||||
complete -c just -n "__fish_use_subcommand" -s v -l verbose -d 'Use verbose output'
|
||||
complete -c just -n "__fish_use_subcommand" -l changelog -d 'Print changelog'
|
||||
complete -c just -n "__fish_use_subcommand" -l choose -d 'Select one or more recipes to run using a binary chooser. If `--chooser` is not passed the chooser defaults to the value of $JUST_CHOOSER, falling back to `fzf`'
|
||||
complete -c just -n "__fish_use_subcommand" -l dump -d 'Print justfile'
|
||||
complete -c just -n "__fish_use_subcommand" -s e -l edit -d 'Edit justfile with editor given by $VISUAL or $EDITOR, falling back to `vim`'
|
||||
complete -c just -n "__fish_use_subcommand" -l evaluate -d 'Evaluate and print all variables. If a variable name is given as an argument, only print that variable\'s value.'
|
||||
complete -c just -n "__fish_use_subcommand" -l fmt -d 'Format and overwrite justfile'
|
||||
complete -c just -n "__fish_use_subcommand" -l init -d 'Initialize new justfile in project root'
|
||||
complete -c just -n "__fish_use_subcommand" -s l -l list -d 'List available recipes and their arguments'
|
||||
complete -c just -n "__fish_use_subcommand" -l summary -d 'List names of available recipes'
|
||||
complete -c just -n "__fish_use_subcommand" -l variables -d 'List names of variables'
|
||||
complete -c just -n "__fish_use_subcommand" -s h -l help -d 'Print help information'
|
||||
complete -c just -n "__fish_use_subcommand" -s V -l version -d 'Print version information'
|
||||
complete -c just -l chooser -d 'Override binary invoked by `--choose`' -r
|
||||
complete -c just -l color -d 'Print colorful output' -r -f -a "{auto '',always '',never ''}"
|
||||
complete -c just -l command-color -d 'Echo recipe lines in <COMMAND-COLOR>' -r -f -a "{black '',blue '',cyan '',green '',purple '',red '',yellow ''}"
|
||||
complete -c just -l dump-format -d 'Dump justfile as <FORMAT>' -r -f -a "{just '',json ''}"
|
||||
complete -c just -l list-heading -d 'Print <TEXT> before list' -r
|
||||
complete -c just -l list-prefix -d 'Print <TEXT> before each list item' -r
|
||||
complete -c just -s f -l justfile -d 'Use <JUSTFILE> as justfile' -r -F
|
||||
complete -c just -l set -d 'Override <VARIABLE> with <VALUE>' -r
|
||||
complete -c just -l shell -d 'Invoke <SHELL> to run recipes' -r
|
||||
complete -c just -l shell-arg -d 'Invoke shell with <SHELL-ARG> as an argument' -r
|
||||
complete -c just -s d -l working-directory -d 'Use <WORKING-DIRECTORY> as working directory. --justfile must also be set' -r -F
|
||||
complete -c just -s c -l command -d 'Run an arbitrary command with the working directory, `.env`, overrides, and exports set' -r
|
||||
complete -c just -l completions -d 'Print shell completion script for <SHELL>' -r -f -a "{bash '',elvish '',fish '',powershell '',zsh ''}"
|
||||
complete -c just -s s -l show -d 'Show information about <RECIPE>' -r
|
||||
complete -c just -l dotenv-filename -d 'Search for environment file named <DOTENV-FILENAME> instead of `.env`' -r
|
||||
complete -c just -s E -l dotenv-path -d 'Load <DOTENV-PATH> as environment file instead of searching for one' -r -F
|
||||
complete -c just -l check -d 'Run `--fmt` in \'check\' mode. Exits with 0 if justfile is formatted correctly. Exits with 1 and prints a diff if formatting is required.'
|
||||
complete -c just -l yes -d 'Automatically confirm all recipes.'
|
||||
complete -c just -s n -l dry-run -d 'Print what just would do without doing it'
|
||||
complete -c just -l highlight -d 'Highlight echoed recipe lines in bold'
|
||||
complete -c just -l no-aliases -d 'Don\'t show aliases in list'
|
||||
complete -c just -l no-deps -d 'Don\'t run recipe dependencies'
|
||||
complete -c just -l no-dotenv -d 'Don\'t load `.env` file'
|
||||
complete -c just -l no-highlight -d 'Don\'t highlight echoed recipe lines in bold'
|
||||
complete -c just -s q -l quiet -d 'Suppress all output'
|
||||
complete -c just -l shell-command -d 'Invoke <COMMAND> with the shell used to run recipe lines and backticks'
|
||||
complete -c just -l clear-shell-args -d 'Clear shell arguments'
|
||||
complete -c just -s u -l unsorted -d 'Return list and summary entries in source order'
|
||||
complete -c just -l unstable -d 'Enable unstable features'
|
||||
complete -c just -s v -l verbose -d 'Use verbose output'
|
||||
complete -c just -l changelog -d 'Print changelog'
|
||||
complete -c just -l choose -d 'Select one or more recipes to run using a binary chooser. If `--chooser` is not passed the chooser defaults to the value of $JUST_CHOOSER, falling back to `fzf`'
|
||||
complete -c just -l dump -d 'Print justfile'
|
||||
complete -c just -s e -l edit -d 'Edit justfile with editor given by $VISUAL or $EDITOR, falling back to `vim`'
|
||||
complete -c just -l evaluate -d 'Evaluate and print all variables. If a variable name is given as an argument, only print that variable\'s value.'
|
||||
complete -c just -l fmt -d 'Format and overwrite justfile'
|
||||
complete -c just -l init -d 'Initialize new justfile in project root'
|
||||
complete -c just -s l -l list -d 'List available recipes and their arguments'
|
||||
complete -c just -l summary -d 'List names of available recipes'
|
||||
complete -c just -l variables -d 'List names of variables'
|
||||
complete -c just -s h -l help -d 'Print help'
|
||||
complete -c just -s V -l version -d 'Print version'
|
||||
|
@ -11,7 +11,8 @@ Register-ArgumentCompleter -Native -CommandName 'just' -ScriptBlock {
|
||||
$element = $commandElements[$i]
|
||||
if ($element -isnot [StringConstantExpressionAst] -or
|
||||
$element.StringConstantType -ne [StringConstantType]::BareWord -or
|
||||
$element.Value.StartsWith('-')) {
|
||||
$element.Value.StartsWith('-') -or
|
||||
$element.Value -eq $wordToComplete) {
|
||||
break
|
||||
}
|
||||
$element.Value
|
||||
@ -38,7 +39,7 @@ Register-ArgumentCompleter -Native -CommandName 'just' -ScriptBlock {
|
||||
[CompletionResult]::new('-s', 's', [CompletionResultType]::ParameterName, 'Show information about <RECIPE>')
|
||||
[CompletionResult]::new('--show', 'show', [CompletionResultType]::ParameterName, 'Show information about <RECIPE>')
|
||||
[CompletionResult]::new('--dotenv-filename', 'dotenv-filename', [CompletionResultType]::ParameterName, 'Search for environment file named <DOTENV-FILENAME> instead of `.env`')
|
||||
[CompletionResult]::new('-E', 'E', [CompletionResultType]::ParameterName, 'Load <DOTENV-PATH> as environment file instead of searching for one')
|
||||
[CompletionResult]::new('-E', 'E ', [CompletionResultType]::ParameterName, 'Load <DOTENV-PATH> as environment file instead of searching for one')
|
||||
[CompletionResult]::new('--dotenv-path', 'dotenv-path', [CompletionResultType]::ParameterName, 'Load <DOTENV-PATH> as environment file instead of searching for one')
|
||||
[CompletionResult]::new('--check', 'check', [CompletionResultType]::ParameterName, 'Run `--fmt` in ''check'' mode. Exits with 0 if justfile is formatted correctly. Exits with 1 and prints a diff if formatting is required.')
|
||||
[CompletionResult]::new('--yes', 'yes', [CompletionResultType]::ParameterName, 'Automatically confirm all recipes.')
|
||||
@ -70,10 +71,10 @@ Register-ArgumentCompleter -Native -CommandName 'just' -ScriptBlock {
|
||||
[CompletionResult]::new('--list', 'list', [CompletionResultType]::ParameterName, 'List available recipes and their arguments')
|
||||
[CompletionResult]::new('--summary', 'summary', [CompletionResultType]::ParameterName, 'List names of available recipes')
|
||||
[CompletionResult]::new('--variables', 'variables', [CompletionResultType]::ParameterName, 'List names of variables')
|
||||
[CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information')
|
||||
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
|
||||
[CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version information')
|
||||
[CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version information')
|
||||
[CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help')
|
||||
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help')
|
||||
[CompletionResult]::new('-V', 'V ', [CompletionResultType]::ParameterName, 'Print version')
|
||||
[CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version')
|
||||
break
|
||||
}
|
||||
})
|
||||
|
@ -15,35 +15,35 @@ _just() {
|
||||
|
||||
local context curcontext="$curcontext" state line
|
||||
local common=(
|
||||
'--chooser=[Override binary invoked by `--choose`]' \
|
||||
'--chooser=[Override binary invoked by \`--choose\`]: : ' \
|
||||
'--color=[Print colorful output]: :(auto always never)' \
|
||||
'--command-color=[Echo recipe lines in <COMMAND-COLOR>]: :(black blue cyan green purple red yellow)' \
|
||||
'--dump-format=[Dump justfile as <FORMAT>]: :(just json)' \
|
||||
'--list-heading=[Print <TEXT> before list]' \
|
||||
'--list-prefix=[Print <TEXT> before each list item]' \
|
||||
'-f+[Use <JUSTFILE> as justfile]' \
|
||||
'--justfile=[Use <JUSTFILE> as justfile]' \
|
||||
'*--set[Override <VARIABLE> with <VALUE>]: :_just_variables' \
|
||||
'--shell=[Invoke <SHELL> to run recipes]' \
|
||||
'*--shell-arg=[Invoke shell with <SHELL-ARG> as an argument]' \
|
||||
'-d+[Use <WORKING-DIRECTORY> as working directory. --justfile must also be set]' \
|
||||
'--working-directory=[Use <WORKING-DIRECTORY> as working directory. --justfile must also be set]' \
|
||||
'-c+[Run an arbitrary command with the working directory, `.env`, overrides, and exports set]' \
|
||||
'--command=[Run an arbitrary command with the working directory, `.env`, overrides, and exports set]' \
|
||||
'--completions=[Print shell completion script for <SHELL>]: :(zsh bash fish powershell elvish)' \
|
||||
'-s+[Show information about <RECIPE>]: :_just_commands' \
|
||||
'--show=[Show information about <RECIPE>]: :_just_commands' \
|
||||
'(-E --dotenv-path)--dotenv-filename=[Search for environment file named <DOTENV-FILENAME> instead of `.env`]' \
|
||||
'-E+[Load <DOTENV-PATH> as environment file instead of searching for one]' \
|
||||
'--dotenv-path=[Load <DOTENV-PATH> as environment file instead of searching for one]' \
|
||||
'--check[Run `--fmt` in '\''check'\'' mode. Exits with 0 if justfile is formatted correctly. Exits with 1 and prints a diff if formatting is required.]' \
|
||||
'--dump-format=[Dump justfile as <FORMAT>]:FORMAT:(just json)' \
|
||||
'--list-heading=[Print <TEXT> before list]:TEXT: ' \
|
||||
'--list-prefix=[Print <TEXT> before each list item]:TEXT: ' \
|
||||
'-f+[Use <JUSTFILE> as justfile]: :_files' \
|
||||
'--justfile=[Use <JUSTFILE> as justfile]: :_files' \
|
||||
'*--set=[Override <VARIABLE> with <VALUE>]: :(_just_variables)' \
|
||||
'--shell=[Invoke <SHELL> to run recipes]: : ' \
|
||||
'*--shell-arg=[Invoke shell with <SHELL-ARG> as an argument]: : ' \
|
||||
'-d+[Use <WORKING-DIRECTORY> as working directory. --justfile must also be set]: :_files' \
|
||||
'--working-directory=[Use <WORKING-DIRECTORY> as working directory. --justfile must also be set]: :_files' \
|
||||
'*-c+[Run an arbitrary command with the working directory, \`.env\`, overrides, and exports set]: : ' \
|
||||
'*--command=[Run an arbitrary command with the working directory, \`.env\`, overrides, and exports set]: : ' \
|
||||
'*--completions=[Print shell completion script for <SHELL>]:SHELL:(bash elvish fish powershell zsh)' \
|
||||
'-s+[Show information about <RECIPE>]: :(_just_commands)' \
|
||||
'--show=[Show information about <RECIPE>]: :(_just_commands)' \
|
||||
'(-E --dotenv-path)--dotenv-filename=[Search for environment file named <DOTENV-FILENAME> instead of \`.env\`]: : ' \
|
||||
'-E+[Load <DOTENV-PATH> as environment file instead of searching for one]: :_files' \
|
||||
'--dotenv-path=[Load <DOTENV-PATH> as environment file instead of searching for one]: :_files' \
|
||||
'--check[Run \`--fmt\` in '\''check'\'' mode. Exits with 0 if justfile is formatted correctly. Exits with 1 and prints a diff if formatting is required.]' \
|
||||
'--yes[Automatically confirm all recipes.]' \
|
||||
'(-q --quiet)-n[Print what just would do without doing it]' \
|
||||
'(-q --quiet)--dry-run[Print what just would do without doing it]' \
|
||||
'--highlight[Highlight echoed recipe lines in bold]' \
|
||||
'--no-aliases[Don'\''t show aliases in list]' \
|
||||
'--no-deps[Don'\''t run recipe dependencies]' \
|
||||
'--no-dotenv[Don'\''t load `.env` file]' \
|
||||
'--no-dotenv[Don'\''t load \`.env\` file]' \
|
||||
'--no-highlight[Don'\''t highlight echoed recipe lines in bold]' \
|
||||
'(-n --dry-run)-q[Suppress all output]' \
|
||||
'(-n --dry-run)--quiet[Suppress all output]' \
|
||||
@ -55,10 +55,10 @@ _just() {
|
||||
'*-v[Use verbose output]' \
|
||||
'*--verbose[Use verbose output]' \
|
||||
'--changelog[Print changelog]' \
|
||||
'--choose[Select one or more recipes to run using a binary chooser. If `--chooser` is not passed the chooser defaults to the value of $JUST_CHOOSER, falling back to `fzf`]' \
|
||||
'--choose[Select one or more recipes to run using a binary chooser. If \`--chooser\` is not passed the chooser defaults to the value of \$JUST_CHOOSER, falling back to \`fzf\`]' \
|
||||
'--dump[Print justfile]' \
|
||||
'-e[Edit justfile with editor given by $VISUAL or $EDITOR, falling back to `vim`]' \
|
||||
'--edit[Edit justfile with editor given by $VISUAL or $EDITOR, falling back to `vim`]' \
|
||||
'-e[Edit justfile with editor given by \$VISUAL or \$EDITOR, falling back to \`vim\`]' \
|
||||
'--edit[Edit justfile with editor given by \$VISUAL or \$EDITOR, falling back to \`vim\`]' \
|
||||
'--evaluate[Evaluate and print all variables. If a variable name is given as an argument, only print that variable'\''s value.]' \
|
||||
'--fmt[Format and overwrite justfile]' \
|
||||
'--init[Initialize new justfile in project root]' \
|
||||
@ -66,10 +66,10 @@ _just() {
|
||||
'--list[List available recipes and their arguments]' \
|
||||
'--summary[List names of available recipes]' \
|
||||
'--variables[List names of variables]' \
|
||||
'-h[Print help information]' \
|
||||
'--help[Print help information]' \
|
||||
'-V[Print version information]' \
|
||||
'--version[Print version information]' \
|
||||
'-h[Print help]' \
|
||||
'--help[Print help]' \
|
||||
'-V[Print version]' \
|
||||
'--version[Print version]' \
|
||||
)
|
||||
|
||||
_arguments "${_arguments_options[@]}" $common \
|
||||
@ -114,6 +114,7 @@ _just() {
|
||||
esac
|
||||
|
||||
return ret
|
||||
|
||||
}
|
||||
|
||||
(( $+functions[_just_commands] )) ||
|
||||
@ -138,7 +139,8 @@ _just_commands() {
|
||||
|
||||
}
|
||||
|
||||
(( $+functions[_just_variables] )) ||
|
||||
if [ "$funcstack[1]" = "_just" ]; then
|
||||
(( $+functions[_just_variables] )) ||
|
||||
_just_variables() {
|
||||
[[ $PREFIX = -* ]] && return 1
|
||||
integer ret=1
|
||||
@ -158,3 +160,6 @@ _just_variables() {
|
||||
}
|
||||
|
||||
_just "$@"
|
||||
else
|
||||
compdef _just just
|
||||
fi
|
||||
|
@ -43,21 +43,19 @@ pub(crate) const ZSH_COMPLETION_REPLACEMENTS: &[(&str, &str)] = &[
|
||||
r" local common=(",
|
||||
),
|
||||
(
|
||||
r"'*--set=[Override <VARIABLE> with <VALUE>]' \",
|
||||
r"'*--set[Override <VARIABLE> with <VALUE>]: :_just_variables' \",
|
||||
r"'*--set=[Override <VARIABLE> with <VALUE>]:VARIABLE: :VARIABLE: ' \",
|
||||
r"'*--set=[Override <VARIABLE> with <VALUE>]: :(_just_variables)' \",
|
||||
),
|
||||
(
|
||||
r"'-s+[Show information about <RECIPE>]' \
|
||||
'--show=[Show information about <RECIPE>]' \",
|
||||
r"'-s+[Show information about <RECIPE>]: :_just_commands' \
|
||||
'--show=[Show information about <RECIPE>]: :_just_commands' \",
|
||||
r"'()-s+[Show information about <RECIPE>]:RECIPE: ' \
|
||||
'()--show=[Show information about <RECIPE>]:RECIPE: ' \",
|
||||
r"'-s+[Show information about <RECIPE>]: :(_just_commands)' \
|
||||
'--show=[Show information about <RECIPE>]: :(_just_commands)' \",
|
||||
),
|
||||
(
|
||||
"'::ARGUMENTS -- Overrides and recipe(s) to run, defaulting to the first recipe in the \
|
||||
justfile:_files' \\
|
||||
&& ret=0
|
||||
\x20\x20\x20\x20
|
||||
",
|
||||
"'*::ARGUMENTS -- Overrides and recipe(s) to run, defaulting to the first recipe in the \
|
||||
justfile:' \\
|
||||
&& ret=0",
|
||||
r#")
|
||||
|
||||
_arguments "${_arguments_options[@]}" $common \
|
||||
@ -105,9 +103,7 @@ pub(crate) const ZSH_COMPLETION_REPLACEMENTS: &[(&str, &str)] = &[
|
||||
"#,
|
||||
),
|
||||
(
|
||||
" local commands; commands=(
|
||||
\x20\x20\x20\x20\x20\x20\x20\x20
|
||||
)",
|
||||
" local commands; commands=()",
|
||||
r#" [[ $PREFIX = -* ]] && return 1
|
||||
integer ret=1
|
||||
local variables; variables=(
|
||||
@ -206,10 +202,10 @@ pub(crate) const BASH_COMPLETION_REPLACEMENTS: &[(&str, &str)] = &[
|
||||
fi
|
||||
fi"#,
|
||||
),
|
||||
(r" just)", r#" "$1")"#),
|
||||
(r" just)", r#" "$1")"#),
|
||||
(
|
||||
r"local i cur prev opts cmds",
|
||||
r"local i cur prev words cword opts cmds",
|
||||
r"local i cur prev opts cmd",
|
||||
r"local i cur prev words cword opts cmd",
|
||||
),
|
||||
(
|
||||
r#" cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
|
454
src/config.rs
454
src/config.rs
@ -1,13 +1,14 @@
|
||||
use {
|
||||
super::*,
|
||||
clap::{App, AppSettings, Arg, ArgGroup, ArgMatches, ArgSettings},
|
||||
clap::{
|
||||
builder::{styling::AnsiColor, FalseyValueParser, PossibleValuesParser, Styles},
|
||||
value_parser, Arg, ArgAction, ArgGroup, ArgMatches, Command,
|
||||
},
|
||||
};
|
||||
|
||||
pub(crate) const CHOOSER_ENVIRONMENT_KEY: &str = "JUST_CHOOSER";
|
||||
|
||||
pub(crate) const CHOOSE_HELP: &str = "Select one or more recipes to run using a binary chooser. \
|
||||
If `--chooser` is not passed the chooser defaults to the \
|
||||
value of $JUST_CHOOSER, falling back to `fzf`";
|
||||
const CHOOSE_HELP: &str = "Select one or more recipes to run using a binary chooser. \
|
||||
If `--chooser` is not passed the chooser defaults to the \
|
||||
value of $JUST_CHOOSER, falling back to `fzf`";
|
||||
|
||||
pub(crate) fn chooser_default(justfile: &Path) -> OsString {
|
||||
let mut chooser = OsString::new();
|
||||
@ -76,16 +77,7 @@ mod cmd {
|
||||
];
|
||||
|
||||
pub(crate) const ARGLESS: &[&str] = &[
|
||||
CHANGELOG,
|
||||
COMPLETIONS,
|
||||
DUMP,
|
||||
EDIT,
|
||||
FORMAT,
|
||||
INIT,
|
||||
LIST,
|
||||
SHOW,
|
||||
SUMMARY,
|
||||
VARIABLES,
|
||||
CHANGELOG, DUMP, EDIT, FORMAT, INIT, LIST, SUMMARY, VARIABLES,
|
||||
];
|
||||
}
|
||||
|
||||
@ -147,270 +139,308 @@ mod arg {
|
||||
}
|
||||
|
||||
impl Config {
|
||||
pub(crate) fn app() -> App<'static, 'static> {
|
||||
let app = App::new(env!("CARGO_PKG_NAME"))
|
||||
.help_message("Print help information")
|
||||
.version_message("Print version information")
|
||||
.setting(AppSettings::ColoredHelp)
|
||||
.setting(AppSettings::TrailingVarArg)
|
||||
pub(crate) fn app() -> Command {
|
||||
let app = Command::new(env!("CARGO_PKG_NAME"))
|
||||
.bin_name(env!("CARGO_PKG_NAME"))
|
||||
.trailing_var_arg(true)
|
||||
.styles(
|
||||
Styles::styled()
|
||||
.header(AnsiColor::Yellow.on_default())
|
||||
.usage(AnsiColor::Yellow.on_default())
|
||||
.literal(AnsiColor::Green.on_default())
|
||||
.placeholder(AnsiColor::Green.on_default())
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(arg::CHECK)
|
||||
Arg::new(arg::CHECK)
|
||||
.long("check")
|
||||
.action(ArgAction::SetTrue)
|
||||
.requires(cmd::FORMAT)
|
||||
.help("Run `--fmt` in 'check' mode. Exits with 0 if justfile is formatted correctly. Exits with 1 and prints a diff if formatting is required."),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(arg::CHOOSER)
|
||||
Arg::new(arg::CHOOSER)
|
||||
.long("chooser")
|
||||
.takes_value(true)
|
||||
.env("JUST_CHOOSER")
|
||||
.action(ArgAction::Set)
|
||||
.help("Override binary invoked by `--choose`"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(arg::COLOR)
|
||||
Arg::new(arg::COLOR)
|
||||
.long("color")
|
||||
.takes_value(true)
|
||||
.possible_values(arg::COLOR_VALUES)
|
||||
.action(ArgAction::Set)
|
||||
.value_parser(PossibleValuesParser::new(arg::COLOR_VALUES))
|
||||
.default_value(arg::COLOR_AUTO)
|
||||
.help("Print colorful output"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(arg::COMMAND_COLOR)
|
||||
Arg::new(arg::COMMAND_COLOR)
|
||||
.long("command-color")
|
||||
.takes_value(true)
|
||||
.possible_values(arg::COMMAND_COLOR_VALUES)
|
||||
.action(ArgAction::Set)
|
||||
.value_parser(PossibleValuesParser::new(arg::COMMAND_COLOR_VALUES))
|
||||
.help("Echo recipe lines in <COMMAND-COLOR>"),
|
||||
)
|
||||
.arg(Arg::with_name(arg::YES).long("yes").help("Automatically confirm all recipes."))
|
||||
.arg(Arg::new(arg::YES).long("yes").action(ArgAction::SetTrue).help("Automatically confirm all recipes."))
|
||||
.arg(
|
||||
Arg::with_name(arg::DRY_RUN)
|
||||
.short("n")
|
||||
Arg::new(arg::DRY_RUN)
|
||||
.short('n')
|
||||
.long("dry-run")
|
||||
.action(ArgAction::SetTrue)
|
||||
.help("Print what just would do without doing it")
|
||||
.conflicts_with(arg::QUIET),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(arg::DUMP_FORMAT)
|
||||
Arg::new(arg::DUMP_FORMAT)
|
||||
.long("dump-format")
|
||||
.takes_value(true)
|
||||
.possible_values(arg::DUMP_FORMAT_VALUES)
|
||||
.action(ArgAction::Set)
|
||||
.value_parser(PossibleValuesParser::new(arg::DUMP_FORMAT_VALUES))
|
||||
.default_value(arg::DUMP_FORMAT_JUST)
|
||||
.value_name("FORMAT")
|
||||
.help("Dump justfile as <FORMAT>"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(arg::HIGHLIGHT)
|
||||
Arg::new(arg::HIGHLIGHT)
|
||||
.long("highlight")
|
||||
.action(ArgAction::SetTrue)
|
||||
.help("Highlight echoed recipe lines in bold")
|
||||
.overrides_with(arg::NO_HIGHLIGHT),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(arg::LIST_HEADING)
|
||||
Arg::new(arg::LIST_HEADING)
|
||||
.long("list-heading")
|
||||
.help("Print <TEXT> before list")
|
||||
.value_name("TEXT")
|
||||
.takes_value(true),
|
||||
.action(ArgAction::Set),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(arg::LIST_PREFIX)
|
||||
Arg::new(arg::LIST_PREFIX)
|
||||
.long("list-prefix")
|
||||
.help("Print <TEXT> before each list item")
|
||||
.value_name("TEXT")
|
||||
.takes_value(true),
|
||||
.action(ArgAction::Set),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(arg::NO_ALIASES)
|
||||
Arg::new(arg::NO_ALIASES)
|
||||
.long("no-aliases")
|
||||
.help("Don't show aliases in list")
|
||||
.action(ArgAction::SetTrue)
|
||||
.help("Don't show aliases in list"),
|
||||
)
|
||||
.arg (
|
||||
Arg::with_name(arg::NO_DEPS)
|
||||
Arg::new(arg::NO_DEPS)
|
||||
.long("no-deps")
|
||||
.alias("no-dependencies")
|
||||
.action(ArgAction::SetTrue)
|
||||
.help("Don't run recipe dependencies")
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(arg::NO_DOTENV)
|
||||
Arg::new(arg::NO_DOTENV)
|
||||
.long("no-dotenv")
|
||||
.action(ArgAction::SetTrue)
|
||||
.help("Don't load `.env` file"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(arg::NO_HIGHLIGHT)
|
||||
Arg::new(arg::NO_HIGHLIGHT)
|
||||
.long("no-highlight")
|
||||
.action(ArgAction::SetTrue)
|
||||
.help("Don't highlight echoed recipe lines in bold")
|
||||
.overrides_with(arg::HIGHLIGHT),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(arg::JUSTFILE)
|
||||
.short("f")
|
||||
Arg::new(arg::JUSTFILE)
|
||||
.short('f')
|
||||
.long("justfile")
|
||||
.takes_value(true)
|
||||
.action(ArgAction::Set)
|
||||
.value_parser(value_parser!(PathBuf))
|
||||
.help("Use <JUSTFILE> as justfile"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(arg::QUIET)
|
||||
.short("q")
|
||||
Arg::new(arg::QUIET)
|
||||
.short('q')
|
||||
.long("quiet")
|
||||
.action(ArgAction::SetTrue)
|
||||
.help("Suppress all output")
|
||||
.conflicts_with(arg::DRY_RUN),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(arg::SET)
|
||||
Arg::new(arg::SET)
|
||||
.long("set")
|
||||
.takes_value(true)
|
||||
.action(ArgAction::Append)
|
||||
.number_of_values(2)
|
||||
.value_names(&["VARIABLE", "VALUE"])
|
||||
.multiple(true)
|
||||
.value_names(["VARIABLE", "VALUE"])
|
||||
.help("Override <VARIABLE> with <VALUE>"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(arg::SHELL)
|
||||
Arg::new(arg::SHELL)
|
||||
.long("shell")
|
||||
.takes_value(true)
|
||||
.action(ArgAction::Set)
|
||||
.help("Invoke <SHELL> to run recipes"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(arg::SHELL_ARG)
|
||||
Arg::new(arg::SHELL_ARG)
|
||||
.long("shell-arg")
|
||||
.takes_value(true)
|
||||
.multiple(true)
|
||||
.number_of_values(1)
|
||||
.action(ArgAction::Append)
|
||||
.allow_hyphen_values(true)
|
||||
.overrides_with(arg::CLEAR_SHELL_ARGS)
|
||||
.help("Invoke shell with <SHELL-ARG> as an argument"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(arg::SHELL_COMMAND)
|
||||
Arg::new(arg::SHELL_COMMAND)
|
||||
.long("shell-command")
|
||||
.requires(cmd::COMMAND)
|
||||
.action(ArgAction::SetTrue)
|
||||
.help("Invoke <COMMAND> with the shell used to run recipe lines and backticks"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(arg::CLEAR_SHELL_ARGS)
|
||||
Arg::new(arg::CLEAR_SHELL_ARGS)
|
||||
.long("clear-shell-args")
|
||||
.action(ArgAction::SetTrue)
|
||||
.overrides_with(arg::SHELL_ARG)
|
||||
.help("Clear shell arguments"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(arg::UNSORTED)
|
||||
Arg::new(arg::UNSORTED)
|
||||
.long("unsorted")
|
||||
.short("u")
|
||||
.short('u')
|
||||
.action(ArgAction::SetTrue)
|
||||
.help("Return list and summary entries in source order"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(arg::UNSTABLE)
|
||||
Arg::new(arg::UNSTABLE)
|
||||
.long("unstable")
|
||||
.env("JUST_UNSTABLE")
|
||||
.action(ArgAction::SetTrue)
|
||||
.value_parser(FalseyValueParser::new())
|
||||
.help("Enable unstable features"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(arg::VERBOSE)
|
||||
.short("v")
|
||||
Arg::new(arg::VERBOSE)
|
||||
.short('v')
|
||||
.long("verbose")
|
||||
.multiple(true)
|
||||
.action(ArgAction::Count)
|
||||
.help("Use verbose output"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(arg::WORKING_DIRECTORY)
|
||||
.short("d")
|
||||
Arg::new(arg::WORKING_DIRECTORY)
|
||||
.short('d')
|
||||
.long("working-directory")
|
||||
.takes_value(true)
|
||||
.action(ArgAction::Set)
|
||||
.value_parser(value_parser!(PathBuf))
|
||||
.help("Use <WORKING-DIRECTORY> as working directory. --justfile must also be set")
|
||||
.requires(arg::JUSTFILE),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(cmd::CHANGELOG)
|
||||
Arg::new(cmd::CHANGELOG)
|
||||
.long("changelog")
|
||||
.action(ArgAction::SetTrue)
|
||||
.help("Print changelog"),
|
||||
)
|
||||
.arg(Arg::with_name(cmd::CHOOSE).long("choose").help(CHOOSE_HELP))
|
||||
.arg(Arg::new(cmd::CHOOSE).long("choose").action(ArgAction::SetTrue).help(CHOOSE_HELP))
|
||||
.arg(
|
||||
Arg::with_name(cmd::COMMAND)
|
||||
Arg::new(cmd::COMMAND)
|
||||
.long("command")
|
||||
.short("c")
|
||||
.min_values(1)
|
||||
.short('c')
|
||||
.num_args(1..)
|
||||
.allow_hyphen_values(true)
|
||||
.action(ArgAction::Append)
|
||||
.value_parser(value_parser!(std::ffi::OsString))
|
||||
.help(
|
||||
"Run an arbitrary command with the working directory, `.env`, overrides, and exports \
|
||||
set",
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(cmd::COMPLETIONS)
|
||||
Arg::new(cmd::COMPLETIONS)
|
||||
.long("completions")
|
||||
.takes_value(true)
|
||||
.action(ArgAction::Append)
|
||||
.num_args(1..)
|
||||
.value_name("SHELL")
|
||||
.possible_values(&clap::Shell::variants())
|
||||
.set(ArgSettings::CaseInsensitive)
|
||||
.value_parser(value_parser!(clap_complete::Shell))
|
||||
.ignore_case(true)
|
||||
.help("Print shell completion script for <SHELL>"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(cmd::DUMP)
|
||||
Arg::new(cmd::DUMP)
|
||||
.long("dump")
|
||||
.action(ArgAction::SetTrue)
|
||||
.help("Print justfile"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(cmd::EDIT)
|
||||
.short("e")
|
||||
Arg::new(cmd::EDIT)
|
||||
.short('e')
|
||||
.long("edit")
|
||||
.action(ArgAction::SetTrue)
|
||||
.help("Edit justfile with editor given by $VISUAL or $EDITOR, falling back to `vim`"),
|
||||
)
|
||||
.arg(Arg::with_name(cmd::EVALUATE).long("evaluate").help(
|
||||
"Evaluate and print all variables. If a variable name is given as an argument, only print \
|
||||
that variable's value.",
|
||||
))
|
||||
.arg(
|
||||
Arg::with_name(cmd::FORMAT)
|
||||
Arg::new(cmd::EVALUATE)
|
||||
.long("evaluate")
|
||||
.action(ArgAction::SetTrue)
|
||||
.help(
|
||||
"Evaluate and print all variables. If a variable name is given as an argument, only \
|
||||
print that variable's value.",
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
Arg::new(cmd::FORMAT)
|
||||
.long("fmt")
|
||||
.alias("format")
|
||||
.action(ArgAction::SetTrue)
|
||||
.help("Format and overwrite justfile"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(cmd::INIT)
|
||||
Arg::new(cmd::INIT)
|
||||
.long("init")
|
||||
.alias("initialize")
|
||||
.action(ArgAction::SetTrue)
|
||||
.help("Initialize new justfile in project root"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(cmd::LIST)
|
||||
.short("l")
|
||||
Arg::new(cmd::LIST)
|
||||
.short('l')
|
||||
.long("list")
|
||||
.action(ArgAction::SetTrue)
|
||||
.help("List available recipes and their arguments"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(cmd::SHOW)
|
||||
.short("s")
|
||||
Arg::new(cmd::SHOW)
|
||||
.short('s')
|
||||
.long("show")
|
||||
.takes_value(true)
|
||||
.action(ArgAction::Set)
|
||||
.value_name("RECIPE")
|
||||
.conflicts_with(arg::ARGUMENTS)
|
||||
.help("Show information about <RECIPE>"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(cmd::SUMMARY)
|
||||
Arg::new(cmd::SUMMARY)
|
||||
.long("summary")
|
||||
.action(ArgAction::SetTrue)
|
||||
.help("List names of available recipes"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(cmd::VARIABLES)
|
||||
Arg::new(cmd::VARIABLES)
|
||||
.long("variables")
|
||||
.action(ArgAction::SetTrue)
|
||||
.help("List names of variables"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(arg::DOTENV_FILENAME)
|
||||
Arg::new(arg::DOTENV_FILENAME)
|
||||
.long("dotenv-filename")
|
||||
.takes_value(true)
|
||||
.action(ArgAction::Set)
|
||||
.help("Search for environment file named <DOTENV-FILENAME> instead of `.env`")
|
||||
.conflicts_with(arg::DOTENV_PATH),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(arg::DOTENV_PATH)
|
||||
.short("E")
|
||||
Arg::new(arg::DOTENV_PATH)
|
||||
.short('E')
|
||||
.long("dotenv-path")
|
||||
.action(ArgAction::Set)
|
||||
.value_parser(value_parser!(PathBuf))
|
||||
.help("Load <DOTENV-PATH> as environment file instead of searching for one")
|
||||
.takes_value(true),
|
||||
)
|
||||
.group(ArgGroup::with_name("SUBCOMMAND").args(cmd::ALL))
|
||||
.group(ArgGroup::new("SUBCOMMAND").args(cmd::ALL))
|
||||
.arg(
|
||||
Arg::with_name(arg::ARGUMENTS)
|
||||
.multiple(true)
|
||||
Arg::new(arg::ARGUMENTS)
|
||||
.num_args(1..)
|
||||
.action(ArgAction::Append)
|
||||
.help("Overrides and recipe(s) to run, defaulting to the first recipe in the justfile"),
|
||||
);
|
||||
|
||||
@ -434,12 +464,12 @@ impl Config {
|
||||
|
||||
fn color_from_matches(matches: &ArgMatches) -> ConfigResult<Color> {
|
||||
let value = matches
|
||||
.value_of(arg::COLOR)
|
||||
.get_one::<String>(arg::COLOR)
|
||||
.ok_or_else(|| ConfigError::Internal {
|
||||
message: "`--color` had no value".to_string(),
|
||||
})?;
|
||||
|
||||
match value {
|
||||
match value.as_str() {
|
||||
arg::COLOR_AUTO => Ok(Color::auto()),
|
||||
arg::COLOR_ALWAYS => Ok(Color::always()),
|
||||
arg::COLOR_NEVER => Ok(Color::never()),
|
||||
@ -450,8 +480,8 @@ impl Config {
|
||||
}
|
||||
|
||||
fn command_color_from_matches(matches: &ArgMatches) -> ConfigResult<Option<ansi_term::Color>> {
|
||||
if let Some(value) = matches.value_of(arg::COMMAND_COLOR) {
|
||||
match value {
|
||||
if let Some(value) = matches.get_one::<String>(arg::COMMAND_COLOR) {
|
||||
match value.as_str() {
|
||||
arg::COMMAND_COLOR_BLACK => Ok(Some(ansi_term::Color::Black)),
|
||||
arg::COMMAND_COLOR_BLUE => Ok(Some(ansi_term::Color::Blue)),
|
||||
arg::COMMAND_COLOR_CYAN => Ok(Some(ansi_term::Color::Cyan)),
|
||||
@ -469,13 +499,14 @@ impl Config {
|
||||
}
|
||||
|
||||
fn dump_format_from_matches(matches: &ArgMatches) -> ConfigResult<DumpFormat> {
|
||||
let value = matches
|
||||
.value_of(arg::DUMP_FORMAT)
|
||||
.ok_or_else(|| ConfigError::Internal {
|
||||
message: "`--dump-format` had no value".to_string(),
|
||||
})?;
|
||||
let value =
|
||||
matches
|
||||
.get_one::<String>(arg::DUMP_FORMAT)
|
||||
.ok_or_else(|| ConfigError::Internal {
|
||||
message: "`--dump-format` had no value".to_string(),
|
||||
})?;
|
||||
|
||||
match value {
|
||||
match value.as_str() {
|
||||
arg::DUMP_FORMAT_JSON => Ok(DumpFormat::Json),
|
||||
arg::DUMP_FORMAT_JUST => Ok(DumpFormat::Just),
|
||||
_ => Err(ConfigError::Internal {
|
||||
@ -487,36 +518,37 @@ impl Config {
|
||||
pub(crate) fn from_matches(matches: &ArgMatches) -> ConfigResult<Self> {
|
||||
let invocation_directory = env::current_dir().context(config_error::CurrentDirContext)?;
|
||||
|
||||
let verbosity = if matches.is_present(arg::QUIET) {
|
||||
let verbosity = if matches.get_flag(arg::QUIET) {
|
||||
Verbosity::Quiet
|
||||
} else {
|
||||
Verbosity::from_flag_occurrences(matches.occurrences_of(arg::VERBOSE))
|
||||
Verbosity::from_flag_occurrences(matches.get_count(arg::VERBOSE))
|
||||
};
|
||||
|
||||
let color = Self::color_from_matches(matches)?;
|
||||
let command_color = Self::command_color_from_matches(matches)?;
|
||||
|
||||
let set_count = matches.occurrences_of(arg::SET);
|
||||
let mut overrides = BTreeMap::new();
|
||||
if set_count > 0 {
|
||||
let mut values = matches.values_of(arg::SET).unwrap();
|
||||
for _ in 0..set_count {
|
||||
overrides.insert(
|
||||
values.next().unwrap().to_owned(),
|
||||
values.next().unwrap().to_owned(),
|
||||
);
|
||||
if let Some(mut values) = matches.get_many::<String>(arg::SET) {
|
||||
while let (Some(k), Some(v)) = (values.next(), values.next()) {
|
||||
overrides.insert(k.into(), v.into());
|
||||
}
|
||||
}
|
||||
|
||||
let positional = Positional::from_values(matches.values_of(arg::ARGUMENTS));
|
||||
let positional = Positional::from_values(
|
||||
matches
|
||||
.get_many::<String>(arg::ARGUMENTS)
|
||||
.map(|s| s.map(String::as_str)),
|
||||
);
|
||||
|
||||
for (name, value) in positional.overrides {
|
||||
overrides.insert(name.clone(), value.clone());
|
||||
}
|
||||
|
||||
let search_config = {
|
||||
let justfile = matches.value_of(arg::JUSTFILE).map(PathBuf::from);
|
||||
let working_directory = matches.value_of(arg::WORKING_DIRECTORY).map(PathBuf::from);
|
||||
let justfile = matches.get_one::<PathBuf>(arg::JUSTFILE).map(Into::into);
|
||||
let working_directory = matches
|
||||
.get_one::<PathBuf>(arg::WORKING_DIRECTORY)
|
||||
.map(Into::into);
|
||||
|
||||
if let Some(search_directory) = positional.search_directory.map(PathBuf::from) {
|
||||
if justfile.is_some() || working_directory.is_some() {
|
||||
@ -543,7 +575,7 @@ impl Config {
|
||||
};
|
||||
|
||||
for subcommand in cmd::ARGLESS {
|
||||
if matches.is_present(subcommand) {
|
||||
if matches.get_flag(subcommand) {
|
||||
match (!overrides.is_empty(), !positional.arguments.is_empty()) {
|
||||
(false, false) => {}
|
||||
(true, false) => {
|
||||
@ -569,41 +601,37 @@ impl Config {
|
||||
}
|
||||
}
|
||||
|
||||
let subcommand = if matches.is_present(cmd::CHANGELOG) {
|
||||
let subcommand = if matches.get_flag(cmd::CHANGELOG) {
|
||||
Subcommand::Changelog
|
||||
} else if matches.is_present(cmd::CHOOSE) {
|
||||
} else if matches.get_flag(cmd::CHOOSE) {
|
||||
Subcommand::Choose {
|
||||
chooser: matches.value_of(arg::CHOOSER).map(str::to_owned),
|
||||
chooser: matches.get_one::<String>(arg::CHOOSER).map(Into::into),
|
||||
overrides,
|
||||
}
|
||||
} else if let Some(values) = matches.values_of_os(cmd::COMMAND) {
|
||||
let mut arguments = values.map(OsStr::to_owned).collect::<Vec<OsString>>();
|
||||
} else if let Some(values) = matches.get_many::<OsString>(cmd::COMMAND) {
|
||||
let mut arguments = values.map(Into::into).collect::<Vec<OsString>>();
|
||||
Subcommand::Command {
|
||||
binary: arguments.remove(0),
|
||||
arguments,
|
||||
overrides,
|
||||
}
|
||||
} else if let Some(shell) = matches.value_of(cmd::COMPLETIONS) {
|
||||
Subcommand::Completions {
|
||||
shell: shell.to_owned(),
|
||||
}
|
||||
} else if matches.is_present(cmd::EDIT) {
|
||||
} else if let Some(&shell) = matches.get_one::<clap_complete::Shell>(cmd::COMPLETIONS) {
|
||||
Subcommand::Completions { shell }
|
||||
} else if matches.get_flag(cmd::EDIT) {
|
||||
Subcommand::Edit
|
||||
} else if matches.is_present(cmd::SUMMARY) {
|
||||
} else if matches.get_flag(cmd::SUMMARY) {
|
||||
Subcommand::Summary
|
||||
} else if matches.is_present(cmd::DUMP) {
|
||||
} else if matches.get_flag(cmd::DUMP) {
|
||||
Subcommand::Dump
|
||||
} else if matches.is_present(cmd::FORMAT) {
|
||||
} else if matches.get_flag(cmd::FORMAT) {
|
||||
Subcommand::Format
|
||||
} else if matches.is_present(cmd::INIT) {
|
||||
} else if matches.get_flag(cmd::INIT) {
|
||||
Subcommand::Init
|
||||
} else if matches.is_present(cmd::LIST) {
|
||||
} else if matches.get_flag(cmd::LIST) {
|
||||
Subcommand::List
|
||||
} else if let Some(name) = matches.value_of(cmd::SHOW) {
|
||||
Subcommand::Show {
|
||||
name: name.to_owned(),
|
||||
}
|
||||
} else if matches.is_present(cmd::EVALUATE) {
|
||||
} else if let Some(name) = matches.get_one::<String>(cmd::SHOW).map(Into::into) {
|
||||
Subcommand::Show { name }
|
||||
} else if matches.get_flag(cmd::EVALUATE) {
|
||||
if positional.arguments.len() > 1 {
|
||||
return Err(ConfigError::SubcommandArguments {
|
||||
subcommand: cmd::EVALUATE,
|
||||
@ -619,7 +647,7 @@ impl Config {
|
||||
variable: positional.arguments.into_iter().next(),
|
||||
overrides,
|
||||
}
|
||||
} else if matches.is_present(cmd::VARIABLES) {
|
||||
} else if matches.get_flag(cmd::VARIABLES) {
|
||||
Subcommand::Variables
|
||||
} else {
|
||||
Subcommand::Run {
|
||||
@ -628,55 +656,46 @@ impl Config {
|
||||
}
|
||||
};
|
||||
|
||||
let shell_args = if matches.occurrences_of(arg::SHELL_ARG) > 0
|
||||
|| matches.occurrences_of(arg::CLEAR_SHELL_ARGS) > 0
|
||||
{
|
||||
Some(
|
||||
matches
|
||||
.values_of(arg::SHELL_ARG)
|
||||
.map_or(Vec::new(), |shell_args| {
|
||||
shell_args.map(str::to_owned).collect()
|
||||
}),
|
||||
)
|
||||
let shell_args = if matches.get_flag(arg::CLEAR_SHELL_ARGS) {
|
||||
Some(Vec::new())
|
||||
} else {
|
||||
None
|
||||
matches
|
||||
.get_many::<String>(arg::SHELL_ARG)
|
||||
.map(|s| s.map(Into::into).collect())
|
||||
};
|
||||
|
||||
let unstable = matches.is_present(arg::UNSTABLE)
|
||||
|| env::var_os("JUST_UNSTABLE")
|
||||
.map(|val| !(val == "false" || val == "0" || val.is_empty()))
|
||||
.unwrap_or_default();
|
||||
let unstable = matches.get_flag(arg::UNSTABLE);
|
||||
|
||||
Ok(Self {
|
||||
check: matches.is_present(arg::CHECK),
|
||||
check: matches.get_flag(arg::CHECK),
|
||||
color,
|
||||
command_color,
|
||||
dotenv_filename: matches.value_of(arg::DOTENV_FILENAME).map(str::to_owned),
|
||||
dotenv_path: matches.value_of(arg::DOTENV_PATH).map(PathBuf::from),
|
||||
dry_run: matches.is_present(arg::DRY_RUN),
|
||||
dotenv_filename: matches
|
||||
.get_one::<String>(arg::DOTENV_FILENAME)
|
||||
.map(Into::into),
|
||||
dotenv_path: matches.get_one::<PathBuf>(arg::DOTENV_PATH).map(Into::into),
|
||||
dry_run: matches.get_flag(arg::DRY_RUN),
|
||||
dump_format: Self::dump_format_from_matches(matches)?,
|
||||
highlight: !matches.is_present(arg::NO_HIGHLIGHT),
|
||||
highlight: !matches.get_flag(arg::NO_HIGHLIGHT),
|
||||
invocation_directory,
|
||||
list_heading: matches
|
||||
.value_of(arg::LIST_HEADING)
|
||||
.unwrap_or("Available recipes:\n")
|
||||
.to_owned(),
|
||||
.get_one::<String>(arg::LIST_HEADING)
|
||||
.map_or_else(|| "Available recipes:\n".into(), Into::into),
|
||||
list_prefix: matches
|
||||
.value_of(arg::LIST_PREFIX)
|
||||
.unwrap_or(" ")
|
||||
.to_owned(),
|
||||
load_dotenv: !matches.is_present(arg::NO_DOTENV),
|
||||
no_aliases: matches.is_present(arg::NO_ALIASES),
|
||||
no_dependencies: matches.is_present(arg::NO_DEPS),
|
||||
.get_one::<String>(arg::LIST_PREFIX)
|
||||
.map_or_else(|| " ".into(), Into::into),
|
||||
load_dotenv: !matches.get_flag(arg::NO_DOTENV),
|
||||
no_aliases: matches.get_flag(arg::NO_ALIASES),
|
||||
no_dependencies: matches.get_flag(arg::NO_DEPS),
|
||||
search_config,
|
||||
shell: matches.value_of(arg::SHELL).map(str::to_owned),
|
||||
shell: matches.get_one::<String>(arg::SHELL).map(Into::into),
|
||||
shell_args,
|
||||
shell_command: matches.is_present(arg::SHELL_COMMAND),
|
||||
shell_command: matches.get_flag(arg::SHELL_COMMAND),
|
||||
subcommand,
|
||||
unsorted: matches.is_present(arg::UNSORTED),
|
||||
unsorted: matches.get_flag(arg::UNSORTED),
|
||||
unstable,
|
||||
verbosity,
|
||||
yes: matches.is_present(arg::YES),
|
||||
yes: matches.get_flag(arg::YES),
|
||||
})
|
||||
}
|
||||
|
||||
@ -701,9 +720,11 @@ impl Config {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
use pretty_assertions::assert_eq;
|
||||
use {
|
||||
super::*,
|
||||
clap::error::{ContextKind, ContextValue},
|
||||
pretty_assertions::assert_eq,
|
||||
};
|
||||
|
||||
macro_rules! test {
|
||||
{
|
||||
@ -748,10 +769,11 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
fn test(arguments: &[&str], want: Config) {
|
||||
let app = Config::app();
|
||||
let matches = app
|
||||
.get_matches_from_safe(arguments)
|
||||
.try_get_matches_from(arguments)
|
||||
.expect("argument parsing failed");
|
||||
let have = Config::from_matches(&matches).expect("config parsing failed");
|
||||
assert_eq!(have, want);
|
||||
@ -771,7 +793,7 @@ mod tests {
|
||||
|
||||
let app = Config::app();
|
||||
|
||||
app.get_matches_from_safe(arguments).expect_err("Expected clap error");
|
||||
app.try_get_matches_from(arguments).expect_err("Expected clap error");
|
||||
}
|
||||
};
|
||||
{
|
||||
@ -789,7 +811,7 @@ mod tests {
|
||||
|
||||
let app = Config::app();
|
||||
|
||||
let matches = app.get_matches_from_safe(arguments).expect("Matching fails");
|
||||
let matches = app.try_get_matches_from(arguments).expect("Matching fails");
|
||||
|
||||
match Config::from_matches(&matches).expect_err("config parsing succeeded") {
|
||||
$error => { $($check)? }
|
||||
@ -799,6 +821,30 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! error_matches {
|
||||
(
|
||||
name: $name:ident,
|
||||
args: [$($arg:expr),*],
|
||||
error: $error:pat,
|
||||
$(check: $check:block,)?
|
||||
) => {
|
||||
#[test]
|
||||
fn $name() {
|
||||
let arguments = &[
|
||||
"just",
|
||||
$($arg,)*
|
||||
];
|
||||
|
||||
let app = Config::app();
|
||||
|
||||
match app.try_get_matches_from(arguments) {
|
||||
Err($error) => { $($check)? }
|
||||
other => panic!("Unexpected result from get matches: {other:?}")
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! map {
|
||||
{} => {
|
||||
BTreeMap::new()
|
||||
@ -1124,13 +1170,13 @@ mod tests {
|
||||
test! {
|
||||
name: subcommand_completions,
|
||||
args: ["--completions", "bash"],
|
||||
subcommand: Subcommand::Completions{shell: "bash".to_owned()},
|
||||
subcommand: Subcommand::Completions{ shell: clap_complete::Shell::Bash },
|
||||
}
|
||||
|
||||
test! {
|
||||
name: subcommand_completions_uppercase,
|
||||
args: ["--completions", "BASH"],
|
||||
subcommand: Subcommand::Completions{shell: "BASH".to_owned()},
|
||||
subcommand: Subcommand::Completions{ shell: clap_complete::Shell::Bash },
|
||||
}
|
||||
|
||||
error! {
|
||||
@ -1400,13 +1446,17 @@ mod tests {
|
||||
error: ConfigError::SearchDirConflict,
|
||||
}
|
||||
|
||||
error! {
|
||||
error_matches! {
|
||||
name: completions_arguments,
|
||||
args: ["--completions", "zsh", "foo"],
|
||||
error: ConfigError::SubcommandArguments { subcommand, arguments },
|
||||
error: error,
|
||||
check: {
|
||||
assert_eq!(subcommand, cmd::COMPLETIONS);
|
||||
assert_eq!(arguments, &["foo"]);
|
||||
assert_eq!(error.kind(), clap::error::ErrorKind::InvalidValue);
|
||||
assert_eq!(error.context().collect::<Vec<_>>(), vec![
|
||||
(ContextKind::InvalidArg, &ContextValue::String("--completions <SHELL>...".into())),
|
||||
(ContextKind::InvalidValue, &ContextValue::String("foo".into())),
|
||||
(ContextKind::ValidValue, &ContextValue::Strings(["bash".into(), "elvish".into(), "fish".into(), "powershell".into(), "zsh".into()].into())),
|
||||
]);
|
||||
},
|
||||
}
|
||||
|
||||
@ -1490,13 +1540,17 @@ mod tests {
|
||||
},
|
||||
}
|
||||
|
||||
error! {
|
||||
error_matches! {
|
||||
name: show_arguments,
|
||||
args: ["--show", "foo", "bar"],
|
||||
error: ConfigError::SubcommandArguments { subcommand, arguments },
|
||||
error: error,
|
||||
check: {
|
||||
assert_eq!(subcommand, cmd::SHOW);
|
||||
assert_eq!(arguments, &["bar"]);
|
||||
assert_eq!(error.kind(), clap::error::ErrorKind::ArgumentConflict);
|
||||
assert_eq!(error.context().collect::<Vec<_>>(), vec![
|
||||
(ContextKind::InvalidArg, &ContextValue::String("--show <RECIPE>".into())),
|
||||
(ContextKind::PriorArg, &ContextValue::String("[ARGUMENTS]...".into())),
|
||||
(ContextKind::Usage, &ContextValue::StyledStr("\u{1b}[33mUsage:\u{1b}[0m \u{1b}[32mjust\u{1b}[0m \u{1b}[32m--show\u{1b}[0m\u{1b}[32m \u{1b}[0m\u{1b}[32m<RECIPE>\u{1b}[0m \u{1b}[32m[ARGUMENTS]...\u{1b}[0m".into())),
|
||||
]);
|
||||
},
|
||||
}
|
||||
|
||||
|
10
src/error.rs
10
src/error.rs
@ -142,10 +142,13 @@ pub(crate) enum Error<'src> {
|
||||
line_number: Option<usize>,
|
||||
signal: i32,
|
||||
},
|
||||
TmpdirIo {
|
||||
TempdirIo {
|
||||
recipe: &'src str,
|
||||
io_error: io::Error,
|
||||
},
|
||||
TempfileIo {
|
||||
io_error: io::Error,
|
||||
},
|
||||
Unknown {
|
||||
recipe: &'src str,
|
||||
line_number: Option<usize>,
|
||||
@ -403,10 +406,13 @@ impl<'src> ColorDisplay for Error<'src> {
|
||||
write!(f, "Recipe `{recipe}` was terminated by signal {signal}")?;
|
||||
}
|
||||
}
|
||||
TmpdirIo { recipe, io_error } => {
|
||||
TempdirIo { recipe, io_error } => {
|
||||
write!(f, "Recipe `{recipe}` could not be run because of an IO error while trying to create a temporary \
|
||||
directory or write a file to that directory: {io_error}")?;
|
||||
}
|
||||
TempfileIo { io_error } => {
|
||||
write!(f, "Tempfile I/O error: {io_error}")?;
|
||||
}
|
||||
Unknown { recipe, line_number} => {
|
||||
if let Some(n) = line_number {
|
||||
write!(f, "Recipe `{recipe}` failed on line {n} for an unknown reason")?;
|
||||
|
@ -504,7 +504,10 @@ mod tests {
|
||||
fn dir_not_unicode() {
|
||||
use std::os::unix::ffi::OsStrExt;
|
||||
assert_eq!(
|
||||
dir("foo", || Some(OsStr::from_bytes(b"\xe0\x80\x80").into())).unwrap_err(),
|
||||
dir("foo", || Some(
|
||||
std::ffi::OsStr::from_bytes(b"\xe0\x80\x80").into()
|
||||
))
|
||||
.unwrap_err(),
|
||||
"unable to convert foo directory path to string: <20><><EFBFBD>",
|
||||
);
|
||||
}
|
||||
|
@ -42,10 +42,10 @@ pub(crate) use {
|
||||
cmp,
|
||||
collections::{BTreeMap, BTreeSet, HashMap},
|
||||
env,
|
||||
ffi::{OsStr, OsString},
|
||||
ffi::OsString,
|
||||
fmt::{self, Debug, Display, Formatter},
|
||||
fs,
|
||||
io::{self, Cursor, Write},
|
||||
io::{self, Write},
|
||||
iter::{self, FromIterator},
|
||||
mem,
|
||||
ops::Deref,
|
||||
|
@ -336,7 +336,7 @@ impl<'src, D> Recipe<'src, D> {
|
||||
Some(tempdir) => tempdir_builder.tempdir_in(context.search.working_directory.join(tempdir)),
|
||||
None => tempdir_builder.tempdir(),
|
||||
}
|
||||
.map_err(|error| Error::TmpdirIo {
|
||||
.map_err(|error| Error::TempdirIo {
|
||||
recipe: self.name(),
|
||||
io_error: error,
|
||||
})?;
|
||||
@ -344,7 +344,7 @@ impl<'src, D> Recipe<'src, D> {
|
||||
path.push(shebang.script_filename(self.name()));
|
||||
|
||||
{
|
||||
let mut f = fs::File::create(&path).map_err(|error| Error::TmpdirIo {
|
||||
let mut f = fs::File::create(&path).map_err(|error| Error::TempdirIo {
|
||||
recipe: self.name(),
|
||||
io_error: error,
|
||||
})?;
|
||||
@ -372,14 +372,14 @@ impl<'src, D> Recipe<'src, D> {
|
||||
}
|
||||
|
||||
f.write_all(text.as_bytes())
|
||||
.map_err(|error| Error::TmpdirIo {
|
||||
.map_err(|error| Error::TempdirIo {
|
||||
recipe: self.name(),
|
||||
io_error: error,
|
||||
})?;
|
||||
}
|
||||
|
||||
// make script executable
|
||||
Platform::set_execute_permission(&path).map_err(|error| Error::TmpdirIo {
|
||||
Platform::set_execute_permission(&path).map_err(|error| Error::TempdirIo {
|
||||
recipe: self.name(),
|
||||
io_error: error,
|
||||
})?;
|
||||
|
@ -1,4 +1,8 @@
|
||||
use super::*;
|
||||
use {
|
||||
super::*,
|
||||
std::io::{Read, Seek},
|
||||
tempfile::tempfile,
|
||||
};
|
||||
|
||||
const INIT_JUSTFILE: &str = "default:\n echo 'Hello, world!'\n";
|
||||
|
||||
@ -15,7 +19,7 @@ pub(crate) enum Subcommand {
|
||||
overrides: BTreeMap<String, String>,
|
||||
},
|
||||
Completions {
|
||||
shell: String,
|
||||
shell: clap_complete::Shell,
|
||||
},
|
||||
Dump,
|
||||
Edit,
|
||||
@ -50,7 +54,7 @@ impl Subcommand {
|
||||
Self::changelog();
|
||||
return Ok(());
|
||||
}
|
||||
Completions { shell } => return Self::completions(shell),
|
||||
Completions { shell } => return Self::completions(*shell),
|
||||
Init => return Self::init(config),
|
||||
Run {
|
||||
arguments,
|
||||
@ -213,10 +217,7 @@ impl Subcommand {
|
||||
return Err(Error::NoChoosableRecipes);
|
||||
}
|
||||
|
||||
let chooser = chooser
|
||||
.map(OsString::from)
|
||||
.or_else(|| env::var_os(config::CHOOSER_ENVIRONMENT_KEY))
|
||||
.unwrap_or_else(|| config::chooser_default(&search.justfile));
|
||||
let chooser = chooser.map_or_else(|| config::chooser_default(&search.justfile), From::from);
|
||||
|
||||
let result = justfile
|
||||
.settings
|
||||
@ -275,8 +276,8 @@ impl Subcommand {
|
||||
justfile.run(config, search, overrides, &recipes)
|
||||
}
|
||||
|
||||
fn completions(shell: &str) -> RunResult<'static, ()> {
|
||||
use clap::Shell;
|
||||
fn completions(shell: clap_complete::Shell) -> RunResult<'static, ()> {
|
||||
use clap_complete::Shell;
|
||||
|
||||
fn replace(haystack: &mut String, needle: &str, replacement: &str) -> RunResult<'static, ()> {
|
||||
if let Some(index) = haystack.find(needle) {
|
||||
@ -289,15 +290,28 @@ impl Subcommand {
|
||||
}
|
||||
}
|
||||
|
||||
let shell = shell
|
||||
.parse::<Shell>()
|
||||
.expect("Invalid value for clap::Shell");
|
||||
let mut script = {
|
||||
let mut tempfile = tempfile().map_err(|io_error| Error::TempfileIo { io_error })?;
|
||||
|
||||
let buffer = Vec::new();
|
||||
let mut cursor = Cursor::new(buffer);
|
||||
Config::app().gen_completions_to(env!("CARGO_PKG_NAME"), shell, &mut cursor);
|
||||
let buffer = cursor.into_inner();
|
||||
let mut script = String::from_utf8(buffer).expect("Clap completion not UTF-8");
|
||||
clap_complete::generate(
|
||||
shell,
|
||||
&mut crate::config::Config::app(),
|
||||
env!("CARGO_PKG_NAME"),
|
||||
&mut tempfile,
|
||||
);
|
||||
|
||||
tempfile
|
||||
.rewind()
|
||||
.map_err(|io_error| Error::TempfileIo { io_error })?;
|
||||
|
||||
let mut buffer = String::new();
|
||||
|
||||
tempfile
|
||||
.read_to_string(&mut buffer)
|
||||
.map_err(|io_error| Error::TempfileIo { io_error })?;
|
||||
|
||||
buffer
|
||||
};
|
||||
|
||||
match shell {
|
||||
Shell::Bash => {
|
||||
@ -319,7 +333,7 @@ impl Subcommand {
|
||||
replace(&mut script, needle, replacement)?;
|
||||
}
|
||||
}
|
||||
Shell::Elvish => {}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
println!("{}", script.trim());
|
||||
|
@ -10,7 +10,7 @@ pub(crate) fn config(args: &[&str]) -> Config {
|
||||
|
||||
let app = Config::app();
|
||||
|
||||
let matches = app.get_matches_from_safe(args).unwrap();
|
||||
let matches = app.try_get_matches_from(args).unwrap();
|
||||
|
||||
Config::from_matches(&matches).unwrap()
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ pub(crate) enum Verbosity {
|
||||
}
|
||||
|
||||
impl Verbosity {
|
||||
pub(crate) fn from_flag_occurrences(flag_occurrences: u64) -> Self {
|
||||
pub(crate) fn from_flag_occurrences(flag_occurrences: u8) -> Self {
|
||||
match flag_occurrences {
|
||||
0 => Taciturn,
|
||||
1 => Loquacious,
|
||||
|
@ -39,17 +39,12 @@ test! {
|
||||
echo XYZ
|
||||
",
|
||||
args: ("--command"),
|
||||
stderr: &format!("
|
||||
error: The argument '--command <COMMAND>' requires a value but none was supplied
|
||||
stderr: "
|
||||
error: a value is required for '--command <COMMAND>...' but none was supplied
|
||||
|
||||
USAGE:
|
||||
just{EXE_SUFFIX} --color <COLOR> --dump-format <FORMAT> --shell <SHELL> \
|
||||
<--changelog|--choose|--command <COMMAND>|--completions <SHELL>|--dump|--edit|\
|
||||
--evaluate|--fmt|--init|--list|--show <RECIPE>|--summary|--variables>
|
||||
|
||||
For more information try --help
|
||||
"),
|
||||
status: EXIT_FAILURE,
|
||||
For more information, try '--help'.
|
||||
",
|
||||
status: 2,
|
||||
}
|
||||
|
||||
test! {
|
||||
|
@ -15,10 +15,10 @@ test! {
|
||||
name: check_without_fmt,
|
||||
justfile: "",
|
||||
args: ("--check"),
|
||||
stderr_regex: "error: The following required arguments were not provided:
|
||||
--fmt
|
||||
stderr_regex: "error: the following required arguments were not provided:
|
||||
--fmt
|
||||
(.|\\n)+",
|
||||
status: EXIT_FAILURE,
|
||||
status: 2,
|
||||
}
|
||||
|
||||
test! {
|
||||
|
@ -189,6 +189,7 @@ impl Test {
|
||||
}
|
||||
|
||||
impl Test {
|
||||
#[track_caller]
|
||||
pub(crate) fn run(self) -> Output {
|
||||
if let Some(justfile) = &self.justfile {
|
||||
let justfile = unindent(justfile);
|
||||
|
Loading…
Reference in New Issue
Block a user