diff --git a/e2e/tasks/test_task_depends_post b/e2e/tasks/test_task_depends_post new file mode 100644 index 0000000000..e4123ff138 --- /dev/null +++ b/e2e/tasks/test_task_depends_post @@ -0,0 +1,32 @@ +#!/usr/bin/env bash + +# ensures depends_post and depends can be used on separate tasks +cat <mise.toml +[tasks.one] +run = "echo one" + +[tasks.two] +depends = ["one"] +run = "echo two" + +[tasks.three] +depends_post = ["two"] +run = "echo three" +EOF +assert "mise task deps" "one +three +two +├── three +└── one" +assert "mise run three" + +# TODO: this does not work with how mise is designed currently. Tasks can only ever be run once per run session. This will require hefty refactoring if it is ever supported +# uses depends and depends_post on the same task +#cat <mise.toml +#tasks."util:donothing" = "" +#[tasks.hi] +#depends = "util:donothing" +#run = "echo hi" +#depends_post = "util:donothing" +#EOF +#assert "mise run hi" diff --git a/src/task/deps.rs b/src/task/deps.rs index b28199c3f6..b99a774d95 100644 --- a/src/task/deps.rs +++ b/src/task/deps.rs @@ -23,6 +23,7 @@ impl Deps { let mut graph = DiGraph::new(); let mut indexes = HashMap::new(); let mut stack = vec![]; + let mut seen = HashSet::new(); let mut add_idx = |task: &Task, graph: &mut DiGraph| { *indexes @@ -45,6 +46,10 @@ impl Deps { .flatten_ok() .collect::>>()?; while let Some(a) = stack.pop() { + if seen.contains(&a) { + // prevent infinite loop + continue; + } let a_idx = add_idx(&a, &mut graph); let (pre, post) = a.resolve_depends(&all_tasks_to_run)?; for b in pre { @@ -57,6 +62,7 @@ impl Deps { graph.update_edge(b_idx, a_idx, ()); stack.push(b.clone()); } + seen.insert(a); } let (tx, _) = channel::unbounded(); let sent = HashSet::new(); diff --git a/src/task/mod.rs b/src/task/mod.rs index 0d07a6a0ea..af1f7d9cc9 100644 --- a/src/task/mod.rs +++ b/src/task/mod.rs @@ -264,8 +264,11 @@ impl Task { .filter_ok(|t| t.name != self.name) .collect::>>()?; for dep in depends.clone() { - depends.extend(dep.all_depends()?); + let mut extra = dep.all_depends()?; + extra.retain(|t| t.name != self.name); // prevent depending on ourself + depends.extend(extra); } + let depends = depends.into_iter().unique().collect(); Ok(depends) }