diff --git a/lib/components/fabro-manifest/src/lib.rs b/lib/components/fabro-manifest/src/lib.rs index 8dc010510..762265d13 100644 --- a/lib/components/fabro-manifest/src/lib.rs +++ b/lib/components/fabro-manifest/src/lib.rs @@ -3,7 +3,7 @@ reason = "CLI manifest builder: sync file I/O building install manifests" )] -mod working_tree; +mod workflow_bundle; use std::collections::HashMap; use std::path::{Path, PathBuf}; @@ -27,9 +27,10 @@ use fabro_workflow::git::{ }; use fabro_workflow::static_reference::ReferenceKind; -use crate::working_tree::{ - CollectWorkingTreeInput, CollectedDocument, CollectedFileReferenceType, CollectedSourceInput, - CollectedWorkingTree, manifest_path_from_absolute, normalize_absolute_path, +use crate::workflow_bundle::{ + CollectWorkflowBundleInput, CollectedDocument, CollectedFileReferenceType, + CollectedSourceInput, CollectedWorkflowBundle, manifest_path_from_absolute, + normalize_absolute_path, }; #[derive(Debug, Default)] @@ -168,7 +169,7 @@ pub fn build_run_manifest(input: ManifestBuildInput) -> Result { workflow_settings.run.inputs.extend(input.input_overrides); let target_path = root_location.graph.clone(); let user_config_source = user_settings_path.map(read_source_input).transpose()?; - let collected = working_tree::collect_working_tree(CollectWorkingTreeInput { + let collected = workflow_bundle::collect_workflow_bundle(CollectWorkflowBundleInput { cwd: &input.cwd, root_location, inputs: &workflow_settings.run.inputs, @@ -219,13 +220,13 @@ struct AssembledCurrentManifest { } fn assemble_current_manifest( - collected: CollectedWorkingTree, + collected: CollectedWorkflowBundle, cwd: &Path, ) -> Result { let root = collected .workflows .get(&collected.entrypoint) - .ok_or_else(|| anyhow!("root workflow missing from collected working tree"))?; + .ok_or_else(|| anyhow!("root workflow missing from collected workflow bundle"))?; let target_key = manifest_path_from_absolute(&root.graph.access_path, cwd)?.to_string(); let root_source = root.graph.source.clone(); diff --git a/lib/components/fabro-manifest/src/working_tree.rs b/lib/components/fabro-manifest/src/workflow_bundle.rs similarity index 95% rename from lib/components/fabro-manifest/src/working_tree.rs rename to lib/components/fabro-manifest/src/workflow_bundle.rs index b2af413c4..3256f7f6e 100644 --- a/lib/components/fabro-manifest/src/working_tree.rs +++ b/lib/components/fabro-manifest/src/workflow_bundle.rs @@ -18,7 +18,7 @@ use fabro_workflow::static_reference::{ AttributeScope, ReferenceKind, reference_kind_for_attribute, }; -pub(super) struct CollectWorkingTreeInput<'a> { +pub(super) struct CollectWorkflowBundleInput<'a> { pub(super) cwd: &'a Path, pub(super) root_location: WorkflowLocation, pub(super) inputs: &'a HashMap, @@ -32,7 +32,7 @@ pub(super) struct CollectedSourceInput { } #[derive(Clone, Debug)] -pub(super) struct CollectedWorkingTree { +pub(super) struct CollectedWorkflowBundle { pub(super) entrypoint: CollectedPath, pub(super) workflows: BTreeMap, pub(super) project_config: Option, @@ -73,7 +73,7 @@ pub(super) struct CollectedFileReference { pub(super) from_access_path: Option, } -/// A canonical virtual coordinate inside one collected working-tree closure. +/// A canonical virtual coordinate inside one collected workflow bundle. #[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] pub(super) struct CollectedPath(String); @@ -692,7 +692,7 @@ impl<'a> CollectionDraft<'a> { entrypoint: DocumentId, project_config: Option, user_config: Option, - ) -> Result { + ) -> Result { let documents = finalize_documents(self.documents)?; let mut workflows = BTreeMap::new(); for workflow in self.workflows.into_values() { @@ -723,7 +723,7 @@ impl<'a> CollectionDraft<'a> { }); } - Ok(CollectedWorkingTree { + Ok(CollectedWorkflowBundle { entrypoint: documents[entrypoint.0].path.clone(), workflows, project_config: project_config.map(|document| documents[document.0].clone()), @@ -799,9 +799,9 @@ fn finalize_documents(drafts: Vec) -> Result, -) -> Result { +pub(super) fn collect_workflow_bundle( + input: CollectWorkflowBundleInput<'_>, +) -> Result { let mut draft = CollectionDraft::new(input.cwd, input.inputs)?; let root_graph_access_path = normalized_absolute_access_path(&input.root_location.graph)?; let root_graph_path = @@ -824,7 +824,7 @@ pub(super) fn collect_working_tree( let mut root = draft .workflows .remove(&root_key) - .ok_or_else(|| anyhow!("root workflow missing from collected working tree"))?; + .ok_or_else(|| anyhow!("root workflow missing from collected workflow bundle"))?; draft.collect_config_dockerfile(project_config, &mut root.files)?; draft.workflows.insert(root_key, root); } @@ -1046,10 +1046,10 @@ mod tests { std::fs::write(path, source).expect("fixture file should be written"); } - fn collect_graph(cwd: &Path, graph: &Path) -> Result { + fn collect_graph(cwd: &Path, graph: &Path) -> Result { let inputs = HashMap::new(); let root_location = WorkflowLocation::resolve(graph, cwd)?; - collect_working_tree(CollectWorkingTreeInput { + collect_workflow_bundle(CollectWorkflowBundleInput { cwd, root_location, inputs: &inputs, @@ -1058,15 +1058,15 @@ mod tests { }) } - fn logical_contents(tree: &CollectedWorkingTree) -> BTreeMap { + fn logical_contents(bundle: &CollectedWorkflowBundle) -> BTreeMap { let mut contents = BTreeMap::new(); - if let Some(config) = &tree.project_config { + if let Some(config) = &bundle.project_config { contents.insert(config.path.to_string(), config.source.clone()); } - if let Some(config) = &tree.user_config { + if let Some(config) = &bundle.user_config { contents.insert(config.path.to_string(), config.source.clone()); } - for workflow in tree.workflows.values() { + for workflow in bundle.workflows.values() { contents.insert( workflow.graph.path.to_string(), workflow.graph.source.clone(), @@ -1082,16 +1082,16 @@ mod tests { } fn logical_provenance( - tree: &CollectedWorkingTree, + bundle: &CollectedWorkflowBundle, ) -> BTreeMap)> { let mut paths_by_access = HashMap::new(); - if let Some(config) = &tree.project_config { + if let Some(config) = &bundle.project_config { paths_by_access.insert(config.access_path.clone(), config.path.to_string()); } - if let Some(config) = &tree.user_config { + if let Some(config) = &bundle.user_config { paths_by_access.insert(config.access_path.clone(), config.path.to_string()); } - for workflow in tree.workflows.values() { + for workflow in bundle.workflows.values() { paths_by_access.insert( workflow.graph.access_path.clone(), workflow.graph.path.to_string(), @@ -1108,7 +1108,7 @@ mod tests { } let mut provenance = BTreeMap::new(); - for workflow in tree.workflows.values() { + for workflow in bundle.workflows.values() { for file in workflow.files.values() { let from = file.reference.from_access_path.as_ref().map(|access_path| { paths_by_access @@ -1166,7 +1166,7 @@ mod tests { } #[test] - fn collector_captures_complete_workflow_and_config_closure() { + fn collector_captures_complete_workflow_bundle() { let temp = tempfile::tempdir().expect("temp directory should be created"); let project = temp.path().join("project"); let root = project.join(".fabro/workflows/root"); @@ -1232,7 +1232,7 @@ dockerfile = { path = "Dockerfile" } ); let inputs = HashMap::new(); - let tree = collect_working_tree(CollectWorkingTreeInput { + let bundle = collect_workflow_bundle(CollectWorkflowBundleInput { cwd: &project, root_location: WorkflowLocation::resolve(&root.join("workflow.toml"), &project) .expect("root workflow should resolve"), @@ -1246,15 +1246,15 @@ dockerfile = { path = "Dockerfile" } source: user_config.to_owned(), }), }) - .expect("working tree should collect"); + .expect("workflow bundle should collect"); assert_eq!( - tree.entrypoint.as_str(), + bundle.entrypoint.as_str(), ".fabro/workflows/root/workflow.fabro" ); - assert_eq!(tree.workflows.len(), 2); + assert_eq!(bundle.workflows.len(), 2); assert_eq!( - logical_contents(&tree) + logical_contents(&bundle) .keys() .map(String::as_str) .collect::>(), @@ -1300,22 +1300,22 @@ dockerfile = { path = "Dockerfile" } let (first_cwd, first_workflow) = fixture(first.path()); let (second_cwd, second_workflow) = fixture(second.path()); - let first_tree = - collect_graph(&first_cwd, &first_workflow).expect("first working tree should collect"); - let second_tree = collect_graph(&second_cwd, &second_workflow) - .expect("second working tree should collect"); + let first_bundle = collect_graph(&first_cwd, &first_workflow) + .expect("first workflow bundle should collect"); + let second_bundle = collect_graph(&second_cwd, &second_workflow) + .expect("second workflow bundle should collect"); - assert_eq!(first_tree.entrypoint, second_tree.entrypoint); + assert_eq!(first_bundle.entrypoint, second_bundle.entrypoint); assert_eq!( - logical_contents(&first_tree), - logical_contents(&second_tree) + logical_contents(&first_bundle), + logical_contents(&second_bundle) ); assert_eq!( - logical_provenance(&first_tree), - logical_provenance(&second_tree) + logical_provenance(&first_bundle), + logical_provenance(&second_bundle) ); assert_eq!( - first_tree.entrypoint.as_str(), + first_bundle.entrypoint.as_str(), "_fabro_external/entrypoint/workflow.fabro" ); } @@ -1389,11 +1389,11 @@ dockerfile = { path = "Dockerfile" } let second = tempfile::tempdir().expect("second temp directory should be created"); let (first_cwd, first_root) = fixture(first.path()); let (second_cwd, second_root) = fixture(second.path()); - let tree = - collect_graph(&first_cwd, &first_root).expect("first working tree should collect"); + let bundle = + collect_graph(&first_cwd, &first_root).expect("first workflow bundle should collect"); let moved = - collect_graph(&second_cwd, &second_root).expect("moved working tree should collect"); - let entrypoint = &tree.entrypoint; + collect_graph(&second_cwd, &second_root).expect("moved workflow bundle should collect"); + let entrypoint = &bundle.entrypoint; let resolved = virtual_reference_path( entrypoint .as_path() @@ -1404,13 +1404,13 @@ dockerfile = { path = "Dockerfile" } .expect("child reference should resolve"); assert_eq!(resolved, Path::new("_fabro_external/child/workflow.fabro")); - assert!(tree.workflows.contains_key( + assert!(bundle.workflows.contains_key( &CollectedPath::try_new(resolved).expect("child path should be canonical") )); - assert_eq!(logical_contents(&tree), logical_contents(&moved)); - assert_eq!(logical_provenance(&tree), logical_provenance(&moved)); - assert_eq!(tree.entrypoint, moved.entrypoint); - for path in logical_contents(&tree).into_keys() { + assert_eq!(logical_contents(&bundle), logical_contents(&moved)); + assert_eq!(logical_provenance(&bundle), logical_provenance(&moved)); + assert_eq!(bundle.entrypoint, moved.entrypoint); + for path in logical_contents(&bundle).into_keys() { assert!(!path.contains(first.path().file_name().unwrap().to_string_lossy().as_ref())); CollectedPath::try_new(path).expect("every collected coordinate should be canonical"); } @@ -1433,15 +1433,15 @@ dockerfile = { path = "Dockerfile" } ); write_file(&cwd.join("prompt.md"), "prompt\n"); - let tree = collect_graph(cwd, &graph).expect("working tree should collect"); - let root = tree + let bundle = collect_graph(cwd, &graph).expect("workflow bundle should collect"); + let root = bundle .workflows - .get(&tree.entrypoint) + .get(&bundle.entrypoint) .expect("root workflow should be present"); assert_eq!(root.files.len(), 1); let assembled = - crate::assemble_current_manifest(tree, cwd).expect("legacy manifest should assemble"); + crate::assemble_current_manifest(bundle, cwd).expect("legacy manifest should assemble"); assert_eq!(assembled.workflows["workflow.fabro"].files.len(), 1); } @@ -1613,7 +1613,7 @@ dockerfile = { path = "Dockerfile" } assert_ne!(first_commit, ahead_commit); collect_graph(&checkout, &checkout.join("workflow.fabro")) - .expect("working tree should collect"); + .expect("workflow bundle should collect"); let origin_commit = origin .find_reference("refs/heads/main")