From a2a7c8e5beb3929f683fee6f030271fdd5b3a695 Mon Sep 17 00:00:00 2001 From: branchseer Date: Sun, 15 Feb 2026 20:39:21 +0800 Subject: [PATCH 1/3] feat: improve stdio handling with async writers --- crates/vite_task/Cargo.toml | 2 +- crates/vite_task/src/session/event.rs | 6 - crates/vite_task/src/session/execute/mod.rs | 134 ++++++++++++------ crates/vite_task/src/session/execute/spawn.rs | 75 +++++----- crates/vite_task/src/session/mod.rs | 7 +- .../vite_task/src/session/reporter/labeled.rs | 95 ++++++------- crates/vite_task/src/session/reporter/mod.rs | 133 ++++++++++------- .../vite_task/src/session/reporter/plain.rs | 69 ++++----- .../fixtures/task-list/snapshots.toml | 2 +- .../task-list/snapshots/vp run in script.snap | 22 ++- 10 files changed, 318 insertions(+), 227 deletions(-) diff --git a/crates/vite_task/Cargo.toml b/crates/vite_task/Cargo.toml index c1224d45..14aaad7c 100644 --- a/crates/vite_task/Cargo.toml +++ b/crates/vite_task/Cargo.toml @@ -31,7 +31,7 @@ serde = { workspace = true, features = ["derive", "rc"] } serde_json = { workspace = true } smallvec.workspace = true thiserror = { workspace = true } -tokio = { workspace = true, features = ["rt-multi-thread", "io-std", "macros", "sync"] } +tokio = { workspace = true, features = ["rt-multi-thread", "io-std", "io-util", "macros", "sync"] } tracing = { workspace = true } twox-hash = { workspace = true } vite_glob = { workspace = true } diff --git a/crates/vite_task/src/session/event.rs b/crates/vite_task/src/session/event.rs index 6f997b8f..62c77687 100644 --- a/crates/vite_task/src/session/event.rs +++ b/crates/vite_task/src/session/event.rs @@ -43,12 +43,6 @@ pub enum ExecutionError { PostRunFingerprint(#[source] anyhow::Error), } -#[derive(Debug)] -pub enum OutputKind { - Stdout, - Stderr, -} - #[derive(Debug)] pub enum CacheDisabledReason { InProcessExecution, diff --git a/crates/vite_task/src/session/execute/mod.rs b/crates/vite_task/src/session/execute/mod.rs index 90c71dca..37c0d23c 100644 --- a/crates/vite_task/src/session/execute/mod.rs +++ b/crates/vite_task/src/session/execute/mod.rs @@ -4,22 +4,25 @@ pub mod spawn; use std::{process::Stdio, sync::Arc}; use futures_util::FutureExt; +use tokio::io::AsyncWriteExt as _; use vite_path::AbsolutePath; -use vite_task_plan::{ExecutionGraph, ExecutionItemKind, LeafExecutionKind, SpawnExecution}; +use vite_task_plan::{ + ExecutionGraph, ExecutionItemKind, LeafExecutionKind, SpawnCommand, SpawnExecution, +}; use self::{ fingerprint::PostRunFingerprint, - spawn::{OutputKind as SpawnOutputKind, spawn_with_tracking}, + spawn::{SpawnResult, spawn_with_tracking}, }; use super::{ cache::{CommandCacheValue, ExecutionCache}, event::{ CacheDisabledReason, CacheErrorKind, CacheNotUpdatedReason, CacheStatus, CacheUpdateStatus, - ExecutionError, OutputKind, + ExecutionError, }, reporter::{ ExitStatus, GraphExecutionReporter, GraphExecutionReporterBuilder, LeafExecutionPath, - LeafExecutionReporter, StdinSuggestion, + LeafExecutionReporter, StdioSuggestion, }, }; use crate::{Session, session::execute::spawn::SpawnTrackResult}; @@ -116,10 +119,13 @@ impl ExecutionContext<'_> { match leaf_execution_kind { LeafExecutionKind::InProcess(in_process_execution) => { // In-process (built-in) commands: caching is disabled, execute synchronously - leaf_reporter.start(CacheStatus::Disabled(CacheDisabledReason::InProcessExecution)); + let mut stdio_config = leaf_reporter + .start(CacheStatus::Disabled(CacheDisabledReason::InProcessExecution)); let execution_output = in_process_execution.execute(); - leaf_reporter.output(OutputKind::Stdout, execution_output.stdout.into()); + // Write output to the stdout writer from StdioConfig + let _ = stdio_config.stdout_writer.write_all(&execution_output.stdout).await; + let _ = stdio_config.stdout_writer.flush().await; leaf_reporter.finish( None, @@ -147,9 +153,10 @@ impl ExecutionContext<'_> { /// /// The full lifecycle is: /// 1. Cache lookup (determines cache status) -/// 2. `leaf_reporter.start(cache_status)` -/// 3. If cache hit: replay cached outputs → finish -/// 4. If cache miss/disabled: spawn process → stream output → update cache → finish +/// 2. `leaf_reporter.start(cache_status)` → `StdioConfig` +/// 3. If cache hit: replay cached outputs via `StdioConfig` writers → finish +/// 4. If `Inherited` suggestion AND caching disabled: `spawn_inherited()` → finish +/// 5. Else (piped): `spawn_with_tracking()` with writers → cache update → finish /// /// Errors (cache lookup failure, spawn failure, cache update failure) are reported /// through `leaf_reporter.finish()` and do not abort the caller. @@ -197,20 +204,20 @@ pub async fn execute_spawn( (CacheStatus::Disabled(CacheDisabledReason::NoCacheMetadata), None) }; - // 2. Report execution start with the determined cache status - leaf_reporter.start(cache_status); + // 2. Report execution start with the determined cache status. + // Returns StdioConfig with the reporter's suggestion and async writers. + let mut stdio_config = leaf_reporter.start(cache_status); - // 3. If cache hit, replay outputs and finish early. + // 3. If cache hit, replay outputs via the StdioConfig writers and finish early. // No need to actually execute the command — just replay what was cached. if let Some(cached) = cached_value { for output in cached.std_outputs.iter() { - leaf_reporter.output( - match output.kind { - SpawnOutputKind::StdOut => OutputKind::Stdout, - SpawnOutputKind::StdErr => OutputKind::Stderr, - }, - output.content.clone().into(), - ); + let writer: &mut (dyn tokio::io::AsyncWrite + Unpin) = match output.kind { + spawn::OutputKind::StdOut => &mut stdio_config.stdout_writer, + spawn::OutputKind::StdErr => &mut stdio_config.stderr_writer, + }; + let _ = writer.write_all(&output.content).await; + let _ = writer.flush().await; } leaf_reporter.finish( None, @@ -220,24 +227,44 @@ pub async fn execute_spawn( return SpawnOutcome::CacheHit; } - // 4. Execute spawn (cache miss or disabled). - // Track file system access if caching is enabled (for future cache updates). + // 4. Determine actual stdio mode based on the suggestion AND cache state. + // Inherited stdio is only used when the reporter suggests it AND caching is + // completely disabled (no cache_metadata). If caching is enabled but missed, + // we still need piped mode to capture output for the cache update. + let use_inherited = + stdio_config.suggestion == StdioSuggestion::Inherited && cache_metadata.is_none(); + + if use_inherited { + // Inherited mode: all three stdio FDs (stdin, stdout, stderr) are inherited + // from the parent process. No fspy tracking, no output capture. + // Drop the StdioConfig writers before spawning to avoid holding tokio::io::Stdout + // while the child also writes to the same FD. + drop(stdio_config); + + match spawn_inherited(&spawn_execution.spawn_command).await { + Ok(result) => { + leaf_reporter.finish( + Some(result.exit_status), + CacheUpdateStatus::NotUpdated(CacheNotUpdatedReason::CacheDisabled), + None, + ); + return SpawnOutcome::Spawned(result.exit_status); + } + Err(err) => { + leaf_reporter.finish( + None, + CacheUpdateStatus::NotUpdated(CacheNotUpdatedReason::CacheDisabled), + Some(ExecutionError::Spawn(err)), + ); + return SpawnOutcome::Failed; + } + } + } + + // 5. Piped mode: execute spawn with tracking, streaming output to writers. let mut track_result_with_cache_metadata = cache_metadata.map(|cache_metadata| (SpawnTrackResult::default(), cache_metadata)); - // Determine the child process's stdin mode based on: - // - The reporter's suggestion (inherited only when appropriate, e.g., single task) - // - Whether caching is disabled (inherited stdin would make output non-deterministic, - // breaking cache semantics) - let stdin = if leaf_reporter.stdin_suggestion() == StdinSuggestion::Inherited - && cache_metadata.is_none() - { - Stdio::inherit() - } else { - Stdio::null() - }; - - // Execute command with tracking, streaming output in real-time via the reporter #[expect( clippy::large_futures, reason = "spawn_with_tracking manages process I/O and creates a large future" @@ -245,16 +272,8 @@ pub async fn execute_spawn( let result = match spawn_with_tracking( &spawn_execution.spawn_command, cache_base_path, - stdin, - |kind, content| { - leaf_reporter.output( - match kind { - SpawnOutputKind::StdOut => OutputKind::Stdout, - SpawnOutputKind::StdErr => OutputKind::Stderr, - }, - content, - ); - }, + &mut stdio_config.stdout_writer, + &mut stdio_config.stderr_writer, track_result_with_cache_metadata.as_mut().map(|(track_result, _)| track_result), ) .await @@ -270,7 +289,7 @@ pub async fn execute_spawn( } }; - // 5. Update cache if successful and determine cache update status. + // 6. Update cache if successful and determine cache update status. // Errors during cache update are terminal (reported through finish). let (cache_update_status, cache_error) = if let Some((track_result, cache_metadata)) = track_result_with_cache_metadata @@ -315,7 +334,7 @@ pub async fn execute_spawn( (CacheUpdateStatus::NotUpdated(CacheNotUpdatedReason::CacheDisabled), None) }; - // 6. Finish the leaf execution with the result and optional cache error. + // 7. Finish the leaf execution with the result and optional cache error. // Cache update/fingerprint failures are reported but do not affect the outcome — // the process ran, so we return its actual exit status. leaf_reporter.finish(Some(result.exit_status), cache_update_status, cache_error); @@ -323,6 +342,29 @@ pub async fn execute_spawn( SpawnOutcome::Spawned(result.exit_status) } +/// Spawn a command with all three stdio file descriptors inherited from the parent. +/// +/// Used when the reporter suggests inherited stdio AND caching is disabled. +/// All three FDs (stdin, stdout, stderr) are inherited, allowing interactive input +/// and direct terminal output. No fspy tracking is performed since there's no +/// cache to update. +/// +/// The child process will see `is_terminal() == true` for stdout/stderr when the +/// parent is running in a terminal. This is expected behavior. +async fn spawn_inherited(spawn_command: &SpawnCommand) -> anyhow::Result { + let mut cmd = fspy::Command::new(spawn_command.program_path.as_path()); + cmd.args(spawn_command.args.iter().map(vite_str::Str::as_str)); + cmd.envs(spawn_command.all_envs.iter()); + cmd.current_dir(&*spawn_command.cwd); + cmd.stdin(Stdio::inherit()).stdout(Stdio::inherit()).stderr(Stdio::inherit()); + + let start = std::time::Instant::now(); + let mut child = cmd.into_tokio_command().spawn()?; + let exit_status = child.wait().await?; + + Ok(SpawnResult { exit_status, duration: start.elapsed() }) +} + impl Session<'_> { /// Execute an execution graph, reporting events through the provided reporter builder. /// diff --git a/crates/vite_task/src/session/execute/spawn.rs b/crates/vite_task/src/session/execute/spawn.rs index 68cd6558..db63b912 100644 --- a/crates/vite_task/src/session/execute/spawn.rs +++ b/crates/vite_task/src/session/execute/spawn.rs @@ -7,11 +7,10 @@ use std::{ }; use bincode::{Decode, Encode}; -use bstr::BString; use fspy::AccessMode; use rustc_hash::FxHashSet; use serde::Serialize; -use tokio::io::AsyncReadExt as _; +use tokio::io::{AsyncReadExt as _, AsyncWrite, AsyncWriteExt as _}; use vite_path::{AbsolutePath, RelativePathBuf}; use vite_task_plan::SpawnCommand; @@ -57,28 +56,26 @@ pub struct SpawnTrackResult { pub path_writes: FxHashSet, } -/// Spawn a command with file system tracking via fspy. +/// Spawn a command with file system tracking via fspy, using piped stdio. /// /// Returns the execution result including captured outputs, exit status, /// and tracked file accesses. /// -/// - `stdin` controls the child process's stdin (typically `Stdio::null()` or `Stdio::inherit()`). -/// - `on_output` is called in real-time as stdout/stderr data arrives. +/// - stdin is always `/dev/null` (piped mode is for non-interactive execution). +/// - `stdout_writer`/`stderr_writer` receive the child's stdout/stderr output in real-time. /// - `track_result` if provided, will be populated with captured outputs and path accesses for caching. If `None`, tracking is disabled. +#[expect(clippy::future_not_send, reason = "uses !Send dyn AsyncWrite writers internally")] #[expect( clippy::too_many_lines, reason = "spawn logic is inherently sequential and splitting would reduce clarity" )] -pub async fn spawn_with_tracking( +pub async fn spawn_with_tracking( spawn_command: &SpawnCommand, workspace_root: &AbsolutePath, - stdin: Stdio, - mut on_output: F, + stdout_writer: &mut (dyn AsyncWrite + Unpin), + stderr_writer: &mut (dyn AsyncWrite + Unpin), track_result: Option<&mut SpawnTrackResult>, -) -> anyhow::Result -where - F: FnMut(OutputKind, BString), -{ +) -> anyhow::Result { /// The tracking state of the spawned process enum TrackingState<'a> { /// Tacking is enabled, with the tracked child and result reference @@ -92,7 +89,7 @@ where cmd.args(spawn_command.args.iter().map(vite_str::Str::as_str)); cmd.envs(spawn_command.all_envs.iter()); cmd.current_dir(&*spawn_command.cwd); - cmd.stdin(stdin).stdout(Stdio::piped()).stderr(Stdio::piped()); + cmd.stdin(Stdio::null()).stdout(Stdio::piped()).stderr(Stdio::piped()); let mut tracking_state = if let Some(track_result) = track_result { // track_result is Some. Spawn with tracking enabled @@ -122,37 +119,49 @@ where let start = Instant::now(); - // Helper closure to process output chunks - let mut process_output = |kind: OutputKind, content: Vec| { - // Emit event immediately - on_output(kind, content.clone().into()); - - // Store outputs for caching - if let Some(outputs) = &mut outputs { - // Merge consecutive outputs of the same kind for caching - if let Some(last) = outputs.last_mut() - && last.kind == kind - { - last.content.extend(&content); - } else { - outputs.push(StdOutput { kind, content }); - } - } - }; - // Read from both stdout and stderr concurrently using select! loop { tokio::select! { result = child_stdout.read(&mut stdout_buf), if !stdout_done => { match result? { 0 => stdout_done = true, - n => process_output(OutputKind::StdOut, stdout_buf[..n].to_vec()), + n => { + let content = stdout_buf[..n].to_vec(); + // Write to the async writer immediately + stdout_writer.write_all(&content).await?; + stdout_writer.flush().await?; + // Store outputs for caching + if let Some(outputs) = &mut outputs { + if let Some(last) = outputs.last_mut() + && last.kind == OutputKind::StdOut + { + last.content.extend(&content); + } else { + outputs.push(StdOutput { kind: OutputKind::StdOut, content }); + } + } + } } } result = child_stderr.read(&mut stderr_buf), if !stderr_done => { match result? { 0 => stderr_done = true, - n => process_output(OutputKind::StdErr, stderr_buf[..n].to_vec()), + n => { + let content = stderr_buf[..n].to_vec(); + // Write to the async writer immediately + stderr_writer.write_all(&content).await?; + stderr_writer.flush().await?; + // Store outputs for caching + if let Some(outputs) = &mut outputs { + if let Some(last) = outputs.last_mut() + && last.kind == OutputKind::StdErr + { + last.content.extend(&content); + } else { + outputs.push(StdOutput { kind: OutputKind::StdErr, content }); + } + } + } } } else => break, diff --git a/crates/vite_task/src/session/mod.rs b/crates/vite_task/src/session/mod.rs index feb0c684..aa90d040 100644 --- a/crates/vite_task/src/session/mod.rs +++ b/crates/vite_task/src/session/mod.rs @@ -246,8 +246,7 @@ impl<'a> Session<'a> { .await } Ok(graph) => { - let builder = - LabeledReporterBuilder::new(std::io::stdout(), self.workspace_path()); + let builder = LabeledReporterBuilder::new(self.workspace_path()); Ok(self .execute_graph(graph, Box::new(builder)) .await @@ -392,7 +391,7 @@ impl<'a> Session<'a> { let cwd = Arc::clone(&self.cwd); let graph = self.plan_from_cli_run(cwd, run_command).await?; - let builder = LabeledReporterBuilder::new(std::io::stdout(), self.workspace_path()); + let builder = LabeledReporterBuilder::new(self.workspace_path()); Ok(self.execute_graph(graph, Box::new(builder)).await.err().unwrap_or(ExitStatus::SUCCESS)) } @@ -468,7 +467,7 @@ impl<'a> Session<'a> { let cache = self.cache()?; // Create a plain (standalone) reporter — no graph awareness, no summary - let plain_reporter = reporter::PlainReporter::new(std::io::stdout(), silent_if_cache_hit); + let plain_reporter = reporter::PlainReporter::new(silent_if_cache_hit); // Execute the spawn directly using the free function, bypassing the graph pipeline match execute::execute_spawn( diff --git a/crates/vite_task/src/session/reporter/labeled.rs b/crates/vite_task/src/session/reporter/labeled.rs index 781ae6ef..800c5726 100644 --- a/crates/vite_task/src/session/reporter/labeled.rs +++ b/crates/vite_task/src/session/reporter/labeled.rs @@ -11,7 +11,6 @@ use std::{ time::Duration, }; -use bstr::BString; use owo_colors::Style; use vite_path::AbsolutePath; use vite_str::Str; @@ -19,13 +18,13 @@ use vite_task_plan::{ExecutionGraph, ExecutionItemDisplay, ExecutionItemKind, Le use super::{ CACHE_MISS_STYLE, COMMAND_STYLE, ColorizeExt, ExitStatus, GraphExecutionReporter, - GraphExecutionReporterBuilder, LeafExecutionPath, LeafExecutionReporter, StdinSuggestion, - format_command_display, write_cache_hit_message, write_command_with_cache_status, - write_error_message, + GraphExecutionReporterBuilder, LeafExecutionPath, LeafExecutionReporter, StdioConfig, + StdioSuggestion, format_command_display, write_cache_hit_message, + write_command_with_cache_status, write_error_message, }; use crate::session::{ cache::format_cache_status_summary, - event::{CacheStatus, CacheUpdateStatus, ExecutionError, OutputKind, exit_status_to_code}, + event::{CacheStatus, CacheUpdateStatus, ExecutionError, exit_status_to_code}, }; /// Information tracked for each leaf execution, used in the final summary. @@ -56,13 +55,12 @@ struct ExecutionStats { /// /// This is safe because execution is single-threaded and sequential — only one leaf /// reporter is active at a time. -struct SharedReporterState { - writer: W, +struct SharedReporterState { executions: Vec, stats: ExecutionStats, /// Total number of spawned leaf executions in the graph (including nested `Expanded` - /// subgraphs). Computed once at build time and used to determine the stdin suggestion: - /// inherited stdin is only suggested when there is exactly one spawn leaf. + /// subgraphs). Computed once at build time and used to determine the stdio suggestion: + /// inherited stdio is only suggested when there is exactly one spawn leaf. spawn_leaf_count: usize, } @@ -99,27 +97,24 @@ pub(super) fn count_spawn_leaves(graph: &ExecutionGraph) -> usize { /// - Skips full summary (no Statistics/Task Details sections) /// - Shows only cache status inline /// - Results in clean output showing just the command's stdout/stderr -pub struct LabeledReporterBuilder { - writer: W, +pub struct LabeledReporterBuilder { workspace_path: Arc, } -impl LabeledReporterBuilder { +impl LabeledReporterBuilder { /// Create a new labeled reporter builder. /// - /// - `writer`: The output stream (typically `std::io::stdout()`). /// - `workspace_path`: The workspace root, used to compute relative cwds in display. - pub const fn new(writer: W, workspace_path: Arc) -> Self { - Self { writer, workspace_path } + pub const fn new(workspace_path: Arc) -> Self { + Self { workspace_path } } } -impl GraphExecutionReporterBuilder for LabeledReporterBuilder { +impl GraphExecutionReporterBuilder for LabeledReporterBuilder { fn build(self: Box, graph: &Arc) -> Box { let spawn_leaf_count = count_spawn_leaves(graph); Box::new(LabeledGraphReporter { shared: Rc::new(RefCell::new(SharedReporterState { - writer: self.writer, executions: Vec::new(), stats: ExecutionStats::default(), spawn_leaf_count, @@ -134,13 +129,13 @@ impl GraphExecutionReporterBuilder for LabeledReporterBuilde /// /// Creates [`LabeledLeafReporter`] instances for each leaf execution. The leaf reporters /// share mutable state with this reporter via `Rc>`. -pub struct LabeledGraphReporter { - shared: Rc>>, +pub struct LabeledGraphReporter { + shared: Rc>, graph: Arc, workspace_path: Arc, } -impl GraphExecutionReporter for LabeledGraphReporter { +impl GraphExecutionReporter for LabeledGraphReporter { fn new_leaf_execution(&mut self, path: &LeafExecutionPath) -> Box { // Look up display info from the graph using the path let display = path.resolve_display(&self.graph).cloned(); @@ -154,7 +149,7 @@ impl GraphExecutionReporter for LabeledGraphReporter { } fn finish(self: Box) -> Result<(), ExitStatus> { - let mut shared = self.shared.borrow_mut(); + let shared = self.shared.borrow(); // Print summary. // Special case: single execution without display info (e.g., synthetic via nested expansion) @@ -162,10 +157,12 @@ impl GraphExecutionReporter for LabeledGraphReporter { let is_single_displayless = shared.executions.len() == 1 && shared.executions[0].display.is_none(); if !is_single_displayless { - // Destructure to get simultaneous mutable access to writer and immutable - // access to executions/stats, satisfying the borrow checker. - let SharedReporterState { ref mut writer, ref executions, ref stats, .. } = *shared; - print_summary(writer, executions, stats, &self.workspace_path); + print_summary( + &mut std::io::stdout(), + &shared.executions, + &shared.stats, + &self.workspace_path, + ); } // Determine exit code based on failed tasks and infrastructure errors: @@ -204,10 +201,10 @@ impl GraphExecutionReporter for LabeledGraphReporter { /// Leaf-level reporter created by [`LabeledGraphReporter::new_leaf_execution`]. /// -/// Writes output in real-time to the shared writer and updates shared stats/errors +/// Writes display output in real-time to stdout and updates shared stats/errors /// via `Rc>`. -struct LabeledLeafReporter { - shared: Rc>>, +struct LabeledLeafReporter { + shared: Rc>, /// Display info for this execution, looked up from the graph via the path. display: Option, workspace_path: Arc, @@ -218,20 +215,8 @@ struct LabeledLeafReporter { is_cache_hit: bool, } -impl LeafExecutionReporter for LabeledLeafReporter { - fn stdin_suggestion(&self) -> StdinSuggestion { - // Only suggest inherited stdin when the graph has exactly one spawned leaf - // execution. With multiple spawned tasks, stdin should not be shared — each - // task gets /dev/null to avoid contention. - let shared = self.shared.borrow(); - if shared.spawn_leaf_count == 1 { - StdinSuggestion::Inherited - } else { - StdinSuggestion::Null - } - } - - fn start(&mut self, cache_status: CacheStatus) { +impl LeafExecutionReporter for LabeledLeafReporter { + fn start(&mut self, cache_status: CacheStatus) -> StdioConfig { self.started = true; self.is_cache_hit = matches!(cache_status, CacheStatus::Hit { .. }); @@ -247,7 +232,7 @@ impl LeafExecutionReporter for LabeledLeafReporter { // Print command line with cache status (if display info is available) if let Some(ref display) = self.display { write_command_with_cache_status( - &mut shared.writer, + &mut std::io::stdout(), display, &self.workspace_path, &cache_status, @@ -261,12 +246,19 @@ impl LeafExecutionReporter for LabeledLeafReporter { exit_status: None, error_message: None, }); - } - fn output(&mut self, _kind: OutputKind, content: BString) { - let mut shared = self.shared.borrow_mut(); - let _ = shared.writer.write_all(&content); - let _ = shared.writer.flush(); + // Determine stdio suggestion: inherited only when exactly one spawn leaf + let suggestion = if shared.spawn_leaf_count == 1 { + StdioSuggestion::Inherited + } else { + StdioSuggestion::Piped + }; + + StdioConfig { + suggestion, + stdout_writer: Box::new(tokio::io::stdout()), + stderr_writer: Box::new(tokio::io::stderr()), + } } fn finish( @@ -276,13 +268,14 @@ impl LeafExecutionReporter for LabeledLeafReporter { error: Option, ) { let mut shared = self.shared.borrow_mut(); + let mut stdout = std::io::stdout(); // Handle errors — format the full error chain using anyhow's `{:#}` formatter // (joins cause chain with `: ` separators). let has_error = error.is_some(); if let Some(error) = error { let message: Str = vite_str::format!("{:#}", anyhow::Error::from(error)); - write_error_message(&mut shared.writer, &message); + write_error_message(&mut stdout, &message); // Update the execution info if start() was called (an entry was pushed). // Without the `self.started` guard, `last_mut()` would return a @@ -312,14 +305,14 @@ impl LeafExecutionReporter for LabeledLeafReporter { // For executions without display info (synthetics via nested expansion) that are // cache hits, print the cache hit message if self.started && self.display.is_none() && self.is_cache_hit { - write_cache_hit_message(&mut shared.writer); + write_cache_hit_message(&mut stdout); } // Add a trailing newline after each task's output for readability. // Skip if start() was never called (e.g. cache lookup failure) — there's // no task output to separate. if self.started { - let _ = writeln!(shared.writer); + let _ = writeln!(stdout); } } } diff --git a/crates/vite_task/src/session/reporter/mod.rs b/crates/vite_task/src/session/reporter/mod.rs index 30d78876..3e468845 100644 --- a/crates/vite_task/src/session/reporter/mod.rs +++ b/crates/vite_task/src/session/reporter/mod.rs @@ -31,18 +31,18 @@ use std::{ sync::{Arc, LazyLock}, }; -use bstr::BString; pub use labeled::LabeledReporterBuilder; use owo_colors::{Style, Styled}; pub use plain::PlainReporter; use smallvec::SmallVec; +use tokio::io::AsyncWrite; use vite_path::AbsolutePath; use vite_str::Str; use vite_task_plan::{ExecutionGraph, ExecutionItem, ExecutionItemDisplay, ExecutionItemKind}; use super::{ cache::format_cache_status_inline, - event::{CacheStatus, CacheUpdateStatus, ExecutionError, OutputKind}, + event::{CacheStatus, CacheUpdateStatus, ExecutionError}, }; // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ @@ -61,26 +61,45 @@ impl ExitStatus { } // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -// Stdin suggestion +// Stdio suggestion and configuration // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -/// Suggestion from the reporter about what stdin mode to use for a spawned process. +/// Suggestion from the reporter about what stdio mode to use for a spawned process. /// -/// The actual stdin mode is determined by [`execute_spawn`](super::execute::execute_spawn) +/// The actual stdio mode is determined by [`execute_spawn`](super::execute::execute_spawn) /// based on this suggestion AND whether caching is enabled for the task: -/// - `Inherited` is only used when the suggestion is `Inherited` AND caching is disabled. -/// This prevents non-deterministic user input from corrupting cached output. -/// - `Null` is always respected as-is. +/// - `Inherited` is only honoured when caching is disabled (`cache_metadata` is `None`). +/// With caching enabled, the execution engine overrides to `Piped` so that output can +/// be captured for the cache. +/// - `Piped` is always respected as-is. #[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum StdinSuggestion { - /// Suggest connecting the child process's stdin to /dev/null (or NUL on Windows). - /// Used when multiple tasks run in sequence and stdin should not be shared. - Null, - /// Suggest inheriting stdin from the parent process, allowing interactive input. +pub enum StdioSuggestion { + /// stdin is `/dev/null`, stdout and stderr are piped into the reporter's + /// [`AsyncWrite`] streams. Used when multiple tasks run concurrently and + /// stdio should not be shared. + Piped, + /// All three file descriptors (stdin, stdout, stderr) are inherited from the + /// parent process, allowing interactive input and direct terminal output. /// Only effective when caching is disabled for the task. Inherited, } +/// Stdio configuration returned by [`LeafExecutionReporter::start`]. +/// +/// Contains the reporter's suggestion for the stdio mode together with two +/// async writers that receive the child process's stdout and stderr when the +/// execution engine decides to use piped mode. The writers are always provided +/// because the engine may override the suggestion (e.g. when caching forces +/// piped mode even though the reporter suggested inherited). +pub struct StdioConfig { + /// The reporter's preferred stdio mode. + pub suggestion: StdioSuggestion, + /// Async writer for the child process's stdout (used in piped mode and cache replay). + pub stdout_writer: Box, + /// Async writer for the child process's stderr (used in piped mode and cache replay). + pub stderr_writer: Box, +} + // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ // Leaf execution path — identifies a leaf within a (potentially nested) execution graph // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ @@ -207,27 +226,24 @@ pub trait GraphExecutionReporter { /// Reporter for a single leaf execution (one spawned process or in-process command). /// -/// Lifecycle: `start()` → zero or more `output()` → `finish()`. +/// Lifecycle: `start()` → `finish()`. /// /// `start()` may not be called before `finish()` if an error occurs before the cache /// status is determined (e.g., cache lookup failure). pub trait LeafExecutionReporter { - /// Suggest which stdin mode to use for the spawned process. - /// - /// Called by [`execute_spawn`](super::execute::execute_spawn) before spawning to - /// determine the child process's stdin configuration. The final decision also - /// depends on whether caching is enabled — inherited stdin is only used when - /// the suggestion is [`StdinSuggestion::Inherited`] AND the task has no cache - /// metadata (caching disabled). - fn stdin_suggestion(&self) -> StdinSuggestion; - /// Report that execution is starting with the given cache status. /// /// Called after the cache lookup completes, before any output is produced. - fn start(&mut self, cache_status: CacheStatus); - - /// Report a chunk of output (stdout or stderr) from the executing process. - fn output(&mut self, kind: OutputKind, content: BString); + /// Returns a [`StdioConfig`] containing: + /// - The reporter's stdio mode suggestion (inherited or piped). + /// - Two [`AsyncWrite`] streams for receiving the child's stdout and stderr + /// (used when the execution engine decides on piped mode, or for cache replay). + /// + /// The execution engine decides the actual stdio mode based on the suggestion + /// AND whether caching is enabled — inherited stdio is only used when the + /// suggestion is [`StdioSuggestion::Inherited`] AND the task has no cache + /// metadata (caching disabled). + fn start(&mut self, cache_status: CacheStatus) -> StdioConfig; /// Finalize this leaf execution. /// @@ -337,7 +353,10 @@ mod tests { }; use super::*; - use crate::session::reporter::labeled::count_spawn_leaves; + use crate::session::{ + event::{CacheDisabledReason, CacheStatus}, + reporter::labeled::count_spawn_leaves, + }; /// Create a dummy `AbsolutePath` for test fixtures. fn test_path() -> Arc { @@ -479,30 +498,34 @@ mod tests { } // ──────────────────────────────────────────────────────────── - // PlainReporter stdin_suggestion tests + // PlainReporter stdio suggestion tests // ──────────────────────────────────────────────────────────── #[test] fn plain_reporter_always_suggests_inherited() { - let reporter = PlainReporter::new(Vec::::new(), false); - assert_eq!(reporter.stdin_suggestion(), StdinSuggestion::Inherited); + let mut reporter = PlainReporter::new(false); + let stdio_config = + reporter.start(CacheStatus::Disabled(CacheDisabledReason::NoCacheMetadata)); + assert_eq!(stdio_config.suggestion, StdioSuggestion::Inherited); } #[test] fn plain_reporter_suggests_inherited_even_when_silent() { - let reporter = PlainReporter::new(Vec::::new(), true); - assert_eq!(reporter.stdin_suggestion(), StdinSuggestion::Inherited); + let mut reporter = PlainReporter::new(true); + let stdio_config = + reporter.start(CacheStatus::Disabled(CacheDisabledReason::NoCacheMetadata)); + assert_eq!(stdio_config.suggestion, StdioSuggestion::Inherited); } // ──────────────────────────────────────────────────────────── - // LabeledLeafReporter stdin_suggestion tests + // LabeledLeafReporter stdio suggestion tests // ──────────────────────────────────────────────────────────── /// Build a `LabeledGraphReporter` for the given graph and return a leaf reporter /// for the first node's first item. fn build_labeled_leaf(graph: ExecutionGraph) -> Box { let graph_arc = Arc::new(graph); - let builder = Box::new(LabeledReporterBuilder::new(Vec::::new(), test_path())); + let builder = Box::new(LabeledReporterBuilder::new(test_path())); let mut reporter = builder.build(&graph_arc); // Create a leaf reporter for the first node @@ -513,33 +536,37 @@ mod tests { #[test] fn labeled_reporter_single_spawn_suggests_inherited() { let graph = ExecutionGraph::from_node_list([spawn_task("build")]); - let leaf = build_labeled_leaf(graph); - assert_eq!(leaf.stdin_suggestion(), StdinSuggestion::Inherited); + let mut leaf = build_labeled_leaf(graph); + let stdio_config = leaf.start(CacheStatus::Disabled(CacheDisabledReason::NoCacheMetadata)); + assert_eq!(stdio_config.suggestion, StdioSuggestion::Inherited); } #[test] - fn labeled_reporter_multiple_spawns_suggests_null() { + fn labeled_reporter_multiple_spawns_suggests_piped() { let graph = ExecutionGraph::from_node_list([spawn_task("build"), spawn_task("test")]); - let leaf = build_labeled_leaf(graph); - assert_eq!(leaf.stdin_suggestion(), StdinSuggestion::Null); + let mut leaf = build_labeled_leaf(graph); + let stdio_config = leaf.start(CacheStatus::Disabled(CacheDisabledReason::NoCacheMetadata)); + assert_eq!(stdio_config.suggestion, StdioSuggestion::Piped); } #[test] - fn labeled_reporter_single_in_process_suggests_inherited() { - // Zero spawn leaves → spawn_leaf_count == 0, so not == 1 → Null + fn labeled_reporter_single_in_process_suggests_piped() { + // Zero spawn leaves → spawn_leaf_count == 0, so not == 1 → Piped // This is correct: in-process executions don't spawn child processes, - // so stdin suggestion doesn't apply to them. + // so stdio suggestion doesn't apply to them. let graph = ExecutionGraph::from_node_list([in_process_task("echo")]); - let leaf = build_labeled_leaf(graph); - assert_eq!(leaf.stdin_suggestion(), StdinSuggestion::Null); + let mut leaf = build_labeled_leaf(graph); + let stdio_config = leaf.start(CacheStatus::Disabled(CacheDisabledReason::NoCacheMetadata)); + assert_eq!(stdio_config.suggestion, StdioSuggestion::Piped); } #[test] fn labeled_reporter_one_spawn_one_in_process_suggests_inherited() { // One spawn leaf + one in-process → spawn_leaf_count == 1 → Inherited let graph = ExecutionGraph::from_node_list([spawn_task("build"), in_process_task("echo")]); - let leaf = build_labeled_leaf(graph); - assert_eq!(leaf.stdin_suggestion(), StdinSuggestion::Inherited); + let mut leaf = build_labeled_leaf(graph); + let stdio_config = leaf.start(CacheStatus::Disabled(CacheDisabledReason::NoCacheMetadata)); + assert_eq!(stdio_config.suggestion, StdioSuggestion::Inherited); } #[test] @@ -548,18 +575,20 @@ mod tests { let nested = ExecutionGraph::from_node_list([spawn_task("nested-build")]); let graph = ExecutionGraph::from_node_list([expanded_task("expand", nested)]); - let leaf = build_labeled_leaf(graph); - assert_eq!(leaf.stdin_suggestion(), StdinSuggestion::Inherited); + let mut leaf = build_labeled_leaf(graph); + let stdio_config = leaf.start(CacheStatus::Disabled(CacheDisabledReason::NoCacheMetadata)); + assert_eq!(stdio_config.suggestion, StdioSuggestion::Inherited); } #[test] - fn labeled_reporter_nested_multiple_spawns_suggests_null() { + fn labeled_reporter_nested_multiple_spawns_suggests_piped() { // Nested graph with two spawns let nested = ExecutionGraph::from_node_list([spawn_task("nested-a"), spawn_task("nested-b")]); let graph = ExecutionGraph::from_node_list([expanded_task("expand", nested)]); - let leaf = build_labeled_leaf(graph); - assert_eq!(leaf.stdin_suggestion(), StdinSuggestion::Null); + let mut leaf = build_labeled_leaf(graph); + let stdio_config = leaf.start(CacheStatus::Disabled(CacheDisabledReason::NoCacheMetadata)); + assert_eq!(stdio_config.suggestion, StdioSuggestion::Piped); } } diff --git a/crates/vite_task/src/session/reporter/plain.rs b/crates/vite_task/src/session/reporter/plain.rs index 648487ee..0532019a 100644 --- a/crates/vite_task/src/session/reporter/plain.rs +++ b/crates/vite_task/src/session/reporter/plain.rs @@ -1,28 +1,26 @@ //! Plain reporter — a standalone [`LeafExecutionReporter`] for single-leaf execution. //! //! Used for synthetic executions (e.g., auto-install) where there is no execution graph -//! and no summary is needed. Owns its writer directly with no shared state. +//! and no summary is needed. Writes directly to stdout/stderr with no shared state. -use std::io::Write; - -use bstr::BString; - -use super::{LeafExecutionReporter, StdinSuggestion, write_cache_hit_message, write_error_message}; -use crate::session::event::{CacheStatus, CacheUpdateStatus, ExecutionError, OutputKind}; +use super::{ + LeafExecutionReporter, StdioConfig, StdioSuggestion, write_cache_hit_message, + write_error_message, +}; +use crate::session::event::{CacheStatus, CacheUpdateStatus, ExecutionError}; /// A self-contained [`LeafExecutionReporter`] for single-leaf executions /// (e.g., `execute_synthetic`). /// /// This reporter: -/// - Owns its writer directly (no `Rc` shared state) +/// - Writes display output (errors, cache-hit messages) directly to stdout /// - Has no display info (synthetic executions have no task display) /// - Does not track stats or print summaries /// - Supports `silent_if_cache_hit` to suppress output for cached executions /// /// The exit status is determined by the caller from the `execute_spawn` return value, /// not from the reporter. -pub struct PlainReporter { - writer: W, +pub struct PlainReporter { /// When true, suppresses all output (command line, process output, cache hit message) /// for executions that are cache hits. silent_if_cache_hit: bool, @@ -30,13 +28,12 @@ pub struct PlainReporter { is_cache_hit: bool, } -impl PlainReporter { +impl PlainReporter { /// Create a new plain reporter. /// - /// - `writer`: The output stream (typically `std::io::stdout()`). /// - `silent_if_cache_hit`: If true, suppress all output when the execution is a cache hit. - pub const fn new(writer: W, silent_if_cache_hit: bool) -> Self { - Self { writer, silent_if_cache_hit, is_cache_hit: false } + pub const fn new(silent_if_cache_hit: bool) -> Self { + Self { silent_if_cache_hit, is_cache_hit: false } } /// Returns true if output should be suppressed for this execution. @@ -45,43 +42,51 @@ impl PlainReporter { } } -impl LeafExecutionReporter for PlainReporter { - fn stdin_suggestion(&self) -> StdinSuggestion { - // PlainReporter is used for single-leaf synthetic executions (e.g., auto-install). - // Always suggest inherited stdin so the spawned process can be interactive. - StdinSuggestion::Inherited - } - - fn start(&mut self, cache_status: CacheStatus) { +impl LeafExecutionReporter for PlainReporter { + fn start(&mut self, cache_status: CacheStatus) -> StdioConfig { self.is_cache_hit = matches!(cache_status, CacheStatus::Hit { .. }); + // PlainReporter is used for single-leaf synthetic executions (e.g., auto-install). + // Always suggest inherited stdio so the spawned process can be interactive. // PlainReporter has no display info (synthetic executions), // so there's no command line to print at start. - } - - fn output(&mut self, _kind: OutputKind, content: BString) { - if self.is_silent() { - return; + // + // When silent_if_cache_hit is enabled and we have a cache hit, return + // sink writers that discard output — the cache replay in execute_spawn + // writes directly to these writers, so this is the reporter's only way + // to suppress replayed output. + if self.silent_if_cache_hit && self.is_cache_hit { + StdioConfig { + suggestion: StdioSuggestion::Inherited, + stdout_writer: Box::new(tokio::io::sink()), + stderr_writer: Box::new(tokio::io::sink()), + } + } else { + StdioConfig { + suggestion: StdioSuggestion::Inherited, + stdout_writer: Box::new(tokio::io::stdout()), + stderr_writer: Box::new(tokio::io::stderr()), + } } - let _ = self.writer.write_all(&content); - let _ = self.writer.flush(); } fn finish( - mut self: Box, + self: Box, _status: Option, _cache_update_status: CacheUpdateStatus, error: Option, ) { + let mut stdout = std::io::stdout(); + // Handle errors — format the full error chain and print inline. if let Some(error) = error { let message = vite_str::format!("{:#}", anyhow::Error::from(error)); - write_error_message(&mut self.writer, &message); + write_error_message(&mut stdout, &message); return; } // For cache hits, print the "cache hit" message (unless silent) if self.is_cache_hit && !self.is_silent() { - write_cache_hit_message(&mut self.writer); + write_cache_hit_message(&mut stdout); } } } diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-list/snapshots.toml b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-list/snapshots.toml index 446672c4..5b7347cb 100644 --- a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-list/snapshots.toml +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-list/snapshots.toml @@ -14,5 +14,5 @@ steps = [ [[e2e]] name = "vp run in script" steps = [ - "vp run list-tasks", + { command = "vp run list-tasks", interactions = [{ "expect-milestone" = "task-select::0" }, { "write-key" = "enter" }] }, ] diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-list/snapshots/vp run in script.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-list/snapshots/vp run in script.snap index f4210397..0d1408cb 100644 --- a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-list/snapshots/vp run in script.snap +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-list/snapshots/vp run in script.snap @@ -3,13 +3,33 @@ source: crates/vite_task_bin/tests/e2e_snapshots/main.rs expression: e2e_outputs --- > vp run list-tasks +@ expect-milestone: task-select::0 $ vp run ⊘ cache disabled: no cache config - hello: echo hello from root +Search task (↑/↓ to move, enter to select): +> hello: echo hello from root list-tasks: vp run app#build: echo build app app#lint: echo lint app app#test: echo test app lib#build: echo build lib +@ write-key: enter +$ vp run ⊘ cache disabled: no cache config +$ echo hello from root ⊘ cache disabled: built-in command +hello from root + + +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + Vite+ Task Runner • Execution Summary +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +Statistics: 1 tasks • 0 cache hits • 0 cache misses • 1 cache disabled +Performance: 0% cache hit rate + +Task Details: +──────────────────────────────────────────────── + [1] task-list-test#hello: $ echo hello from root ✓ + → Cache disabled for built-in command +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ From 24195b7483f9b33b25184d835bf9b6aa7d1e8999 Mon Sep 17 00:00:00 2001 From: branchseer Date: Sun, 15 Feb 2026 20:47:43 +0800 Subject: [PATCH 2/3] fix: remove trailing space from statistics line for cross-platform consistency The Statistics line in the execution summary had a trailing space that was preserved on macOS but trimmed by Windows ConPTY. Also updates the task-list 'vp run in script' E2E test to use expect-milestone + enter instead of timing out. --- crates/vite_task/src/session/reporter/labeled.rs | 7 +++---- .../snapshots/associate existing cache.snap | 7 +++---- .../snapshots/builtin different cwd.snap | 9 ++++----- ...th non-zero exit does not show cache not updated.snap | 5 ++--- .../snapshots/task with cache disabled.snap | 5 ++--- .../snapshots/task with cache enabled.snap | 5 ++--- .../snapshots/cache miss command change.snap | 7 +++---- .../cache-miss-reasons/snapshots/cwd changed.snap | 5 ++--- .../fixtures/cache-miss-reasons/snapshots/env added.snap | 5 ++--- .../cache-miss-reasons/snapshots/env removed.snap | 5 ++--- .../cache-miss-reasons/snapshots/env value changed.snap | 5 ++--- .../snapshots/input content changed.snap | 5 ++--- .../snapshots/pass-through env added.snap | 5 ++--- .../snapshots/pass-through env removed.snap | 5 ++--- .../fixtures/cache-subcommand/snapshots/cache clean.snap | 7 +++---- .../snapshots/read file with colon in name.snap | 5 ++--- .../env-test prints value from additional_envs.snap | 3 +-- .../snapshots/env-test with different values.snap | 5 ++--- .../fixtures/e2e-lint-cache/snapshots/direct lint.snap | 5 ++--- .../snapshots/exec not triggered from script.snap | 3 +-- .../multiple task failures returns exit code 1.snap | 2 +- .../single task failure returns task exit code.snap | 3 +-- .../snapshots/individual cache for extra args.snap | 9 ++++----- .../snapshots/individual cache for envs.snap | 9 ++++----- .../fixtures/lint-dot-git/snapshots/lint dot git.snap | 5 ++--- .../snapshots/replay logs chronological order.snap | 7 +++---- .../snapshots/shared caching inputs.snap | 9 ++++----- ...ignal terminated task returns non-zero exit code.snap | 3 +-- .../snapshots/multiple tasks get null stdin.snap | 2 +- .../snapshots/single task no cache inherits stdin.snap | 2 +- .../single task with cache gets null stdin.snap | 2 +- .../fixtures/task-list/snapshots/vp run in script.snap | 4 ++-- .../snapshots/no trailing newline.snap | 3 +-- .../snapshots/interactive long command truncated.snap | 2 +- .../interactive enter with no results does nothing.snap | 2 +- .../snapshots/interactive escape clears query.snap | 2 +- .../snapshots/interactive scroll long list.snap | 2 +- .../snapshots/interactive search other package task.snap | 2 +- ...teractive search preserves rating within package.snap | 2 +- .../snapshots/interactive search then select.snap | 2 +- .../interactive search with hash skips reorder.snap | 2 +- .../snapshots/interactive select task from lib.snap | 2 +- .../task-select/snapshots/interactive select task.snap | 2 +- .../snapshots/interactive select with recursive.snap | 2 +- .../interactive select with typo and transitive.snap | 2 +- .../snapshots/interactive select with typo.snap | 2 +- ...ursive build runs dependencies before dependents.snap | 2 +- .../transitive build from app runs all dependencies.snap | 2 +- ...sitive build from lib runs only its dependencies.snap | 2 +- .../snapshots/cache hit after file modification.snap | 5 ++--- 50 files changed, 88 insertions(+), 117 deletions(-) diff --git a/crates/vite_task/src/session/reporter/labeled.rs b/crates/vite_task/src/session/reporter/labeled.rs index 800c5726..3671b27d 100644 --- a/crates/vite_task/src/session/reporter/labeled.rs +++ b/crates/vite_task/src/session/reporter/labeled.rs @@ -380,20 +380,19 @@ fn print_summary( }; // Build statistics line, only including non-empty parts - // Note: trailing space after "cache misses" is intentional for consistent formatting let _ = write!( writer, - "{} {} {} {} ", + "{} {} {} {}", "Statistics:".style(Style::new().bold()), vite_str::format!(" {total} tasks").style(Style::new().bright_white()), vite_str::format!("• {cache_hits} cache hits").style(Style::new().green()), vite_str::format!("• {cache_misses} cache misses").style(CACHE_MISS_STYLE), ); if !cache_disabled_str.is_empty() { - let _ = write!(writer, "{cache_disabled_str} "); + let _ = write!(writer, " {cache_disabled_str}"); } if !failed_str.is_empty() { - let _ = write!(writer, "{failed_str} "); + let _ = write!(writer, " {failed_str}"); } let _ = writeln!(writer); diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/associate-existing-cache/snapshots/associate existing cache.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/associate-existing-cache/snapshots/associate existing cache.snap index 6ebbbe74..5e27e637 100644 --- a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/associate-existing-cache/snapshots/associate existing cache.snap +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/associate-existing-cache/snapshots/associate existing cache.snap @@ -1,7 +1,6 @@ --- source: crates/vite_task_bin/tests/e2e_snapshots/main.rs expression: e2e_outputs -input_file: crates/vite_task_bin/tests/e2e_snapshots/fixtures/associate-existing-cache --- > vp run script1 # cache miss $ print hello @@ -12,7 +11,7 @@ hello Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 0 cache hits • 1 cache misses +Statistics: 1 tasks • 0 cache hits • 1 cache misses Performance: 0% cache hit rate Task Details: @@ -29,7 +28,7 @@ hello Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 1 cache hits • 0 cache misses +Statistics: 1 tasks • 1 cache hits • 0 cache misses Performance: 100% cache hit rate, saved in total Task Details: @@ -48,7 +47,7 @@ world Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 0 cache hits • 1 cache misses +Statistics: 1 tasks • 0 cache hits • 1 cache misses Performance: 0% cache hit rate Task Details: diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/builtin-different-cwd/snapshots/builtin different cwd.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/builtin-different-cwd/snapshots/builtin different cwd.snap index 690fd2b4..a07da593 100644 --- a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/builtin-different-cwd/snapshots/builtin different cwd.snap +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/builtin-different-cwd/snapshots/builtin different cwd.snap @@ -1,7 +1,6 @@ --- source: crates/vite_task_bin/tests/e2e_snapshots/main.rs expression: e2e_outputs -input_file: crates/vite_task_bin/tests/e2e_snapshots/fixtures/builtin-different-cwd --- > cd folder1 && vp run lint # cache miss in folder1 $ vp lint @@ -28,7 +27,7 @@ Finished in on 2 files with 90 rules using threads. Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 0 cache hits • 1 cache misses +Statistics: 1 tasks • 0 cache hits • 1 cache misses Performance: 0% cache hit rate Task Details: @@ -61,7 +60,7 @@ Finished in on 2 files with 90 rules using threads. Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 1 cache hits • 0 cache misses +Statistics: 1 tasks • 1 cache hits • 0 cache misses Performance: 100% cache hit rate, saved in total Task Details: @@ -89,7 +88,7 @@ Finished in on 2 files with 90 rules using threads. Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 0 cache hits • 1 cache misses +Statistics: 1 tasks • 0 cache hits • 1 cache misses Performance: 0% cache hit rate Task Details: @@ -115,7 +114,7 @@ Finished in on 2 files with 90 rules using threads. Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 1 cache hits • 0 cache misses +Statistics: 1 tasks • 1 cache hits • 0 cache misses Performance: 100% cache hit rate, saved in total Task Details: diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/builtin-non-zero-exit/snapshots/builtin command with non-zero exit does not show cache not updated.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/builtin-non-zero-exit/snapshots/builtin command with non-zero exit does not show cache not updated.snap index 4894ce7c..90d7981c 100644 --- a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/builtin-non-zero-exit/snapshots/builtin command with non-zero exit does not show cache not updated.snap +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/builtin-non-zero-exit/snapshots/builtin command with non-zero exit does not show cache not updated.snap @@ -1,7 +1,6 @@ --- source: crates/vite_task_bin/tests/e2e_snapshots/main.rs expression: e2e_outputs -input_file: crates/vite_task_bin/tests/e2e_snapshots/fixtures/builtin-non-zero-exit --- [1]> vp run lint -- -D no-debugger $ vp lint -D no-debugger @@ -21,7 +20,7 @@ Finished in on 1 file with 90 rules using threads. Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 0 cache hits • 1 cache misses • 1 failed +Statistics: 1 tasks • 0 cache hits • 1 cache misses • 1 failed Performance: 0% cache hit rate Task Details: @@ -47,7 +46,7 @@ Finished in on 1 file with 90 rules using threads. Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 0 cache hits • 1 cache misses • 1 failed +Statistics: 1 tasks • 0 cache hits • 1 cache misses • 1 failed Performance: 0% cache hit rate Task Details: diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-disabled/snapshots/task with cache disabled.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-disabled/snapshots/task with cache disabled.snap index 4eb049e7..b3062dc5 100644 --- a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-disabled/snapshots/task with cache disabled.snap +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-disabled/snapshots/task with cache disabled.snap @@ -1,7 +1,6 @@ --- source: crates/vite_task_bin/tests/e2e_snapshots/main.rs expression: e2e_outputs -input_file: crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-disabled --- > vp run no-cache-task # cache miss $ print-file test.txt ⊘ cache disabled: no cache config @@ -12,7 +11,7 @@ test content Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 0 cache hits • 0 cache misses • 1 cache disabled +Statistics: 1 tasks • 0 cache hits • 0 cache misses • 1 cache disabled Performance: 0% cache hit rate Task Details: @@ -29,7 +28,7 @@ test content Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 0 cache hits • 0 cache misses • 1 cache disabled +Statistics: 1 tasks • 0 cache hits • 0 cache misses • 1 cache disabled Performance: 0% cache hit rate Task Details: diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-disabled/snapshots/task with cache enabled.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-disabled/snapshots/task with cache enabled.snap index 140e4e1d..4bc07bee 100644 --- a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-disabled/snapshots/task with cache enabled.snap +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-disabled/snapshots/task with cache enabled.snap @@ -1,7 +1,6 @@ --- source: crates/vite_task_bin/tests/e2e_snapshots/main.rs expression: e2e_outputs -input_file: crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-disabled --- > vp run cached-task # cache miss $ print-file test.txt @@ -12,7 +11,7 @@ test content Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 0 cache hits • 1 cache misses +Statistics: 1 tasks • 0 cache hits • 1 cache misses Performance: 0% cache hit rate Task Details: @@ -29,7 +28,7 @@ test content Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 1 cache hits • 0 cache misses +Statistics: 1 tasks • 1 cache hits • 0 cache misses Performance: 100% cache hit rate, saved in total Task Details: diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-miss-command-change/snapshots/cache miss command change.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-miss-command-change/snapshots/cache miss command change.snap index a953cd0f..2459b8c0 100644 --- a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-miss-command-change/snapshots/cache miss command change.snap +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-miss-command-change/snapshots/cache miss command change.snap @@ -1,7 +1,6 @@ --- source: crates/vite_task_bin/tests/e2e_snapshots/main.rs expression: e2e_outputs -input_file: crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-miss-command-change --- > vp run task # cache miss $ print foo @@ -15,7 +14,7 @@ bar Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 2 tasks • 0 cache hits • 2 cache misses +Statistics: 2 tasks • 0 cache hits • 2 cache misses Performance: 0% cache hit rate Task Details: @@ -40,7 +39,7 @@ bar Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 2 tasks • 1 cache hits • 1 cache misses +Statistics: 2 tasks • 1 cache hits • 1 cache misses Performance: 50% cache hit rate, saved in total Task Details: @@ -62,7 +61,7 @@ bar Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 1 cache hits • 0 cache misses +Statistics: 1 tasks • 1 cache hits • 0 cache misses Performance: 100% cache hit rate, saved in total Task Details: diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-miss-reasons/snapshots/cwd changed.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-miss-reasons/snapshots/cwd changed.snap index 12353f74..448a0b3b 100644 --- a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-miss-reasons/snapshots/cwd changed.snap +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-miss-reasons/snapshots/cwd changed.snap @@ -1,7 +1,6 @@ --- source: crates/vite_task_bin/tests/e2e_snapshots/main.rs expression: e2e_outputs -input_file: crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-miss-reasons --- > vp run test # cache miss $ print-file test.txt @@ -12,7 +11,7 @@ initial content Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 0 cache hits • 1 cache misses +Statistics: 1 tasks • 0 cache hits • 1 cache misses Performance: 0% cache hit rate Task Details: @@ -35,7 +34,7 @@ initial content Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 0 cache hits • 1 cache misses +Statistics: 1 tasks • 0 cache hits • 1 cache misses Performance: 0% cache hit rate Task Details: diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-miss-reasons/snapshots/env added.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-miss-reasons/snapshots/env added.snap index aa09d1a4..4414d10e 100644 --- a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-miss-reasons/snapshots/env added.snap +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-miss-reasons/snapshots/env added.snap @@ -1,7 +1,6 @@ --- source: crates/vite_task_bin/tests/e2e_snapshots/main.rs expression: e2e_outputs -input_file: crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-miss-reasons --- > vp run test # cache miss $ print-file test.txt @@ -12,7 +11,7 @@ initial content Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 0 cache hits • 1 cache misses +Statistics: 1 tasks • 0 cache hits • 1 cache misses Performance: 0% cache hit rate Task Details: @@ -29,7 +28,7 @@ initial content Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 0 cache hits • 1 cache misses +Statistics: 1 tasks • 0 cache hits • 1 cache misses Performance: 0% cache hit rate Task Details: diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-miss-reasons/snapshots/env removed.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-miss-reasons/snapshots/env removed.snap index 7d0a9b12..50992adf 100644 --- a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-miss-reasons/snapshots/env removed.snap +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-miss-reasons/snapshots/env removed.snap @@ -1,7 +1,6 @@ --- source: crates/vite_task_bin/tests/e2e_snapshots/main.rs expression: e2e_outputs -input_file: crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-miss-reasons --- > cross-env MY_ENV=1 vp run test # cache miss $ print-file test.txt @@ -12,7 +11,7 @@ initial content Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 0 cache hits • 1 cache misses +Statistics: 1 tasks • 0 cache hits • 1 cache misses Performance: 0% cache hit rate Task Details: @@ -29,7 +28,7 @@ initial content Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 0 cache hits • 1 cache misses +Statistics: 1 tasks • 0 cache hits • 1 cache misses Performance: 0% cache hit rate Task Details: diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-miss-reasons/snapshots/env value changed.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-miss-reasons/snapshots/env value changed.snap index a1547e6d..3197f138 100644 --- a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-miss-reasons/snapshots/env value changed.snap +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-miss-reasons/snapshots/env value changed.snap @@ -1,7 +1,6 @@ --- source: crates/vite_task_bin/tests/e2e_snapshots/main.rs expression: e2e_outputs -input_file: crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-miss-reasons --- > cross-env MY_ENV=1 vp run test # cache miss $ print-file test.txt @@ -12,7 +11,7 @@ initial content Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 0 cache hits • 1 cache misses +Statistics: 1 tasks • 0 cache hits • 1 cache misses Performance: 0% cache hit rate Task Details: @@ -29,7 +28,7 @@ initial content Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 0 cache hits • 1 cache misses +Statistics: 1 tasks • 0 cache hits • 1 cache misses Performance: 0% cache hit rate Task Details: diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-miss-reasons/snapshots/input content changed.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-miss-reasons/snapshots/input content changed.snap index 34c1440a..b7b5b628 100644 --- a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-miss-reasons/snapshots/input content changed.snap +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-miss-reasons/snapshots/input content changed.snap @@ -1,7 +1,6 @@ --- source: crates/vite_task_bin/tests/e2e_snapshots/main.rs expression: e2e_outputs -input_file: crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-miss-reasons --- > vp run test # cache miss $ print-file test.txt @@ -12,7 +11,7 @@ initial content Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 0 cache hits • 1 cache misses +Statistics: 1 tasks • 0 cache hits • 1 cache misses Performance: 0% cache hit rate Task Details: @@ -31,7 +30,7 @@ modified content Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 0 cache hits • 1 cache misses +Statistics: 1 tasks • 0 cache hits • 1 cache misses Performance: 0% cache hit rate Task Details: diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-miss-reasons/snapshots/pass-through env added.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-miss-reasons/snapshots/pass-through env added.snap index 69670081..baeb9a19 100644 --- a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-miss-reasons/snapshots/pass-through env added.snap +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-miss-reasons/snapshots/pass-through env added.snap @@ -1,7 +1,6 @@ --- source: crates/vite_task_bin/tests/e2e_snapshots/main.rs expression: e2e_outputs -input_file: crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-miss-reasons --- > vp run test # cache miss $ print-file test.txt @@ -12,7 +11,7 @@ initial content Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 0 cache hits • 1 cache misses +Statistics: 1 tasks • 0 cache hits • 1 cache misses Performance: 0% cache hit rate Task Details: @@ -31,7 +30,7 @@ initial content Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 0 cache hits • 1 cache misses +Statistics: 1 tasks • 0 cache hits • 1 cache misses Performance: 0% cache hit rate Task Details: diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-miss-reasons/snapshots/pass-through env removed.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-miss-reasons/snapshots/pass-through env removed.snap index dbd4d05d..5e112f0e 100644 --- a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-miss-reasons/snapshots/pass-through env removed.snap +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-miss-reasons/snapshots/pass-through env removed.snap @@ -1,7 +1,6 @@ --- source: crates/vite_task_bin/tests/e2e_snapshots/main.rs expression: e2e_outputs -input_file: crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-miss-reasons --- > json-edit vite-task.json "_.tasks.test.passThroughEnvs = ['MY_PASSTHROUGH']" # setup @@ -14,7 +13,7 @@ initial content Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 0 cache hits • 1 cache misses +Statistics: 1 tasks • 0 cache hits • 1 cache misses Performance: 0% cache hit rate Task Details: @@ -33,7 +32,7 @@ initial content Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 0 cache hits • 1 cache misses +Statistics: 1 tasks • 0 cache hits • 1 cache misses Performance: 0% cache hit rate Task Details: diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-subcommand/snapshots/cache clean.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-subcommand/snapshots/cache clean.snap index 3b76a3f5..f6f36f8c 100644 --- a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-subcommand/snapshots/cache clean.snap +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-subcommand/snapshots/cache clean.snap @@ -1,7 +1,6 @@ --- source: crates/vite_task_bin/tests/e2e_snapshots/main.rs expression: e2e_outputs -input_file: crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-subcommand --- > vp run cached-task # cache miss $ print-file test.txt @@ -12,7 +11,7 @@ test content Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 0 cache hits • 1 cache misses +Statistics: 1 tasks • 0 cache hits • 1 cache misses Performance: 0% cache hit rate Task Details: @@ -29,7 +28,7 @@ test content Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 1 cache hits • 0 cache misses +Statistics: 1 tasks • 1 cache hits • 0 cache misses Performance: 100% cache hit rate, saved in total Task Details: @@ -48,7 +47,7 @@ test content Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 0 cache hits • 1 cache misses +Statistics: 1 tasks • 0 cache hits • 1 cache misses Performance: 0% cache hit rate Task Details: diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/colon-in-name/snapshots/read file with colon in name.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/colon-in-name/snapshots/read file with colon in name.snap index eafa566a..e400fcc0 100644 --- a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/colon-in-name/snapshots/read file with colon in name.snap +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/colon-in-name/snapshots/read file with colon in name.snap @@ -1,7 +1,6 @@ --- source: crates/vite_task_bin/tests/e2e_snapshots/main.rs expression: e2e_outputs -input_file: crates/vite_task_bin/tests/e2e_snapshots/fixtures/colon-in-name --- > vp run read_colon_in_name # cache miss $ node read_node_fs.js @@ -11,7 +10,7 @@ $ node read_node_fs.js Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 0 cache hits • 1 cache misses +Statistics: 1 tasks • 0 cache hits • 1 cache misses Performance: 0% cache hit rate Task Details: @@ -27,7 +26,7 @@ $ node read_node_fs.js ✓ cache hit, replaying Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 1 cache hits • 0 cache misses +Statistics: 1 tasks • 1 cache hits • 0 cache misses Performance: 100% cache hit rate, saved in total Task Details: diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/e2e-env-test/snapshots/env-test prints value from additional_envs.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/e2e-env-test/snapshots/env-test prints value from additional_envs.snap index 0a88bf40..5b6128bb 100644 --- a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/e2e-env-test/snapshots/env-test prints value from additional_envs.snap +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/e2e-env-test/snapshots/env-test prints value from additional_envs.snap @@ -1,7 +1,6 @@ --- source: crates/vite_task_bin/tests/e2e_snapshots/main.rs expression: e2e_outputs -input_file: crates/vite_task_bin/tests/e2e_snapshots/fixtures/e2e-env-test --- > vp run env-test -- SYNTHETIC_ENV_VAR test_value_from_synthesizer # prints env value $ vp env-test SYNTHETIC_ENV_VAR test_value_from_synthesizer @@ -12,7 +11,7 @@ test_value_from_synthesizer Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 0 cache hits • 1 cache misses +Statistics: 1 tasks • 0 cache hits • 1 cache misses Performance: 0% cache hit rate Task Details: diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/e2e-env-test/snapshots/env-test with different values.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/e2e-env-test/snapshots/env-test with different values.snap index e5da8aa4..5203f28f 100644 --- a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/e2e-env-test/snapshots/env-test with different values.snap +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/e2e-env-test/snapshots/env-test with different values.snap @@ -1,7 +1,6 @@ --- source: crates/vite_task_bin/tests/e2e_snapshots/main.rs expression: e2e_outputs -input_file: crates/vite_task_bin/tests/e2e_snapshots/fixtures/e2e-env-test --- > vp run env-test -- FOO bar # sets FOO=bar $ vp env-test FOO bar @@ -12,7 +11,7 @@ bar Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 0 cache hits • 1 cache misses +Statistics: 1 tasks • 0 cache hits • 1 cache misses Performance: 0% cache hit rate Task Details: @@ -29,7 +28,7 @@ qux Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 0 cache hits • 1 cache misses +Statistics: 1 tasks • 0 cache hits • 1 cache misses Performance: 0% cache hit rate Task Details: diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/e2e-lint-cache/snapshots/direct lint.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/e2e-lint-cache/snapshots/direct lint.snap index 2a73781b..8078ba98 100644 --- a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/e2e-lint-cache/snapshots/direct lint.snap +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/e2e-lint-cache/snapshots/direct lint.snap @@ -1,7 +1,6 @@ --- source: crates/vite_task_bin/tests/e2e_snapshots/main.rs expression: e2e_outputs -input_file: crates/vite_task_bin/tests/e2e_snapshots/fixtures/e2e-lint-cache --- > vp run lint # cache miss $ vp lint @@ -13,7 +12,7 @@ Finished in on 0 files with 90 rules using threads. Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 0 cache hits • 1 cache misses +Statistics: 1 tasks • 0 cache hits • 1 cache misses Performance: 0% cache hit rate Task Details: @@ -41,7 +40,7 @@ Finished in on 1 file with 90 rules using threads. Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 0 cache hits • 1 cache misses +Statistics: 1 tasks • 0 cache hits • 1 cache misses Performance: 0% cache hit rate Task Details: diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/exec-api/snapshots/exec not triggered from script.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/exec-api/snapshots/exec not triggered from script.snap index 60a584fa..eb4fade4 100644 --- a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/exec-api/snapshots/exec not triggered from script.snap +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/exec-api/snapshots/exec not triggered from script.snap @@ -1,7 +1,6 @@ --- source: crates/vite_task_bin/tests/e2e_snapshots/main.rs expression: e2e_outputs -input_file: crates/vite_task_bin/tests/e2e_snapshots/fixtures/exec-api --- > FOO=bar vp run lint-task # no print-env FOO output $ vp lint @@ -13,7 +12,7 @@ Finished in on 0 files with 90 rules using threads. Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 0 cache hits • 1 cache misses +Statistics: 1 tasks • 0 cache hits • 1 cache misses Performance: 0% cache hit rate Task Details: diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/exit-codes/snapshots/multiple task failures returns exit code 1.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/exit-codes/snapshots/multiple task failures returns exit code 1.snap index 17a21b96..acff1d72 100644 --- a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/exit-codes/snapshots/multiple task failures returns exit code 1.snap +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/exit-codes/snapshots/multiple task failures returns exit code 1.snap @@ -12,7 +12,7 @@ expression: e2e_outputs Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 2 tasks • 0 cache hits • 2 cache misses • 2 failed +Statistics: 2 tasks • 0 cache hits • 2 cache misses • 2 failed Performance: 0% cache hit rate Task Details: diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/exit-codes/snapshots/single task failure returns task exit code.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/exit-codes/snapshots/single task failure returns task exit code.snap index d0980ac8..310238da 100644 --- a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/exit-codes/snapshots/single task failure returns task exit code.snap +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/exit-codes/snapshots/single task failure returns task exit code.snap @@ -1,7 +1,6 @@ --- source: crates/vite_task_bin/tests/e2e_snapshots/main.rs expression: e2e_outputs -input_file: crates/vite_task_bin/tests/e2e_snapshots/fixtures/exit-codes --- [42]> vp run pkg-a#fail # exits with code 42 ~/packages/pkg-a$ node -e "process.exit(42)" @@ -11,7 +10,7 @@ input_file: crates/vite_task_bin/tests/e2e_snapshots/fixtures/exit-codes Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 0 cache hits • 1 cache misses • 1 failed +Statistics: 1 tasks • 0 cache hits • 1 cache misses • 1 failed Performance: 0% cache hit rate Task Details: diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/individual-cache-for-adt-args/snapshots/individual cache for extra args.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/individual-cache-for-adt-args/snapshots/individual cache for extra args.snap index 8a4b726d..de8f439e 100644 --- a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/individual-cache-for-adt-args/snapshots/individual cache for extra args.snap +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/individual-cache-for-adt-args/snapshots/individual cache for extra args.snap @@ -1,7 +1,6 @@ --- source: crates/vite_task_bin/tests/e2e_snapshots/main.rs expression: e2e_outputs -input_file: crates/vite_task_bin/tests/e2e_snapshots/fixtures/individual-cache-for-adt-args --- > vp run say a # cache miss $ print a @@ -12,7 +11,7 @@ a Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 0 cache hits • 1 cache misses +Statistics: 1 tasks • 0 cache hits • 1 cache misses Performance: 0% cache hit rate Task Details: @@ -29,7 +28,7 @@ b Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 0 cache hits • 1 cache misses +Statistics: 1 tasks • 0 cache hits • 1 cache misses Performance: 0% cache hit rate Task Details: @@ -46,7 +45,7 @@ a Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 1 cache hits • 0 cache misses +Statistics: 1 tasks • 1 cache hits • 0 cache misses Performance: 100% cache hit rate, saved in total Task Details: @@ -63,7 +62,7 @@ b Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 1 cache hits • 0 cache misses +Statistics: 1 tasks • 1 cache hits • 0 cache misses Performance: 100% cache hit rate, saved in total Task Details: diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/individual-cache-for-envs/snapshots/individual cache for envs.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/individual-cache-for-envs/snapshots/individual cache for envs.snap index 364a30a5..1d0620a0 100644 --- a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/individual-cache-for-envs/snapshots/individual cache for envs.snap +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/individual-cache-for-envs/snapshots/individual cache for envs.snap @@ -1,7 +1,6 @@ --- source: crates/vite_task_bin/tests/e2e_snapshots/main.rs expression: e2e_outputs -input_file: crates/vite_task_bin/tests/e2e_snapshots/fixtures/individual-cache-for-envs --- > FOO=1 vp run hello # cache miss $ print-env FOO @@ -12,7 +11,7 @@ $ print-env FOO Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 0 cache hits • 1 cache misses +Statistics: 1 tasks • 0 cache hits • 1 cache misses Performance: 0% cache hit rate Task Details: @@ -29,7 +28,7 @@ $ print-env FOO ✗ cache miss: envs changed, executing Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 0 cache hits • 1 cache misses +Statistics: 1 tasks • 0 cache hits • 1 cache misses Performance: 0% cache hit rate Task Details: @@ -46,7 +45,7 @@ $ print-env FOO ✓ cache hit, replaying Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 1 cache hits • 0 cache misses +Statistics: 1 tasks • 1 cache hits • 0 cache misses Performance: 100% cache hit rate, saved in total Task Details: @@ -63,7 +62,7 @@ $ print-env FOO ✓ cache hit, replaying Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 1 cache hits • 0 cache misses +Statistics: 1 tasks • 1 cache hits • 0 cache misses Performance: 100% cache hit rate, saved in total Task Details: diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/lint-dot-git/snapshots/lint dot git.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/lint-dot-git/snapshots/lint dot git.snap index 166a6fa5..38ea12c2 100644 --- a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/lint-dot-git/snapshots/lint dot git.snap +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/lint-dot-git/snapshots/lint dot git.snap @@ -1,7 +1,6 @@ --- source: crates/vite_task_bin/tests/e2e_snapshots/main.rs expression: e2e_outputs -input_file: crates/vite_task_bin/tests/e2e_snapshots/fixtures/lint-dot-git --- > mkdir .git @@ -23,7 +22,7 @@ Finished in on 1 file with 90 rules using threads. Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 0 cache hits • 1 cache misses +Statistics: 1 tasks • 0 cache hits • 1 cache misses Performance: 0% cache hit rate Task Details: @@ -51,7 +50,7 @@ Finished in on 1 file with 90 rules using threads. Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 1 cache hits • 0 cache misses +Statistics: 1 tasks • 1 cache hits • 0 cache misses Performance: 100% cache hit rate, saved in total Task Details: diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/replay-logs-chronological-order/snapshots/replay logs chronological order.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/replay-logs-chronological-order/snapshots/replay logs chronological order.snap index 3fd4f93a..7b0be9e8 100644 --- a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/replay-logs-chronological-order/snapshots/replay logs chronological order.snap +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/replay-logs-chronological-order/snapshots/replay logs chronological order.snap @@ -1,7 +1,6 @@ --- source: crates/vite_task_bin/tests/e2e_snapshots/main.rs expression: e2e_outputs -input_file: crates/vite_task_bin/tests/e2e_snapshots/fixtures/replay-logs-chronological-order --- > vp run build # cache miss $ node build.js @@ -104,7 +103,7 @@ $ node build.js Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 0 cache hits • 1 cache misses +Statistics: 1 tasks • 0 cache hits • 1 cache misses Performance: 0% cache hit rate Task Details: @@ -213,7 +212,7 @@ $ node build.js ✓ cache hit, replaying Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 1 cache hits • 0 cache misses +Statistics: 1 tasks • 1 cache hits • 0 cache misses Performance: 100% cache hit rate, saved in total Task Details: @@ -322,7 +321,7 @@ $ node build.js ✓ cache hit, replaying Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 1 cache hits • 0 cache misses +Statistics: 1 tasks • 1 cache hits • 0 cache misses Performance: 100% cache hit rate, saved in total Task Details: diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/shared-caching-inputs/snapshots/shared caching inputs.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/shared-caching-inputs/snapshots/shared caching inputs.snap index f237d447..f42197bc 100644 --- a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/shared-caching-inputs/snapshots/shared caching inputs.snap +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/shared-caching-inputs/snapshots/shared caching inputs.snap @@ -1,7 +1,6 @@ --- source: crates/vite_task_bin/tests/e2e_snapshots/main.rs expression: e2e_outputs -input_file: crates/vite_task_bin/tests/e2e_snapshots/fixtures/shared-caching-inputs --- > vp run script1 # cache miss $ print-file foo.txt @@ -12,7 +11,7 @@ initial content Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 0 cache hits • 1 cache misses +Statistics: 1 tasks • 0 cache hits • 1 cache misses Performance: 0% cache hit rate Task Details: @@ -29,7 +28,7 @@ initial content Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 1 cache hits • 0 cache misses +Statistics: 1 tasks • 1 cache hits • 0 cache misses Performance: 100% cache hit rate, saved in total Task Details: @@ -48,7 +47,7 @@ modified content Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 0 cache hits • 1 cache misses +Statistics: 1 tasks • 0 cache hits • 1 cache misses Performance: 0% cache hit rate Task Details: @@ -65,7 +64,7 @@ modified content Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 1 cache hits • 0 cache misses +Statistics: 1 tasks • 1 cache hits • 0 cache misses Performance: 100% cache hit rate, saved in total Task Details: diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/signal-exit/snapshots/signal terminated task returns non-zero exit code.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/signal-exit/snapshots/signal terminated task returns non-zero exit code.snap index 20a9da9a..c47cb863 100644 --- a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/signal-exit/snapshots/signal terminated task returns non-zero exit code.snap +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/signal-exit/snapshots/signal terminated task returns non-zero exit code.snap @@ -1,7 +1,6 @@ --- source: crates/vite_task_bin/tests/e2e_snapshots/main.rs expression: e2e_outputs -input_file: crates/vite_task_bin/tests/e2e_snapshots/fixtures/signal-exit --- [134]> vp run abort # SIGABRT -> exit code 134 $ node -e "process.kill(process.pid, 6)" @@ -11,7 +10,7 @@ $ node -e "process.kill(process.pid, 6)" Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 0 cache hits • 1 cache misses • 1 failed +Statistics: 1 tasks • 0 cache hits • 1 cache misses • 1 failed Performance: 0% cache hit rate Task Details: diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/stdin-inheritance/snapshots/multiple tasks get null stdin.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/stdin-inheritance/snapshots/multiple tasks get null stdin.snap index a3ee77a0..5d6f5884 100644 --- a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/stdin-inheritance/snapshots/multiple tasks get null stdin.snap +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/stdin-inheritance/snapshots/multiple tasks get null stdin.snap @@ -12,7 +12,7 @@ $ read-stdin ⊘ cache disabled: no cache config Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 2 tasks • 0 cache hits • 1 cache misses • 1 cache disabled +Statistics: 2 tasks • 0 cache hits • 1 cache misses • 1 cache disabled Performance: 0% cache hit rate Task Details: diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/stdin-inheritance/snapshots/single task no cache inherits stdin.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/stdin-inheritance/snapshots/single task no cache inherits stdin.snap index b77a51fd..3ed85c44 100644 --- a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/stdin-inheritance/snapshots/single task no cache inherits stdin.snap +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/stdin-inheritance/snapshots/single task no cache inherits stdin.snap @@ -11,7 +11,7 @@ from-stdin Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 0 cache hits • 0 cache misses • 1 cache disabled +Statistics: 1 tasks • 0 cache hits • 0 cache misses • 1 cache disabled Performance: 0% cache hit rate Task Details: diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/stdin-inheritance/snapshots/single task with cache gets null stdin.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/stdin-inheritance/snapshots/single task with cache gets null stdin.snap index cb690886..c6a38299 100644 --- a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/stdin-inheritance/snapshots/single task with cache gets null stdin.snap +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/stdin-inheritance/snapshots/single task with cache gets null stdin.snap @@ -10,7 +10,7 @@ $ read-stdin Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 0 cache hits • 1 cache misses +Statistics: 1 tasks • 0 cache hits • 1 cache misses Performance: 0% cache hit rate Task Details: diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-list/snapshots/vp run in script.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-list/snapshots/vp run in script.snap index 0d1408cb..b0e427ef 100644 --- a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-list/snapshots/vp run in script.snap +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-list/snapshots/vp run in script.snap @@ -22,7 +22,7 @@ hello from root Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 0 cache hits • 0 cache misses • 1 cache disabled +Statistics: 1 tasks • 0 cache hits • 0 cache misses • 1 cache disabled Performance: 0% cache hit rate Task Details: @@ -36,7 +36,7 @@ Task Details: Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 0 cache hits • 0 cache misses • 1 cache disabled +Statistics: 1 tasks • 0 cache hits • 0 cache misses • 1 cache disabled Performance: 0% cache hit rate Task Details: diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-no-trailing-newline/snapshots/no trailing newline.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-no-trailing-newline/snapshots/no trailing newline.snap index 3f37a22a..8e80c017 100644 --- a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-no-trailing-newline/snapshots/no trailing newline.snap +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-no-trailing-newline/snapshots/no trailing newline.snap @@ -1,7 +1,6 @@ --- source: crates/vite_task_bin/tests/e2e_snapshots/main.rs expression: e2e_outputs -input_file: crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-no-trailing-newline --- > vp run hello # runs echo -n hello $ echo -n foo ⊘ cache disabled: built-in command @@ -14,7 +13,7 @@ bar Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 2 tasks • 0 cache hits • 0 cache misses • 2 cache disabled +Statistics: 2 tasks • 0 cache hits • 0 cache misses • 2 cache disabled Performance: 0% cache hit rate Task Details: diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select-truncate/snapshots/interactive long command truncated.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select-truncate/snapshots/interactive long command truncated.snap index c63b3ce7..0ff4c0d7 100644 --- a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select-truncate/snapshots/interactive long command truncated.snap +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select-truncate/snapshots/interactive long command truncated.snap @@ -46,7 +46,7 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 0 cache hits • 0 cache misses • 1 cache disabled +Statistics: 1 tasks • 0 cache hits • 0 cache misses • 1 cache disabled Performance: 0% cache hit rate Task Details: diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select/snapshots/interactive enter with no results does nothing.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select/snapshots/interactive enter with no results does nothing.snap index dfeebaf9..653c1409 100644 --- a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select/snapshots/interactive enter with no results does nothing.snap +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select/snapshots/interactive enter with no results does nothing.snap @@ -48,7 +48,7 @@ build app Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 0 cache hits • 0 cache misses • 1 cache disabled +Statistics: 1 tasks • 0 cache hits • 0 cache misses • 1 cache disabled Performance: 0% cache hit rate Task Details: diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select/snapshots/interactive escape clears query.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select/snapshots/interactive escape clears query.snap index 6d50d728..116c06ad 100644 --- a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select/snapshots/interactive escape clears query.snap +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select/snapshots/interactive escape clears query.snap @@ -48,7 +48,7 @@ build app Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 0 cache hits • 0 cache misses • 1 cache disabled +Statistics: 1 tasks • 0 cache hits • 0 cache misses • 1 cache disabled Performance: 0% cache hit rate Task Details: diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select/snapshots/interactive scroll long list.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select/snapshots/interactive scroll long list.snap index fbd4a69a..b032faf8 100644 --- a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select/snapshots/interactive scroll long list.snap +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select/snapshots/interactive scroll long list.snap @@ -73,7 +73,7 @@ build app Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 0 cache hits • 0 cache misses • 1 cache disabled +Statistics: 1 tasks • 0 cache hits • 0 cache misses • 1 cache disabled Performance: 0% cache hit rate Task Details: diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select/snapshots/interactive search other package task.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select/snapshots/interactive search other package task.snap index 50258c2d..ccc81642 100644 --- a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select/snapshots/interactive search other package task.snap +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select/snapshots/interactive search other package task.snap @@ -31,7 +31,7 @@ typecheck lib Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 0 cache hits • 0 cache misses • 1 cache disabled +Statistics: 1 tasks • 0 cache hits • 0 cache misses • 1 cache disabled Performance: 0% cache hit rate Task Details: diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select/snapshots/interactive search preserves rating within package.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select/snapshots/interactive search preserves rating within package.snap index b844dac0..dfcbf9e9 100644 --- a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select/snapshots/interactive search preserves rating within package.snap +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select/snapshots/interactive search preserves rating within package.snap @@ -43,7 +43,7 @@ test lib Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 0 cache hits • 0 cache misses • 1 cache disabled +Statistics: 1 tasks • 0 cache hits • 0 cache misses • 1 cache disabled Performance: 0% cache hit rate Task Details: diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select/snapshots/interactive search then select.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select/snapshots/interactive search then select.snap index 6e3ac272..138d4395 100644 --- a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select/snapshots/interactive search then select.snap +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select/snapshots/interactive search then select.snap @@ -32,7 +32,7 @@ lint app Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 0 cache hits • 0 cache misses • 1 cache disabled +Statistics: 1 tasks • 0 cache hits • 0 cache misses • 1 cache disabled Performance: 0% cache hit rate Task Details: diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select/snapshots/interactive search with hash skips reorder.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select/snapshots/interactive search with hash skips reorder.snap index 881383e8..9db7109e 100644 --- a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select/snapshots/interactive search with hash skips reorder.snap +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select/snapshots/interactive search with hash skips reorder.snap @@ -34,7 +34,7 @@ build lib Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 0 cache hits • 0 cache misses • 1 cache disabled +Statistics: 1 tasks • 0 cache hits • 0 cache misses • 1 cache disabled Performance: 0% cache hit rate Task Details: diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select/snapshots/interactive select task from lib.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select/snapshots/interactive select task from lib.snap index b95f84e9..4aaa2919 100644 --- a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select/snapshots/interactive select task from lib.snap +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select/snapshots/interactive select task from lib.snap @@ -27,7 +27,7 @@ build lib Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 0 cache hits • 0 cache misses • 1 cache disabled +Statistics: 1 tasks • 0 cache hits • 0 cache misses • 1 cache disabled Performance: 0% cache hit rate Task Details: diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select/snapshots/interactive select task.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select/snapshots/interactive select task.snap index 0d770bd0..ac252807 100644 --- a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select/snapshots/interactive select task.snap +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select/snapshots/interactive select task.snap @@ -43,7 +43,7 @@ lint app Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 0 cache hits • 0 cache misses • 1 cache disabled +Statistics: 1 tasks • 0 cache hits • 0 cache misses • 1 cache disabled Performance: 0% cache hit rate Task Details: diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select/snapshots/interactive select with recursive.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select/snapshots/interactive select with recursive.snap index e9f81aef..acd834b1 100644 --- a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select/snapshots/interactive select with recursive.snap +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select/snapshots/interactive select with recursive.snap @@ -30,7 +30,7 @@ build app Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 2 tasks • 0 cache hits • 0 cache misses • 2 cache disabled +Statistics: 2 tasks • 0 cache hits • 0 cache misses • 2 cache disabled Performance: 0% cache hit rate Task Details: diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select/snapshots/interactive select with typo and transitive.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select/snapshots/interactive select with typo and transitive.snap index 75d72250..f5bee2b6 100644 --- a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select/snapshots/interactive select with typo and transitive.snap +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select/snapshots/interactive select with typo and transitive.snap @@ -20,7 +20,7 @@ build app Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 2 tasks • 0 cache hits • 0 cache misses • 2 cache disabled +Statistics: 2 tasks • 0 cache hits • 0 cache misses • 2 cache disabled Performance: 0% cache hit rate Task Details: diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select/snapshots/interactive select with typo.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select/snapshots/interactive select with typo.snap index 6d8e0d76..d710f842 100644 --- a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select/snapshots/interactive select with typo.snap +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select/snapshots/interactive select with typo.snap @@ -17,7 +17,7 @@ build app Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 1 tasks • 0 cache hits • 0 cache misses • 1 cache disabled +Statistics: 1 tasks • 0 cache hits • 0 cache misses • 1 cache disabled Performance: 0% cache hit rate Task Details: diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/topological-execution-order/snapshots/recursive build runs dependencies before dependents.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/topological-execution-order/snapshots/recursive build runs dependencies before dependents.snap index 45d3c58c..7027a21b 100644 --- a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/topological-execution-order/snapshots/recursive build runs dependencies before dependents.snap +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/topological-execution-order/snapshots/recursive build runs dependencies before dependents.snap @@ -17,7 +17,7 @@ Building app Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 3 tasks • 0 cache hits • 0 cache misses • 3 cache disabled +Statistics: 3 tasks • 0 cache hits • 0 cache misses • 3 cache disabled Performance: 0% cache hit rate Task Details: diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/topological-execution-order/snapshots/transitive build from app runs all dependencies.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/topological-execution-order/snapshots/transitive build from app runs all dependencies.snap index b86b760b..905651f8 100644 --- a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/topological-execution-order/snapshots/transitive build from app runs all dependencies.snap +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/topological-execution-order/snapshots/transitive build from app runs all dependencies.snap @@ -17,7 +17,7 @@ Building app Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 3 tasks • 0 cache hits • 0 cache misses • 3 cache disabled +Statistics: 3 tasks • 0 cache hits • 0 cache misses • 3 cache disabled Performance: 0% cache hit rate Task Details: diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/topological-execution-order/snapshots/transitive build from lib runs only its dependencies.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/topological-execution-order/snapshots/transitive build from lib runs only its dependencies.snap index b352d2da..aa074606 100644 --- a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/topological-execution-order/snapshots/transitive build from lib runs only its dependencies.snap +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/topological-execution-order/snapshots/transitive build from lib runs only its dependencies.snap @@ -14,7 +14,7 @@ Building lib Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 2 tasks • 0 cache hits • 0 cache misses • 2 cache disabled +Statistics: 2 tasks • 0 cache hits • 0 cache misses • 2 cache disabled Performance: 0% cache hit rate Task Details: diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/vite-task-smoke/snapshots/cache hit after file modification.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/vite-task-smoke/snapshots/cache hit after file modification.snap index 48a61a94..4ac8bb58 100644 --- a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/vite-task-smoke/snapshots/cache hit after file modification.snap +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/vite-task-smoke/snapshots/cache hit after file modification.snap @@ -1,7 +1,6 @@ --- source: crates/vite_task_bin/tests/e2e_snapshots/main.rs expression: e2e_outputs -input_file: crates/vite_task_bin/tests/e2e_snapshots/fixtures/vite-task-smoke --- > vp run test-task # cache miss $ echo hello ⊘ cache disabled: built-in command @@ -15,7 +14,7 @@ console.log('foo'); Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 2 tasks • 0 cache hits • 1 cache misses • 1 cache disabled +Statistics: 2 tasks • 0 cache hits • 1 cache misses • 1 cache disabled Performance: 0% cache hit rate Task Details: @@ -40,7 +39,7 @@ console.log('bar'); Vite+ Task Runner • Execution Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Statistics: 2 tasks • 0 cache hits • 1 cache misses • 1 cache disabled +Statistics: 2 tasks • 0 cache hits • 1 cache misses • 1 cache disabled Performance: 0% cache hit rate Task Details: From 7f78666326fb2f47e7fbce23409b9b9e614f9f14 Mon Sep 17 00:00:00 2001 From: branchseer Date: Sun, 15 Feb 2026 21:13:18 +0800 Subject: [PATCH 3/3] test: add E2E tests for stdio detection across all task count and cache combinations --- .../fixtures/stdio-detection/package.json | 4 ++ .../packages/other/package.json | 7 +++ .../stdio-detection/pnpm-workspace.yaml | 2 + .../fixtures/stdio-detection/snapshots.toml | 57 ++++++++++++++++++ .../multiple tasks, cache disabled.snap | 31 ++++++++++ .../snapshots/multiple tasks, cache hit.snap | 58 +++++++++++++++++++ .../snapshots/multiple tasks, cache miss.snap | 31 ++++++++++ .../single task, cache disabled.snap | 23 ++++++++ .../snapshots/single task, cache hit.snap | 42 ++++++++++++++ .../snapshots/single task, cache miss.snap | 23 ++++++++ .../fixtures/stdio-detection/vite-task.json | 13 +++++ packages/tools/package.json | 1 + packages/tools/src/check-tty.js | 15 +++++ 13 files changed, 307 insertions(+) create mode 100644 crates/vite_task_bin/tests/e2e_snapshots/fixtures/stdio-detection/package.json create mode 100644 crates/vite_task_bin/tests/e2e_snapshots/fixtures/stdio-detection/packages/other/package.json create mode 100644 crates/vite_task_bin/tests/e2e_snapshots/fixtures/stdio-detection/pnpm-workspace.yaml create mode 100644 crates/vite_task_bin/tests/e2e_snapshots/fixtures/stdio-detection/snapshots.toml create mode 100644 crates/vite_task_bin/tests/e2e_snapshots/fixtures/stdio-detection/snapshots/multiple tasks, cache disabled.snap create mode 100644 crates/vite_task_bin/tests/e2e_snapshots/fixtures/stdio-detection/snapshots/multiple tasks, cache hit.snap create mode 100644 crates/vite_task_bin/tests/e2e_snapshots/fixtures/stdio-detection/snapshots/multiple tasks, cache miss.snap create mode 100644 crates/vite_task_bin/tests/e2e_snapshots/fixtures/stdio-detection/snapshots/single task, cache disabled.snap create mode 100644 crates/vite_task_bin/tests/e2e_snapshots/fixtures/stdio-detection/snapshots/single task, cache hit.snap create mode 100644 crates/vite_task_bin/tests/e2e_snapshots/fixtures/stdio-detection/snapshots/single task, cache miss.snap create mode 100644 crates/vite_task_bin/tests/e2e_snapshots/fixtures/stdio-detection/vite-task.json create mode 100755 packages/tools/src/check-tty.js diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/stdio-detection/package.json b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/stdio-detection/package.json new file mode 100644 index 00000000..6de4ed0e --- /dev/null +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/stdio-detection/package.json @@ -0,0 +1,4 @@ +{ + "name": "stdio-detection-test", + "private": true +} diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/stdio-detection/packages/other/package.json b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/stdio-detection/packages/other/package.json new file mode 100644 index 00000000..48d6c781 --- /dev/null +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/stdio-detection/packages/other/package.json @@ -0,0 +1,7 @@ +{ + "name": "other", + "scripts": { + "check-tty": "check-tty", + "check-tty-cached": "check-tty" + } +} diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/stdio-detection/pnpm-workspace.yaml b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/stdio-detection/pnpm-workspace.yaml new file mode 100644 index 00000000..924b55f4 --- /dev/null +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/stdio-detection/pnpm-workspace.yaml @@ -0,0 +1,2 @@ +packages: + - packages/* diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/stdio-detection/snapshots.toml b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/stdio-detection/snapshots.toml new file mode 100644 index 00000000..7204c9d9 --- /dev/null +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/stdio-detection/snapshots.toml @@ -0,0 +1,57 @@ +# Tests stdio mode detection across all combinations of task count and cache state. +# +# `check-tty` prints whether each stdio stream is a TTY. In the PTY test +# environment, inherited stdio shows as "tty"; piped/null shows as "not-tty". +# +# Only one combination produces inherited (TTY) stdio: a single task with +# caching disabled. All other combinations use piped stdio — either because +# multiple tasks require labeled output, or because caching needs to capture +# or replay output. + +# ─── Single task ───────────────────────────────────────────────── + +[[e2e]] +name = "single task, cache disabled" +# Expect: all stdio inherited from terminal (tty) +steps = [ + "vp run check-tty", +] + +[[e2e]] +name = "single task, cache miss" +# Expect: stdio piped for cache capture (not-tty) +steps = [ + "vp run check-tty-cached", +] + +[[e2e]] +name = "single task, cache hit" +# Expect: first run is a miss (not-tty), second run replays cached output +steps = [ + "vp run check-tty-cached", + "vp run check-tty-cached", +] + +# ─── Multiple tasks (-r) ──────────────────────────────────────── + +[[e2e]] +name = "multiple tasks, cache disabled" +# Expect: stdio piped for labeled output (not-tty) +steps = [ + "vp run -r check-tty", +] + +[[e2e]] +name = "multiple tasks, cache miss" +# Expect: stdio piped (not-tty) +steps = [ + "vp run -r check-tty-cached", +] + +[[e2e]] +name = "multiple tasks, cache hit" +# Expect: first run is a miss (not-tty), second run replays cached output +steps = [ + "vp run -r check-tty-cached", + "vp run -r check-tty-cached", +] diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/stdio-detection/snapshots/multiple tasks, cache disabled.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/stdio-detection/snapshots/multiple tasks, cache disabled.snap new file mode 100644 index 00000000..56088f27 --- /dev/null +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/stdio-detection/snapshots/multiple tasks, cache disabled.snap @@ -0,0 +1,31 @@ +--- +source: crates/vite_task_bin/tests/e2e_snapshots/main.rs +expression: e2e_outputs +--- +> vp run -r check-tty +~/packages/other$ check-tty +stdin:not-tty +stdout:not-tty +stderr:not-tty + +$ check-tty ⊘ cache disabled: no cache config +stdin:not-tty +stdout:not-tty +stderr:not-tty + + +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + Vite+ Task Runner • Execution Summary +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +Statistics: 2 tasks • 0 cache hits • 1 cache misses • 1 cache disabled +Performance: 0% cache hit rate + +Task Details: +──────────────────────────────────────────────── + [1] other#check-tty: ~/packages/other$ check-tty ✓ + → Cache miss: no previous cache entry found + ······················································· + [2] stdio-detection-test#check-tty: $ check-tty ✓ + → Cache disabled in task configuration +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/stdio-detection/snapshots/multiple tasks, cache hit.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/stdio-detection/snapshots/multiple tasks, cache hit.snap new file mode 100644 index 00000000..707718c8 --- /dev/null +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/stdio-detection/snapshots/multiple tasks, cache hit.snap @@ -0,0 +1,58 @@ +--- +source: crates/vite_task_bin/tests/e2e_snapshots/main.rs +expression: e2e_outputs +--- +> vp run -r check-tty-cached +~/packages/other$ check-tty +stdin:not-tty +stdout:not-tty +stderr:not-tty + +$ check-tty +stdin:not-tty +stdout:not-tty +stderr:not-tty + + +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + Vite+ Task Runner • Execution Summary +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +Statistics: 2 tasks • 0 cache hits • 2 cache misses +Performance: 0% cache hit rate + +Task Details: +──────────────────────────────────────────────── + [1] other#check-tty-cached: ~/packages/other$ check-tty ✓ + → Cache miss: no previous cache entry found + ······················································· + [2] stdio-detection-test#check-tty-cached: $ check-tty ✓ + → Cache miss: no previous cache entry found +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +> vp run -r check-tty-cached +~/packages/other$ check-tty ✓ cache hit, replaying +stdin:not-tty +stdout:not-tty +stderr:not-tty + +$ check-tty ✓ cache hit, replaying +stdin:not-tty +stdout:not-tty +stderr:not-tty + + +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + Vite+ Task Runner • Execution Summary +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +Statistics: 2 tasks • 2 cache hits • 0 cache misses +Performance: 100% cache hit rate, saved in total + +Task Details: +──────────────────────────────────────────────── + [1] other#check-tty-cached: ~/packages/other$ check-tty ✓ + → Cache hit - output replayed - saved + ······················································· + [2] stdio-detection-test#check-tty-cached: $ check-tty ✓ + → Cache hit - output replayed - saved +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/stdio-detection/snapshots/multiple tasks, cache miss.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/stdio-detection/snapshots/multiple tasks, cache miss.snap new file mode 100644 index 00000000..2a2d6eeb --- /dev/null +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/stdio-detection/snapshots/multiple tasks, cache miss.snap @@ -0,0 +1,31 @@ +--- +source: crates/vite_task_bin/tests/e2e_snapshots/main.rs +expression: e2e_outputs +--- +> vp run -r check-tty-cached +~/packages/other$ check-tty +stdin:not-tty +stdout:not-tty +stderr:not-tty + +$ check-tty +stdin:not-tty +stdout:not-tty +stderr:not-tty + + +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + Vite+ Task Runner • Execution Summary +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +Statistics: 2 tasks • 0 cache hits • 2 cache misses +Performance: 0% cache hit rate + +Task Details: +──────────────────────────────────────────────── + [1] other#check-tty-cached: ~/packages/other$ check-tty ✓ + → Cache miss: no previous cache entry found + ······················································· + [2] stdio-detection-test#check-tty-cached: $ check-tty ✓ + → Cache miss: no previous cache entry found +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/stdio-detection/snapshots/single task, cache disabled.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/stdio-detection/snapshots/single task, cache disabled.snap new file mode 100644 index 00000000..afea75d1 --- /dev/null +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/stdio-detection/snapshots/single task, cache disabled.snap @@ -0,0 +1,23 @@ +--- +source: crates/vite_task_bin/tests/e2e_snapshots/main.rs +expression: e2e_outputs +--- +> vp run check-tty +$ check-tty ⊘ cache disabled: no cache config +stdin:tty +stdout:tty +stderr:tty + + +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + Vite+ Task Runner • Execution Summary +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +Statistics: 1 tasks • 0 cache hits • 0 cache misses • 1 cache disabled +Performance: 0% cache hit rate + +Task Details: +──────────────────────────────────────────────── + [1] stdio-detection-test#check-tty: $ check-tty ✓ + → Cache disabled in task configuration +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/stdio-detection/snapshots/single task, cache hit.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/stdio-detection/snapshots/single task, cache hit.snap new file mode 100644 index 00000000..5381bb2f --- /dev/null +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/stdio-detection/snapshots/single task, cache hit.snap @@ -0,0 +1,42 @@ +--- +source: crates/vite_task_bin/tests/e2e_snapshots/main.rs +expression: e2e_outputs +--- +> vp run check-tty-cached +$ check-tty +stdin:not-tty +stdout:not-tty +stderr:not-tty + + +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + Vite+ Task Runner • Execution Summary +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +Statistics: 1 tasks • 0 cache hits • 1 cache misses +Performance: 0% cache hit rate + +Task Details: +──────────────────────────────────────────────── + [1] stdio-detection-test#check-tty-cached: $ check-tty ✓ + → Cache miss: no previous cache entry found +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +> vp run check-tty-cached +$ check-tty ✓ cache hit, replaying +stdin:not-tty +stdout:not-tty +stderr:not-tty + + +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + Vite+ Task Runner • Execution Summary +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +Statistics: 1 tasks • 1 cache hits • 0 cache misses +Performance: 100% cache hit rate, saved in total + +Task Details: +──────────────────────────────────────────────── + [1] stdio-detection-test#check-tty-cached: $ check-tty ✓ + → Cache hit - output replayed - saved +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/stdio-detection/snapshots/single task, cache miss.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/stdio-detection/snapshots/single task, cache miss.snap new file mode 100644 index 00000000..2d0a4310 --- /dev/null +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/stdio-detection/snapshots/single task, cache miss.snap @@ -0,0 +1,23 @@ +--- +source: crates/vite_task_bin/tests/e2e_snapshots/main.rs +expression: e2e_outputs +--- +> vp run check-tty-cached +$ check-tty +stdin:not-tty +stdout:not-tty +stderr:not-tty + + +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + Vite+ Task Runner • Execution Summary +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +Statistics: 1 tasks • 0 cache hits • 1 cache misses +Performance: 0% cache hit rate + +Task Details: +──────────────────────────────────────────────── + [1] stdio-detection-test#check-tty-cached: $ check-tty ✓ + → Cache miss: no previous cache entry found +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/stdio-detection/vite-task.json b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/stdio-detection/vite-task.json new file mode 100644 index 00000000..626205d1 --- /dev/null +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/stdio-detection/vite-task.json @@ -0,0 +1,13 @@ +{ + "cacheScripts": true, + "tasks": { + "check-tty": { + "command": "check-tty", + "cache": false + }, + "check-tty-cached": { + "command": "check-tty", + "cache": true + } + } +} diff --git a/packages/tools/package.json b/packages/tools/package.json index a242446e..769b10ef 100644 --- a/packages/tools/package.json +++ b/packages/tools/package.json @@ -7,6 +7,7 @@ "print-file": "./src/print-file.ts", "print-env": "./src/print-env.js", "json-edit": "./src/json-edit.ts", + "check-tty": "./src/check-tty.js", "read-stdin": "./src/read-stdin.js", "replace-file-content": "./src/replace-file-content.ts" }, diff --git a/packages/tools/src/check-tty.js b/packages/tools/src/check-tty.js new file mode 100755 index 00000000..abe46e0e --- /dev/null +++ b/packages/tools/src/check-tty.js @@ -0,0 +1,15 @@ +#!/usr/bin/env node + +// Reports whether each stdio stream is connected to a TTY. +// Used to detect whether the task runner inherited stdio (TTY) or piped it. +// +// Output format: +// stdin:tty or stdin:not-tty +// stdout:tty or stdout:not-tty +// stderr:tty or stderr:not-tty +const stdinTty = process.stdin.isTTY ? 'tty' : 'not-tty'; +const stdoutTty = process.stdout.isTTY ? 'tty' : 'not-tty'; +const stderrTty = process.stderr.isTTY ? 'tty' : 'not-tty'; +console.log(`stdin:${stdinTty}`); +console.log(`stdout:${stdoutTty}`); +console.log(`stderr:${stderrTty}`);