Remove init helper, try load_config and handle NotFound
Inline the struct construction directly into Quire::load and
Quire::new, removing the private init helper. Also switch from
a pre-flight .exists() check to matching on the FennelError::Io
NotFound case, which is more robust against TOCTOU races.
https://claude.ai/code/session_01W3WDZKLhnmqcipFUGDKHaD
diff --git a/quire-server/src/quire/mod.rs b/quire-server/src/quire/mod.rs
index 837adc0..54500c3 100644
--- a/quire-server/src/quire/mod.rs
+++ b/quire-server/src/quire/mod.rs
@@ -8,7 +8,7 @@ use crate::ci::{Ci, Executor, Runs};
use crate::{RepoNameError, Result};
pub use quire_core::telemetry::SentryConfig;
-use quire_core::fennel::Fennel;
+use quire_core::fennel::{Fennel, FennelError};
use quire_core::secret::SecretString;
/// Parsed global configuration (`/var/quire/config.fnl`).
@@ -231,26 +231,28 @@ impl Quire {
/// Returns built-in defaults if the file is absent; propagates parse errors.
pub fn load(base_dir: PathBuf) -> Result<Self> {
let config_path = base_dir.join("config.fnl");
- let config = if config_path.exists() {
- Fennel::load_config(&config_path)?
- } else {
- tracing::warn!(path = %config_path.display(), "config file not found, using defaults");
- GlobalConfig::default()
+ let config = match Fennel::load_config::<GlobalConfig>(&config_path) {
+ Ok(config) => config,
+ Err(FennelError::Io(e)) if e.kind() == std::io::ErrorKind::NotFound => {
+ tracing::warn!(path = %config_path.display(), "config file not found, using defaults");
+ GlobalConfig::default()
+ }
+ Err(e) => return Err(e.into()),
};
- Ok(Self::init(base_dir, config))
- }
-
- fn init(base_dir: PathBuf, config: GlobalConfig) -> Self {
- Self {
+ Ok(Self {
base_dir,
config,
db_pool: Arc::new(OnceLock::new()),
- }
+ })
}
#[cfg(test)]
pub fn new(base_dir: PathBuf, config: GlobalConfig) -> Self {
- Self::init(base_dir, config)
+ Self {
+ base_dir,
+ config,
+ db_pool: Arc::new(OnceLock::new()),
+ }
}
pub fn base_dir(&self) -> &Path {