mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-08-28 05:27:41 +00:00
Rename collector to workflow bundle
This commit is contained in:
parent
0e703a7770
commit
afd06bf560
2 changed files with 58 additions and 57 deletions
|
|
@ -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<BuiltManifest> {
|
|||
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<AssembledCurrentManifest> {
|
||||
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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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<String, toml::Value>,
|
||||
|
|
@ -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<CollectedPath, CollectedWorkflow>,
|
||||
pub(super) project_config: Option<CollectedDocument>,
|
||||
|
|
@ -73,7 +73,7 @@ pub(super) struct CollectedFileReference {
|
|||
pub(super) from_access_path: Option<PathBuf>,
|
||||
}
|
||||
|
||||
/// 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<DocumentId>,
|
||||
user_config: Option<DocumentId>,
|
||||
) -> Result<CollectedWorkingTree> {
|
||||
) -> Result<CollectedWorkflowBundle> {
|
||||
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<DraftDocument>) -> Result<Vec<CollectedDocumen
|
|||
.collect())
|
||||
}
|
||||
|
||||
pub(super) fn collect_working_tree(
|
||||
input: CollectWorkingTreeInput<'_>,
|
||||
) -> Result<CollectedWorkingTree> {
|
||||
pub(super) fn collect_workflow_bundle(
|
||||
input: CollectWorkflowBundleInput<'_>,
|
||||
) -> Result<CollectedWorkflowBundle> {
|
||||
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<CollectedWorkingTree> {
|
||||
fn collect_graph(cwd: &Path, graph: &Path) -> Result<CollectedWorkflowBundle> {
|
||||
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<String, String> {
|
||||
fn logical_contents(bundle: &CollectedWorkflowBundle) -> BTreeMap<String, String> {
|
||||
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<String, (CollectedFileReferenceType, String, Option<String>)> {
|
||||
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::<Vec<_>>(),
|
||||
|
|
@ -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")
|
||||
Loading…
Add table
Reference in a new issue