@@ -10,6 +10,10 @@ use std::process::ExitStatus;
1010
1111use chrono:: Local ;
1212use owo_colors:: OwoColorize ;
13+ use vite_install:: package_manager:: {
14+ PackageManagerType , package_manager_bin_path, package_manager_install_dir,
15+ resolve_package_manager_from_package_json,
16+ } ;
1317use vite_path:: { AbsolutePath , AbsolutePathBuf } ;
1418use vite_shared:: output;
1519
@@ -27,6 +31,10 @@ const LABEL_WIDTH: usize = 10;
2731
2832/// Execute the which command.
2933pub async fn execute ( cwd : AbsolutePathBuf , tool : & str ) -> Result < ExitStatus , Error > {
34+ if let Some ( status) = execute_package_manager_tool ( & cwd, tool) ? {
35+ return Ok ( status) ;
36+ }
37+
3038 // Check if this is a core tool
3139 if CORE_TOOLS . contains ( & tool) {
3240 return execute_core_tool ( cwd, tool) . await ;
@@ -44,6 +52,67 @@ pub async fn execute(cwd: AbsolutePathBuf, tool: &str) -> Result<ExitStatus, Err
4452 Ok ( exit_status ( 1 ) )
4553}
4654
55+ fn execute_package_manager_tool (
56+ cwd : & AbsolutePath ,
57+ tool : & str ,
58+ ) -> Result < Option < ExitStatus > , Error > {
59+ let Some ( expected_type) = package_manager_type_for_tool ( tool) else {
60+ return Ok ( None ) ;
61+ } ;
62+ let Some ( resolution) = resolve_package_manager_from_package_json ( cwd) ? else {
63+ return Ok ( None ) ;
64+ } ;
65+ if resolution. package_manager_type != expected_type {
66+ return Ok ( None ) ;
67+ }
68+
69+ let Some ( install_dir) =
70+ package_manager_install_dir ( resolution. package_manager_type , & resolution. version )
71+ else {
72+ return Ok ( None ) ;
73+ } ;
74+ let name = resolution. package_manager_type . to_string ( ) ;
75+ let bin_name = package_manager_bin_name ( tool, resolution. package_manager_type ) ;
76+ let tool_path = package_manager_bin_path ( & install_dir, bin_name) ;
77+
78+ println ! ( "{}" , tool_path. as_path( ) . display( ) ) ;
79+ println ! (
80+ " {:<LABEL_WIDTH$} {}" ,
81+ "Package:" . dimmed( ) ,
82+ format!( "{}@{}" , name, resolution. version) . bright_blue( )
83+ ) ;
84+ println ! (
85+ " {:<LABEL_WIDTH$} {}" ,
86+ "Source:" . dimmed( ) ,
87+ resolution. source_path. as_path( ) . display( ) . to_string( ) . dimmed( )
88+ ) ;
89+
90+ Ok ( Some ( ExitStatus :: default ( ) ) )
91+ }
92+
93+ fn package_manager_type_for_tool ( tool : & str ) -> Option < PackageManagerType > {
94+ match tool {
95+ "npm" | "npx" => Some ( PackageManagerType :: Npm ) ,
96+ "pnpm" | "pnpx" => Some ( PackageManagerType :: Pnpm ) ,
97+ "yarn" | "yarnpkg" => Some ( PackageManagerType :: Yarn ) ,
98+ "bun" | "bunx" => Some ( PackageManagerType :: Bun ) ,
99+ _ => None ,
100+ }
101+ }
102+
103+ fn package_manager_bin_name ( tool : & str , package_manager_type : PackageManagerType ) -> & str {
104+ match ( tool, package_manager_type) {
105+ ( "npx" , PackageManagerType :: Npm ) => "npx" ,
106+ ( "pnpx" , PackageManagerType :: Pnpm ) => "pnpx" ,
107+ ( "yarnpkg" , PackageManagerType :: Yarn ) => "yarnpkg" ,
108+ ( "bunx" , PackageManagerType :: Bun ) => "bunx" ,
109+ ( _, PackageManagerType :: Npm ) => "npm" ,
110+ ( _, PackageManagerType :: Pnpm ) => "pnpm" ,
111+ ( _, PackageManagerType :: Yarn ) => "yarn" ,
112+ ( _, PackageManagerType :: Bun ) => "bun" ,
113+ }
114+ }
115+
47116/// Execute which for a core tool (node, npm, npx).
48117async fn execute_core_tool ( cwd : AbsolutePathBuf , tool : & str ) -> Result < ExitStatus , Error > {
49118 // Resolve version for current directory
0 commit comments