Skip to content

Commit

Permalink
Support nested configuration files and XDG config directory
Browse files Browse the repository at this point in the history
  • Loading branch information
uncenter committed Dec 10, 2024
1 parent 8398e61 commit 8f99583
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 158 deletions.
166 changes: 31 additions & 135 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ panic = "abort"
[dependencies]
anyhow = { version = "1.0", features = ["backtrace"] }
clap = { version = "4.5", features = ["derive"] }
dirs = "5.0"
env_logger = { version = "0.11", features = [
"humantime",
], default-features = false }
Expand All @@ -38,3 +37,4 @@ tempfile = "3.10"
termcolor = "1.4"
thiserror = "1.0"
toml = "0.8"
user_dirs = "0.2.0"
41 changes: 19 additions & 22 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,6 @@ use clap::ValueEnum;
use serde::{Deserialize, Serialize};
use std::path::PathBuf;
use std::{env, fs, io};
use thiserror::Error;

#[remain::sorted]
#[derive(Error, Debug)]
pub enum ConfigError {
#[error("could not find home directory")]
HomeDirNotFound,
}

/// This struct is the actual config type consumed through the codebase. It is boostrapped via its
/// public methods and uses [`EntryConfig`], a private struct, under the hood in order to
Expand All @@ -34,20 +26,25 @@ impl Config {
// Within this method, we check if the config file is empty before deserializing it. Users
// should be able to proceed with empty config files. If empty or not found, then we fall
// back to the "EntryConfig" default before conversion.
let home = dirs::home_dir().ok_or(ConfigError::HomeDirNotFound)?;
let path = home.join(".config").join("gfold.toml");
let entry_config = match fs::read_to_string(path) {
Ok(contents) => {
if contents.is_empty() {
EntryConfig::default()
} else {
toml::from_str(&contents)?
}
}
Err(e) => match e.kind() {
io::ErrorKind::NotFound => EntryConfig::default(),
_ => return Err(e.into()),
},
let config_dir = user_dirs::config_dir()?;
let home_dir = user_dirs::home_dir()?;

let paths = [
config_dir.join("gfold.toml"),
config_dir.join("gfold").join("config.toml"),
home_dir.join(".config").join("gfold.toml"),
];

let path = match paths.into_iter().find(|p| p.exists()) {
Some(path) => path,
None => return Ok(Self::try_config_default()?),
};

let contents = fs::read_to_string(path)?;
let entry_config = if contents.is_empty() {
EntryConfig::default()
} else {
toml::from_str(&contents)?
};
Ok(Self::from_entry_config(&entry_config)?)
}
Expand Down

0 comments on commit 8f99583

Please sign in to comment.