mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-09-13 23:14:17 +00:00
refactor(settings): resolve workflow settings
This commit is contained in:
parent
48c5737bd5
commit
e7d890bbf5
7 changed files with 96 additions and 12 deletions
|
|
@ -16,7 +16,8 @@ pub use fabro_util::path::expand_tilde;
|
|||
pub use home::Home;
|
||||
pub use resolve::{
|
||||
ResolveError, resolve_cli, resolve_cli_from_file, resolve_project, resolve_project_from_file,
|
||||
resolve_run, resolve_run_from_file, resolve_server, resolve_server_from_file,
|
||||
resolve_run, resolve_run_from_file, resolve_server, resolve_server_from_file, resolve_workflow,
|
||||
resolve_workflow_from_file,
|
||||
};
|
||||
pub use storage::{RunScratch, ServerState, Storage};
|
||||
|
||||
|
|
|
|||
|
|
@ -12,11 +12,10 @@ use serde::Serialize;
|
|||
|
||||
use crate::config::ConfigLayer;
|
||||
use crate::run;
|
||||
use crate::{resolve_project_from_file, resolve_run_from_file};
|
||||
use crate::{resolve_project_from_file, resolve_run_from_file, resolve_workflow_from_file};
|
||||
use fabro_types::settings::SettingsFile;
|
||||
|
||||
const CONFIG_FILENAME: &str = "fabro.toml";
|
||||
const RUN_GRAPH_FILE: &str = "workflow.fabro";
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct WorkflowPathResolution {
|
||||
pub resolved_workflow_path: PathBuf,
|
||||
|
|
@ -91,13 +90,10 @@ pub fn resolve_workflow_path(
|
|||
if path.extension().is_some_and(|ext| ext == "toml") {
|
||||
match run::load_run_config(&path) {
|
||||
Ok(cfg) => {
|
||||
let graph = cfg
|
||||
.as_v2()
|
||||
.workflow
|
||||
.as_ref()
|
||||
.and_then(|w| w.graph.as_deref())
|
||||
.unwrap_or(RUN_GRAPH_FILE);
|
||||
let dot_path = run::resolve_graph_path(&path, graph);
|
||||
let workflow = resolve_workflow_from_file(cfg.as_v2()).map_err(|errors| {
|
||||
anyhow::anyhow!("Failed to resolve workflow settings: {errors:?}")
|
||||
})?;
|
||||
let dot_path = run::resolve_graph_path(&path, &workflow.graph);
|
||||
Ok(WorkflowPathResolution {
|
||||
resolved_workflow_path: path.clone(),
|
||||
dot_path,
|
||||
|
|
|
|||
|
|
@ -3,9 +3,10 @@ mod error;
|
|||
mod project;
|
||||
mod run;
|
||||
mod server;
|
||||
mod workflow;
|
||||
|
||||
use fabro_types::settings::{
|
||||
CliSettings, ProjectSettings, RunSettings, ServerSettings, SettingsFile,
|
||||
CliSettings, ProjectSettings, RunSettings, ServerSettings, SettingsFile, WorkflowSettings,
|
||||
};
|
||||
|
||||
pub use cli::resolve_cli;
|
||||
|
|
@ -13,6 +14,7 @@ pub use error::ResolveError;
|
|||
pub use project::resolve_project;
|
||||
pub use run::resolve_run;
|
||||
pub use server::resolve_server;
|
||||
pub use workflow::resolve_workflow;
|
||||
|
||||
pub fn resolve_cli_from_file(file: &SettingsFile) -> Result<CliSettings, Vec<ResolveError>> {
|
||||
let mut errors = Vec::new();
|
||||
|
|
@ -60,6 +62,19 @@ pub fn resolve_run_from_file(file: &SettingsFile) -> Result<RunSettings, Vec<Res
|
|||
}
|
||||
}
|
||||
|
||||
pub fn resolve_workflow_from_file(
|
||||
file: &SettingsFile,
|
||||
) -> Result<WorkflowSettings, Vec<ResolveError>> {
|
||||
let mut errors = Vec::new();
|
||||
let layer = file.workflow.as_ref().cloned().unwrap_or_default();
|
||||
let resolved = resolve_workflow(&layer, &mut errors);
|
||||
if errors.is_empty() {
|
||||
Ok(resolved)
|
||||
} else {
|
||||
Err(errors)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn require_interp(
|
||||
value: Option<&fabro_types::settings::InterpString>,
|
||||
path: &str,
|
||||
|
|
|
|||
20
lib/crates/fabro-config/src/resolve/workflow.rs
Normal file
20
lib/crates/fabro-config/src/resolve/workflow.rs
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
use fabro_types::settings::workflow::{WorkflowLayer, WorkflowSettings};
|
||||
|
||||
use super::ResolveError;
|
||||
|
||||
const DEFAULT_WORKFLOW_GRAPH: &str = "workflow.fabro";
|
||||
|
||||
pub fn resolve_workflow(
|
||||
layer: &WorkflowLayer,
|
||||
_errors: &mut Vec<ResolveError>,
|
||||
) -> WorkflowSettings {
|
||||
WorkflowSettings {
|
||||
name: layer.name.clone(),
|
||||
description: layer.description.clone(),
|
||||
graph: layer
|
||||
.graph
|
||||
.clone()
|
||||
.unwrap_or_else(|| DEFAULT_WORKFLOW_GRAPH.to_string()),
|
||||
metadata: layer.metadata.clone(),
|
||||
}
|
||||
}
|
||||
43
lib/crates/fabro-config/tests/resolve_workflow.rs
Normal file
43
lib/crates/fabro-config/tests/resolve_workflow.rs
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
use fabro_config::resolve_workflow_from_file;
|
||||
use fabro_types::settings::SettingsFile;
|
||||
|
||||
#[test]
|
||||
fn resolves_workflow_defaults_from_empty_settings() {
|
||||
let settings = SettingsFile::default();
|
||||
|
||||
let workflow = resolve_workflow_from_file(&settings).expect("empty settings should resolve");
|
||||
|
||||
assert_eq!(workflow.graph, "workflow.fabro");
|
||||
assert!(workflow.name.is_none());
|
||||
assert!(workflow.description.is_none());
|
||||
assert!(workflow.metadata.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn resolves_workflow_graph_and_metadata() {
|
||||
let settings: SettingsFile = fabro_config::ConfigLayer::parse(
|
||||
r#"
|
||||
_version = 1
|
||||
|
||||
[workflow]
|
||||
name = "Ship"
|
||||
description = "Primary flow"
|
||||
graph = "graphs/ship.dot"
|
||||
|
||||
[workflow.metadata]
|
||||
tier = "gold"
|
||||
"#,
|
||||
)
|
||||
.expect("fixture should parse")
|
||||
.into();
|
||||
|
||||
let workflow = resolve_workflow_from_file(&settings).expect("workflow settings should resolve");
|
||||
|
||||
assert_eq!(workflow.name.as_deref(), Some("Ship"));
|
||||
assert_eq!(workflow.description.as_deref(), Some("Primary flow"));
|
||||
assert_eq!(workflow.graph, "graphs/ship.dot");
|
||||
assert_eq!(
|
||||
workflow.metadata.get("tier").map(String::as_str),
|
||||
Some("gold")
|
||||
);
|
||||
}
|
||||
|
|
@ -57,4 +57,4 @@ pub use size::{ParseSizeError, Size};
|
|||
pub use splice_array::{SPLICE_MARKER, SpliceArray, SpliceArrayError};
|
||||
pub use tree::{ParseError, SettingsFile, parse_settings_file};
|
||||
pub use version::{CURRENT_VERSION, SchemaVersion, VersionError, validate_version};
|
||||
pub use workflow::WorkflowLayer;
|
||||
pub use workflow::{WorkflowLayer, WorkflowSettings};
|
||||
|
|
|
|||
|
|
@ -7,6 +7,15 @@ use std::collections::HashMap;
|
|||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// A structurally resolved `[workflow]` view for consumers.
|
||||
#[derive(Debug, Clone, Default, PartialEq)]
|
||||
pub struct WorkflowSettings {
|
||||
pub name: Option<String>,
|
||||
pub description: Option<String>,
|
||||
pub graph: String,
|
||||
pub metadata: HashMap<String, String>,
|
||||
}
|
||||
|
||||
/// A sparse `[workflow]` layer as it appears in a single settings file.
|
||||
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue