diff --git a/src/config.rs b/src/config.rs index d0b91d67..11023fc8 100644 --- a/src/config.rs +++ b/src/config.rs @@ -24,6 +24,7 @@ pub(crate) struct Config { pub(crate) list_submodules: bool, pub(crate) load_dotenv: bool, pub(crate) no_aliases: bool, + pub(crate) allow_missing: bool, pub(crate) no_dependencies: bool, pub(crate) one: bool, pub(crate) search_config: SearchConfig, @@ -103,6 +104,7 @@ mod arg { pub(crate) const NO_HIGHLIGHT: &str = "NO-HIGHLIGHT"; pub(crate) const ONE: &str = "ONE"; pub(crate) const QUIET: &str = "QUIET"; + pub(crate) const ALLOW_MISSING: &str = "ALLOW-MISSING"; pub(crate) const SET: &str = "SET"; pub(crate) const SHELL: &str = "SHELL"; pub(crate) const SHELL_ARG: &str = "SHELL-ARG"; @@ -315,6 +317,13 @@ impl Config { .help("Suppress all output") .conflicts_with(arg::DRY_RUN), ) + .arg( + Arg::new(arg::ALLOW_MISSING) + .long("allow-missing") + .env("JUST_ALLOW_MISSING") + .action(ArgAction::SetTrue) + .help("Suppress error code"), + ) .arg( Arg::new(arg::SET) .long("set") @@ -729,6 +738,7 @@ impl Config { list_submodules: matches.get_flag(arg::LIST_SUBMODULES), load_dotenv: !matches.get_flag(arg::NO_DOTENV), no_aliases: matches.get_flag(arg::NO_ALIASES), + allow_missing: matches.get_flag(arg::ALLOW_MISSING), no_dependencies: matches.get_flag(arg::NO_DEPS), one: matches.get_flag(arg::ONE), search_config, diff --git a/src/run.rs b/src/run.rs index a07b73bb..00b809d1 100644 --- a/src/run.rs +++ b/src/run.rs @@ -15,9 +15,9 @@ pub fn run(args: impl Iterator + Clone>) -> Result<() let config = Config::from_matches(&matches).map_err(Error::from); - let (color, verbosity) = config + let (color, verbosity, allow_missing) = config .as_ref() - .map(|config| (config.color, config.verbosity)) + .map(|config| (config.color, config.verbosity, config.allow_missing)) .unwrap_or_default(); let loader = Loader::new(); @@ -28,6 +28,12 @@ pub fn run(args: impl Iterator + Clone>) -> Result<() config.subcommand.execute(&config, &loader) }) .map_err(|error| { + if allow_missing { + if let Error::UnknownRecipe { .. } = error { + return 0; + } + } + if !verbosity.quiet() && error.print_message() { eprintln!("{}", error.color_display(color.stderr())); } diff --git a/tests/allow_missing.rs b/tests/allow_missing.rs new file mode 100644 index 00000000..2d74f27a --- /dev/null +++ b/tests/allow_missing.rs @@ -0,0 +1,33 @@ +use super::*; + +#[test] +fn fail_on_unknown_recipe() { + Test::new() + .arg("execute") + .justfile( + " + build: + echo \"Building...\" + ", + ) + .stderr("error: Justfile does not contain recipe `execute`.\n") + .stdout("") + .status(1) + .run(); +} + +#[test] +fn ignore_unknown_recipe() { + Test::new() + .args(["--allow-missing", "execute"]) + .justfile( + " + build: + echo \"Building...\" + ", + ) + .stderr("") + .stdout("") + .status(0) + .run(); +} diff --git a/tests/lib.rs b/tests/lib.rs index 7c85460b..fb0cf661 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -33,6 +33,7 @@ mod test; mod allow_duplicate_recipes; mod allow_duplicate_variables; +mod allow_missing; mod assert_stdout; mod assert_success; mod assertions;