diff --git a/src/justfile.rs b/src/justfile.rs index 148c936..d921d97 100644 --- a/src/justfile.rs +++ b/src/justfile.rs @@ -23,10 +23,6 @@ pub(crate) struct Justfile<'src> { } impl<'src> Justfile<'src> { - pub(crate) fn count(&self) -> usize { - self.recipes.len() - } - pub(crate) fn suggest_recipe(&self, input: &str) -> Option> { let mut suggestions = self .recipes diff --git a/src/subcommand.rs b/src/subcommand.rs index 13fd69a..ad016eb 100644 --- a/src/subcommand.rs +++ b/src/subcommand.rs @@ -533,18 +533,39 @@ impl Subcommand { } fn summary(config: &Config, justfile: &Justfile) { - if justfile.count() == 0 { - if config.verbosity.loud() { - eprintln!("Justfile contains no recipes."); + let mut printed = 0; + Self::summary_recursive(config, &mut Vec::new(), &mut printed, justfile); + println!(); + + if printed == 0 && config.verbosity.loud() { + eprintln!("Justfile contains no recipes."); + } + } + + fn summary_recursive<'a>( + config: &Config, + components: &mut Vec<&'a str>, + printed: &mut usize, + justfile: &'a Justfile, + ) { + let path = components.join("::"); + + for recipe in justfile.public_recipes(config.unsorted) { + if *printed > 0 { + print!(" "); } - } else { - let summary = justfile - .public_recipes(config.unsorted) - .iter() - .map(|recipe| recipe.name()) - .collect::>() - .join(" "); - println!("{summary}"); + if path.is_empty() { + print!("{}", recipe.name()); + } else { + print!("{}::{}", path, recipe.name()); + } + *printed += 1; + } + + for (name, module) in &justfile.modules { + components.push(name); + Self::summary_recursive(config, components, printed, module); + components.pop(); } } diff --git a/tests/lib.rs b/tests/lib.rs index 5caae7d..15799fb 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -87,6 +87,7 @@ mod show; mod slash_operator; mod string; mod subsequents; +mod summary; mod tempdir; mod undefined_variables; mod unstable; diff --git a/tests/misc.rs b/tests/misc.rs index 8629a58..1592df2 100644 --- a/tests/misc.rs +++ b/tests/misc.rs @@ -187,41 +187,6 @@ c: b stderr: "echo a\necho b\necho c\necho d\n", } -test! { - name: summary, - justfile: "b: a -a: -d: c -c: b -_z: _y -_y: -", - args: ("--summary"), - stdout: "a b c d\n", -} - -test! { - name: summary_sorted, - justfile: " -b: -c: -a: -", - args: ("--summary"), - stdout: "a b c\n", -} - -test! { - name: summary_unsorted, - justfile: " -b: -c: -a: -", - args: ("--summary", "--unsorted"), - stdout: "b c a\n", -} - test! { name: select, justfile: "b: diff --git a/tests/quiet.rs b/tests/quiet.rs index d906d9e..8fc0e4f 100644 --- a/tests/quiet.rs +++ b/tests/quiet.rs @@ -121,12 +121,6 @@ test! { status: EXIT_FAILURE, } -test! { - name: summary_none, - justfile: "", - args: ("--summary", "--quiet"), -} - test! { name: quiet_shebang, justfile: " diff --git a/tests/summary.rs b/tests/summary.rs new file mode 100644 index 0000000..ee27ca0 --- /dev/null +++ b/tests/summary.rs @@ -0,0 +1,73 @@ +use super::*; + +test! { + name: summary, + justfile: "b: a +a: +d: c +c: b +_z: _y +_y: +", + args: ("--summary"), + stdout: "a b c d\n", +} + +test! { + name: summary_sorted, + justfile: " +b: +c: +a: +", + args: ("--summary"), + stdout: "a b c\n", +} + +test! { + name: summary_unsorted, + justfile: " +b: +c: +a: +", + args: ("--summary", "--unsorted"), + stdout: "b c a\n", +} + +test! { + name: summary_none, + justfile: "", + args: ("--summary", "--quiet"), + stdout: "\n\n\n", +} + +#[test] +fn no_recipes() { + Test::new() + .arg("--summary") + .stderr("Justfile contains no recipes.\n") + .stdout("\n\n\n") + .run(); +} + +#[test] +fn submodule_recipes() { + Test::new() + .write("foo.just", "mod bar\nfoo:") + .write("bar.just", "mod baz\nbar:") + .write("baz.just", "mod biz\nbaz:") + .write("biz.just", "biz:") + .justfile( + " + mod foo + + bar: + ", + ) + .test_round_trip(false) + .arg("--unstable") + .arg("--summary") + .stdout("bar foo::foo foo::bar::bar foo::bar::baz::baz foo::bar::baz::biz::biz\n") + .run(); +}