Allow listing recipes in submodules with --list-submodules
(#2113)
This commit is contained in:
parent
d2b10e04d3
commit
d38c1add13
@ -30,7 +30,7 @@ _just() {
|
|||||||
|
|
||||||
case "${cmd}" in
|
case "${cmd}" in
|
||||||
just)
|
just)
|
||||||
opts="-n -f -q -u -v -d -c -e -l -s -E -g -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 --groups --man --show --summary --variables --dotenv-filename --dotenv-path --global-justfile --timestamp --timestamp-format --help --version [ARGUMENTS]..."
|
opts="-n -f -q -u -v -d -c -e -l -s -E -g -h -V --check --chooser --color --command-color --yes --dry-run --dump-format --highlight --list-heading --list-prefix --list-submodules --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 --groups --man --show --summary --variables --dotenv-filename --dotenv-path --global-justfile --timestamp --timestamp-format --help --version [ARGUMENTS]..."
|
||||||
if [[ ${cur} == -* ]] ; then
|
if [[ ${cur} == -* ]] ; then
|
||||||
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
|
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
|
||||||
return 0
|
return 0
|
||||||
|
@ -46,6 +46,7 @@ set edit:completion:arg-completer[just] = {|@words|
|
|||||||
cand -n 'Print what just would do without doing it'
|
cand -n 'Print what just would do without doing it'
|
||||||
cand --dry-run 'Print what just would do without doing it'
|
cand --dry-run 'Print what just would do without doing it'
|
||||||
cand --highlight 'Highlight echoed recipe lines in bold'
|
cand --highlight 'Highlight echoed recipe lines in bold'
|
||||||
|
cand --list-submodules 'List recipes in submodules'
|
||||||
cand --no-aliases 'Don''t show aliases in list'
|
cand --no-aliases 'Don''t show aliases in list'
|
||||||
cand --no-deps 'Don''t run recipe dependencies'
|
cand --no-deps 'Don''t run recipe dependencies'
|
||||||
cand --no-dotenv 'Don''t load `.env` file'
|
cand --no-dotenv 'Don''t load `.env` file'
|
||||||
|
@ -57,6 +57,7 @@ complete -c just -l check -d 'Run `--fmt` in \'check\' mode. Exits with 0 if jus
|
|||||||
complete -c just -l yes -d 'Automatically confirm all recipes.'
|
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 -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 highlight -d 'Highlight echoed recipe lines in bold'
|
||||||
|
complete -c just -l list-submodules -d 'List recipes in submodules'
|
||||||
complete -c just -l no-aliases -d 'Don\'t show aliases in list'
|
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-deps -d 'Don\'t run recipe dependencies'
|
||||||
complete -c just -l no-dotenv -d 'Don\'t load `.env` file'
|
complete -c just -l no-dotenv -d 'Don\'t load `.env` file'
|
||||||
|
@ -49,6 +49,7 @@ Register-ArgumentCompleter -Native -CommandName 'just' -ScriptBlock {
|
|||||||
[CompletionResult]::new('-n', 'n', [CompletionResultType]::ParameterName, 'Print what just would do without doing it')
|
[CompletionResult]::new('-n', 'n', [CompletionResultType]::ParameterName, 'Print what just would do without doing it')
|
||||||
[CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'Print what just would do without doing it')
|
[CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'Print what just would do without doing it')
|
||||||
[CompletionResult]::new('--highlight', 'highlight', [CompletionResultType]::ParameterName, 'Highlight echoed recipe lines in bold')
|
[CompletionResult]::new('--highlight', 'highlight', [CompletionResultType]::ParameterName, 'Highlight echoed recipe lines in bold')
|
||||||
|
[CompletionResult]::new('--list-submodules', 'list-submodules', [CompletionResultType]::ParameterName, 'List recipes in submodules')
|
||||||
[CompletionResult]::new('--no-aliases', 'no-aliases', [CompletionResultType]::ParameterName, 'Don''t show aliases in list')
|
[CompletionResult]::new('--no-aliases', 'no-aliases', [CompletionResultType]::ParameterName, 'Don''t show aliases in list')
|
||||||
[CompletionResult]::new('--no-deps', 'no-deps', [CompletionResultType]::ParameterName, 'Don''t run recipe dependencies')
|
[CompletionResult]::new('--no-deps', 'no-deps', [CompletionResultType]::ParameterName, 'Don''t run recipe dependencies')
|
||||||
[CompletionResult]::new('--no-dotenv', 'no-dotenv', [CompletionResultType]::ParameterName, 'Don''t load `.env` file')
|
[CompletionResult]::new('--no-dotenv', 'no-dotenv', [CompletionResultType]::ParameterName, 'Don''t load `.env` file')
|
||||||
|
@ -44,6 +44,7 @@ _just() {
|
|||||||
'(-q --quiet)-n[Print what just would do without doing it]' \
|
'(-q --quiet)-n[Print what just would do without doing it]' \
|
||||||
'(-q --quiet)--dry-run[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]' \
|
'--highlight[Highlight echoed recipe lines in bold]' \
|
||||||
|
'--list-submodules[List recipes in submodules]' \
|
||||||
'--no-aliases[Don'\''t show aliases in list]' \
|
'--no-aliases[Don'\''t show aliases in list]' \
|
||||||
'--no-deps[Don'\''t run recipe dependencies]' \
|
'--no-deps[Don'\''t run recipe dependencies]' \
|
||||||
'--no-dotenv[Don'\''t load \`.env\` file]' \
|
'--no-dotenv[Don'\''t load \`.env\` file]' \
|
||||||
|
@ -32,6 +32,7 @@ pub(crate) struct Config {
|
|||||||
pub(crate) invocation_directory: PathBuf,
|
pub(crate) invocation_directory: PathBuf,
|
||||||
pub(crate) list_heading: String,
|
pub(crate) list_heading: String,
|
||||||
pub(crate) list_prefix: String,
|
pub(crate) list_prefix: String,
|
||||||
|
pub(crate) list_submodules: bool,
|
||||||
pub(crate) load_dotenv: bool,
|
pub(crate) load_dotenv: bool,
|
||||||
pub(crate) no_aliases: bool,
|
pub(crate) no_aliases: bool,
|
||||||
pub(crate) no_dependencies: bool,
|
pub(crate) no_dependencies: bool,
|
||||||
@ -97,11 +98,12 @@ mod arg {
|
|||||||
pub(crate) const DOTENV_PATH: &str = "DOTENV-PATH";
|
pub(crate) const DOTENV_PATH: &str = "DOTENV-PATH";
|
||||||
pub(crate) const DRY_RUN: &str = "DRY-RUN";
|
pub(crate) const DRY_RUN: &str = "DRY-RUN";
|
||||||
pub(crate) const DUMP_FORMAT: &str = "DUMP-FORMAT";
|
pub(crate) const DUMP_FORMAT: &str = "DUMP-FORMAT";
|
||||||
pub(crate) const GLOBAL_JUSTFILE: &str = "GLOBAL_JUSTFILE";
|
pub(crate) const GLOBAL_JUSTFILE: &str = "GLOBAL-JUSTFILE";
|
||||||
pub(crate) const HIGHLIGHT: &str = "HIGHLIGHT";
|
pub(crate) const HIGHLIGHT: &str = "HIGHLIGHT";
|
||||||
pub(crate) const JUSTFILE: &str = "JUSTFILE";
|
pub(crate) const JUSTFILE: &str = "JUSTFILE";
|
||||||
pub(crate) const LIST_HEADING: &str = "LIST-HEADING";
|
pub(crate) const LIST_HEADING: &str = "LIST-HEADING";
|
||||||
pub(crate) const LIST_PREFIX: &str = "LIST-PREFIX";
|
pub(crate) const LIST_PREFIX: &str = "LIST-PREFIX";
|
||||||
|
pub(crate) const LIST_SUBMODULES: &str = "LIST-SUBMODULES";
|
||||||
pub(crate) const NO_ALIASES: &str = "NO-ALIASES";
|
pub(crate) const NO_ALIASES: &str = "NO-ALIASES";
|
||||||
pub(crate) const NO_DEPS: &str = "NO-DEPS";
|
pub(crate) const NO_DEPS: &str = "NO-DEPS";
|
||||||
pub(crate) const NO_DOTENV: &str = "NO-DOTENV";
|
pub(crate) const NO_DOTENV: &str = "NO-DOTENV";
|
||||||
@ -112,7 +114,7 @@ mod arg {
|
|||||||
pub(crate) const SHELL_ARG: &str = "SHELL-ARG";
|
pub(crate) const SHELL_ARG: &str = "SHELL-ARG";
|
||||||
pub(crate) const SHELL_COMMAND: &str = "SHELL-COMMAND";
|
pub(crate) const SHELL_COMMAND: &str = "SHELL-COMMAND";
|
||||||
pub(crate) const TIMESTAMP: &str = "TIMESTAMP";
|
pub(crate) const TIMESTAMP: &str = "TIMESTAMP";
|
||||||
pub(crate) const TIMESTAMP_FORMAT: &str = "TIMESTAMP_FORMAT";
|
pub(crate) const TIMESTAMP_FORMAT: &str = "TIMESTAMP-FORMAT";
|
||||||
pub(crate) const UNSORTED: &str = "UNSORTED";
|
pub(crate) const UNSORTED: &str = "UNSORTED";
|
||||||
pub(crate) const UNSTABLE: &str = "UNSTABLE";
|
pub(crate) const UNSTABLE: &str = "UNSTABLE";
|
||||||
pub(crate) const VERBOSE: &str = "VERBOSE";
|
pub(crate) const VERBOSE: &str = "VERBOSE";
|
||||||
@ -236,6 +238,13 @@ impl Config {
|
|||||||
.value_name("TEXT")
|
.value_name("TEXT")
|
||||||
.action(ArgAction::Set),
|
.action(ArgAction::Set),
|
||||||
)
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::new(arg::LIST_SUBMODULES)
|
||||||
|
.long("list-submodules")
|
||||||
|
.help("List recipes in submodules")
|
||||||
|
.action(ArgAction::SetTrue)
|
||||||
|
.env("JUST_LIST_SUBMODULES"),
|
||||||
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(arg::NO_ALIASES)
|
Arg::new(arg::NO_ALIASES)
|
||||||
.long("no-aliases")
|
.long("no-aliases")
|
||||||
@ -754,6 +763,7 @@ impl Config {
|
|||||||
list_prefix: matches
|
list_prefix: matches
|
||||||
.get_one::<String>(arg::LIST_PREFIX)
|
.get_one::<String>(arg::LIST_PREFIX)
|
||||||
.map_or_else(|| " ".into(), Into::into),
|
.map_or_else(|| " ".into(), Into::into),
|
||||||
|
list_submodules: matches.get_flag(arg::LIST_SUBMODULES),
|
||||||
load_dotenv: !matches.get_flag(arg::NO_DOTENV),
|
load_dotenv: !matches.get_flag(arg::NO_DOTENV),
|
||||||
no_aliases: matches.get_flag(arg::NO_ALIASES),
|
no_aliases: matches.get_flag(arg::NO_ALIASES),
|
||||||
no_dependencies: matches.get_flag(arg::NO_DEPS),
|
no_dependencies: matches.get_flag(arg::NO_DEPS),
|
||||||
|
@ -488,6 +488,12 @@ impl Subcommand {
|
|||||||
.ok_or_else(|| Error::UnknownSubmodule { path: path.clone() })?;
|
.ok_or_else(|| Error::UnknownSubmodule { path: path.clone() })?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Self::list_module(config, module, 0);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn list_module(config: &Config, module: &Justfile, depth: usize) {
|
||||||
let aliases = if config.no_aliases {
|
let aliases = if config.no_aliases {
|
||||||
BTreeMap::new()
|
BTreeMap::new()
|
||||||
} else {
|
} else {
|
||||||
@ -532,7 +538,11 @@ impl Subcommand {
|
|||||||
.max()
|
.max()
|
||||||
.unwrap_or(0);
|
.unwrap_or(0);
|
||||||
|
|
||||||
|
let list_prefix = config.list_prefix.repeat(depth + 1);
|
||||||
|
|
||||||
|
if depth == 0 {
|
||||||
print!("{}", config.list_heading);
|
print!("{}", config.list_heading);
|
||||||
|
}
|
||||||
|
|
||||||
let groups = {
|
let groups = {
|
||||||
let mut groups = BTreeMap::<Option<String>, Vec<&Recipe>>::new();
|
let mut groups = BTreeMap::<Option<String>, Vec<&Recipe>>::new();
|
||||||
@ -557,7 +567,7 @@ impl Subcommand {
|
|||||||
let no_groups = groups.contains_key(&None) && groups.len() == 1;
|
let no_groups = groups.contains_key(&None) && groups.len() == 1;
|
||||||
|
|
||||||
if !no_groups {
|
if !no_groups {
|
||||||
print!("{}", config.list_prefix);
|
print!("{list_prefix}");
|
||||||
if let Some(group_name) = group {
|
if let Some(group_name) = group {
|
||||||
println!("[{group_name}]");
|
println!("[{group_name}]");
|
||||||
} else {
|
} else {
|
||||||
@ -580,8 +590,7 @@ impl Subcommand {
|
|||||||
if doc.lines().count() > 1 {
|
if doc.lines().count() > 1 {
|
||||||
for line in doc.lines() {
|
for line in doc.lines() {
|
||||||
println!(
|
println!(
|
||||||
"{}{} {}",
|
"{list_prefix}{} {}",
|
||||||
config.list_prefix,
|
|
||||||
config.color.stdout().doc().paint("#"),
|
config.color.stdout().doc().paint("#"),
|
||||||
config.color.stdout().doc().paint(line),
|
config.color.stdout().doc().paint(line),
|
||||||
);
|
);
|
||||||
@ -590,8 +599,7 @@ impl Subcommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
print!(
|
print!(
|
||||||
"{}{}",
|
"{list_prefix}{}",
|
||||||
config.list_prefix,
|
|
||||||
RecipeSignature { name, recipe }.color_display(config.color.stdout())
|
RecipeSignature { name, recipe }.color_display(config.color.stdout())
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -611,11 +619,21 @@ impl Subcommand {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for submodule in module.modules(config) {
|
if config.list_submodules {
|
||||||
println!("{}{} ...", config.list_prefix, submodule.name(),);
|
for (i, submodule) in module.modules(config).into_iter().enumerate() {
|
||||||
|
if i + groups.len() > 0 {
|
||||||
|
println!();
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
println!("{list_prefix}{}:", submodule.name());
|
||||||
|
|
||||||
|
Self::list_module(config, submodule, depth + 1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for submodule in module.modules(config) {
|
||||||
|
println!("{list_prefix}{} ...", submodule.name(),);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn show<'src>(
|
fn show<'src>(
|
||||||
|
130
tests/list.rs
130
tests/list.rs
@ -223,3 +223,133 @@ fn list_unknown_submodule() {
|
|||||||
.status(1)
|
.status(1)
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn list_with_groups_in_modules() {
|
||||||
|
Test::new()
|
||||||
|
.justfile(
|
||||||
|
"
|
||||||
|
[group('FOO')]
|
||||||
|
foo:
|
||||||
|
|
||||||
|
mod bar
|
||||||
|
",
|
||||||
|
)
|
||||||
|
.write("bar.just", "[group('BAZ')]\nbaz:")
|
||||||
|
.test_round_trip(false)
|
||||||
|
.args(["--unstable", "--list", "--list-submodules"])
|
||||||
|
.stdout(
|
||||||
|
"
|
||||||
|
Available recipes:
|
||||||
|
[FOO]
|
||||||
|
foo
|
||||||
|
|
||||||
|
bar:
|
||||||
|
[BAZ]
|
||||||
|
baz
|
||||||
|
",
|
||||||
|
)
|
||||||
|
.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn list_displays_recipes_in_submodules() {
|
||||||
|
Test::new()
|
||||||
|
.write("foo.just", "bar:\n @echo FOO")
|
||||||
|
.justfile(
|
||||||
|
"
|
||||||
|
mod foo
|
||||||
|
",
|
||||||
|
)
|
||||||
|
.test_round_trip(false)
|
||||||
|
.args(["--unstable", "--list", "--list-submodules"])
|
||||||
|
.stdout(
|
||||||
|
"
|
||||||
|
Available recipes:
|
||||||
|
foo:
|
||||||
|
bar
|
||||||
|
",
|
||||||
|
)
|
||||||
|
.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn modules_are_space_separated_in_output() {
|
||||||
|
Test::new()
|
||||||
|
.write("foo.just", "foo:")
|
||||||
|
.write("bar.just", "bar:")
|
||||||
|
.justfile(
|
||||||
|
"
|
||||||
|
mod foo
|
||||||
|
|
||||||
|
mod bar
|
||||||
|
",
|
||||||
|
)
|
||||||
|
.test_round_trip(false)
|
||||||
|
.args(["--unstable", "--list", "--list-submodules"])
|
||||||
|
.stdout(
|
||||||
|
"
|
||||||
|
Available recipes:
|
||||||
|
bar:
|
||||||
|
bar
|
||||||
|
|
||||||
|
foo:
|
||||||
|
foo
|
||||||
|
",
|
||||||
|
)
|
||||||
|
.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn module_recipe_list_alignment_ignores_private_recipes() {
|
||||||
|
Test::new()
|
||||||
|
.write(
|
||||||
|
"foo.just",
|
||||||
|
"
|
||||||
|
# foos
|
||||||
|
foo:
|
||||||
|
@echo FOO
|
||||||
|
|
||||||
|
[private]
|
||||||
|
barbarbar:
|
||||||
|
@echo BAR
|
||||||
|
|
||||||
|
@_bazbazbaz:
|
||||||
|
@echo BAZ
|
||||||
|
",
|
||||||
|
)
|
||||||
|
.justfile("mod foo")
|
||||||
|
.test_round_trip(false)
|
||||||
|
.args(["--unstable", "--list", "--list-submodules"])
|
||||||
|
.stdout(
|
||||||
|
"
|
||||||
|
Available recipes:
|
||||||
|
foo:
|
||||||
|
foo # foos
|
||||||
|
",
|
||||||
|
)
|
||||||
|
.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn nested_modules_are_properly_indented() {
|
||||||
|
Test::new()
|
||||||
|
.write("foo.just", "mod bar")
|
||||||
|
.write("bar.just", "baz:\n @echo FOO")
|
||||||
|
.justfile(
|
||||||
|
"
|
||||||
|
mod foo
|
||||||
|
",
|
||||||
|
)
|
||||||
|
.test_round_trip(false)
|
||||||
|
.args(["--unstable", "--list", "--list-submodules"])
|
||||||
|
.stdout(
|
||||||
|
"
|
||||||
|
Available recipes:
|
||||||
|
foo:
|
||||||
|
bar:
|
||||||
|
baz
|
||||||
|
",
|
||||||
|
)
|
||||||
|
.run();
|
||||||
|
}
|
||||||
|
@ -258,7 +258,7 @@ impl Test {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !compare("status", output.status.code().unwrap(), self.status)
|
if !compare("status", output.status.code(), Some(self.status))
|
||||||
| (self.stdout_regex.is_none() && !compare("stdout", output_stdout, &stdout))
|
| (self.stdout_regex.is_none() && !compare("stdout", output_stdout, &stdout))
|
||||||
| (self.stderr_regex.is_none() && !compare("stderr", output_stderr, &stderr))
|
| (self.stderr_regex.is_none() && !compare("stderr", output_stderr, &stderr))
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user