diff --git a/CHANGELOG.md b/CHANGELOG.md index 7273d39a..70ebcac6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Features +- $BAT_CONFIG_DIR is now a recognized environment variable and has precedent over $XDG_CONFIG_HOME. (@billrisher) ## Bugfixes diff --git a/src/bin/bat/directories.rs b/src/bin/bat/directories.rs index 7bb3e7d5..1a2f1996 100644 --- a/src/bin/bat/directories.rs +++ b/src/bin/bat/directories.rs @@ -4,8 +4,9 @@ use std::path::{Path, PathBuf}; use lazy_static::lazy_static; /// Wrapper for 'dirs' that treats MacOS more like Linux, by following the XDG specification. -/// This means that the `XDG_CACHE_HOME` and `XDG_CONFIG_HOME` environment variables are -/// checked first. The fallback directories are `~/.cache/bat` and `~/.config/bat`, respectively. +/// The `XDG_CACHE_HOME` environment variable is checked first. `BAT_CONFIG_DIR` +/// is then checked before the `XDG_CONFIG_HOME` environment variable. +/// The fallback directories are `~/.cache/bat` and `~/.config/bat`, respectively. pub struct BatProjectDirs { cache_dir: PathBuf, config_dir: PathBuf, @@ -14,17 +15,24 @@ pub struct BatProjectDirs { impl BatProjectDirs { fn new() -> Option { let cache_dir = BatProjectDirs::get_cache_dir()?; + + // Checks whether or not $BAT_CONFIG_DIR exists. If it doesn't, set our config dir + // to our system's default configuration home. + let config_dir = if let Some(config_dir_op) = env::var_os("BAT_CONFIG_DIR") + .map(PathBuf::from) { + config_dir_op + } else { + #[cfg(target_os = "macos")] + let config_dir_op = env::var_os("XDG_CONFIG_HOME") + .map(PathBuf::from) + .filter(|p| p.is_absolute()) + .or_else(|| dirs_next::home_dir().map(|d| d.join(".config"))); - #[cfg(target_os = "macos")] - let config_dir_op = env::var_os("XDG_CONFIG_HOME") - .map(PathBuf::from) - .filter(|p| p.is_absolute()) - .or_else(|| dirs_next::home_dir().map(|d| d.join(".config"))); + #[cfg(not(target_os = "macos"))] + let config_dir_op = dirs_next::config_dir(); - #[cfg(not(target_os = "macos"))] - let config_dir_op = dirs_next::config_dir(); - - let config_dir = config_dir_op.map(|d| d.join("bat"))?; + config_dir_op.map(|d| d.join("bat"))? + }; Some(BatProjectDirs { cache_dir, diff --git a/tests/integration_tests.rs b/tests/integration_tests.rs index 18f16123..942894fd 100644 --- a/tests/integration_tests.rs +++ b/tests/integration_tests.rs @@ -747,6 +747,25 @@ fn config_location_when_generating() { assert!(tmp_config_path.exists()); } +#[test] +fn config_location_from_bat_config_dir_variable() { + let bat_conf_dir = tempdir().expect("can't create temporary directory.").path().join("bat_conf_dir/"); + + // Create file at BAT_CONFIG_DIR + bat_with_config() + .env("BAT_CONFIG_DIR", bat_conf_dir.to_str().unwrap()) + .arg("--generate-config-file") + .assert() + .success() + .stdout( + predicate::str::is_match("Success! Config file written to .*config\n") + .unwrap() + ); + + // Ensure generated config file exists. + assert!(bat_conf_dir.join("config").exists()); +} + #[test] fn config_read_arguments_from_file() { bat_with_config()