use std::path::PathBuf;
use std::sync::OnceLock;
use etcetera::base_strategy::{BaseStrategy, choose_base_strategy};
static CONFIG_PATH: OnceLock<PathBuf> = OnceLock::new();
pub fn set_config_path(path: PathBuf) {
CONFIG_PATH.set(path).ok();
}
pub fn is_config_path_explicit() -> bool {
CONFIG_PATH.get().is_some()
}
pub fn config_path() -> Option<PathBuf> {
if let Some(path) = CONFIG_PATH.get() {
return Some(path.clone());
}
if let Ok(path) = std::env::var("WORKTRUNK_CONFIG_PATH") {
return Some(PathBuf::from(path));
}
default_config_path()
}
pub fn default_config_path() -> Option<PathBuf> {
let strategy = choose_base_strategy().ok()?;
Some(strategy.config_dir().join("worktrunk").join("config.toml"))
}
pub fn system_config_path() -> Option<PathBuf> {
if let Ok(path) = std::env::var("WORKTRUNK_SYSTEM_CONFIG_PATH") {
let path = PathBuf::from(path);
if path.exists() {
return Some(path);
}
return None;
}
for dir in &system_config_dirs() {
let path = dir.join("worktrunk").join("config.toml");
if path.exists() {
return Some(path);
}
}
None
}
pub fn default_system_config_path() -> Option<PathBuf> {
if let Ok(path) = std::env::var("WORKTRUNK_SYSTEM_CONFIG_PATH") {
return Some(PathBuf::from(path));
}
system_config_dirs()
.first()
.map(|dir| dir.join("worktrunk").join("config.toml"))
}
fn system_config_dirs() -> Vec<PathBuf> {
#[cfg(unix)]
if let Ok(dirs_str) = std::env::var("XDG_CONFIG_DIRS") {
let dirs: Vec<PathBuf> = dirs_str
.split(':')
.filter(|d| !d.is_empty())
.map(PathBuf::from)
.collect();
if !dirs.is_empty() {
return dirs;
}
}
platform_default_dirs()
}
#[allow(clippy::vec_init_then_push)]
fn platform_default_dirs() -> Vec<PathBuf> {
let mut dirs = Vec::new();
#[cfg(target_os = "macos")]
{
dirs.push(PathBuf::from("/Library/Application Support"));
}
#[cfg(target_os = "windows")]
{
if let Ok(program_data) = std::env::var("PROGRAMDATA") {
dirs.push(PathBuf::from(program_data));
}
}
#[cfg(unix)]
dirs.push(PathBuf::from("/etc/xdg"));
dirs
}