trim config wrapper and storage override helpers

This commit is contained in:
Bryan Helmkamp 2026-04-23 12:01:49 -04:00
parent 9220af6e80
commit 30986207cb
No known key found for this signature in database
8 changed files with 66 additions and 56 deletions

View file

@ -187,9 +187,9 @@ mod tests {
use std::path::PathBuf;
use fabro_config::parse_settings_layer;
use fabro_config::user::apply_storage_dir_override;
use fabro_types::settings::InterpString;
use fabro_types::settings::cli::{CliLayer, CliOutputLayer, OutputFormat, OutputVerbosity};
use fabro_types::settings::server::{ServerLayer, ServerStorageLayer};
use fabro_util::printer::Printer;
use tokio::sync::OnceCell;
@ -223,6 +223,18 @@ mod tests {
}
}
fn with_storage_dir_override(
mut layer: fabro_types::settings::SettingsLayer,
path: &std::path::Path,
) -> fabro_types::settings::SettingsLayer {
let server = layer.server.get_or_insert_with(ServerLayer::default);
let storage = server
.storage
.get_or_insert_with(ServerStorageLayer::default);
storage.root = Some(InterpString::parse(&path.display().to_string()));
layer
}
#[test]
fn context_exposes_resolved_output_and_explicit_json_state() {
let ctx = synthetic_context(true, Printer::Default);
@ -248,9 +260,9 @@ root = "/srv/fabro/default"
"#,
)
.expect("settings fixture should parse");
let override_disk_settings = apply_storage_dir_override(
let override_disk_settings = with_storage_dir_override(
base_disk_settings.clone(),
Some(std::path::Path::new("/srv/fabro/override")),
std::path::Path::new("/srv/fabro/override"),
);
let (base_settings, base_user_settings) =

View file

@ -1464,16 +1464,13 @@ async fn run_install_github_inner(
let existing_config_contents =
std::fs::read_to_string(&config_path).context("failed to read existing settings.toml")?;
let parsed_settings = user_config::apply_storage_dir_override(
fabro_config::parse_settings_layer(&existing_config_contents)
.context("failed to parse existing settings.toml")?,
args.storage_dir.as_deref(),
);
let storage_dir = local_server::storage_dir(&parsed_settings).unwrap_or_else(|_| {
args.storage_dir
.clone_path()
.unwrap_or_else(default_storage_dir)
});
let parsed_settings = fabro_config::parse_settings_layer(&existing_config_contents)
.context("failed to parse existing settings.toml")?;
let storage_dir = args
.storage_dir
.clone_path()
.or_else(|| local_server::storage_dir(&parsed_settings).ok())
.unwrap_or_else(default_storage_dir);
let server_was_running =
ServerDaemon::load_running(&Storage::new(&storage_dir).runtime_directory())?.is_some();
let mut doc: toml::Value = toml::from_str(&existing_config_contents)
@ -1777,11 +1774,8 @@ async fn run_install_inner(args: &InstallArgs, ctx: &CommandContext) -> Result<(
toml::to_string_pretty(&doc)?
};
let install_settings = user_config::apply_storage_dir_override(
fabro_config::parse_settings_layer(&settings_toml)
.context("failed to parse generated settings.toml")?,
args.storage_dir.as_deref(),
);
let install_settings = fabro_config::parse_settings_layer(&settings_toml)
.context("failed to parse generated settings.toml")?;
fabro_config::ServerSettingsBuilder::from_layer(&install_settings)?;
// Secrets and auth material

View file

@ -9,8 +9,9 @@ use std::path::{Component, Path, PathBuf};
use anyhow::{Context, Result, anyhow};
use fabro_api::types;
use fabro_config::load::load_settings_for_workflow;
use fabro_config::parse_settings_layer;
use fabro_config::project::{self, discover_project_config, resolve_workflow_path};
use fabro_config::run::{parse_run_config, resolve_run_goal};
use fabro_config::run::resolve_run_goal;
use fabro_graphviz::graph::AttrValue;
use fabro_graphviz::parser;
use fabro_sandbox::daytona::detect_repo_info;
@ -325,7 +326,8 @@ fn collect_workflow_config_files(
config: &types::ManifestWorkflowConfig,
files: &mut HashMap<String, types::ManifestFileEntry>,
) -> Result<()> {
let config_layer = parse_run_config(&config.source)?;
let config_layer = parse_settings_layer(&config.source)
.map_err(|err| anyhow!("Failed to parse run config TOML: {err}"))?;
let dockerfile = config_layer
.run
.as_ref()

View file

@ -4,7 +4,8 @@ use std::str::FromStr;
use anyhow::Result;
pub(crate) use fabro_client::ServerTarget;
use fabro_config::UserSettingsBuilder;
pub(crate) use fabro_config::user::*;
pub(crate) use fabro_config::user::{active_settings_path, default_storage_dir};
use fabro_config::user::{default_socket_path, load_settings_config};
use fabro_types::settings::cli::CliTargetSettings;
use fabro_types::settings::{CliNamespace, SettingsLayer};
use fabro_util::version::FABRO_VERSION;
@ -31,6 +32,24 @@ pub(crate) fn load_settings_with_config_and_storage_dir(
Ok(apply_storage_dir_override(layer, storage_dir))
}
fn apply_storage_dir_override(
mut layer: SettingsLayer,
storage_dir: Option<&Path>,
) -> SettingsLayer {
use fabro_types::settings::InterpString;
use fabro_types::settings::server::{ServerLayer, ServerStorageLayer};
if let Some(dir) = storage_dir {
let server = layer.server.get_or_insert_with(ServerLayer::default);
let storage = server
.storage
.get_or_insert_with(ServerStorageLayer::default);
storage.root = Some(InterpString::parse(&dir.display().to_string()));
}
layer
}
/// Pull the resolved CLI target configuration out of `[cli.target]`.
/// Returns either an http(s) URL or a unix socket path.
fn cli_target_from_settings(settings: &CliNamespace) -> Option<String> {

View file

@ -1,9 +1,8 @@
//! Workflow / run config loading helpers.
//!
//! Thin wrappers around `parse_settings_layer` / `load_settings_path` plus
//! path resolution for the `[workflow] graph` override. Runtime types
//! that used to be re-exported from here live under
//! `fabro_types::settings::run` now.
//! Helpers for loading workflow-local settings and resolving runtime goal /
//! graph paths. Runtime types that used to be re-exported from here live
//! under `fabro_types::settings::run` now.
#![expect(
clippy::disallowed_methods,
@ -15,15 +14,8 @@ use std::path::{Path, PathBuf};
use fabro_types::settings::SettingsLayer;
use fabro_types::settings::run::{ResolvedGoalSource, ResolvedRunGoal, RunGoalLayer};
use crate::Result;
use crate::load::{load_settings_path, resolve_goal_file_path};
use crate::parse::parse_settings_layer;
use crate::{Error, Result};
/// Load and parse a run config from a TOML file.
pub fn parse_run_config(contents: &str) -> Result<SettingsLayer> {
parse_settings_layer(contents)
.map_err(|err| Error::parse("Failed to parse run config TOML", err))
}
/// Load and parse a run config from a TOML file.
///

View file

@ -63,24 +63,6 @@ fn load_v2_layer_from_path(path: &Path) -> Result<SettingsLayer> {
load_settings_path(path)
}
/// Override the resolved storage root in a settings layer with a runtime path.
pub fn apply_storage_dir_override(
mut layer: SettingsLayer,
storage_dir: Option<&Path>,
) -> SettingsLayer {
use fabro_types::settings::interp::InterpString;
use fabro_types::settings::server::{ServerLayer, ServerStorageLayer};
if let Some(dir) = storage_dir {
let server = layer.server.get_or_insert_with(ServerLayer::default);
let storage = server
.storage
.get_or_insert_with(ServerStorageLayer::default);
storage.root = Some(InterpString::parse(&dir.display().to_string()));
}
layer
}
#[cfg(test)]
mod tests {
use super::{

View file

@ -5,7 +5,6 @@ use std::sync::Arc;
use anyhow::{Result, anyhow, bail};
use fabro_api::types;
use fabro_config::project::resolve_working_directory;
use fabro_config::run::parse_run_config;
use fabro_config::{WorkflowSettingsBuilder, parse_settings_layer};
use fabro_graphviz::graph::{Graph, is_llm_handler_type};
use fabro_graphviz::render::apply_direction;
@ -199,7 +198,8 @@ fn root_workflow_config_layer(
return Ok(SettingsLayer::default());
};
let mut layer = parse_run_config(&config.source)?;
let mut layer = parse_settings_layer(&config.source)
.map_err(|err| anyhow!("Failed to parse run config TOML: {err}"))?;
resolve_manifest_dockerfile(&mut layer, Path::new(&config.path), &workflow.files)?;
Ok(layer)
}

View file

@ -6,12 +6,12 @@ use std::time::Duration;
use anyhow::Context;
use clap::Args;
use fabro_config::bind::{self, Bind, BindRequest};
use fabro_config::user::{apply_storage_dir_override, load_settings_config};
use fabro_config::user::load_settings_config;
use fabro_config::{ServerSettingsBuilder, Storage};
use fabro_install::{OBJECT_STORE_ACCESS_KEY_ID_ENV, OBJECT_STORE_SECRET_ACCESS_KEY_ENV};
use fabro_sandbox::SandboxProvider;
use fabro_types::settings::server::{
GithubIntegrationStrategy, ServerLayer, ServerListenLayer, WebhookStrategy,
GithubIntegrationStrategy, ServerLayer, ServerListenLayer, ServerStorageLayer, WebhookStrategy,
};
use fabro_types::settings::{
Combine, GithubIntegrationSettings, InterpString, ObjectStoreSettings, ServerListenSettings,
@ -191,7 +191,16 @@ fn apply_runtime_settings(
args: &ServeArgs,
data_dir: &Path,
) -> SettingsLayer {
apply_storage_dir_override(apply_serve_overrides(base, args), Some(data_dir))
apply_storage_dir_override(apply_serve_overrides(base, args), data_dir)
}
fn apply_storage_dir_override(mut settings: SettingsLayer, data_dir: &Path) -> SettingsLayer {
let server = settings.server.get_or_insert_with(ServerLayer::default);
let storage = server
.storage
.get_or_insert_with(ServerStorageLayer::default);
storage.root = Some(InterpString::parse(&data_dir.display().to_string()));
settings
}
async fn resolve_github_webhook_ip_allowlist(