Skip to content

Commit 0bbc51c

Browse files
committed
list: show fallback recipes when fallback is enabled
When `set fallback` is active and `just --list` is run, the output now also includes recipes from parent justfiles, displayed under a "Fallback recipes from <path>" heading. This walks up the directory tree, loading each parent justfile until one without fallback is found. Fixes #1500
1 parent 20a0961 commit 0bbc51c

File tree

3 files changed

+87
-3
lines changed

3 files changed

+87
-3
lines changed

src/search.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ const DEFAULT_JUSTFILE_NAME: &str = JUSTFILE_NAMES[0];
44
pub(crate) const JUSTFILE_NAMES: [&str; 2] = ["justfile", ".justfile"];
55
const PROJECT_ROOT_CHILDREN: &[&str] = &[".bzr", ".git", ".hg", ".svn", "_darcs"];
66

7-
#[derive(Debug)]
7+
#[derive(Debug, Clone)]
88
pub(crate) struct Search {
99
pub(crate) justfile: PathBuf,
1010
pub(crate) working_directory: PathBuf,

src/subcommand.rs

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ impl Subcommand {
107107
}
108108
Dump { format } => Self::dump(compilation, *format)?,
109109
Groups => Self::groups(config, justfile),
110-
List { path } => Self::list(config, justfile, path)?,
110+
List { path } => Self::list(config, loader, &search, justfile, path)?,
111111
Run { arguments } => Self::run(config, loader, search, compilation, arguments)?,
112112
Show { path } => Self::show(config, justfile, path)?,
113113
Summary => Self::summary(config, justfile),
@@ -475,7 +475,13 @@ impl Subcommand {
475475
Ok(())
476476
}
477477

478-
fn list(config: &Config, mut module: &Justfile, path: &ModulePath) -> RunResult<'static> {
478+
fn list<'src>(
479+
config: &Config,
480+
loader: &'src Loader,
481+
search: &Search,
482+
mut module: &Justfile,
483+
path: &ModulePath,
484+
) -> RunResult<'src> {
479485
for name in &path.path {
480486
module = module
481487
.modules
@@ -487,6 +493,56 @@ impl Subcommand {
487493

488494
Self::list_module(config, 0, &config.groups, module)?;
489495

496+
// If fallback is enabled and we're at the top level, also list
497+
// recipes from parent justfiles so users can see the full set of
498+
// available recipes.
499+
let fallback = module.settings.fallback
500+
&& matches!(
501+
config.search_config,
502+
SearchConfig::FromInvocationDirectory | SearchConfig::FromSearchDirectory { .. }
503+
);
504+
505+
if fallback && path.path.is_empty() {
506+
let mut parent_search = search.clone();
507+
508+
while let Ok(next) = parent_search.search_parent_directory(config.ceiling.as_deref()) {
509+
parent_search = next;
510+
511+
let parent_path = parent_search
512+
.justfile
513+
.parent()
514+
.unwrap_or_else(|| Path::new("."));
515+
516+
if let Ok(compilation) = Self::compile(config, loader, &parent_search) {
517+
let parent_justfile = &compilation.justfile;
518+
519+
let has_recipes = !parent_justfile
520+
.public_recipes(config)
521+
.is_empty()
522+
;
523+
524+
if has_recipes {
525+
println!();
526+
println!(
527+
"{}",
528+
config.color.stdout().doc().paint(&format!(
529+
"# Fallback recipes from {}",
530+
parent_path.display()
531+
))
532+
);
533+
Self::list_module(config, parent_justfile, 0);
534+
}
535+
536+
// Stop walking if this parent doesn't also have fallback
537+
if !parent_justfile.settings.fallback {
538+
break;
539+
}
540+
} else {
541+
break;
542+
}
543+
}
544+
}
545+
490546
Ok(())
491547
}
492548

tests/fallback.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,3 +368,31 @@ fn works_with_modules() {
368368
.stdout("BAZ\n")
369369
.success();
370370
}
371+
372+
#[test]
373+
fn list_shows_fallback_recipes() {
374+
Test::new()
375+
.justfile(
376+
"
377+
# A parent recipe
378+
parent-recipe:
379+
echo parent
380+
",
381+
)
382+
.write(
383+
"sub/justfile",
384+
unindent(
385+
"
386+
set fallback
387+
388+
# A child recipe
389+
child-recipe:
390+
echo child
391+
",
392+
),
393+
)
394+
.args(["--list"])
395+
.current_dir("sub")
396+
.stdout_regex("(?s).*child-recipe.*Fallback.*parent-recipe.*")
397+
.success();
398+
}

0 commit comments

Comments
 (0)