Skip to content

Commit 3a2d42d

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 2b37230 commit 3a2d42d

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
@@ -105,7 +105,7 @@ impl Subcommand {
105105
}
106106
Dump => Self::dump(config, compilation)?,
107107
Groups => Self::groups(config, justfile),
108-
List { path } => Self::list(config, justfile, path)?,
108+
List { path } => Self::list(config, loader, &search, justfile, path)?,
109109
Run { arguments } => Self::run(config, loader, search, compilation, arguments)?,
110110
Show { path } => Self::show(config, justfile, path)?,
111111
Summary => Self::summary(config, justfile),
@@ -468,7 +468,13 @@ impl Subcommand {
468468
Ok(())
469469
}
470470

471-
fn list(config: &Config, mut module: &Justfile, path: &ModulePath) -> RunResult<'static> {
471+
fn list<'src>(
472+
config: &Config,
473+
loader: &'src Loader,
474+
search: &Search,
475+
mut module: &Justfile,
476+
path: &ModulePath,
477+
) -> RunResult<'src> {
472478
for name in &path.path {
473479
module = module
474480
.modules
@@ -480,6 +486,56 @@ impl Subcommand {
480486

481487
Self::list_module(config, module, 0);
482488

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

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)