mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-09-15 23:32:46 +00:00
refactor(home): move Home to fabro-util so all crates can share it
Home lived in fabro-config, which meant fabro-types (a dependency of fabro-config) could not use it — forcing Settings::storage_dir() to duplicate the FABRO_HOME / dirs::home_dir() fallback logic. Moving Home to the leaf crate fabro-util breaks this layering constraint and lets Settings::storage_dir() delegate to Home::from_env().storage_dir(). Also adds stable accessors: storage_dir, socket_path, workflows_dir, logs_dir, tmp_dir. fabro-config re-exports Home for API compatibility. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
cd392b29c7
commit
c8af7e0638
6 changed files with 128 additions and 89 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
|
@ -2014,6 +2014,7 @@ dependencies = [
|
|||
"clap",
|
||||
"dirs",
|
||||
"fabro-macros",
|
||||
"fabro-util",
|
||||
"hex",
|
||||
"serde",
|
||||
"serde_json",
|
||||
|
|
|
|||
|
|
@ -1,77 +1 @@
|
|||
use std::path::{Path, PathBuf};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct Home {
|
||||
root: PathBuf,
|
||||
}
|
||||
|
||||
impl Home {
|
||||
#[must_use]
|
||||
pub fn new(root: impl Into<PathBuf>) -> Self {
|
||||
Self { root: root.into() }
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn from_env() -> Self {
|
||||
if let Some(root) = std::env::var_os("FABRO_HOME") {
|
||||
return Self::new(root);
|
||||
}
|
||||
|
||||
let root =
|
||||
dirs::home_dir().map_or_else(|| PathBuf::from(".fabro"), |home| home.join(".fabro"));
|
||||
Self::new(root)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn root(&self) -> &Path {
|
||||
&self.root
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn user_config(&self) -> PathBuf {
|
||||
self.root.join("settings.toml")
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn server_config(&self) -> PathBuf {
|
||||
self.root.join("settings.toml")
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn certs_dir(&self) -> PathBuf {
|
||||
self.root.join("certs")
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn skills_dir(&self) -> PathBuf {
|
||||
self.root.join("skills")
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::Home;
|
||||
|
||||
#[test]
|
||||
fn accessors_are_relative_to_root() {
|
||||
let home = Home::new("/tmp/fabro-home");
|
||||
|
||||
assert_eq!(home.root(), std::path::Path::new("/tmp/fabro-home"));
|
||||
assert_eq!(
|
||||
home.user_config(),
|
||||
std::path::Path::new("/tmp/fabro-home/settings.toml")
|
||||
);
|
||||
assert_eq!(
|
||||
home.server_config(),
|
||||
std::path::Path::new("/tmp/fabro-home/settings.toml")
|
||||
);
|
||||
assert_eq!(
|
||||
home.certs_dir(),
|
||||
std::path::Path::new("/tmp/fabro-home/certs")
|
||||
);
|
||||
assert_eq!(
|
||||
home.skills_dir(),
|
||||
std::path::Path::new("/tmp/fabro-home/skills")
|
||||
);
|
||||
}
|
||||
}
|
||||
pub use fabro_util::Home;
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ chrono = { workspace = true, features = ["serde"] }
|
|||
clap = { workspace = true, optional = true }
|
||||
dirs.workspace = true
|
||||
fabro-macros = { path = "../fabro-macros" }
|
||||
fabro-util = { path = "../fabro-util" }
|
||||
hex.workspace = true
|
||||
serde.workspace = true
|
||||
serde_json.workspace = true
|
||||
|
|
|
|||
|
|
@ -181,15 +181,9 @@ impl Settings {
|
|||
}
|
||||
|
||||
pub fn storage_dir(&self) -> PathBuf {
|
||||
self.storage_dir.clone().unwrap_or_else(|| {
|
||||
std::env::var_os("FABRO_HOME")
|
||||
.map(|root| PathBuf::from(root).join("storage"))
|
||||
.or_else(|| dirs::home_dir().map(|home| home.join(".fabro")))
|
||||
.map_or_else(
|
||||
|| PathBuf::from(".fabro/storage"),
|
||||
|root| root.join("storage"),
|
||||
)
|
||||
})
|
||||
self.storage_dir
|
||||
.clone()
|
||||
.unwrap_or_else(|| fabro_util::Home::from_env().storage_dir())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -199,11 +193,9 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn storage_dir_defaults_to_home_storage_subdir() {
|
||||
let home = dirs::home_dir().expect("home directory should be available for tests");
|
||||
|
||||
assert_eq!(
|
||||
Settings::default().storage_dir(),
|
||||
home.join(".fabro/storage")
|
||||
fabro_util::Home::from_env().storage_dir()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
119
lib/crates/fabro-util/src/home.rs
Normal file
119
lib/crates/fabro-util/src/home.rs
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
use std::path::{Path, PathBuf};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct Home {
|
||||
root: PathBuf,
|
||||
}
|
||||
|
||||
impl Home {
|
||||
#[must_use]
|
||||
pub fn new(root: impl Into<PathBuf>) -> Self {
|
||||
Self { root: root.into() }
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn from_env() -> Self {
|
||||
if let Some(root) = std::env::var_os("FABRO_HOME") {
|
||||
return Self::new(root);
|
||||
}
|
||||
|
||||
let root =
|
||||
dirs::home_dir().map_or_else(|| PathBuf::from(".fabro"), |home| home.join(".fabro"));
|
||||
Self::new(root)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn root(&self) -> &Path {
|
||||
&self.root
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn user_config(&self) -> PathBuf {
|
||||
self.root.join("settings.toml")
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn server_config(&self) -> PathBuf {
|
||||
self.root.join("settings.toml")
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn certs_dir(&self) -> PathBuf {
|
||||
self.root.join("certs")
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn skills_dir(&self) -> PathBuf {
|
||||
self.root.join("skills")
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn storage_dir(&self) -> PathBuf {
|
||||
self.root.join("storage")
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn socket_path(&self) -> PathBuf {
|
||||
self.root.join("fabro.sock")
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn workflows_dir(&self) -> PathBuf {
|
||||
self.root.join("workflows")
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn logs_dir(&self) -> PathBuf {
|
||||
self.root.join("logs")
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn tmp_dir(&self) -> PathBuf {
|
||||
self.root.join("tmp")
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::Home;
|
||||
|
||||
#[test]
|
||||
fn accessors_are_relative_to_root() {
|
||||
let home = Home::new("/tmp/fabro-home");
|
||||
|
||||
assert_eq!(home.root(), std::path::Path::new("/tmp/fabro-home"));
|
||||
assert_eq!(
|
||||
home.user_config(),
|
||||
std::path::Path::new("/tmp/fabro-home/settings.toml")
|
||||
);
|
||||
assert_eq!(
|
||||
home.server_config(),
|
||||
std::path::Path::new("/tmp/fabro-home/settings.toml")
|
||||
);
|
||||
assert_eq!(
|
||||
home.certs_dir(),
|
||||
std::path::Path::new("/tmp/fabro-home/certs")
|
||||
);
|
||||
assert_eq!(
|
||||
home.skills_dir(),
|
||||
std::path::Path::new("/tmp/fabro-home/skills")
|
||||
);
|
||||
assert_eq!(
|
||||
home.storage_dir(),
|
||||
std::path::Path::new("/tmp/fabro-home/storage")
|
||||
);
|
||||
assert_eq!(
|
||||
home.socket_path(),
|
||||
std::path::Path::new("/tmp/fabro-home/fabro.sock")
|
||||
);
|
||||
assert_eq!(
|
||||
home.workflows_dir(),
|
||||
std::path::Path::new("/tmp/fabro-home/workflows")
|
||||
);
|
||||
assert_eq!(
|
||||
home.logs_dir(),
|
||||
std::path::Path::new("/tmp/fabro-home/logs")
|
||||
);
|
||||
assert_eq!(home.tmp_dir(), std::path::Path::new("/tmp/fabro-home/tmp"));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
pub mod backoff;
|
||||
pub mod check_report;
|
||||
pub mod env;
|
||||
pub mod home;
|
||||
pub mod json;
|
||||
pub mod path;
|
||||
pub mod printer;
|
||||
|
|
@ -13,4 +14,5 @@ pub mod warnings;
|
|||
|
||||
#[doc(hidden)]
|
||||
pub use console;
|
||||
pub use home::Home;
|
||||
pub use warnings::WARNINGS;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue