diff --git a/src/bin/bat/app.rs b/src/bin/bat/app.rs index b3d48cba..c784eabf 100644 --- a/src/bin/bat/app.rs +++ b/src/bin/bat/app.rs @@ -57,15 +57,27 @@ impl App { } fn matches(interactive_output: bool) -> Result { + // Check if we should skip config file processing for special arguments + // that don't require full application setup (help, version, diagnostic) + let should_skip_config = wild::args_os().any(|arg| { + matches!(arg.to_str(), Some("-h" | "--help" | "-V" | "--version" | "--diagnostic" | "--diagnostics")) + }); + let args = if wild::args_os().nth(1) == Some("cache".into()) { // Skip the config file and env vars wild::args_os().collect::>() - } else if wild::args_os().any(|arg| arg == "--no-config") { - // Skip the arguments in bats config file + } else 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 help, version, or diagnostic information let mut cli_args = wild::args_os(); - let mut args = get_args_from_env_vars(); + let mut args = if should_skip_config { + // For special commands, don't even try to load env vars that might fail + vec![] + } else { + get_args_from_env_vars() + }; // Put the zero-th CLI argument (program name) first args.insert(0, cli_args.next().unwrap()); diff --git a/tests/integration_tests.rs b/tests/integration_tests.rs index f0ebef12..6b9d7263 100644 --- a/tests/integration_tests.rs +++ b/tests/integration_tests.rs @@ -1286,6 +1286,81 @@ fn diagnostic_sanity_check() { .stderr(""); } +#[test] +fn help_works_with_invalid_config() { + let tmp_dir = tempdir().expect("can create temporary directory"); + let tmp_config_path = tmp_dir.path().join("invalid-config.conf"); + + // Write an invalid config file + std::fs::write(&tmp_config_path, "--invalid-option").expect("can write config file"); + + // --help should work despite invalid 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")); + + // -h should also work + bat_with_config() + .env("BAT_CONFIG_PATH", tmp_config_path.to_str().unwrap()) + .arg("-h") + .assert() + .success() + .stdout(predicate::str::contains("A cat(1) clone with wings")); +} + +#[test] +fn version_works_with_invalid_config() { + let tmp_dir = tempdir().expect("can create temporary directory"); + let tmp_config_path = tmp_dir.path().join("invalid-config.conf"); + + // Write an invalid config file + std::fs::write(&tmp_config_path, "--invalid-option").expect("can write config file"); + + // --version should work despite invalid config + bat_with_config() + .env("BAT_CONFIG_PATH", tmp_config_path.to_str().unwrap()) + .arg("--version") + .assert() + .success() + .stdout(predicate::str::contains("bat ")); + + // -V should also work + bat_with_config() + .env("BAT_CONFIG_PATH", tmp_config_path.to_str().unwrap()) + .arg("-V") + .assert() + .success() + .stdout(predicate::str::contains("bat ")); +} + +#[test] +fn diagnostic_works_with_invalid_config() { + let tmp_dir = tempdir().expect("can create temporary directory"); + let tmp_config_path = tmp_dir.path().join("invalid-config.conf"); + + // Write an invalid config file + std::fs::write(&tmp_config_path, "--invalid-option").expect("can write config file"); + + // --diagnostic should work despite invalid config + bat_with_config() + .env("BAT_CONFIG_PATH", tmp_config_path.to_str().unwrap()) + .arg("--diagnostic") + .assert() + .success() + .stdout(predicate::str::contains("#### Software version")); + + // --diagnostics (alias) should also work + bat_with_config() + .env("BAT_CONFIG_PATH", tmp_config_path.to_str().unwrap()) + .arg("--diagnostics") + .assert() + .success() + .stdout(predicate::str::contains("#### Software version")); +} + #[test] fn config_location_test() { bat_with_config()