Skip to content

Commit 1ee0066

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 ef34388 commit 1ee0066

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
}
@@ -175,6 +179,7 @@ impl<W: Write> LabeledReporter<W> {
175179
self.executions.push(ExecutionInfo {
176180
display: None,
177181
cache_status,
182+
cache_update_status: None,
178183
exit_status: None,
179184
error_message: None,
180185
});
@@ -217,6 +222,7 @@ impl<W: Write> LabeledReporter<W> {
217222
self.executions.push(ExecutionInfo {
218223
display: Some(display),
219224
cache_status,
225+
cache_update_status: None,
220226
exit_status: None,
221227
error_message: None,
222228
});
@@ -244,17 +250,23 @@ impl<W: Write> LabeledReporter<W> {
244250
self.stats.failed += 1;
245251
}
246252

247-
fn handle_finish(&mut self, execution_id: ExecutionId, status: Option<i32>) {
253+
fn handle_finish(
254+
&mut self,
255+
execution_id: ExecutionId,
256+
status: Option<i32>,
257+
cache_update_status: CacheUpdateStatus,
258+
) {
248259
// Update failure statistics
249260
if let Some(s) = status {
250261
if s != 0 {
251262
self.stats.failed += 1;
252263
}
253264
}
254265

255-
// Update execution info exit status
266+
// Update execution info
256267
if let Some(exec) = self.executions.last_mut() {
257268
exec.exit_status = status;
269+
exec.cache_update_status = Some(cache_update_status);
258270
}
259271

260272
// Add a line break after each task's output for better readability
@@ -433,6 +445,14 @@ impl<W: Write> LabeledReporter<W> {
433445
};
434446
let _ = writeln!(self.writer, " {}", styled_summary);
435447

448+
// Cache update status (only shown for NonZeroExitStatus)
449+
if let Some(ref cache_update_status) = exec.cache_update_status {
450+
if let Some(update_msg) = format_cache_update_status(cache_update_status) {
451+
let _ =
452+
writeln!(self.writer, " {}", update_msg.style(Style::new().yellow()));
453+
}
454+
}
455+
436456
// Error message if present
437457
if let Some(ref error_msg) = exec.error_message {
438458
let _ = writeln!(
@@ -489,8 +509,8 @@ impl<W: Write> Reporter for LabeledReporter<W> {
489509
ExecutionEventKind::Error { message } => {
490510
self.handle_error(event.execution_id, message);
491511
}
492-
ExecutionEventKind::Finish { status, cache_update_status: _ } => {
493-
self.handle_finish(event.execution_id, status);
512+
ExecutionEventKind::Finish { status, cache_update_status } => {
513+
self.handle_finish(event.execution_id, status, cache_update_status);
494514
}
495515
}
496516
}
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)