diff options
-rw-r--r-- | src/resolve.rs | 67 | ||||
-rw-r--r-- | src/types.rs | 4 |
2 files changed, 68 insertions, 3 deletions
diff --git a/src/resolve.rs b/src/resolve.rs index 14294d1..a01f5c5 100644 --- a/src/resolve.rs +++ b/src/resolve.rs @@ -64,6 +64,62 @@ enum ResolveState { Resolved, } +pub fn runtime_depends<'a, I>( + tasks: &'a TaskMap, + deps: I, +) -> Result<HashSet<&'a OutputRef>, Vec<Error>> +where + I: IntoIterator<Item = &'a OutputRef>, +{ + fn add_dep<'a>( + ret: &mut HashSet<&'a OutputRef>, + tasks: &'a TaskMap, + dep: &'a OutputRef, + ) -> Vec<Error> { + if !ret.insert(dep) { + return Vec::new(); + } + + let task = &dep.task; + let task_def = match tasks.get(&task.id) { + Some(task) => task, + None => return vec![Error::TaskNotFound(DepChain(vec![task.clone()]))], + }; + + let output = match task_def.output.get(&dep.output) { + Some(output) => output, + None => { + return vec![Error::OutputNotFound( + DepChain(vec![task.clone()]), + dep.output.clone(), + )]; + } + }; + + let mut errors = Vec::new(); + for runtime_dep in &output.runtime_depends { + for mut error in add_dep(ret, tasks, runtime_dep) { + error.extend(task.clone()); + errors.push(error); + } + } + errors + } + + let mut ret = HashSet::new(); + let mut errors = Vec::new(); + + for dep in deps { + errors.extend(add_dep(&mut ret, tasks, dep)); + } + + if !errors.is_empty() { + return Err(errors); + } + + Ok(ret) +} + #[derive(Debug)] pub struct Resolver<'a> { tasks: &'a TaskMap, @@ -122,8 +178,15 @@ impl<'a> Resolver<'a> { handle_errors(self.add_task(inherit, None)); } - for dep in task_def.get_depend_outputs() { - handle_errors(self.add_task(&dep.task, Some(&dep.output))); + match runtime_depends(self.tasks, task_def.get_depend_outputs()) { + Ok(rdeps) => { + for rdep in rdeps { + handle_errors(self.add_task(&rdep.task, Some(&rdep.output))); + } + } + Err(errors) => { + handle_errors(errors); + } } if ret.is_empty() { diff --git a/src/types.rs b/src/types.rs index af0fb92..0b85393 100644 --- a/src/types.rs +++ b/src/types.rs @@ -1,7 +1,7 @@ use serde::{Deserialize, Serialize}; use sha2::Sha256; use std::{ - collections::{HashMap, HashSet}, + collections::{BTreeSet, HashMap, HashSet}, fmt::Display, }; @@ -107,6 +107,8 @@ fn default_output_name() -> String { #[derive(Clone, Debug, Deserialize, Serialize)] pub struct Output { pub path: Option<String>, + #[serde(default)] + pub runtime_depends: BTreeSet<OutputRef>, } #[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq, PartialOrd, Ord, Hash)] |