Repository: casey/just
Pull request #1794 (2023-12-29 03:01:21)

Print submodules in --summary


Patch:
diff --git a/src/justfile.rs b/src/justfile.rs
index 148c936e..d921d97d 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<Suggestion<'src>> {
     let mut suggestions = self
       .recipes
diff --git a/src/subcommand.rs b/src/subcommand.rs
index 13fd69a9..ad016eb1 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::<Vec<&str>>()
-        .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();
     }
   }
 


Test patch:
diff --git a/tests/lib.rs b/tests/lib.rs
index 5caae7d2..15799fb7 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 8629a583..1592df2c 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 d906d9e4..8fc0e4f6 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 00000000..ee27ca0f
--- /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();
+}