//! Configuration for doot operations. use serde::{Deserialize, Serialize}; use std::path::PathBuf; /// Doot runtime configuration. #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Settings { /// Directory containing dotfile sources. pub source_dir: PathBuf, /// Doot configuration directory. pub config_dir: PathBuf, /// State and data directory. pub state_dir: PathBuf, /// Path to the state file. pub state_file: PathBuf, /// Directory for file backups. pub backup_dir: PathBuf, /// Directory for snapshots. pub snapshot_dir: PathBuf, /// Path to age identity file. pub identity_file: PathBuf, /// Simulate actions without writing. pub dry_run: bool, /// Enable verbose output. pub verbose: bool, } impl Settings { /// Creates a new config with the given source directory. #[tracing::instrument(skip_all, fields(source_dir = %source_dir.display()))] pub fn new(source_dir: PathBuf) -> Self { let config_dir = Self::default_config_dir(); let state_dir = Self::default_state_dir(); Self { source_dir, config_dir: config_dir.clone(), state_dir: state_dir.clone(), state_file: state_dir.join("state.json"), backup_dir: state_dir.join("backups"), snapshot_dir: state_dir.join("snapshots"), identity_file: config_dir.join("identity.txt"), dry_run: false, verbose: false, } } /// Returns DOOT_HOME if set, otherwise the real home directory. /// Use DOOT_HOME for sandboxed testing. pub fn home_dir() -> PathBuf { doot_utils::xdg::home_dir() } /// Returns the default configuration directory. pub fn default_config_dir() -> PathBuf { if let Ok(doot_home) = std::env::var("DOOT_HOME") { return PathBuf::from(doot_home).join(".config/doot"); } doot_utils::xdg::config_home().join("doot") } /// Returns the default state directory. pub fn default_state_dir() -> PathBuf { if let Ok(doot_home) = std::env::var("DOOT_HOME") { return PathBuf::from(doot_home).join(".local/state/doot"); } doot_utils::xdg::state_home().join("doot") } /// Returns the default source directory. pub fn default_source_dir() -> PathBuf { Self::default_config_dir() } /// Returns the default config file path. pub fn default_config_file() -> PathBuf { Self::default_config_dir().join("doot.doot") } /// Sets dry run mode. pub fn dry_run(mut self, dry_run: bool) -> Self { self.dry_run = dry_run; self } /// Sets verbose mode. pub fn verbose(mut self, verbose: bool) -> Self { self.verbose = verbose; self } /// Creates all required directories. #[tracing::instrument(skip(self))] pub fn ensure_dirs(&self) -> std::io::Result<()> { std::fs::create_dir_all(&self.config_dir)?; std::fs::create_dir_all(&self.state_dir)?; std::fs::create_dir_all(&self.backup_dir)?; std::fs::create_dir_all(&self.snapshot_dir)?; Ok(()) } } impl Default for Settings { fn default() -> Self { Self::new(Self::default_source_dir()) } }