Skip to content

Commit 3a69079

Browse files
authored
feat: show command with cwd in summary (#186)
# Improve task execution display in UI This PR enhances the task execution display by showing both the command and working directory in the task summary: - Shows the command in the task summary for better visibility - Displays the working directory prefix when not empty (e.g., `~/subfolder$ command`) - Uses consistent styling for cache miss messages - Extracts command display logic to a reusable function - Updates all snapshot tests to reflect the new display format These changes make it easier to understand what commands are being executed and in which directory, improving the overall user experience.
1 parent aff7bf6 commit 3a69079

18 files changed

Lines changed: 104 additions & 81 deletions

File tree

crates/vite_task/src/schedule.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use crate::{
1414
config::{DisplayOptions, ResolvedTask, Workspace},
1515
execute::{OutputKind, execute_task},
1616
fs::FileSystem,
17+
ui::get_display_command,
1718
};
1819

1920
#[derive(Debug)]
@@ -26,6 +27,7 @@ pub struct ExecutionPlan {
2627
/// Status of a task before execution
2728
#[derive(Debug, Serialize, Deserialize, Clone)]
2829
pub struct PreExecutionStatus {
30+
pub display_command: Option<String>,
2931
pub task: ResolvedTask,
3032
pub cache_status: CacheStatus,
3133
pub display_options: DisplayOptions,
@@ -148,7 +150,12 @@ impl ExecutionPlan {
148150
.await?;
149151

150152
let has_inner_runner = step.resolved_config.config.command.has_inner_runner();
151-
let pre_execution_status = PreExecutionStatus { task: step, cache_status, display_options };
153+
let pre_execution_status = PreExecutionStatus {
154+
display_command: get_display_command(display_options, &step),
155+
task: step,
156+
cache_status,
157+
display_options,
158+
};
152159

153160
// The inner runner is expected to display the command and the cache status. The outer runner will skip displaying them.
154161
if !has_inner_runner {

crates/vite_task/src/ui.rs

Lines changed: 37 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use vite_path::RelativePath;
66

77
use crate::{
88
cache::{CacheMiss, FingerprintMismatch},
9+
config::{DisplayOptions, ResolvedTask},
910
fingerprint::PostRunFingerprintMismatch,
1011
schedule::{CacheStatus, ExecutionFailure, ExecutionSummary, PreExecutionStatus},
1112
};
@@ -22,27 +23,38 @@ impl<T: owo_colors::OwoColorize> ColorizeExt for T {
2223
}
2324
}
2425

26+
const COMMAND_STYLE: Style = Style::new().cyan();
27+
const CACHE_MISS_STYLE: Style = Style::new().purple();
28+
29+
pub fn get_display_command(display_options: DisplayOptions, task: &ResolvedTask) -> Option<String> {
30+
let display_command = if display_options.hide_command {
31+
if let Ok(outer_command) = std::env::var("VITE_OUTER_COMMAND") {
32+
outer_command
33+
} else {
34+
return None;
35+
}
36+
} else {
37+
task.resolved_command.fingerprint.command.to_string()
38+
};
39+
40+
let cwd = task.resolved_command.fingerprint.cwd.as_str();
41+
Some(format!(
42+
"{}$ {}",
43+
if cwd.is_empty() { format_args!("") } else { format_args!("~/{}", cwd) },
44+
display_command
45+
))
46+
}
47+
2548
/// Displayed before the task is executed
2649
impl Display for PreExecutionStatus {
2750
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
28-
let display_command = format!("$ {}", &self.task.resolved_command.fingerprint.command);
29-
let outer_command =
30-
format!("$ {}", std::env::var("VITE_OUTER_COMMAND").unwrap_or_default());
31-
let display_command: Option<Styled<&String>> = if self.display_options.hide_command {
32-
if outer_command != "$ " {
33-
Some(outer_command.style(Style::new().cyan()))
34-
} else {
35-
None
36-
}
37-
} else {
38-
Some(display_command.style(Style::new().cyan()))
39-
};
51+
let display_command = self.display_command.as_ref().map(|cmd| cmd.style(COMMAND_STYLE));
4052

4153
// Print cache status with improved, shorter messages
4254
match &self.cache_status {
4355
CacheStatus::CacheMiss(CacheMiss::NotFound) => {
4456
// No message for "Cache not found" as requested
45-
tracing::debug!("{}", "Cache not found".style(Style::new().yellow()));
57+
tracing::debug!("{}", "Cache not found".style(CACHE_MISS_STYLE));
4658
if let Some(display_command) = &display_command {
4759
writeln!(f, "{}", display_command)?;
4860
}
@@ -86,7 +98,7 @@ impl Display for PreExecutionStatus {
8698
format_args!("✗ cache miss: {}, executing", reason),
8799
if display_command.is_some() { ")" } else { "" },
88100
)
89-
.style(Style::new().yellow().dimmed())
101+
.style(CACHE_MISS_STYLE.dimmed())
90102
)?;
91103
}
92104
CacheStatus::CacheHit => {
@@ -166,7 +178,7 @@ impl Display for ExecutionSummary {
166178
"Statistics:".style(Style::new().bold()),
167179
format!("{} tasks", total).style(Style::new().bright_white()),
168180
format!("• {} cache hits", cache_hits).style(Style::new().green()),
169-
format!("• {} cache misses", cache_misses).style(Style::new().yellow()),
181+
format!("• {} cache misses", cache_misses).style(CACHE_MISS_STYLE),
170182
if failed > 0 {
171183
format!("• {} failed", failed).style(Style::new().red()).to_string()
172184
} else if skipped > 0 {
@@ -186,7 +198,7 @@ impl Display for ExecutionSummary {
186198
cache_rate.to_string().style(if cache_rate >= 75 {
187199
Style::new().green().bold()
188200
} else if cache_rate >= 50 {
189-
Style::new().yellow()
201+
CACHE_MISS_STYLE
190202
} else {
191203
Style::new().red()
192204
})
@@ -212,6 +224,10 @@ impl Display for ExecutionSummary {
212224
task_name.style(Style::new().bright_white().bold())
213225
)?;
214226

227+
if let Some(display_command) = &status.pre_execution_status.display_command {
228+
write!(f, ": {}", display_command.style(COMMAND_STYLE))?;
229+
}
230+
215231
// Execution result icon and status
216232
match &status.execution_result {
217233
Ok(exit_status) if *exit_status == 0 => {
@@ -246,14 +262,14 @@ impl Display for ExecutionSummary {
246262
)?;
247263
}
248264
CacheStatus::CacheMiss(miss) => {
249-
write!(f, " {}", "→ Cache miss: ".style(Style::new().yellow()))?;
265+
write!(f, " {}", "→ Cache miss: ".style(CACHE_MISS_STYLE))?;
250266

251267
match miss {
252268
CacheMiss::NotFound => {
253269
writeln!(
254270
f,
255271
"{}",
256-
"no previous cache entry found".style(Style::new().yellow())
272+
"no previous cache entry found".style(CACHE_MISS_STYLE)
257273
)?;
258274
}
259275
CacheMiss::FingerprintMismatch(mismatch) => {
@@ -336,13 +352,13 @@ impl Display for ExecutionSummary {
336352
writeln!(
337353
f,
338354
"{}",
339-
"configuration changed".style(Style::new().yellow())
355+
"configuration changed".style(CACHE_MISS_STYLE)
340356
)?;
341357
} else {
342358
writeln!(
343359
f,
344360
"{}",
345-
changes.join("; ").style(Style::new().yellow())
361+
changes.join("; ").style(CACHE_MISS_STYLE)
346362
)?;
347363
}
348364
}
@@ -353,7 +369,7 @@ impl Display for ExecutionSummary {
353369
f,
354370
"{}",
355371
format!("content of input '{}' changed", path)
356-
.style(Style::new().yellow())
372+
.style(CACHE_MISS_STYLE)
357373
)?;
358374
}
359375
}

packages/cli/snap-tests/associate-existing-cache/snap.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ Performance: 0% cache hit rate
1212

1313
Task Details:
1414
────────────────────────────────────────────────
15-
[1] script1 ✓
15+
[1] script1: $ echo hello
1616
→ Cache miss: no previous cache entry found
1717
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1818

@@ -30,7 +30,7 @@ Performance: 100% cache hit rate
3030

3131
Task Details:
3232
────────────────────────────────────────────────
33-
[1] script2 ✓
33+
[1] script2: $ echo hello
3434
→ Cache hit - output replayed
3535
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
3636

@@ -49,6 +49,6 @@ Performance: 0% cache hit rate
4949

5050
Task Details:
5151
────────────────────────────────────────────────
52-
[1] script2 ✓
52+
[1] script2: $ echo world
5353
→ Cache miss: command changed from echo hello to echo world
5454
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

packages/cli/snap-tests/cache-clean/snap.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ Performance: 0% cache hit rate
1212

1313
Task Details:
1414
────────────────────────────────────────────────
15-
[1] hello ✓
15+
[1] hello: $ echo hello
1616
→ Cache miss: no previous cache entry found
1717
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1818

@@ -30,7 +30,7 @@ Performance: 100% cache hit rate
3030

3131
Task Details:
3232
────────────────────────────────────────────────
33-
[1] hello ✓
33+
[1] hello: $ echo hello
3434
→ Cache hit - output replayed
3535
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
3636

@@ -49,7 +49,7 @@ Performance: 0% cache hit rate
4949

5050
Task Details:
5151
────────────────────────────────────────────────
52-
[1] hello ✓
52+
[1] hello: $ echo hello
5353
→ Cache miss: no previous cache entry found
5454
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
5555

@@ -68,6 +68,6 @@ Performance: 0% cache hit rate
6868

6969
Task Details:
7070
────────────────────────────────────────────────
71-
[1] hello ✓
71+
[1] hello: $ echo hello
7272
→ Cache miss: no previous cache entry found
7373
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

packages/cli/snap-tests/cache-miss-command-change/snap.txt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ Performance: 0% cache hit rate
1515

1616
Task Details:
1717
────────────────────────────────────────────────
18-
[1] hello(subcommand 0) ✓
18+
[1] hello(subcommand 0): $ echo foo
1919
→ Cache miss: no previous cache entry found
2020
·······················································
21-
[2] hello ✓
21+
[2] hello: $ echo bar
2222
→ Cache miss: no previous cache entry found
2323
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
2424

@@ -40,10 +40,10 @@ Performance: 50% cache hit rate
4040

4141
Task Details:
4242
────────────────────────────────────────────────
43-
[1] hello(subcommand 0) ✓
43+
[1] hello(subcommand 0): $ echo baz
4444
→ Cache miss: command changed from echo foo to echo baz
4545
·······················································
46-
[2] hello ✓
46+
[2] hello: $ echo bar
4747
→ Cache hit - output replayed
4848
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
4949

@@ -62,6 +62,6 @@ Performance: 100% cache hit rate
6262

6363
Task Details:
6464
────────────────────────────────────────────────
65-
[1] hello ✓
65+
[1] hello: $ echo bar
6666
→ Cache hit - output replayed
6767
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

packages/cli/snap-tests/change-passthrough-env-config/snap.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ Performance: 0% cache hit rate
1212

1313
Task Details:
1414
────────────────────────────────────────────────
15-
[1] hello ✓
15+
[1] hello: $ node -p process.env.MY_ENV
1616
→ Cache miss: no previous cache entry found
1717
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1818

@@ -30,7 +30,7 @@ Performance: 100% cache hit rate
3030

3131
Task Details:
3232
────────────────────────────────────────────────
33-
[1] hello ✓
33+
[1] hello: $ node -p process.env.MY_ENV
3434
→ Cache hit - output replayed
3535
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
3636

@@ -49,6 +49,6 @@ Performance: 0% cache hit rate
4949

5050
Task Details:
5151
────────────────────────────────────────────────
52-
[1] hello ✓
52+
[1] hello: $ node -p process.env.MY_ENV
5353
→ Cache miss: pass-through env configuration changed from ["MY_ENV"] to ["MY_ENV, MY_ENV2"]
5454
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

packages/cli/snap-tests/check-oxlint-env/snap.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ Performance: 0% cache hit rate
1212

1313
Task Details:
1414
────────────────────────────────────────────────
15-
[1] check-oxlint-env#check ✓
15+
[1] check-oxlint-env#check: $ node check.js
1616
→ Cache miss: no previous cache entry found
1717
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1818

@@ -32,6 +32,6 @@ Performance: 0% cache hit rate
3232

3333
Task Details:
3434
────────────────────────────────────────────────
35-
[1] check-oxlint-env#check ✓
35+
[1] check-oxlint-env#check: $ node check.js
3636
→ Cache miss: no previous cache entry found
3737
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

packages/cli/snap-tests/exit-code/snap.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ Performance: 0% cache hit rate
1212

1313
Task Details:
1414
────────────────────────────────────────────────
15-
[1] script1 ✓
15+
[1] script1: $ echo success
1616
→ Cache miss: no previous cache entry found
1717
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1818

@@ -30,7 +30,7 @@ Performance: 100% cache hit rate
3030

3131
Task Details:
3232
────────────────────────────────────────────────
33-
[1] script1 ✓
33+
[1] script1: $ echo success
3434
→ Cache hit - output replayed
3535
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
3636

@@ -48,7 +48,7 @@ Performance: 0% cache hit rate
4848

4949
Task Details:
5050
────────────────────────────────────────────────
51-
[1] script2 ✗ (exit code: 1)
51+
[1] script2: $ node failure.js ✗ (exit code: 1)
5252
→ Cache miss: no previous cache entry found
5353
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
5454

@@ -66,6 +66,6 @@ Performance: 0% cache hit rate
6666

6767
Task Details:
6868
────────────────────────────────────────────────
69-
[1] script2 ✗ (exit code: 1)
69+
[1] script2: $ node failure.js ✗ (exit code: 1)
7070
→ Cache miss: no previous cache entry found
7171
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

packages/cli/snap-tests/individual-cache-for-adt-args/snap.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ Performance: 0% cache hit rate
1212

1313
Task Details:
1414
────────────────────────────────────────────────
15-
[1] echo ✓
15+
[1] echo: $ echo a
1616
→ Cache miss: no previous cache entry found
1717
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1818

@@ -30,7 +30,7 @@ Performance: 0% cache hit rate
3030

3131
Task Details:
3232
────────────────────────────────────────────────
33-
[1] echo ✓
33+
[1] echo: $ echo b
3434
→ Cache miss: no previous cache entry found
3535
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
3636

@@ -48,7 +48,7 @@ Performance: 100% cache hit rate
4848

4949
Task Details:
5050
────────────────────────────────────────────────
51-
[1] echo ✓
51+
[1] echo: $ echo a
5252
→ Cache hit - output replayed
5353
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
5454

@@ -66,6 +66,6 @@ Performance: 100% cache hit rate
6666

6767
Task Details:
6868
────────────────────────────────────────────────
69-
[1] echo ✓
69+
[1] echo: $ echo b
7070
→ Cache hit - output replayed
7171
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

0 commit comments

Comments
 (0)