Skip to content

Commit cf7593e

Browse files
committed
fix: stop intercepting vite as vp and synthesize vpr in task scripts (#1186)
## Summary - **Fix**: `VitePlusCommandHandler` was intercepting both `vp` and `vite` program names in task scripts. This caused `vp run dev` to fail with "Invalid vite task command" when a package.json script used bare `vite` (e.g. `"dev": "vite"`), because `vite` is a separate tool, not a vp alias. Now only `vp` and `vpr` are intercepted; `vite` runs verbatim as an external process. - **Feat**: `vpr` commands in task scripts (e.g. `"ready": "vpr hello && vpr dev"`) are now expanded to `vp run` and synthesized in-session, avoiding unnecessary process spawns. ## Test plan - [x] Added snap test `command-run-script-vite-program` covering: - bare `vite`, `vite -h`, `vite --version` all run verbatim - `vpr hello` synthesized in-session - chained `vpr hello-vpr && vpr dev-version` both synthesized - [x] All 254 global snap tests pass - [x] All 22 Rust unit tests pass - [x] Verified on real reproduction project (`vp run dev` starts Vite dev server) Closes #1176
1 parent a3c80d5 commit cf7593e

5 files changed

Lines changed: 79 additions & 8 deletions

File tree

packages/cli/binding/src/cli.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -551,18 +551,18 @@ impl CommandHandler for VitePlusCommandHandler {
551551
&mut self,
552552
command: &mut ScriptCommand,
553553
) -> anyhow::Result<HandledCommand> {
554-
// Intercept both "vp" and "vite" commands in task scripts.
555-
// "vp" is the conventional alias used in vite-plus task configs.
556-
// "vite" must also be intercepted so that `vite test`, `vite build`, etc.
557-
// in task scripts are synthesized in-session rather than spawning a new CLI process.
554+
// Intercept "vp" and "vpr" commands in task scripts so that `vp test`, `vp build`,
555+
// `vpr build`, etc. are synthesized in-session rather than spawning a new CLI process.
558556
let program = command.program.as_str();
559-
if program != "vp" && program != "vite" {
557+
if program != "vp" && program != "vpr" {
560558
return Ok(HandledCommand::Verbatim);
561559
}
562-
// Parse "vp <args>" using CLIArgs — always use "vp" as the program name
563-
// so clap shows "Usage: vp ..." even if the original command was "vite ..."
560+
// "vpr <args>" is shorthand for "vp run <args>", so prepend "run" for parsing.
561+
let is_vpr = program == "vpr";
564562
let cli_args = match CLIArgs::try_parse_from(
565-
iter::once("vp").chain(command.args.iter().map(Str::as_str)),
563+
iter::once("vp")
564+
.chain(is_vpr.then_some("run"))
565+
.chain(command.args.iter().map(Str::as_str)),
566566
) {
567567
Ok(args) => args,
568568
Err(err) if err.kind() == ErrorKind::InvalidSubcommand => {
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"name": "command-run-script-vite-program",
3+
"version": "1.0.0",
4+
"scripts": {
5+
"dev": "vite",
6+
"dev-help": "vite -h",
7+
"dev-version": "vite --version",
8+
"hello": "echo hello from script",
9+
"hello-vpr": "vpr hello",
10+
"ready": "vpr hello-vpr && vpr dev-version"
11+
},
12+
"packageManager": "pnpm@10.19.0"
13+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
const fs = require('fs');
2+
fs.mkdirSync('node_modules/.bin', { recursive: true });
3+
fs.writeFileSync(
4+
'node_modules/.bin/vite',
5+
'#!/usr/bin/env node\nconst args = process.argv.slice(2);\nconsole.log(args.length ? "vite " + args.join(" ") : "vite");\n',
6+
{ mode: 0o755 },
7+
);
8+
fs.writeFileSync('node_modules/.bin/vite.cmd', '@node "%~dp0\\vite" %*\n');
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
> node setup-bin.js
2+
> vp run dev # should run vite binary, not parse as vp subcommand
3+
VITE+ - The Unified Toolchain for the Web
4+
5+
$ vite ⊘ cache disabled
6+
vite
7+
8+
9+
> vp run dev-help # should run vite -h, not parse as vp subcommand
10+
VITE+ - The Unified Toolchain for the Web
11+
12+
$ vite -h ⊘ cache disabled
13+
vite -h
14+
15+
16+
> vp run dev-version # should run vite --version, not parse as vp subcommand
17+
VITE+ - The Unified Toolchain for the Web
18+
19+
$ vite --version ⊘ cache disabled
20+
vite --version
21+
22+
23+
> vp run hello-vpr # vpr in script should be synthesized in-session
24+
VITE+ - The Unified Toolchain for the Web
25+
26+
$ echo hello from script ⊘ cache disabled
27+
hello from script
28+
29+
30+
> vp run ready # chained vpr commands should both be synthesized
31+
VITE+ - The Unified Toolchain for the Web
32+
33+
$ echo hello from script ⊘ cache disabled
34+
hello from script
35+
36+
$ vite --version ⊘ cache disabled
37+
vite --version
38+
39+
---
40+
vp run: 0/2 cache hit (0%). (Run `vp run --last-details` for full details)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"commands": [
3+
{ "command": "node setup-bin.js", "ignoreOutput": true },
4+
"vp run dev # should run vite binary, not parse as vp subcommand",
5+
"vp run dev-help # should run vite -h, not parse as vp subcommand",
6+
"vp run dev-version # should run vite --version, not parse as vp subcommand",
7+
"vp run hello-vpr # vpr in script should be synthesized in-session",
8+
"vp run ready # chained vpr commands should both be synthesized"
9+
]
10+
}

0 commit comments

Comments
 (0)