diff options
author | Matthias Schiffer <mschiffer@universe-factory.net> | 2021-01-27 18:25:28 +0100 |
---|---|---|
committer | Matthias Schiffer <mschiffer@universe-factory.net> | 2021-01-27 18:25:28 +0100 |
commit | acd9f744d2252a13c8b9e34a663497d7284e96a0 (patch) | |
tree | e7548e6f4416db74b0fa9db1e147a1c048dc5b58 /src | |
parent | 2de44d3fea66298e55ac98568e20b9baa2b601f3 (diff) | |
download | rebel-acd9f744d2252a13c8b9e34a663497d7284e96a0.tar rebel-acd9f744d2252a13c8b9e34a663497d7284e96a0.zip |
resolve: collect all dependency errors
Diffstat (limited to 'src')
-rw-r--r-- | src/main.rs | 8 | ||||
-rw-r--r-- | src/resolve.rs | 41 |
2 files changed, 26 insertions, 23 deletions
diff --git a/src/main.rs b/src/main.rs index 5dfe079..43221cc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,7 +5,6 @@ mod recipe; mod resolve; mod types; -use resolve::Result; use types::*; fn main() { @@ -21,8 +20,11 @@ fn main() { let mut rsv = resolve::Resolver::new(&tasks); - if let Result::Err(error) = rsv.add_goal(&"ls:build".to_string()) { - eprintln!("{}", error); + let errors = rsv.add_goal(&"ls:build".to_string()); + if !errors.is_empty() { + for error in errors { + eprintln!("{}", error); + } std::process::exit(1); } let taskset = rsv.to_taskset(); diff --git a/src/resolve.rs b/src/resolve.rs index ec2ec1a..b386590 100644 --- a/src/resolve.rs +++ b/src/resolve.rs @@ -51,8 +51,6 @@ impl fmt::Display for Error { impl std::error::Error for Error {} -pub type Result<T> = std::result::Result<T, Error>; - #[derive(PartialEq)] enum ResolveState { Resolving, @@ -81,46 +79,49 @@ impl<'a> Resolver<'a> { true } - pub fn add_task(&mut self, task: &TaskRef) -> Result<()> { + pub fn add_task(&mut self, task: &TaskRef) -> Vec<Error> { match self.resolve_state.get(task) { Some(ResolveState::Resolving) => { - return Err(Error::DependencyCycle(vec![task.clone()])) + return vec![Error::DependencyCycle(vec![task.clone()])] } - Some(ResolveState::Resolved) => return Ok(()), + Some(ResolveState::Resolved) => return vec![], None => (), } let task_def = match self.tasks.get(task) { - None => return Err(Error::TaskNotFound(vec![task.clone()])), + None => return vec![Error::TaskNotFound(vec![task.clone()])], Some(task_def) => task_def, }; self.resolve_state .insert(task.clone(), ResolveState::Resolving); - for dep in &task_def.depends { - let res = self.add_task(dep); - if let Err(mut error) = res { - self.resolve_state.remove(task); + let mut ret = Vec::new(); + for dep in &task_def.depends { + let errors = self.add_task(dep); + for mut error in errors { error.extend(task.clone()); - - return Err(error); + ret.push(error); } } - *self - .resolve_state - .get_mut(task) - .expect("Missing resolve_state") = ResolveState::Resolved; + if ret.is_empty() { + *self + .resolve_state + .get_mut(task) + .expect("Missing resolve_state") = ResolveState::Resolved; + } else { + self.resolve_state.remove(task); + } - Ok(()) + ret } - pub fn add_goal(&mut self, task: &TaskRef) -> Result<()> { - self.add_task(task)?; + pub fn add_goal(&mut self, task: &TaskRef) -> Vec<Error> { + let ret = self.add_task(task); debug_assert!(self.tasks_resolved()); - Ok(()) + ret } pub fn to_taskset(self) -> HashSet<TaskRef> { |