Skip to content

Commit c5f92cb

Browse files
authored
Merge branch 'main' into codex/napi-cross-runner-fix
2 parents 41df722 + 637dc51 commit c5f92cb

4 files changed

Lines changed: 58 additions & 9 deletions

File tree

‎README.md‎

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
<p align="center">
2-
<a href="https://viteplus.dev" target="_blank" rel="noopener noreferrer">
3-
<picture>
4-
<source media="(prefers-color-scheme: dark)" srcset="./docs/public/logo-dark.svg">
5-
<source media="(prefers-color-scheme: light)" srcset="./docs/public/logo.svg">
6-
<img alt="Vite+" src="./docs/public/logo.svg" height="60">
7-
</picture>
2+
<a href="https://viteplus.dev/#gh-light-mode-only" target="_blank" rel="noopener noreferrer">
3+
<img alt="Vite+" src="./docs/public/logo.svg" width="412">
4+
</a>
5+
<a href="https://viteplus.dev/#gh-dark-mode-only" target="_blank" rel="noopener noreferrer">
6+
<img alt="Vite+" src="./docs/public/logo-dark.svg" width="412">
87
</a>
98
</p>
109

‎crates/vp_global_cli/Cargo.toml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ path = "src/main.rs"
1313

1414
[dependencies]
1515
chrono = { workspace = true }
16-
clap = { workspace = true, features = ["derive"] }
16+
clap = { workspace = true, features = ["derive", "string"] }
1717
clap_complete = { workspace = true, features = ["unstable-dynamic"] }
1818
directories = { workspace = true }
1919
dialoguer = { workspace = true }

‎crates/vp_global_cli/src/cli.rs‎

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1283,6 +1283,25 @@ fn maybe_print_runtime_header(command: &str, args: &[String], show_header: bool)
12831283
print_runtime_header(show_header);
12841284
}
12851285

1286+
fn sanitize_subcommand_aliases_for_completion(cmd: &mut clap::Command) {
1287+
for subcmd in cmd.get_subcommands_mut() {
1288+
if subcmd.get_visible_aliases().next().is_some() {
1289+
let aliases: Vec<String> = subcmd.get_all_aliases().map(str::to_string).collect();
1290+
// Clear aliases and re-add them as hidden.
1291+
*subcmd = std::mem::take(subcmd).alias(None::<&str>).aliases(aliases);
1292+
}
1293+
sanitize_subcommand_aliases_for_completion(subcmd);
1294+
}
1295+
}
1296+
1297+
/// Build a completion command with hidden aliases so clap_complete's ID-based
1298+
/// deduplication preserves canonical names.
1299+
pub fn command_for_completion() -> clap::Command {
1300+
let mut cmd = Args::command();
1301+
sanitize_subcommand_aliases_for_completion(&mut cmd);
1302+
cmd
1303+
}
1304+
12861305
/// Build a clap Command with custom help formatting matching the JS CLI output.
12871306
pub fn command_with_help() -> clap::Command {
12881307
command_with_help_with_options(RenderOptions::default())
@@ -1338,6 +1357,37 @@ mod tests {
13381357
args.iter().map(|arg| (*arg).to_string()).collect()
13391358
}
13401359

1360+
#[test]
1361+
fn command_for_completion_preserves_canonical_subcommands() {
1362+
let mut cmd = super::command_for_completion();
1363+
for (parent, alias, name) in [
1364+
(None, "i", "install"),
1365+
(None, "up", "update"),
1366+
(None, "rm", "remove"),
1367+
(None, "un", "remove"),
1368+
(None, "uninstall", "remove"),
1369+
(Some("pm"), "ls", "list"),
1370+
] {
1371+
let cmd = match parent {
1372+
Some(name) => cmd.find_subcommand_mut(name).unwrap(),
1373+
None => &mut cmd,
1374+
};
1375+
let candidates =
1376+
clap_complete::engine::complete(cmd, vec!["vp".into(), "".into()], 1, None)
1377+
.unwrap();
1378+
1379+
assert!(
1380+
candidates.iter().any(|c| c.get_value() == name),
1381+
"missing {name}: {candidates:?}"
1382+
);
1383+
assert!(
1384+
!candidates.iter().any(|c| c.get_value() == alias),
1385+
"alias {alias} should be hidden from candidates: {candidates:?}"
1386+
);
1387+
assert_eq!(cmd.find_subcommand(alias).unwrap().get_name(), name);
1388+
}
1389+
}
1390+
13411391
#[test]
13421392
fn raw_subcommand_is_the_token_as_written() {
13431393
assert_eq!(raw_subcommand(&argv(&["vp", "fmt", "src/"])), Some("fmt"));

‎crates/vp_global_cli/src/main.rs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ use vp_shared::{exit_code_from_status, output};
4040

4141
pub use crate::cli::try_parse_args_from;
4242
use crate::cli::{
43-
RenderOptions, command_with_help, raw_subcommand, run_command, run_command_with_options,
43+
RenderOptions, command_for_completion, raw_subcommand, run_command, run_command_with_options,
4444
try_parse_args_from_with_options,
4545
};
4646

@@ -414,7 +414,7 @@ async fn main() -> ExitCode {
414414
// Best-effort and silent: mid-typing values are often not (yet) dirs.
415415
let _ = apply_chdir(&current, &dir);
416416
}
417-
CompleteEnv::with_factory(command_with_help).var("VP_COMPLETE").complete();
417+
CompleteEnv::with_factory(command_for_completion).var("VP_COMPLETE").complete();
418418

419419
// Check for shim mode (invoked as node, npm, or npx)
420420
let argv0 = args.first().map(|s| s.as_str()).unwrap_or("vp");

0 commit comments

Comments
 (0)