mirror of
https://github.com/sharkdp/bat.git
synced 2026-02-08 00:32:08 +00:00
Ensure --help respects valid config file
While still ignoring ignoring invalid arguments in the config
This commit is contained in:
@@ -186,6 +186,20 @@ impl App {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Build argument list with env vars and CLI args (without config file)
|
||||
fn build_args_without_config() -> Vec<std::ffi::OsString> {
|
||||
let mut cli_args = wild::args_os();
|
||||
let mut args = get_args_from_env_vars();
|
||||
|
||||
// Put the zero-th CLI argument (program name) first
|
||||
args.insert(0, cli_args.next().unwrap());
|
||||
|
||||
// .. and the rest at the end
|
||||
cli_args.for_each(|a| args.push(a));
|
||||
|
||||
args
|
||||
}
|
||||
|
||||
fn matches(interactive_output: bool) -> Result<ArgMatches> {
|
||||
// Check if we should skip config file processing for special arguments
|
||||
// that don't require full application setup (version, diagnostic)
|
||||
@@ -196,50 +210,40 @@ impl App {
|
||||
)
|
||||
});
|
||||
|
||||
// Check if help was requested - help should go through the same code path
|
||||
// but be forgiving of config file errors
|
||||
// Check if help was requested - help should read the config file but be
|
||||
// forgiving of invalid arguments (so configured theme etc. can be used)
|
||||
let help_requested =
|
||||
wild::args_os().any(|arg| matches!(arg.to_str(), Some("-h" | "--help")));
|
||||
|
||||
let args = if wild::args_os().nth(1) == Some("cache".into()) {
|
||||
if wild::args_os().nth(1) == Some("cache".into()) {
|
||||
// Skip the config file and env vars
|
||||
let args = wild::args_os().collect::<Vec<_>>();
|
||||
return Ok(clap_app::build_app(interactive_output).get_matches_from(args));
|
||||
}
|
||||
|
||||
wild::args_os().collect::<Vec<_>>()
|
||||
} else if wild::args_os().any(|arg| arg == "--no-config") || should_skip_config {
|
||||
if wild::args_os().any(|arg| arg == "--no-config") || should_skip_config {
|
||||
// Skip the arguments in bats config file when --no-config is present
|
||||
// or when user requests version or diagnostic information
|
||||
let args = Self::build_args_without_config();
|
||||
return Ok(clap_app::build_app(interactive_output).get_matches_from(args));
|
||||
}
|
||||
|
||||
let mut cli_args = wild::args_os();
|
||||
let mut args = get_args_from_env_vars();
|
||||
|
||||
// Put the zero-th CLI argument (program name) first
|
||||
args.insert(0, cli_args.next().unwrap());
|
||||
|
||||
// .. and the rest at the end
|
||||
cli_args.for_each(|a| args.push(a));
|
||||
|
||||
args
|
||||
} else if help_requested {
|
||||
// Help goes through the normal config path but only uses env vars for themes
|
||||
// to avoid failing on invalid config options
|
||||
let mut cli_args = wild::args_os();
|
||||
let mut args = get_args_from_env_vars();
|
||||
|
||||
// Put the zero-th CLI argument (program name) first
|
||||
args.insert(0, cli_args.next().unwrap());
|
||||
|
||||
// .. and the rest at the end (includes --help and other CLI args)
|
||||
cli_args.for_each(|a| args.push(a));
|
||||
args
|
||||
} else {
|
||||
// Build arguments with config file
|
||||
let mut cli_args = wild::args_os();
|
||||
|
||||
// Read arguments from bats config file
|
||||
let mut args = match get_args_from_env_opts_var() {
|
||||
let config_args = match get_args_from_env_opts_var() {
|
||||
Some(result) => result,
|
||||
None => get_args_from_config_file(),
|
||||
}
|
||||
.map_err(|_| "Could not parse configuration file")?;
|
||||
};
|
||||
|
||||
// For help, ignore config file parse errors (use empty config instead)
|
||||
// For non-help, propagate the error
|
||||
let mut args = if help_requested {
|
||||
config_args.unwrap_or_default()
|
||||
} else {
|
||||
config_args.map_err(|_| "Could not parse configuration file")?
|
||||
};
|
||||
|
||||
// Selected env vars supersede config vars
|
||||
args.extend(get_args_from_env_vars());
|
||||
@@ -249,11 +253,23 @@ impl App {
|
||||
|
||||
// .. and the rest at the end
|
||||
cli_args.for_each(|a| args.push(a));
|
||||
args
|
||||
};
|
||||
|
||||
// For help, try parsing with config, and if clap fails (e.g., invalid
|
||||
// argument in config), fall back to parsing without config file args
|
||||
if help_requested {
|
||||
let app = clap_app::build_app(interactive_output);
|
||||
match app.try_get_matches_from(args) {
|
||||
Ok(matches) => Ok(matches),
|
||||
Err(_) => {
|
||||
// Config has invalid arguments, fall back to just env vars + CLI args
|
||||
let fallback_args = Self::build_args_without_config();
|
||||
Ok(clap_app::build_app(interactive_output).get_matches_from(fallback_args))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Ok(clap_app::build_app(interactive_output).get_matches_from(args))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn config(&self, inputs: &[Input]) -> Result<Config<'_>> {
|
||||
let style_components = self.style_components()?;
|
||||
|
||||
@@ -1479,6 +1479,28 @@ fn help_works_with_invalid_config() {
|
||||
.stdout(predicate::str::contains("A cat(1) clone with wings"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn help_uses_valid_config() {
|
||||
let tmp_dir = tempdir().expect("can create temporary directory");
|
||||
let tmp_config_path = tmp_dir.path().join("valid-config.conf");
|
||||
|
||||
// Write a valid config file with an invalid theme (so we can see a warning)
|
||||
std::fs::write(&tmp_config_path, "--theme=NonExistentThemeName123")
|
||||
.expect("can write config file");
|
||||
|
||||
// --help should read the config file and try to use the theme
|
||||
// (we'll see a warning about unknown theme. This is the easiest way to prove the theme is read from config.)
|
||||
bat_with_config()
|
||||
.env("BAT_CONFIG_PATH", tmp_config_path.to_str().unwrap())
|
||||
.arg("--help")
|
||||
.assert()
|
||||
.success()
|
||||
.stdout(predicate::str::contains(
|
||||
"A cat(1) clone with syntax highlighting",
|
||||
))
|
||||
.stderr(predicate::str::contains("Unknown theme"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn version_works_with_invalid_config() {
|
||||
let tmp_dir = tempdir().expect("can create temporary directory");
|
||||
|
||||
Reference in New Issue
Block a user