diff --git a/crates/vite_task/src/schedule.rs b/crates/vite_task/src/schedule.rs index 73a82b7e86..a9cd43d72d 100644 --- a/crates/vite_task/src/schedule.rs +++ b/crates/vite_task/src/schedule.rs @@ -32,6 +32,7 @@ pub struct PreExecutionStatus { pub cache_status: CacheStatus, pub display_options: DisplayOptions, } + #[derive(Debug, Serialize, Deserialize, Clone)] pub enum CacheStatus { /// Cache miss with reason. @@ -127,8 +128,31 @@ impl ExecutionPlan { #[tracing::instrument(skip(self, workspace))] pub async fn execute(self, workspace: &mut Workspace) -> Result { let mut execution_statuses = Vec::::with_capacity(self.steps.len()); + let mut has_failed = false; for step in self.steps { - execution_statuses.push(Self::execute_resolved_task(step, workspace).await?); + if has_failed { + // skip executing the task and display the task name and index + let display_options = step.display_options; + execution_statuses.push(ExecutionStatus { + execution_id: Uuid::new_v4().to_string(), + pre_execution_status: PreExecutionStatus { + display_command: get_display_command(display_options, &step), + task: step, + cache_status: CacheStatus::CacheMiss(CacheMiss::NotFound), + display_options, + }, + execution_result: Err(ExecutionFailure::SkippedDueToFailedDependency), + }); + continue; + } + + let status = Self::execute_resolved_task(step, workspace).await?; + if let Ok(exit_status) = status.execution_result { + if exit_status != 0 { + has_failed = true; + } + } + execution_statuses.push(status); } Ok(ExecutionSummary { execution_statuses }) } diff --git a/packages/cli/snap-tests/fail-fast/failure.js b/packages/cli/snap-tests/fail-fast/failure.js new file mode 100644 index 0000000000..4ea3e5e02e --- /dev/null +++ b/packages/cli/snap-tests/fail-fast/failure.js @@ -0,0 +1,2 @@ +console.log('failure'); +process.exit(1); diff --git a/packages/cli/snap-tests/fail-fast/package.json b/packages/cli/snap-tests/fail-fast/package.json new file mode 100644 index 0000000000..50295b344b --- /dev/null +++ b/packages/cli/snap-tests/fail-fast/package.json @@ -0,0 +1,10 @@ +{ + "scripts": { + "ready": "vite run test && vite run script4", + "test": "vite run script1 && vite run script2 && vite run script3", + "script1": "echo 'success 1'", + "script2": "node failure.js", + "script3": "echo 'success 3'", + "script4": "echo 'success 4'" + } +} diff --git a/packages/cli/snap-tests/fail-fast/snap.txt b/packages/cli/snap-tests/fail-fast/snap.txt new file mode 100644 index 0000000000..eebf0e3cbf --- /dev/null +++ b/packages/cli/snap-tests/fail-fast/snap.txt @@ -0,0 +1,61 @@ +[1]> vite run test # skip script3 when script2 failed +$ echo 'success 1' +success 1 + + +$ node failure.js +failure + + + +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + Vite+ Task Runner • Execution Summary +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +Statistics: 3 tasks • 0 cache hits • 3 cache misses • 1 failed +Performance: 0% cache hit rate + +Task Details: +──────────────────────────────────────────────── + [1] script1: $ echo 'success 1' ✓ + → Cache miss: no previous cache entry found + ······················································· + [2] script2: $ node failure.js ✗ (exit code: 1) + → Cache miss: no previous cache entry found + ······················································· + [3] test: $ vite run script3 ⊘ (skipped: dependency failed) + → Cache miss: no previous cache entry found +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +[1]> vite run ready # support nested tasks +$ echo 'success 1' (✓ cache hit, replaying) +success 1 + + +$ node failure.js +failure + + + + +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + Vite+ Task Runner • Execution Summary +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +Statistics: 4 tasks • 1 cache hits • 3 cache misses • 1 failed +Performance: 25% cache hit rate, ms saved in total + +Task Details: +──────────────────────────────────────────────── + [1] script1: $ echo 'success 1' ✓ + → Cache hit - output replayed - ms saved + ······················································· + [2] script2: $ node failure.js ✗ (exit code: 1) + → Cache miss: no previous cache entry found + ······················································· + [3] test: $ vite run script3 ⊘ (skipped: dependency failed) + → Cache miss: no previous cache entry found + ······················································· + [4] ready: $ vite run script4 ⊘ (skipped: dependency failed) + → Cache miss: no previous cache entry found +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ diff --git a/packages/cli/snap-tests/fail-fast/steps.json b/packages/cli/snap-tests/fail-fast/steps.json new file mode 100644 index 0000000000..f7c32510ad --- /dev/null +++ b/packages/cli/snap-tests/fail-fast/steps.json @@ -0,0 +1,9 @@ +{ + "env": { + "VITE_DISABLE_AUTO_INSTALL": "1" + }, + "commands": [ + "vite run test # skip script3 when script2 failed", + "vite run ready # support nested tasks" + ] +}