Skip to content

Commit ec802a4

Browse files
Merge pull request #396 from gnpaone/sync-action
Sync source repo
2 parents 7aa3da1 + cad1967 commit ec802a4

9 files changed

Lines changed: 186 additions & 25 deletions

File tree

completions/just.bash

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ _just() {
3030

3131
case "${cmd}" in
3232
just)
33-
opts="-E -n -g -f -q -u -v -d -c -e -l -s -h -V --alias-style --ceiling --check --chooser --clear-shell-args --color --command-color --cygpath --dotenv-filename --dotenv-path --dry-run --dump-format --explain --global-justfile --highlight --justfile --list-heading --list-prefix --list-submodules --no-aliases --no-deps --no-dotenv --no-highlight --one --quiet --allow-missing --set --shell --shell-arg --shell-command --tempdir --timestamp --timestamp-format --unsorted --unstable --verbose --working-directory --yes --changelog --choose --command --completions --dump --edit --evaluate --fmt --groups --init --list --man --request --show --summary --usage --variables --help --version [ARGUMENTS]..."
33+
opts="-E -n -g -f -q -u -v -d -c -e -l -s -h -V --alias-style --ceiling --check --chooser --clear-shell-args --color --command-color --cygpath --dotenv-filename --dotenv-path --dry-run --dump-format --explain --global-justfile --highlight --justfile --list-heading --list-prefix --list-submodules --group --no-aliases --no-deps --no-dotenv --no-highlight --one --quiet --allow-missing --set --shell --shell-arg --shell-command --tempdir --timestamp --timestamp-format --unsorted --unstable --verbose --working-directory --yes --changelog --choose --command --completions --dump --edit --evaluate --fmt --groups --init --list --man --request --show --summary --usage --variables --help --version [ARGUMENTS]..."
3434
if [[ ${cur} == -* ]] ; then
3535
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
3636
return 0
@@ -108,6 +108,10 @@ _just() {
108108
COMPREPLY=($(compgen -f "${cur}"))
109109
return 0
110110
;;
111+
--group)
112+
COMPREPLY=($(compgen -f "${cur}"))
113+
return 0
114+
;;
111115
--set)
112116
COMPREPLY=($(compgen -f "${cur}"))
113117
return 0

completions/just.elvish

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ set edit:completion:arg-completer[just] = {|@words|
3131
cand --justfile 'Use <JUSTFILE> as justfile'
3232
cand --list-heading 'Print <TEXT> before list'
3333
cand --list-prefix 'Print <TEXT> before each list item'
34+
cand --group 'Only list recipes in <GROUP>'
3435
cand --set 'Override <VARIABLE> with <VALUE>'
3536
cand --shell 'Invoke <SHELL> to run recipes'
3637
cand --shell-arg 'Invoke shell with <SHELL-ARG> as an argument'

completions/just.fish

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ just\t''"
3535
complete -c just -s f -l justfile -d 'Use <JUSTFILE> as justfile' -r -F
3636
complete -c just -l list-heading -d 'Print <TEXT> before list' -r
3737
complete -c just -l list-prefix -d 'Print <TEXT> before each list item' -r
38+
complete -c just -l group -d 'Only list recipes in <GROUP>' -r
3839
complete -c just -l set -d 'Override <VARIABLE> with <VALUE>' -r
3940
complete -c just -l shell -d 'Invoke <SHELL> to run recipes' -r
4041
complete -c just -l shell-arg -d 'Invoke shell with <SHELL-ARG> as an argument' -r

completions/just.powershell

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ Register-ArgumentCompleter -Native -CommandName 'just' -ScriptBlock {
3434
[CompletionResult]::new('--justfile', '--justfile', [CompletionResultType]::ParameterName, 'Use <JUSTFILE> as justfile')
3535
[CompletionResult]::new('--list-heading', '--list-heading', [CompletionResultType]::ParameterName, 'Print <TEXT> before list')
3636
[CompletionResult]::new('--list-prefix', '--list-prefix', [CompletionResultType]::ParameterName, 'Print <TEXT> before each list item')
37+
[CompletionResult]::new('--group', '--group', [CompletionResultType]::ParameterName, 'Only list recipes in <GROUP>')
3738
[CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'Override <VARIABLE> with <VALUE>')
3839
[CompletionResult]::new('--shell', '--shell', [CompletionResultType]::ParameterName, 'Invoke <SHELL> to run recipes')
3940
[CompletionResult]::new('--shell-arg', '--shell-arg', [CompletionResultType]::ParameterName, 'Invoke shell with <SHELL-ARG> as an argument')

completions/just.zsh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ _just() {
2929
'--justfile=[Use <JUSTFILE> as justfile]: :_files' \
3030
'--list-heading=[Print <TEXT> before list]:TEXT:_default' \
3131
'--list-prefix=[Print <TEXT> before each list item]:TEXT:_default' \
32+
'*--group=[Only list recipes in <GROUP>]: :_default' \
3233
'*--set=[Override <VARIABLE> with <VALUE>]: :(_just_variables)' \
3334
'--shell=[Invoke <SHELL> to run recipes]: :_default' \
3435
'*--shell-arg=[Invoke shell with <SHELL-ARG> as an argument]: :_default' \

src/config.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ pub(crate) struct Config {
2424
pub(crate) dry_run: bool,
2525
pub(crate) dump_format: DumpFormat,
2626
pub(crate) explain: bool,
27+
pub(crate) groups: Vec<String>,
2728
pub(crate) highlight: bool,
2829
pub(crate) invocation_directory: PathBuf,
2930
pub(crate) list_heading: String,
@@ -110,6 +111,7 @@ mod arg {
110111
pub(crate) const GLOBAL_JUSTFILE: &str = "GLOBAL-JUSTFILE";
111112
pub(crate) const HIGHLIGHT: &str = "HIGHLIGHT";
112113
pub(crate) const JUSTFILE: &str = "JUSTFILE";
114+
pub(crate) const GROUP: &str = "GROUP";
113115
pub(crate) const LIST_HEADING: &str = "LIST-HEADING";
114116
pub(crate) const LIST_PREFIX: &str = "LIST-PREFIX";
115117
pub(crate) const LIST_SUBMODULES: &str = "LIST-SUBMODULES";
@@ -316,6 +318,14 @@ impl Config {
316318
.action(ArgAction::SetTrue)
317319
.requires(cmd::LIST),
318320
)
321+
.arg(
322+
Arg::new(arg::GROUP)
323+
.long("group")
324+
.env("JUST_GROUP")
325+
.help("Only list recipes in <GROUP>")
326+
.action(ArgAction::Append)
327+
.requires(cmd::LIST),
328+
)
319329
.arg(
320330
Arg::new(arg::NO_ALIASES)
321331
.long("no-aliases")
@@ -827,6 +837,10 @@ impl Config {
827837
explain,
828838
highlight: !matches.get_flag(arg::NO_HIGHLIGHT),
829839
invocation_directory: env::current_dir().context(config_error::CurrentDirContext)?,
840+
groups: matches
841+
.get_many::<String>(arg::GROUP)
842+
.map(|s| s.map(Into::into).collect())
843+
.unwrap_or_default(),
830844
list_heading: matches.get_one::<String>(arg::LIST_HEADING).unwrap().into(),
831845
list_prefix: matches.get_one::<String>(arg::LIST_PREFIX).unwrap().into(),
832846
list_submodules: matches.get_flag(arg::LIST_SUBMODULES),

src/error.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,9 @@ pub(crate) enum Error<'src> {
225225
recipe: &'src str,
226226
line_number: Option<usize>,
227227
},
228+
UnknownGroup {
229+
group: String,
230+
},
228231
UnknownOption {
229232
recipe: &'src str,
230233
option: Switch,
@@ -770,6 +773,9 @@ impl ColorDisplay for Error<'_> {
770773
"{count} {overrides} overridden on the command line but not present in justfile",
771774
)?;
772775
}
776+
UnknownGroup { group } => {
777+
write!(f, "Justfile does not contain group `{group}`")?;
778+
}
773779
UnknownRecipe { recipe, suggestion } => {
774780
write!(f, "Justfile does not contain recipe `{recipe}`")?;
775781
if let Some(suggestion) = suggestion {

src/subcommand.rs

Lines changed: 53 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -478,12 +478,17 @@ impl Subcommand {
478478
})?;
479479
}
480480

481-
Self::list_module(config, module, 0);
481+
Self::list_module(config, 0, &config.groups, module)?;
482482

483483
Ok(())
484484
}
485485

486-
fn list_module(config: &Config, module: &Justfile, depth: usize) {
486+
fn list_module(
487+
config: &Config,
488+
depth: usize,
489+
groups: &[String],
490+
module: &Justfile,
491+
) -> RunResult<'static> {
487492
fn print_doc_and_aliases(
488493
config: &Config,
489494
name: &str,
@@ -597,54 +602,76 @@ impl Subcommand {
597602

598603
let list_prefix = config.list_prefix.repeat(depth + 1);
599604

605+
if !groups.is_empty() {
606+
let public_groups = module.public_groups(config);
607+
for group in groups {
608+
if !public_groups.contains(group) {
609+
return Err(Error::UnknownGroup {
610+
group: group.clone(),
611+
});
612+
}
613+
}
614+
}
615+
600616
if depth == 0 {
601617
print!("{}", config.list_heading);
602618
}
603619

604620
let recipe_groups = {
605-
let mut groups = BTreeMap::<Option<String>, Vec<&Recipe>>::new();
621+
let mut recipe_groups = BTreeMap::<Option<String>, Vec<&Recipe>>::new();
606622
for recipe in module.public_recipes(config) {
607-
let recipe_groups = recipe.groups();
608-
if recipe_groups.is_empty() {
609-
groups.entry(None).or_default().push(recipe);
623+
let recipe_groups_list = recipe.groups();
624+
if recipe_groups_list.is_empty() {
625+
recipe_groups.entry(None).or_default().push(recipe);
610626
} else {
611-
for group in recipe_groups {
612-
groups.entry(Some(group)).or_default().push(recipe);
627+
for group in recipe_groups_list {
628+
recipe_groups.entry(Some(group)).or_default().push(recipe);
613629
}
614630
}
615631
}
616-
groups
632+
recipe_groups
617633
};
618634

619635
let submodule_groups = {
620-
let mut groups = BTreeMap::<Option<String>, Vec<&Justfile>>::new();
636+
let mut submodule_groups = BTreeMap::<Option<String>, Vec<&Justfile>>::new();
621637
for submodule in module.public_modules(config) {
622-
let submodule_groups = submodule.groups();
623-
if submodule_groups.is_empty() {
624-
groups.entry(None).or_default().push(submodule);
638+
let submodule_groups_list = submodule.groups();
639+
if submodule_groups_list.is_empty() {
640+
submodule_groups.entry(None).or_default().push(submodule);
625641
} else {
626-
for group in submodule_groups {
627-
groups
642+
for group in submodule_groups_list {
643+
submodule_groups
628644
.entry(Some(group.to_string()))
629645
.or_default()
630646
.push(submodule);
631647
}
632648
}
633649
}
634-
groups
650+
submodule_groups
635651
};
636652

637-
let mut ordered_groups = module
638-
.public_groups(config)
639-
.into_iter()
640-
.map(Some)
641-
.collect::<Vec<Option<String>>>();
653+
let mut ordered_groups = if groups.is_empty() {
654+
module
655+
.public_groups(config)
656+
.into_iter()
657+
.map(Some)
658+
.collect::<Vec<Option<String>>>()
659+
} else {
660+
groups
661+
.iter()
662+
.cloned()
663+
.map(Some)
664+
.collect::<Vec<Option<String>>>()
665+
};
642666

643-
if recipe_groups.contains_key(&None) || submodule_groups.contains_key(&None) {
667+
if groups.is_empty()
668+
&& (recipe_groups.contains_key(&None) || submodule_groups.contains_key(&None))
669+
{
644670
ordered_groups.insert(0, None);
645671
}
646672

647-
let no_groups = ordered_groups.len() == 1 && ordered_groups.first() == Some(&None);
673+
let no_groups =
674+
groups.is_empty() && ordered_groups.len() == 1 && ordered_groups.first() == Some(&None);
648675

649676
let groups_count = if no_groups { 0 } else { ordered_groups.len() };
650677

@@ -720,7 +747,7 @@ impl Subcommand {
720747
}
721748
println!("{list_prefix}{}:", submodule.name());
722749

723-
Self::list_module(config, submodule, depth + 1);
750+
Self::list_module(config, depth + 1, &[], submodule)?;
724751
} else {
725752
print!("{list_prefix}{} ...", submodule.name());
726753
print_doc_and_aliases(
@@ -735,6 +762,8 @@ impl Subcommand {
735762
}
736763
}
737764
}
765+
766+
Ok(())
738767
}
739768

740769
fn show<'src>(config: &Config, module: &Justfile<'src>, path: &ModulePath) -> RunResult<'src> {

tests/groups.rs

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,84 @@
11
use super::*;
22

3+
#[test]
4+
fn list_group_unknown() {
5+
Test::new()
6+
.justfile(
7+
"
8+
[group('foo')]
9+
a:
10+
",
11+
)
12+
.args(["--list", "--group", "bar"])
13+
.stderr("error: Justfile does not contain group `bar`\n")
14+
.failure();
15+
}
16+
17+
#[test]
18+
fn list_group() {
19+
Test::new()
20+
.justfile(
21+
"
22+
[group('alpha')]
23+
a:
24+
[group('alpha')]
25+
[group('beta')]
26+
b:
27+
c:
28+
[group('beta')]
29+
d:
30+
",
31+
)
32+
.args(["--list", "--group", "alpha"])
33+
.stdout(
34+
"
35+
Available recipes:
36+
[alpha]
37+
a
38+
b
39+
",
40+
)
41+
.success();
42+
}
43+
44+
#[test]
45+
fn list_multiple_groups() {
46+
Test::new()
47+
.justfile(
48+
"
49+
[group('alpha')]
50+
a:
51+
[group('alpha')]
52+
[group('beta')]
53+
b:
54+
c:
55+
[group('beta')]
56+
d:
57+
[group('gamma')]
58+
e:
59+
",
60+
)
61+
.args([
62+
"--list", "--group", "alpha", "--group", "beta", "--group", "gamma",
63+
])
64+
.stdout(
65+
"
66+
Available recipes:
67+
[alpha]
68+
a
69+
b
70+
71+
[beta]
72+
b
73+
d
74+
75+
[gamma]
76+
e
77+
",
78+
)
79+
.success();
80+
}
81+
382
#[test]
483
fn list_with_groups() {
584
Test::new()
@@ -282,3 +361,28 @@ fn list_groups_private() {
282361
)
283362
.success();
284363
}
364+
365+
#[test]
366+
fn list_group_with_submodules() {
367+
Test::new()
368+
.justfile(
369+
"
370+
[group('foo')]
371+
a:
372+
373+
b:
374+
375+
mod bar
376+
",
377+
)
378+
.write("bar.just", "c:\nd:")
379+
.args(["--list", "--group", "foo", "--list-submodules"])
380+
.stdout(
381+
"
382+
Available recipes:
383+
[foo]
384+
a
385+
",
386+
)
387+
.success();
388+
}

0 commit comments

Comments
 (0)