diff --git a/crates/vite_task/src/cache.rs b/crates/vite_task/src/cache.rs index 4c0387c0b5..e74123c714 100644 --- a/crates/vite_task/src/cache.rs +++ b/crates/vite_task/src/cache.rs @@ -1,8 +1,8 @@ -use std::{fmt::Display, io::Write, sync::Arc}; +use std::{fmt::Display, io::Write, sync::Arc, time::Duration}; // use bincode::config::{Configuration, standard}; use bincode::{Decode, Encode, decode_from_slice, encode_to_vec}; -use rusqlite::{Connection, OptionalExtension as _}; +use rusqlite::{Connection, OptionalExtension as _, config::DbConfig}; use serde::{Deserialize, Serialize}; use tokio::sync::Mutex; use vite_path::{AbsolutePath, AbsolutePathBuf}; @@ -22,6 +22,7 @@ use crate::{ pub struct CommandCacheValue { pub post_run_fingerprint: PostRunFingerprint, pub std_outputs: Arc<[StdOutput]>, + pub duration: Duration, } impl CommandCacheValue { @@ -31,7 +32,11 @@ impl CommandCacheValue { base_dir: &AbsolutePath, ) -> Result { let post_run_fingerprint = PostRunFingerprint::create(&executed_task, fs, base_dir)?; - Ok(Self { post_run_fingerprint, std_outputs: executed_task.std_outputs }) + Ok(Self { + post_run_fingerprint, + std_outputs: executed_task.std_outputs, + duration: executed_task.duration, + }) } } @@ -86,7 +91,7 @@ impl TaskCache { let db_path = path.join("cache.db"); let conn = Connection::open(db_path.as_path())?; - conn.execute_batch("PRAGMA journal_mode=WAL; BEGIN EXCLUSIVE;")?; + conn.execute_batch("PRAGMA journal_mode=WAL;")?; loop { let user_version: u32 = conn.query_one("PRAGMA user_version", (), |row| row.get(0))?; match user_version { @@ -100,13 +105,18 @@ impl TaskCache { "CREATE TABLE taskrun_to_command (key BLOB PRIMARY KEY, value BLOB);", (), )?; - conn.execute("PRAGMA user_version = 1", ())?; + conn.execute("PRAGMA user_version = 2", ())?; } - 1 => break, // current version - 2.. => return Err(Error::UnrecognizedDbVersion(user_version)), + 1 => { + // old internal db version. reset + conn.set_db_config(DbConfig::SQLITE_DBCONFIG_RESET_DATABASE, true)?; + conn.execute("VACUUM", ())?; + conn.set_db_config(DbConfig::SQLITE_DBCONFIG_RESET_DATABASE, false)?; + } + 2 => break, // current version + 3.. => return Err(Error::UnrecognizedDbVersion(user_version)), } } - conn.execute_batch("COMMIT")?; Ok(Self { conn: Mutex::new(conn), path: cache_path }) } diff --git a/crates/vite_task/src/execute.rs b/crates/vite_task/src/execute.rs index 6e97dfb3cc..df1c763033 100644 --- a/crates/vite_task/src/execute.rs +++ b/crates/vite_task/src/execute.rs @@ -5,6 +5,7 @@ use std::{ path::PathBuf, process::{ExitStatus, Stdio}, sync::{Arc, LazyLock, Mutex}, + time::{Duration, Instant}, }; use bincode::{Decode, Encode}; @@ -53,6 +54,7 @@ pub struct ExecutedTask { pub exit_status: ExitStatus, pub path_reads: HashMap, pub path_writes: HashMap, + pub duration: Duration, } /// Collects stdout/stderr into `outputs` and at the same time writes them to the real stdout/stderr @@ -371,17 +373,24 @@ pub async fn execute_task( let child_stderr = child.stderr.take().unwrap(); let outputs = Mutex::new(Vec::::new()); - let ((), (), exit_status) = try_join3( + + let ((), (), (exit_status, duration)) = try_join3( collect_std_outputs(&outputs, child_stdout, OutputKind::StdOut), collect_std_outputs(&outputs, child_stderr, OutputKind::StdErr), - async move { Ok(child.wait().await?) }, + async move { + let start = Instant::now(); + let exit_status = child.wait().await?; + Ok((exit_status, start.elapsed())) + }, ) .await?; + return Ok(ExecutedTask { std_outputs: outputs.into_inner().unwrap().into(), exit_status, path_reads: HashMap::new(), path_writes: HashMap::new(), + duration, }); } let mut cmd = spy.new_command(&task_parsed_command.program); @@ -451,11 +460,15 @@ pub async fn execute_task( Ok::<_, Error>((path_reads, path_writes)) }; - let ((), (), (path_reads, path_writes), exit_status) = try_join4( + let ((), (), (path_reads, path_writes), (exit_status, duration)) = try_join4( collect_std_outputs(&outputs, child_stdout, OutputKind::StdOut), collect_std_outputs(&outputs, child_stderr, OutputKind::StdErr), path_accesses_fut, - async move { Ok(child.wait().await?) }, + async move { + let start = Instant::now(); + let exit_status = child.wait().await?; + Ok((exit_status, start.elapsed())) + }, ) .await?; @@ -470,7 +483,7 @@ pub async fn execute_task( // let input_paths = gather_inputs(task, base_dir)?; - Ok(ExecutedTask { std_outputs: outputs.into(), exit_status, path_reads, path_writes }) + Ok(ExecutedTask { std_outputs: outputs.into(), exit_status, path_reads, path_writes, duration }) } #[expect(dead_code)] diff --git a/crates/vite_task/src/schedule.rs b/crates/vite_task/src/schedule.rs index 365fa6f3a8..8ddde3cf5d 100644 --- a/crates/vite_task/src/schedule.rs +++ b/crates/vite_task/src/schedule.rs @@ -1,4 +1,4 @@ -use std::{process::ExitStatus, sync::Arc}; +use std::{process::ExitStatus, sync::Arc, time::Duration}; use futures_core::future::BoxFuture; use futures_util::future::FutureExt as _; @@ -39,7 +39,10 @@ pub enum CacheStatus { /// The task will be executed. CacheMiss(CacheMiss), /// Cache hit, will replay - CacheHit, + CacheHit { + /// Duration of the original execution + original_duration: Duration, + }, } /// Status of a task execution @@ -184,7 +187,7 @@ async fn get_cached_or_execute<'a>( ) -> Result<(CacheStatus, BoxFuture<'a, Result>), Error> { Ok(match cache.try_hit(&task, fs, base_dir).await? { Ok(cache_task) => ( - CacheStatus::CacheHit, + CacheStatus::CacheHit { original_duration: cache_task.duration }, ({ async move { if task.display_options.ignore_replay { diff --git a/crates/vite_task/src/ui.rs b/crates/vite_task/src/ui.rs index bbf0f02615..7ff9936109 100644 --- a/crates/vite_task/src/ui.rs +++ b/crates/vite_task/src/ui.rs @@ -1,4 +1,4 @@ -use std::{fmt::Display, sync::LazyLock}; +use std::{fmt::Display, sync::LazyLock, time::Duration}; use itertools::Itertools; use owo_colors::{Style, Styled}; @@ -101,7 +101,7 @@ impl Display for PreExecutionStatus { .style(CACHE_MISS_STYLE.dimmed()) )?; } - CacheStatus::CacheHit => { + CacheStatus::CacheHit { .. } => { if !self.display_options.ignore_replay { if let Some(display_command) = &display_command { write!(f, "{} ", display_command)?; @@ -141,7 +141,7 @@ impl Display for ExecutionSummary { for status in &self.execution_statuses { match &status.pre_execution_status.cache_status { - CacheStatus::CacheHit => cache_hits += 1, + CacheStatus::CacheHit { .. } => cache_hits += 1, CacheStatus::CacheMiss(_) => cache_misses += 1, } @@ -191,11 +191,25 @@ impl Display for ExecutionSummary { let cache_rate = if total > 0 { (cache_hits as f64 / total as f64 * 100.0) as u32 } else { 0 }; - writeln!( + let total_duration = self + .execution_statuses + .iter() + .map(|status| { + if let CacheStatus::CacheHit { original_duration } = + &status.pre_execution_status.cache_status + { + *original_duration + } else { + Duration::ZERO + } + }) + .sum::(); + + write!( f, - "{} {}% cache hit rate", + "{} {} cache hit rate", "Performance:".style(Style::new().bold()), - cache_rate.to_string().style(if cache_rate >= 75 { + format_args!("{}%", cache_rate).style(if cache_rate >= 75 { Style::new().green().bold() } else if cache_rate >= 50 { CACHE_MISS_STYLE @@ -203,6 +217,14 @@ impl Display for ExecutionSummary { Style::new().red() }) )?; + if total_duration > Duration::ZERO { + write!( + f, + ", {:.2?} saved in total", + total_duration.style(Style::new().green().bold()) + )?; + } + writeln!(f)?; writeln!(f)?; // Detailed task results @@ -254,11 +276,12 @@ impl Display for ExecutionSummary { // Cache status details (indented) match &status.pre_execution_status.cache_status { - CacheStatus::CacheHit => { + CacheStatus::CacheHit { original_duration } => { writeln!( f, - " {}", + " {} {}", "→ Cache hit - output replayed".style(Style::new().green()), + format!("- {:.2?} saved", original_duration).style(Style::new().green()) )?; } CacheStatus::CacheMiss(miss) => { diff --git a/packages/cli/snap-tests/associate-existing-cache/snap.txt b/packages/cli/snap-tests/associate-existing-cache/snap.txt index 74ba783a39..cc097c5347 100644 --- a/packages/cli/snap-tests/associate-existing-cache/snap.txt +++ b/packages/cli/snap-tests/associate-existing-cache/snap.txt @@ -26,12 +26,12 @@ hello ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Statistics: 1 tasks • 1 cache hits • 0 cache misses -Performance: 100% cache hit rate +Performance: 100% cache hit rate, ms saved in total Task Details: ──────────────────────────────────────────────── [1] script2: $ echo hello ✓ - → Cache hit - output replayed + → Cache hit - output replayed - ms saved ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ > json-edit package.json '_.scripts.script2 = "echo world"' # update the command of script2 diff --git a/packages/cli/snap-tests/cache-clean/snap.txt b/packages/cli/snap-tests/cache-clean/snap.txt index 5c9bb144ce..562a6fac63 100644 --- a/packages/cli/snap-tests/cache-clean/snap.txt +++ b/packages/cli/snap-tests/cache-clean/snap.txt @@ -26,12 +26,12 @@ hello ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Statistics: 1 tasks • 1 cache hits • 0 cache misses -Performance: 100% cache hit rate +Performance: 100% cache hit rate, ms saved in total Task Details: ──────────────────────────────────────────────── [1] hello: $ echo hello ✓ - → Cache hit - output replayed + → Cache hit - output replayed - ms saved ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ > vite cache clean # clean the cache diff --git a/packages/cli/snap-tests/cache-miss-command-change/snap.txt b/packages/cli/snap-tests/cache-miss-command-change/snap.txt index 33647c7116..37aa739790 100644 --- a/packages/cli/snap-tests/cache-miss-command-change/snap.txt +++ b/packages/cli/snap-tests/cache-miss-command-change/snap.txt @@ -36,7 +36,7 @@ bar ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Statistics: 2 tasks • 1 cache hits • 1 cache misses -Performance: 50% cache hit rate +Performance: 50% cache hit rate, ms saved in total Task Details: ──────────────────────────────────────────────── @@ -44,7 +44,7 @@ Task Details: → Cache miss: command changed from echo foo to echo baz ······················································· [2] hello: $ echo bar ✓ - → Cache hit - output replayed + → Cache hit - output replayed - ms saved ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ > json-edit package.json '_.scripts.hello = "echo bar"' # remove the first subcommand, now the second subcommand becomes the first @@ -58,10 +58,10 @@ bar ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Statistics: 1 tasks • 1 cache hits • 0 cache misses -Performance: 100% cache hit rate +Performance: 100% cache hit rate, ms saved in total Task Details: ──────────────────────────────────────────────── [1] hello: $ echo bar ✓ - → Cache hit - output replayed + → Cache hit - output replayed - ms saved ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ diff --git a/packages/cli/snap-tests/change-passthrough-env-config/snap.txt b/packages/cli/snap-tests/change-passthrough-env-config/snap.txt index ff3aa3fba5..42377f1a7f 100644 --- a/packages/cli/snap-tests/change-passthrough-env-config/snap.txt +++ b/packages/cli/snap-tests/change-passthrough-env-config/snap.txt @@ -26,12 +26,12 @@ $ node -p process.env.MY_ENV (✓ cache hit, replaying) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Statistics: 1 tasks • 1 cache hits • 0 cache misses -Performance: 100% cache hit rate +Performance: 100% cache hit rate, ms saved in total Task Details: ──────────────────────────────────────────────── [1] hello: $ node -p process.env.MY_ENV ✓ - → Cache hit - output replayed + → Cache hit - output replayed - ms saved ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ > json-edit vite-task.json '_.tasks.hello.passThroughEnvs.push("MY_ENV2")' # add a new pass through env diff --git a/packages/cli/snap-tests/exit-code/snap.txt b/packages/cli/snap-tests/exit-code/snap.txt index 8c0fd54ff7..7cf162e23d 100644 --- a/packages/cli/snap-tests/exit-code/snap.txt +++ b/packages/cli/snap-tests/exit-code/snap.txt @@ -26,12 +26,12 @@ success ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Statistics: 1 tasks • 1 cache hits • 0 cache misses -Performance: 100% cache hit rate +Performance: 100% cache hit rate, ms saved in total Task Details: ──────────────────────────────────────────────── [1] script1: $ echo success ✓ - → Cache hit - output replayed + → Cache hit - output replayed - ms saved ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ [1]> vite run script2 # script2 should be failure and not cache diff --git a/packages/cli/snap-tests/individual-cache-for-adt-args/snap.txt b/packages/cli/snap-tests/individual-cache-for-adt-args/snap.txt index c5869f08e3..b6a79b732c 100644 --- a/packages/cli/snap-tests/individual-cache-for-adt-args/snap.txt +++ b/packages/cli/snap-tests/individual-cache-for-adt-args/snap.txt @@ -44,12 +44,12 @@ a ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Statistics: 1 tasks • 1 cache hits • 0 cache misses -Performance: 100% cache hit rate +Performance: 100% cache hit rate, ms saved in total Task Details: ──────────────────────────────────────────────── [1] echo: $ echo a ✓ - → Cache hit - output replayed + → Cache hit - output replayed - ms saved ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ > vite run echo -- b # should hit the cache created in step 2 @@ -62,10 +62,10 @@ b ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Statistics: 1 tasks • 1 cache hits • 0 cache misses -Performance: 100% cache hit rate +Performance: 100% cache hit rate, ms saved in total Task Details: ──────────────────────────────────────────────── [1] echo: $ echo b ✓ - → Cache hit - output replayed + → Cache hit - output replayed - ms saved ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ diff --git a/packages/cli/snap-tests/individual-cache-for-envs/snap.txt b/packages/cli/snap-tests/individual-cache-for-envs/snap.txt index a1c5d8e925..878310fccd 100644 --- a/packages/cli/snap-tests/individual-cache-for-envs/snap.txt +++ b/packages/cli/snap-tests/individual-cache-for-envs/snap.txt @@ -44,12 +44,12 @@ $ node -p process.env.FOO (✓ cache hit, replaying) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Statistics: 1 tasks • 1 cache hits • 0 cache misses -Performance: 100% cache hit rate +Performance: 100% cache hit rate, ms saved in total Task Details: ──────────────────────────────────────────────── [1] hello: $ node -p process.env.FOO ✓ - → Cache hit - output replayed + → Cache hit - output replayed - ms saved ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ > FOO=2 vite run hello # hit cache created in step 2 @@ -62,10 +62,10 @@ $ node -p process.env.FOO (✓ cache hit, replaying) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Statistics: 1 tasks • 1 cache hits • 0 cache misses -Performance: 100% cache hit rate +Performance: 100% cache hit rate, ms saved in total Task Details: ──────────────────────────────────────────────── [1] hello: $ node -p process.env.FOO ✓ - → Cache hit - output replayed + → Cache hit - output replayed - ms saved ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ diff --git a/packages/cli/snap-tests/plain-terminal-ui-nested/snap.txt b/packages/cli/snap-tests/plain-terminal-ui-nested/snap.txt index d6ba9492e8..1ba14ec05b 100644 --- a/packages/cli/snap-tests/plain-terminal-ui-nested/snap.txt +++ b/packages/cli/snap-tests/plain-terminal-ui-nested/snap.txt @@ -44,12 +44,12 @@ Finished in ms on 2 files with rules using threa ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Statistics: 2 tasks • 1 cache hits • 1 cache misses -Performance: 50% cache hit rate +Performance: 50% cache hit rate, ms saved in total Task Details: ──────────────────────────────────────────────── [1] lint: $ vite lint ./src ✓ - → Cache hit - output replayed + → Cache hit - output replayed - ms saved ······················································· [2] lint: $ vite lint ✓ → Cache miss: content of input 'a.ts' changed diff --git a/packages/cli/snap-tests/plain-terminal-ui/snap.txt b/packages/cli/snap-tests/plain-terminal-ui/snap.txt index 4601e48b41..a2a4a2f7d4 100644 --- a/packages/cli/snap-tests/plain-terminal-ui/snap.txt +++ b/packages/cli/snap-tests/plain-terminal-ui/snap.txt @@ -26,12 +26,12 @@ input_content 1 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Statistics: 1 tasks • 1 cache hits • 0 cache misses -Performance: 100% cache hit rate +Performance: 100% cache hit rate, ms saved in total Task Details: ──────────────────────────────────────────────── [1] root-package#hello: $ node hello.mjs ✓ - → Cache hit - output replayed + → Cache hit - output replayed - ms saved ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ > FOO=2 vite run hello # env changed diff --git a/packages/cli/snap-tests/replay-logs-chronological-order/snap.txt b/packages/cli/snap-tests/replay-logs-chronological-order/snap.txt index b260bf9ac8..62d3566d32 100644 --- a/packages/cli/snap-tests/replay-logs-chronological-order/snap.txt +++ b/packages/cli/snap-tests/replay-logs-chronological-order/snap.txt @@ -210,12 +210,12 @@ $ node build.js (✓ cache hit, replaying) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Statistics: 1 tasks • 1 cache hits • 0 cache misses -Performance: 100% cache hit rate +Performance: 100% cache hit rate, ms saved in total Task Details: ──────────────────────────────────────────────── [1] @test/replay-logs-chronological-order#build: $ node build.js ✓ - → Cache hit - output replayed + → Cache hit - output replayed - ms saved ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ > vite run build 2>&1 # should hit the cache and make sure the replay order is chronological @@ -320,12 +320,12 @@ $ node build.js (✓ cache hit, replaying) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Statistics: 1 tasks • 1 cache hits • 0 cache misses -Performance: 100% cache hit rate +Performance: 100% cache hit rate, ms saved in total Task Details: ──────────────────────────────────────────────── [1] @test/replay-logs-chronological-order#build: $ node build.js ✓ - → Cache hit - output replayed + → Cache hit - output replayed - ms saved ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ > vite run build 2>&1 # should hit the cache and make sure the replay order is chronological again @@ -430,12 +430,12 @@ $ node build.js (✓ cache hit, replaying) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Statistics: 1 tasks • 1 cache hits • 0 cache misses -Performance: 100% cache hit rate +Performance: 100% cache hit rate, ms saved in total Task Details: ──────────────────────────────────────────────── [1] @test/replay-logs-chronological-order#build: $ node build.js ✓ - → Cache hit - output replayed + → Cache hit - output replayed - ms saved ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ > vite run build 2>&1 # should hit the cache and make sure the replay order is chronological again @@ -540,10 +540,10 @@ $ node build.js (✓ cache hit, replaying) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Statistics: 1 tasks • 1 cache hits • 0 cache misses -Performance: 100% cache hit rate +Performance: 100% cache hit rate, ms saved in total Task Details: ──────────────────────────────────────────────── [1] @test/replay-logs-chronological-order#build: $ node build.js ✓ - → Cache hit - output replayed + → Cache hit - output replayed - ms saved ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ diff --git a/packages/cli/snap-tests/same-name-as-builtin/snap.txt b/packages/cli/snap-tests/same-name-as-builtin/snap.txt index 64b7cd4858..b73b2dc2a5 100644 --- a/packages/cli/snap-tests/same-name-as-builtin/snap.txt +++ b/packages/cli/snap-tests/same-name-as-builtin/snap.txt @@ -38,10 +38,10 @@ lint script ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Statistics: 1 tasks • 1 cache hits • 0 cache misses -Performance: 100% cache hit rate +Performance: 100% cache hit rate, ms saved in total Task Details: ──────────────────────────────────────────────── [1] lint: $ echo lint script ✓ - → Cache hit - output replayed + → Cache hit - output replayed - ms saved ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ diff --git a/packages/cli/snap-tests/shared-caching-inputs/snap.txt b/packages/cli/snap-tests/shared-caching-inputs/snap.txt index 4d942170ad..bd1cf6fbee 100644 --- a/packages/cli/snap-tests/shared-caching-inputs/snap.txt +++ b/packages/cli/snap-tests/shared-caching-inputs/snap.txt @@ -26,12 +26,12 @@ bar ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Statistics: 1 tasks • 1 cache hits • 0 cache misses -Performance: 100% cache hit rate +Performance: 100% cache hit rate, ms saved in total Task Details: ──────────────────────────────────────────────── [1] script2: $ cat foo.txt ✓ - → Cache hit - output replayed + → Cache hit - output replayed - ms saved ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ > echo baz > foo.txt # change the input file to invalidate the cache @@ -63,10 +63,10 @@ baz ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Statistics: 1 tasks • 1 cache hits • 0 cache misses -Performance: 100% cache hit rate +Performance: 100% cache hit rate, ms saved in total Task Details: ──────────────────────────────────────────────── [1] script1: $ cat foo.txt ✓ - → Cache hit - output replayed + → Cache hit - output replayed - ms saved ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ diff --git a/packages/cli/snap-tests/test-nested-tasks/snap.txt b/packages/cli/snap-tests/test-nested-tasks/snap.txt index da6f546cf9..e8a7bb2c92 100644 --- a/packages/cli/snap-tests/test-nested-tasks/snap.txt +++ b/packages/cli/snap-tests/test-nested-tasks/snap.txt @@ -27,10 +27,10 @@ hello vite ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Statistics: 1 tasks • 1 cache hits • 0 cache misses -Performance: 100% cache hit rate +Performance: 100% cache hit rate, ms saved in total Task Details: ──────────────────────────────────────────────── [1] script1: $ echo 'hello vite' ✓ - → Cache hit - output replayed + → Cache hit - output replayed - ms saved ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ diff --git a/packages/tools/src/utils.ts b/packages/tools/src/utils.ts index 6c90473254..5720726aa9 100644 --- a/packages/tools/src/utils.ts +++ b/packages/tools/src/utils.ts @@ -10,7 +10,7 @@ export function replaceUnstableOutput(output: string, cwd?: string) { // date .replaceAll(/\d{2}:\d{2}:\d{2}/g, '') // oxlint - .replaceAll(/\d+(?:\.\d+)?s|\d+ms/g, 'ms') + .replaceAll(/\d+(?:\.\d+)?(?:s|ms)/g, 'ms') .replaceAll(/with \d+ rules/g, 'with rules') .replaceAll(/using \d+ threads/g, 'using threads') // pnpm