Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions crates/vite_task/src/session/execute/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ struct ExecutionContext<'a> {
impl ExecutionContext<'_> {
/// Execute all tasks in an execution graph in dependency order.
///
/// `ExecutionGraph` guarantees acyclicity at construction time and caches a
/// topological order. We iterate `toposort()` in reverse to get execution order
/// `ExecutionGraph` guarantees acyclicity at construction time.
/// We compute a topological order and iterate in reverse to get execution order
/// (dependencies before dependents).
///
/// The `path_prefix` tracks our position within nested execution graphs. For the
Expand All @@ -71,14 +71,15 @@ impl ExecutionContext<'_> {
graph: &ExecutionGraph,
path_prefix: &LeafExecutionPath,
) {
// `toposort()` returns nodes in topological order: for every edge A→B,
// A appears before B. Since our edges mean "A depends on B", dependencies
// (B) appear after their dependents (A). We iterate in reverse to get
// execution order where dependencies run first.
// `compute_topological_order()` returns nodes in topological order: for every
// edge A→B, A appears before B. Since our edges mean "A depends on B",
// dependencies (B) appear after their dependents (A). We iterate in reverse
// to get execution order where dependencies run first.

// Execute tasks in dependency-first order. Each task may have multiple items
// (from `&&`-split commands), which are executed sequentially.
for &node_ix in graph.toposort().iter().rev() {
let topo_order = graph.compute_topological_order();
for &node_ix in topo_order.iter().rev() {
let task_execution = &graph[node_ix];

for (item_idx, item) in task_execution.items.iter().enumerate() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ source: crates/vite_task_bin/tests/e2e_snapshots/main.rs
expression: e2e_outputs
---
[1]> vp run task-a # task-a -> task-b -> task-a cycle
Error: Cycle dependency detected involving task error-cycle-dependency-test#task-b
Error: Cycle dependency detected: error-cycle-dependency-test#task-a -> error-cycle-dependency-test#task-b -> error-cycle-dependency-test#task-a
10 changes: 5 additions & 5 deletions crates/vite_task_plan/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,11 +146,11 @@ pub enum Error {

/// A cycle was detected in the task dependency graph during planning.
///
/// This is caught by `ExecutionGraph::try_from_graph`, which validates that the
/// graph is a DAG. The contained `TaskDisplay` identifies one of the tasks
/// involved in the cycle.
#[error("Cycle dependency detected involving task {0}")]
CycleDependencyDetected(TaskDisplay),
/// This is caught by `AcyclicGraph::try_from_graph`, which validates that the
/// graph is a DAG. The contained path lists all tasks forming the cycle
/// as a closed loop (the first and last elements are the same).
#[error("Cycle dependency detected: {}", _0.iter().map(std::string::ToString::to_string).collect::<Vec<_>>().join(" -> "))]
CycleDependencyDetected(Vec<TaskDisplay>),
}

impl Error {
Expand Down
Loading