From 826142d56fe53f9914540f6854b671f5f81db570 Mon Sep 17 00:00:00 2001 From: fengmk2 Date: Fri, 27 Mar 2026 02:22:38 +0000 Subject: [PATCH] fix(pm): allow registry commands to work outside a project (#1151) Commands like `vp info`, `vp pm search`, `vp pm ping`, and other registry/auth operations no longer require a package.json. When no project is found, these standalone commands fall back to a default npm package manager instance. Project-dependent commands (prune, pack, list, publish, rebuild, fund, audit) still require a package.json and show the existing "No package.json found." error. Closes #1108 --- crates/vite_global_cli/src/commands/mod.rs | 33 ++++++++++++++++++- crates/vite_global_cli/src/commands/pm.rs | 24 ++++++++++++-- .../command-info-no-package-json/snap.txt | 5 +++ .../command-info-no-package-json/steps.json | 6 ++++ 4 files changed, 64 insertions(+), 4 deletions(-) create mode 100644 packages/cli/snap-tests-global/command-info-no-package-json/snap.txt create mode 100644 packages/cli/snap-tests-global/command-info-no-package-json/steps.json diff --git a/crates/vite_global_cli/src/commands/mod.rs b/crates/vite_global_cli/src/commands/mod.rs index 11794f6f9a..2b3af82c2f 100644 --- a/crates/vite_global_cli/src/commands/mod.rs +++ b/crates/vite_global_cli/src/commands/mod.rs @@ -25,7 +25,7 @@ use std::{collections::HashMap, io::BufReader}; -use vite_install::package_manager::PackageManager; +use vite_install::package_manager::{PackageManager, PackageManagerType}; use vite_path::AbsolutePath; use vite_shared::{PrependOptions, prepend_to_path_env}; @@ -118,6 +118,37 @@ pub async fn build_package_manager(cwd: &AbsolutePath) -> Result Result { + match PackageManager::builder(cwd).build().await { + Ok(pm) => Ok(pm), + Err(vite_error::Error::WorkspaceError(vite_workspace::Error::PackageJsonNotFound(_))) + | Err(vite_error::Error::UnrecognizedPackageManager) => { + Ok(default_npm_package_manager(cwd)) + } + Err(e) => Err(e.into()), + } +} + +fn default_npm_package_manager(cwd: &AbsolutePath) -> PackageManager { + PackageManager { + client: PackageManagerType::Npm, + package_name: "npm".into(), + version: "latest".into(), + hash: None, + bin_name: "npm".into(), + workspace_root: cwd.to_absolute_path_buf(), + is_monorepo: false, + install_dir: cwd.to_absolute_path_buf(), + } +} + // Category A: Package manager commands pub mod add; pub mod dedupe; diff --git a/crates/vite_global_cli/src/commands/pm.rs b/crates/vite_global_cli/src/commands/pm.rs index df3196e488..85b8320594 100644 --- a/crates/vite_global_cli/src/commands/pm.rs +++ b/crates/vite_global_cli/src/commands/pm.rs @@ -29,7 +29,9 @@ use vite_install::commands::{ }; use vite_path::AbsolutePathBuf; -use super::{build_package_manager, prepend_js_runtime_to_path_env}; +use super::{ + build_package_manager, build_package_manager_or_npm_default, prepend_js_runtime_to_path_env, +}; use crate::{ cli::{ConfigCommands, DistTagCommands, OwnerCommands, PmCommands, TokenCommands}, error::Error, @@ -45,7 +47,7 @@ pub async fn execute_info( ) -> Result { prepend_js_runtime_to_path_env(&cwd).await?; - let package_manager = build_package_manager(&cwd).await?; + let package_manager = build_package_manager_or_npm_default(&cwd).await?; let options = ViewCommandOptions { package, field, json, pass_through_args }; @@ -64,7 +66,23 @@ pub async fn execute_pm_subcommand( prepend_js_runtime_to_path_env(&cwd).await?; - let package_manager = build_package_manager(&cwd).await?; + // Project-dependent commands require package.json; standalone ones fall back to npm. + let needs_project = matches!( + command, + PmCommands::Prune { .. } + | PmCommands::Pack { .. } + | PmCommands::List { .. } + | PmCommands::Publish { .. } + | PmCommands::Rebuild { .. } + | PmCommands::Fund { .. } + | PmCommands::Audit { .. } + ); + + let package_manager = if needs_project { + build_package_manager(&cwd).await? + } else { + build_package_manager_or_npm_default(&cwd).await? + }; match command { PmCommands::Prune { prod, no_optional, pass_through_args } => { diff --git a/packages/cli/snap-tests-global/command-info-no-package-json/snap.txt b/packages/cli/snap-tests-global/command-info-no-package-json/snap.txt new file mode 100644 index 0000000000..46fab479c8 --- /dev/null +++ b/packages/cli/snap-tests-global/command-info-no-package-json/snap.txt @@ -0,0 +1,5 @@ +> vp info vite@2.0.0 version # should work without package.json +2.0.0 + +> vp pm view vite@2.0.0 version # should work without package.json +2.0.0 diff --git a/packages/cli/snap-tests-global/command-info-no-package-json/steps.json b/packages/cli/snap-tests-global/command-info-no-package-json/steps.json new file mode 100644 index 0000000000..0594cbf220 --- /dev/null +++ b/packages/cli/snap-tests-global/command-info-no-package-json/steps.json @@ -0,0 +1,6 @@ +{ + "commands": [ + "vp info vite@2.0.0 version # should work without package.json", + "vp pm view vite@2.0.0 version # should work without package.json" + ] +}