summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2021-01-26 22:30:40 +0100
committerMatthias Schiffer <mschiffer@universe-factory.net>2021-01-26 22:30:40 +0100
commitb20fb6f26e14bcd21266e9436d72d94b84978dce (patch)
tree4e54d25dd644852ff458d4af49983c3941b50190 /src
parente48108cdef9555565d0715f4b6f39228cfc45376 (diff)
downloadrebel-b20fb6f26e14bcd21266e9436d72d94b84978dce.tar
rebel-b20fb6f26e14bcd21266e9436d72d94b84978dce.zip
resolve: record task list of dependency cycles
Diffstat (limited to 'src')
-rw-r--r--src/resolve.rs35
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;
}
}