Skip to content

Commit 5fc11da

Browse files
committed
fix(cli): suppress Vite+ header in non-TTY and git hook contexts
The banner was printing from every `vp` invocation, cluttering captured output (lefthook/husky, `execSync`, CI pipes, pagers) and the git commit flow when a shell pre-commit hook runs `vp check --fix` — in the hook the colour detection is unreliable, so the banner also rendered in a degraded style. Banner emission now gates on two signals at every call site: - `stdout.is_terminal()` — catches piped/redirected contexts. - `GIT_INDEX_FILE` env var — catches direct shell hooks that inherit the terminal for stdout. Git sets this for pre-commit, commit-msg, and prepare-commit-msg, which is where `vp check --fix` typically runs. Centralised behind `vite_shared::header::print_header()` on the Rust side and a new `printHeader()` helper in `packages/cli/src/utils/ terminal.ts` on the Node CLI side. The interactive `prompts.intro()` in `vp create` and the interactive top-level command picker are left alone — they only run when genuinely interactive. Snap fixtures regenerated to reflect the removed banner lines.
1 parent 90e7beb commit 5fc11da

202 files changed

Lines changed: 84 additions & 583 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

crates/vite_global_cli/src/cli.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2102,8 +2102,7 @@ fn print_runtime_header(show_header: bool) {
21022102
if !show_header {
21032103
return;
21042104
}
2105-
println!("{}", vite_shared::header::vite_plus_header());
2106-
println!();
2105+
vite_shared::header::print_header();
21072106
}
21082107

21092108
/// Build a clap Command with custom help formatting matching the JS CLI output.
@@ -2120,7 +2119,7 @@ pub fn command_with_help_with_options(render_options: RenderOptions) -> clap::Co
21202119
fn apply_custom_help(cmd: clap::Command, render_options: RenderOptions) -> clap::Command {
21212120
let after_help = help::render_help_doc(&help::top_level_help_doc());
21222121
let options_heading = help::render_heading("Options");
2123-
let header = if render_options.show_header {
2122+
let header = if render_options.show_header && vite_shared::header::should_print_header() {
21242123
vite_shared::header::vite_plus_header()
21252124
} else {
21262125
String::new()

crates/vite_global_cli/src/commands/env/mod.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,7 @@ use crate::{
3232
};
3333

3434
fn print_env_header() {
35-
println!("{}", vite_shared::header::vite_plus_header());
36-
println!();
35+
vite_shared::header::print_header();
3736
}
3837

3938
fn should_print_env_header(subcommand: &EnvSubcommands) -> bool {
@@ -140,8 +139,7 @@ pub async fn execute(cwd: AbsolutePathBuf, args: EnvArgs) -> Result<ExitStatus,
140139
if !crate::help::print_unified_clap_help_for_path(&["env"]) {
141140
// Fallback to clap's built-in help printer if unified rendering fails.
142141
use clap::CommandFactory;
143-
println!("{}", vite_shared::header::vite_plus_header());
144-
println!();
142+
vite_shared::header::print_header();
145143
crate::cli::Args::command()
146144
.find_subcommand("env")
147145
.unwrap()

crates/vite_global_cli/src/commands/version.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,8 +161,7 @@ fn detect_system_node_version() -> Option<String> {
161161

162162
/// Execute the `--version` command.
163163
pub async fn execute(cwd: AbsolutePathBuf) -> Result<ExitStatus, Error> {
164-
println!("{}", vite_shared::header::vite_plus_header());
165-
println!();
164+
vite_shared::header::print_header();
166165

167166
println!("vp v{}", env!("CARGO_PKG_VERSION"));
168167
println!();

crates/vite_global_cli/src/help.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -993,8 +993,7 @@ pub fn maybe_print_unified_clap_subcommand_help(argv: &[String]) -> bool {
993993
}
994994

995995
if command_path.len() == 1 && command_path[0] == "env" {
996-
println!("{}", vite_shared::header::vite_plus_header());
997-
println!();
996+
vite_shared::header::print_header();
998997
println!("{}", render_help_doc(&env_help_doc()));
999998
return true;
1000999
}
@@ -1024,17 +1023,15 @@ pub fn maybe_print_unified_delegate_help(
10241023
};
10251024

10261025
if show_header {
1027-
println!("{}", vite_shared::header::vite_plus_header());
1028-
println!();
1026+
vite_shared::header::print_header();
10291027
}
10301028
println!("{}", render_help_doc(&doc));
10311029
true
10321030
}
10331031

10341032
pub fn print_unified_clap_help_for_path(command_path: &[&str]) -> bool {
10351033
if command_path == ["env"] {
1036-
println!("{}", vite_shared::header::vite_plus_header());
1037-
println!();
1034+
vite_shared::header::print_header();
10381035
println!("{}", render_help_doc(&env_help_doc()));
10391036
return true;
10401037
}
@@ -1057,8 +1054,7 @@ pub fn print_unified_clap_help_for_path(command_path: &[&str]) -> bool {
10571054
..doc
10581055
};
10591056

1060-
println!("{}", vite_shared::header::vite_plus_header());
1061-
println!();
1057+
vite_shared::header::print_header();
10621058
println!("{}", render_owned_help_doc(&doc));
10631059
true
10641060
}

crates/vite_global_cli/src/main.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,7 @@ fn extract_invalid_subcommand_details(error: &clap::Error) -> Option<InvalidSubc
116116
}
117117

118118
fn print_invalid_subcommand_error(details: &InvalidSubcommandDetails) {
119-
println!("{}", vite_shared::header::vite_plus_header());
120-
println!();
119+
vite_shared::header::print_header();
121120

122121
let highlighted_subcommand = details.invalid_subcommand.bright_blue().to_string();
123122
output::error(&format!("Command '{highlighted_subcommand}' not found"));
@@ -237,8 +236,7 @@ fn print_unknown_argument_error(error: &clap::Error) -> bool {
237236
return false;
238237
};
239238

240-
println!("{}", vite_shared::header::vite_plus_header());
241-
println!();
239+
vite_shared::header::print_header();
242240

243241
let highlighted_argument = invalid_argument.bright_blue().to_string();
244242
output::error(&format!("Unexpected argument '{highlighted_argument}'"));

crates/vite_shared/src/header.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,36 @@ pub fn vite_plus_header() -> String {
536536
render_header_variant(header_colors.blue, &header_colors.suffix_gradient, true, true)
537537
}
538538

539+
/// Whether the Vite+ banner should be emitted in the current environment.
540+
///
541+
/// The banner is cosmetic and assumes an interactive terminal; it's
542+
/// suppressed when:
543+
/// - stdout is piped or redirected (lefthook/husky, `execSync`, CI, pagers).
544+
/// - a git commit-flow hook is running. Direct shell hooks inherit the
545+
/// terminal for stdout, so the TTY check alone doesn't catch them; git
546+
/// sets `GIT_INDEX_FILE` for pre-commit / commit-msg / prepare-commit-msg,
547+
/// which is where `vp check --fix` typically runs.
548+
#[must_use]
549+
pub fn should_print_header() -> bool {
550+
if !std::io::stdout().is_terminal() {
551+
return false;
552+
}
553+
if std::env::var_os("GIT_INDEX_FILE").is_some() {
554+
return false;
555+
}
556+
true
557+
}
558+
559+
/// Emit the Vite+ banner (header line + trailing blank line) to stdout, but
560+
/// only when the environment is interactive. No-op otherwise.
561+
pub fn print_header() {
562+
if !should_print_header() {
563+
return;
564+
}
565+
println!("{}", vite_plus_header());
566+
println!();
567+
}
568+
539569
#[cfg(all(test, unix))]
540570
mod tests {
541571
use std::io::{BufReader, Cursor};

packages/cli/binding/src/cli/help.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -169,14 +169,16 @@ fn print_unknown_argument_error(error: &clap::Error) -> bool {
169169
}
170170

171171
pub(super) fn print_help() {
172-
let header = vite_shared::header::vite_plus_header();
172+
let header = if vite_shared::header::should_print_header() {
173+
format!("{}\n\n", vite_shared::header::vite_plus_header())
174+
} else {
175+
String::new()
176+
};
173177
let bold = "\x1b[1m";
174178
let bold_underline = "\x1b[1;4m";
175179
let reset = "\x1b[0m";
176180
println!(
177-
"{header}
178-
179-
{bold_underline}Usage:{reset} {bold}vp{reset} <COMMAND>
181+
"{header}{bold_underline}Usage:{reset} {bold}vp{reset} <COMMAND>
180182
181183
{bold_underline}Core Commands:{reset}
182184
{bold}dev{reset} Run the development server

packages/cli/snap-tests-global/cli-helper-message/snap.txt

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
> vp -h # show help message
2-
VITE+ - The Unified Toolchain for the Web
32

43
Usage: vp [COMMAND]
54

@@ -55,8 +54,6 @@ Options:
5554
-h, --help Print help
5655

5756
> vp -V # show version
58-
VITE+ - The Unified Toolchain for the Web
59-
6057
vp v<semver>
6158

6259
Local vite-plus:
@@ -76,8 +73,6 @@ Environment:
7673
Node.js v<semver>
7774

7875
> vp install -h # show install help message
79-
VITE+ - The Unified Toolchain for the Web
80-
8176
Usage: vp install [OPTIONS] [PACKAGES]... [-- <PASS_THROUGH_ARGS>...]
8277

8378
Install all dependencies, or add packages if package names are provided
@@ -116,8 +111,6 @@ Documentation: https://viteplus.dev/guide/install
116111

117112

118113
> vp add -h # show add help message
119-
VITE+ - The Unified Toolchain for the Web
120-
121114
Usage: vp add [OPTIONS] <PACKAGES>... [-- <PASS_THROUGH_ARGS>...]
122115

123116
Add packages to dependencies
@@ -146,8 +139,6 @@ Documentation: https://viteplus.dev/guide/install
146139

147140

148141
> vp remove -h # show remove help message
149-
VITE+ - The Unified Toolchain for the Web
150-
151142
Usage: vp remove [OPTIONS] <PACKAGES>... [-- <PASS_THROUGH_ARGS>...]
152143

153144
Remove packages from dependencies
@@ -171,8 +162,6 @@ Documentation: https://viteplus.dev/guide/install
171162

172163

173164
> vp update -h # show update help message
174-
VITE+ - The Unified Toolchain for the Web
175-
176165
Usage: vp update [OPTIONS] [PACKAGES]... [-- <PASS_THROUGH_ARGS>...]
177166

178167
Update packages to their latest versions
@@ -199,8 +188,6 @@ Documentation: https://viteplus.dev/guide/install
199188

200189

201190
> vp link -h # show link help message
202-
VITE+ - The Unified Toolchain for the Web
203-
204191
Usage: vp link [PACKAGE|DIR] [ARGS]...
205192

206193
Link packages for local development
@@ -216,8 +203,6 @@ Documentation: https://viteplus.dev/guide/install
216203

217204

218205
> vp unlink -h # show unlink help message
219-
VITE+ - The Unified Toolchain for the Web
220-
221206
Usage: vp unlink [OPTIONS] [PACKAGE|DIR] [ARGS]...
222207

223208
Unlink packages
@@ -234,8 +219,6 @@ Documentation: https://viteplus.dev/guide/install
234219

235220

236221
> vp dedupe -h # show dedupe help message
237-
VITE+ - The Unified Toolchain for the Web
238-
239222
Usage: vp dedupe [OPTIONS] [-- <PASS_THROUGH_ARGS>...]
240223

241224
Deduplicate dependencies
@@ -251,8 +234,6 @@ Documentation: https://viteplus.dev/guide/install
251234

252235

253236
> vp outdated -h # show outdated help message
254-
VITE+ - The Unified Toolchain for the Web
255-
256237
Usage: vp outdated [OPTIONS] [PACKAGES]... [-- <PASS_THROUGH_ARGS>...]
257238

258239
Check for outdated packages
@@ -279,8 +260,6 @@ Documentation: https://viteplus.dev/guide/install
279260

280261

281262
> vp why -h # show why help message
282-
VITE+ - The Unified Toolchain for the Web
283-
284263
Usage: vp why [OPTIONS] <PACKAGES>... [-- <PASS_THROUGH_ARGS>...]
285264

286265
Show why a package is installed
@@ -309,8 +288,6 @@ Documentation: https://viteplus.dev/guide/install
309288

310289

311290
> vp info -h # show info help message
312-
VITE+ - The Unified Toolchain for the Web
313-
314291
Usage: vp info [OPTIONS] <PACKAGE> [FIELD] [-- <PASS_THROUGH_ARGS>...]
315292

316293
View package information from the registry
@@ -328,8 +305,6 @@ Documentation: https://viteplus.dev/guide/install
328305

329306

330307
> vp pm -h # show pm help message
331-
VITE+ - The Unified Toolchain for the Web
332-
333308
Usage: vp pm <COMMAND>
334309

335310
Forward a command to the package manager
@@ -362,8 +337,6 @@ Documentation: https://viteplus.dev/guide/install
362337

363338

364339
> vp env # show env help message
365-
VITE+ - The Unified Toolchain for the Web
366-
367340
Usage: vp env [COMMAND]
368341

369342
Manage Node.js versions
@@ -423,8 +396,6 @@ Documentation: https://viteplus.dev/guide/env
423396

424397

425398
> vp upgrade -h # show upgrade help message
426-
VITE+ - The Unified Toolchain for the Web
427-
428399
Usage: vp upgrade [OPTIONS] [VERSION]
429400

430401
Update vp itself to the latest version

packages/cli/snap-tests-global/command-add-bun/snap.txt

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
> vp add --help # should show help
2-
VITE+ - The Unified Toolchain for the Web
3-
42
Usage: vp add [OPTIONS] <PACKAGES>... [-- <PASS_THROUGH_ARGS>...]
53

64
Add packages to dependencies
@@ -71,8 +69,6 @@ installed test-vite-plus-install@<semver>
7169
}
7270

7371
> vp install test-vite-plus-package@1.0.0 --save-peer && cat package.json # should install package alias for add
74-
VITE+ - The Unified Toolchain for the Web
75-
7672
bun add v<semver> (af24e281)
7773

7874
installed test-vite-plus-package@<semver>

packages/cli/snap-tests-global/command-add-npm10-with-workspace/snap.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,8 +180,6 @@ up to date in <variable>ms
180180
}
181181

182182
> vp install test-vite-plus-package@1.0.0 --filter "*" --workspace-root -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should install packages alias for add command
183-
VITE+ - The Unified Toolchain for the Web
184-
185183

186184
added 1 package in <variable>ms
187185
{

0 commit comments

Comments
 (0)