Skip to content

Commit 183333e

Browse files
committed
feat(cache): disable cache if there was user input
# Conflicts: # crates/vite_task_bin/tests/e2e_snapshots/fixtures/exit-codes/snapshots/multiple task failures returns exit code 1.snap # crates/vite_task_bin/tests/e2e_snapshots/fixtures/exit-codes/snapshots/single task failure returns task exit code.snap
1 parent 58dbb1c commit 183333e

File tree

10 files changed

+117
-10
lines changed

10 files changed

+117
-10
lines changed

crates/vite_task/src/session/cache/display.rs

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ use std::collections::HashSet;
88
use vite_task_plan::cache_metadata::SpawnFingerprint;
99

1010
use super::{CacheMiss, FingerprintMismatch};
11-
use crate::session::event::{CacheDisabledReason, CacheStatus};
11+
use crate::session::event::{
12+
CacheDisabledReason, CacheNotUpdatedReason, CacheStatus, CacheUpdateStatus,
13+
};
1214

1315
/// Describes a single atomic change between two spawn fingerprints
1416
enum SpawnFingerprintChange {
@@ -283,3 +285,29 @@ pub fn format_cache_status_summary(cache_status: &CacheStatus) -> String {
283285
}
284286
}
285287
}
288+
289+
/// Format cache update status for summary display (post-execution).
290+
///
291+
/// Returns Some(formatted_string) only when the reason is not already clear from CacheStatus.
292+
/// - Updated: No message needed (success is implied)
293+
/// - CacheHit: No message needed (already shown in CacheStatus::Hit)
294+
/// - CacheDisabled: No message needed (already shown in CacheStatus::Disabled)
295+
/// - BuiltInCommand: No message needed (already shown in CacheStatus::Disabled(InProcessExecution))
296+
/// - NonZeroExitStatus: Shows message that cache wasn't updated due to failure
297+
///
298+
/// Note: Returns plain text without styling. The reporter applies colors.
299+
pub fn format_cache_update_status(status: &CacheUpdateStatus) -> Option<String> {
300+
match status {
301+
CacheUpdateStatus::Updated => None,
302+
CacheUpdateStatus::NotUpdated(reason) => match reason {
303+
// These are already clear from CacheStatus in the Start event
304+
CacheNotUpdatedReason::CacheHit => None,
305+
CacheNotUpdatedReason::CacheDisabled => None,
306+
CacheNotUpdatedReason::BuiltInCommand => None,
307+
// This needs to be shown - task failed so cache wasn't updated
308+
CacheNotUpdatedReason::NonZeroExitStatus => {
309+
Some("→ Cache not updated: task failed".to_string())
310+
}
311+
},
312+
}
313+
}

crates/vite_task/src/session/cache/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ use std::{fmt::Display, fs::File, io::Write, sync::Arc, time::Duration};
66

77
use bincode::{Decode, Encode, decode_from_slice, encode_to_vec};
88
// Re-export display functions for convenience
9-
pub use display::{format_cache_status_inline, format_cache_status_summary};
9+
pub use display::{
10+
format_cache_status_inline, format_cache_status_summary, format_cache_update_status,
11+
};
1012
use rusqlite::{Connection, OptionalExtension as _, config::DbConfig};
1113
use serde::{Deserialize, Serialize};
1214
use tokio::sync::Mutex;

crates/vite_task/src/session/event.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ pub enum CacheNotUpdatedReason {
2727
CacheDisabled,
2828
/// Execution exited with non-zero status
2929
NonZeroExitStatus,
30+
/// Built-in command doesn't support caching
31+
BuiltInCommand,
3032
}
3133

3234
#[derive(Debug)]

crates/vite_task/src/session/execute/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,13 +153,13 @@ impl ExecutionContext<'_> {
153153
},
154154
});
155155

156-
// Emit Finish with CacheDisabled status (in-process executions don't cache)
156+
// Emit Finish with BuiltInCommand status (built-in commands don't cache)
157157
self.event_handler.handle_event(ExecutionEvent {
158158
execution_id,
159159
kind: ExecutionEventKind::Finish {
160160
status: Some(0),
161161
cache_update_status: CacheUpdateStatus::NotUpdated(
162-
CacheNotUpdatedReason::CacheDisabled,
162+
CacheNotUpdatedReason::BuiltInCommand,
163163
),
164164
},
165165
});

crates/vite_task/src/session/reporter.rs

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,11 @@ use owo_colors::{Style, Styled};
1111
use vite_path::AbsolutePath;
1212

1313
use super::{
14-
cache::{format_cache_status_inline, format_cache_status_summary},
15-
event::{CacheStatus, ExecutionEvent, ExecutionEventKind, ExecutionId, ExecutionItemDisplay},
14+
cache::{format_cache_status_inline, format_cache_status_summary, format_cache_update_status},
15+
event::{
16+
CacheStatus, CacheUpdateStatus, ExecutionEvent, ExecutionEventKind, ExecutionId,
17+
ExecutionItemDisplay,
18+
},
1619
};
1720

1821
/// Wrap of `OwoColorize` that ignores style if `NO_COLOR` is set.
@@ -55,6 +58,7 @@ const CACHE_MISS_STYLE: Style = Style::new().purple();
5558
struct ExecutionInfo {
5659
display: Option<ExecutionItemDisplay>,
5760
cache_status: CacheStatus, // Non-optional, determined at Start
61+
cache_update_status: Option<CacheUpdateStatus>, // Set at Finish
5862
exit_status: Option<i32>,
5963
error_message: Option<String>,
6064
}
@@ -157,6 +161,7 @@ impl<W: Write> LabeledReporter<W> {
157161
self.executions.push(ExecutionInfo {
158162
display: None,
159163
cache_status,
164+
cache_update_status: None,
160165
exit_status: None,
161166
error_message: None,
162167
});
@@ -199,6 +204,7 @@ impl<W: Write> LabeledReporter<W> {
199204
self.executions.push(ExecutionInfo {
200205
display: Some(display),
201206
cache_status,
207+
cache_update_status: None,
202208
exit_status: None,
203209
error_message: None,
204210
});
@@ -226,17 +232,23 @@ impl<W: Write> LabeledReporter<W> {
226232
self.stats.failed += 1;
227233
}
228234

229-
fn handle_finish(&mut self, execution_id: ExecutionId, status: Option<i32>) {
235+
fn handle_finish(
236+
&mut self,
237+
execution_id: ExecutionId,
238+
status: Option<i32>,
239+
cache_update_status: CacheUpdateStatus,
240+
) {
230241
// Update failure statistics
231242
if let Some(s) = status {
232243
if s != 0 {
233244
self.stats.failed += 1;
234245
}
235246
}
236247

237-
// Update execution info exit status
248+
// Update execution info
238249
if let Some(exec) = self.executions.last_mut() {
239250
exec.exit_status = status;
251+
exec.cache_update_status = Some(cache_update_status);
240252
}
241253

242254
// For direct synthetic execution with cache hit, print message at the bottom
@@ -430,6 +442,14 @@ impl<W: Write> LabeledReporter<W> {
430442
};
431443
let _ = writeln!(self.writer, " {}", styled_summary);
432444

445+
// Cache update status (only shown for NonZeroExitStatus)
446+
if let Some(ref cache_update_status) = exec.cache_update_status {
447+
if let Some(update_msg) = format_cache_update_status(cache_update_status) {
448+
let _ =
449+
writeln!(self.writer, " {}", update_msg.style(Style::new().yellow()));
450+
}
451+
}
452+
433453
// Error message if present
434454
if let Some(ref error_msg) = exec.error_message {
435455
let _ = writeln!(
@@ -486,8 +506,8 @@ impl<W: Write> Reporter for LabeledReporter<W> {
486506
ExecutionEventKind::Error { message } => {
487507
self.handle_error(event.execution_id, message);
488508
}
489-
ExecutionEventKind::Finish { status, cache_update_status: _ } => {
490-
self.handle_finish(event.execution_id, status);
509+
ExecutionEventKind::Finish { status, cache_update_status } => {
510+
self.handle_finish(event.execution_id, status, cache_update_status);
491511
}
492512
}
493513
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"name": "cache-non-zero-exit-test",
3+
"scripts": {
4+
"test": "node -e \"process.exit(1)\""
5+
}
6+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[[e2e]]
2+
name = "failed task does not update cache"
3+
steps = [
4+
"vite run test",
5+
"vite run test",
6+
]
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
---
2+
source: crates/vite_task_bin/tests/e2e_snapshots/main.rs
3+
expression: e2e_outputs
4+
input_file: crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-non-zero-exit
5+
---
6+
[1]> vite run test
7+
$ node -e "process.exit(1)"
8+
9+
10+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
11+
Vite+ Task RunnerExecution Summary
12+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
13+
14+
Statistics: 1 tasks0 cache hits1 cache misses1 failed
15+
Performance: 0% cache hit rate
16+
17+
Task Details:
18+
────────────────────────────────────────────────
19+
[1] cache-non-zero-exit-test#test: $ node -e "process.exit(1)" ✗ (exit code: 1)
20+
Cache miss: no previous cache entry found
21+
Cache not updated: task failed
22+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
23+
24+
[1]> vite run test
25+
$ node -e "process.exit(1)"
26+
27+
28+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
29+
Vite+ Task RunnerExecution Summary
30+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
31+
32+
Statistics: 1 tasks0 cache hits1 cache misses1 failed
33+
Performance: 0% cache hit rate
34+
35+
Task Details:
36+
────────────────────────────────────────────────
37+
[1] cache-non-zero-exit-test#test: $ node -e "process.exit(1)" ✗ (exit code: 1)
38+
Cache miss: no previous cache entry found
39+
Cache not updated: task failed
40+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

crates/vite_task_bin/tests/e2e_snapshots/fixtures/exit-codes/snapshots/multiple task failures returns exit code 1.snap

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ Task Details:
2121
────────────────────────────────────────────────
2222
[1] pkg-b#fail: ~/packages/pkg-b$ node -e "process.exit(7)" ✗ (exit code: 7)
2323
Cache miss: no previous cache entry found
24+
Cache not updated: task failed
2425
·······················································
2526
[2] pkg-a#fail: ~/packages/pkg-a$ node -e "process.exit(42)" ✗ (exit code: 42)
2627
Cache miss: no previous cache entry found
28+
Cache not updated: task failed
2729
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

crates/vite_task_bin/tests/e2e_snapshots/fixtures/exit-codes/snapshots/single task failure returns task exit code.snap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,5 @@ Task Details:
1919
────────────────────────────────────────────────
2020
[1] pkg-a#fail: ~/packages/pkg-a$ node -e "process.exit(42)" ✗ (exit code: 42)
2121
Cache miss: no previous cache entry found
22+
Cache not updated: task failed
2223
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

0 commit comments

Comments
 (0)