diff options
author | Matthias Schiffer <mschiffer@universe-factory.net> | 2021-01-26 22:30:40 +0100 |
---|---|---|
committer | Matthias Schiffer <mschiffer@universe-factory.net> | 2021-01-26 22:30:40 +0100 |
commit | b20fb6f26e14bcd21266e9436d72d94b84978dce (patch) | |
tree | 4e54d25dd644852ff458d4af49983c3941b50190 /src | |
parent | e48108cdef9555565d0715f4b6f39228cfc45376 (diff) | |
download | rebel-b20fb6f26e14bcd21266e9436d72d94b84978dce.tar rebel-b20fb6f26e14bcd21266e9436d72d94b84978dce.zip |
resolve: record task list of dependency cycles
Diffstat (limited to 'src')
-rw-r--r-- | src/resolve.rs | 35 |
1 files changed, 29 insertions, 6 deletions
diff --git a/src/resolve.rs b/src/resolve.rs index 0758016..ab2eef3 100644 --- a/src/resolve.rs +++ b/src/resolve.rs @@ -6,14 +6,20 @@ use crate::types::*; #[derive(Debug)] pub enum Error { TaskNotFound(TaskRef), - DependencyCycle(TaskRef), + DependencyCycle { tasks: Vec<TaskRef>, complete: bool }, } impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - Error::TaskNotFound(id) => write!(f, "Task not found: {}", id), - Error::DependencyCycle(id) => write!(f, "DependencyCycle: {}", id), + Error::TaskNotFound(id) => write!(f, "Task not found: {:?}", id), + Error::DependencyCycle { tasks, complete } => { + write!(f, "Dependency Cycle: {:?}", tasks)?; + if !complete { + write!(f, " (incomplete)")?; + } + Ok(()) + } } } } @@ -43,7 +49,12 @@ impl<'a> Resolver<'a> { pub fn add_goal(&mut self, task: &TaskRef) -> Result<()> { match self.resolve_state.get(task) { - Some(ResolveState::Resolving) => return Err(Error::DependencyCycle(task.clone())), + Some(ResolveState::Resolving) => { + return Err(Error::DependencyCycle { + tasks: vec![task.clone()], + complete: false, + }) + } Some(ResolveState::Resolved) => return Ok(()), None => (), } @@ -57,9 +68,21 @@ impl<'a> Resolver<'a> { .insert(task.clone(), ResolveState::Resolving); for dep in &task_def.depends { - let res = self.add_goal(dep); - if res.is_err() { + let mut res = self.add_goal(dep); + if let Err(ref mut error) = res { self.resolve_state.remove(task); + + if let Error::DependencyCycle { + ref mut tasks, + complete: ref mut complete @ false, + } = error + { + tasks.push(task.clone()); + if tasks[0] == task.as_str() { + *complete = true + } + } + return res; } } |