@@ -8,10 +8,20 @@ use std::{ffi::OsStr, process::ExitStatus};
88use clap:: { CommandFactory , FromArgMatches , Parser , Subcommand } ;
99use clap_complete:: ArgValueCompleter ;
1010use tokio:: runtime:: Runtime ;
11- use vite_path:: { AbsolutePath , AbsolutePathBuf } ;
11+ use vite_path:: AbsolutePathBuf ;
1212use vite_pm_cli:: PackageManagerCommand ;
13+ use vite_shared:: output;
1314
14- use crate :: { commands, error:: Error , help} ;
15+ use crate :: {
16+ commands:: {
17+ self ,
18+ env:: { global_install, package_metadata:: PackageMetadata } ,
19+ } ,
20+ error:: Error ,
21+ help,
22+ } ;
23+
24+ const DEFAULT_GLOBAL_INSTALL_CONCURRENCY : usize = 5 ;
1525
1626#[ derive( Clone , Copy , Debug ) ]
1727pub struct RenderOptions {
@@ -532,19 +542,24 @@ async fn run_package_manager_command(
532542) -> Result < ExitStatus , Error > {
533543 match command {
534544 PackageManagerCommand :: Install {
535- global : true , packages : Some ( pkgs) , node, force, ..
536- } if !pkgs. is_empty ( ) => managed_install ( & pkgs, node. as_deref ( ) , force) . await ,
545+ global : true ,
546+ packages : Some ( pkgs) ,
547+ node,
548+ force,
549+ concurrency,
550+ ..
551+ } if !pkgs. is_empty ( ) => managed_install ( & pkgs, node. as_deref ( ) , force, concurrency) . await ,
537552
538- PackageManagerCommand :: Add { global : true , ref packages , ref node , .. } => {
539- managed_install ( packages, node. as_deref ( ) , false ) . await
540- }
553+ PackageManagerCommand :: Add {
554+ global : true , ref packages, ref node, concurrency , ..
555+ } => managed_install ( packages , node . as_deref ( ) , false , concurrency ) . await ,
541556
542557 PackageManagerCommand :: Remove { global : true , ref packages, dry_run, .. } => {
543558 managed_uninstall ( packages, dry_run) . await
544559 }
545560
546- PackageManagerCommand :: Update { global : true , ref packages, .. } => {
547- managed_update ( & cwd , packages ) . await
561+ PackageManagerCommand :: Update { global : true , ref packages, concurrency , .. } => {
562+ managed_update ( packages , concurrency ) . await
548563 }
549564
550565 // `pm list -g` lists vite-plus-managed globals, not the underlying PM's.
@@ -562,20 +577,28 @@ async fn run_package_manager_command(
562577 }
563578}
564579
565- // snap-test fixtures expect bare lines (no "error:"/"info:" prefix), so
566- // these helpers use `output::raw_stderr`/`output::raw` rather than the
567- // prefixed `output::error`/`output::info`.
568580async fn managed_install (
569581 packages : & [ String ] ,
570582 node : Option < & str > ,
571583 force : bool ,
584+ concurrency : Option < usize > ,
572585) -> Result < ExitStatus , Error > {
573- for package in packages {
574- if let Err ( e) = crate :: commands:: env:: global_install:: install ( package, node, force) . await {
575- vite_shared:: output:: raw_stderr ( & format ! ( "Failed to install {package}: {e}" ) ) ;
576- return Ok ( exit_status ( 1 ) ) ;
577- }
586+ if let Err ( ( package_name, error) ) = crate :: commands:: env:: global_install:: install (
587+ packages,
588+ node,
589+ force,
590+ concurrency. unwrap_or ( DEFAULT_GLOBAL_INSTALL_CONCURRENCY ) ,
591+ false ,
592+ )
593+ . await
594+ {
595+ output:: error ( & format ! (
596+ "Failed to install {}: {error}" ,
597+ package_name. as_deref( ) . unwrap_or( "global packages" )
598+ ) ) ;
599+ return Ok ( exit_status ( 1 ) ) ;
578600 }
601+
579602 Ok ( ExitStatus :: default ( ) )
580603}
581604
@@ -589,21 +612,14 @@ async fn managed_uninstall(packages: &[String], dry_run: bool) -> Result<ExitSta
589612 Ok ( ExitStatus :: default ( ) )
590613}
591614
592- fn is_global_package_up_to_date (
593- installed_version : & str ,
594- registry_version : & str ,
595- installed_node_version : & str ,
596- target_node_version : & str ,
597- ) -> bool {
615+ fn is_global_package_up_to_date ( installed_version : & str , registry_version : & str ) -> bool {
598616 installed_version. trim ( ) == registry_version. trim ( )
599- && installed_node_version. trim ( ) == target_node_version. trim ( )
600617}
601618
602- async fn managed_update ( cwd : & AbsolutePath , packages : & [ String ] ) -> Result < ExitStatus , Error > {
603- use crate :: commands:: env:: {
604- config:: resolve_version, global_install, package_metadata:: PackageMetadata ,
605- } ;
606-
619+ async fn managed_update (
620+ packages : & [ String ] ,
621+ concurrency : Option < usize > ,
622+ ) -> Result < ExitStatus , Error > {
607623 let all_packages = if packages. is_empty ( ) {
608624 let all = PackageMetadata :: list_all ( ) . await ?;
609625 if all. is_empty ( ) {
@@ -615,27 +631,14 @@ async fn managed_update(cwd: &AbsolutePath, packages: &[String]) -> Result<ExitS
615631 None
616632 } ;
617633
618- let target_node_version = resolve_version ( cwd) . await ?. version ;
619634 let mut to_update: Vec < String > = Vec :: new ( ) ;
620635 let mut skipped = 0usize ;
621636
622637 if let Some ( all) = all_packages {
623638 for metadata in all {
624- if metadata. platform . node . trim ( ) != target_node_version. trim ( ) {
625- to_update. push ( metadata. name . clone ( ) ) ;
626- continue ;
627- }
628-
629- match global_install:: latest_package_version ( & metadata. name , Some ( & target_node_version) )
630- . await
631- {
639+ match global_install:: latest_package_version ( & metadata. name ) . await {
632640 Ok ( latest_version)
633- if is_global_package_up_to_date (
634- & metadata. version ,
635- & latest_version,
636- & metadata. platform . node ,
637- & target_node_version,
638- ) =>
641+ if is_global_package_up_to_date ( & metadata. version , & latest_version) =>
639642 {
640643 vite_shared:: output:: raw ( & format ! (
641644 "{} is already up to date (v{})." ,
@@ -662,21 +665,9 @@ async fn managed_update(cwd: &AbsolutePath, packages: &[String]) -> Result<ExitS
662665
663666 let ( package_name, _) = global_install:: parse_package_spec ( package) ;
664667 if let Some ( metadata) = PackageMetadata :: load ( & package_name) . await ? {
665- if metadata. platform . node . trim ( ) != target_node_version. trim ( ) {
666- to_update. push ( package. clone ( ) ) ;
667- continue ;
668- }
669-
670- match global_install:: latest_package_version ( package, Some ( & target_node_version) )
671- . await
672- {
668+ match global_install:: latest_package_version ( package) . await {
673669 Ok ( latest_version)
674- if is_global_package_up_to_date (
675- & metadata. version ,
676- & latest_version,
677- & metadata. platform . node ,
678- & target_node_version,
679- ) =>
670+ if is_global_package_up_to_date ( & metadata. version , & latest_version) =>
680671 {
681672 vite_shared:: output:: raw ( & format ! (
682673 "{} is already up to date (v{})." ,
@@ -704,11 +695,21 @@ async fn managed_update(cwd: &AbsolutePath, packages: &[String]) -> Result<ExitS
704695 return Ok ( ExitStatus :: default ( ) ) ;
705696 }
706697
707- for package in & to_update {
708- if let Err ( e) = global_install:: install ( package, Some ( & target_node_version) , false ) . await {
709- vite_shared:: output:: raw_stderr ( & format ! ( "Failed to update {package}: {e}" ) ) ;
710- return Ok ( exit_status ( 1 ) ) ;
711- }
698+ // Call reinstall logic
699+ if let Err ( ( package_name, error) ) = global_install:: install (
700+ & to_update,
701+ None ,
702+ false ,
703+ concurrency. unwrap_or ( DEFAULT_GLOBAL_INSTALL_CONCURRENCY ) ,
704+ true ,
705+ )
706+ . await
707+ {
708+ output:: error ( & format ! (
709+ "Failed to update {}: {error}" ,
710+ package_name. as_deref( ) . unwrap_or( "global packages" )
711+ ) ) ;
712+ return Ok ( exit_status ( 1 ) ) ;
712713 }
713714 Ok ( ExitStatus :: default ( ) )
714715}
@@ -961,17 +962,12 @@ mod tests {
961962
962963 #[ test]
963964 fn skips_global_update_when_registry_and_node_versions_match ( ) {
964- assert ! ( is_global_package_up_to_date( "5.9.3" , "5.9.3" , "20.18.0" , "20.18.0" ) ) ;
965+ assert ! ( is_global_package_up_to_date( "5.9.3" , "5.9.3" ) ) ;
965966 }
966967
967968 #[ test]
968969 fn updates_global_package_when_registry_version_differs_from_installed_version ( ) {
969- assert ! ( !is_global_package_up_to_date( "5.9.2" , "5.9.3" , "20.18.0" , "20.18.0" ) ) ;
970- }
971-
972- #[ test]
973- fn updates_global_package_when_node_version_differs_from_target_version ( ) {
974- assert ! ( !is_global_package_up_to_date( "5.9.3" , "5.9.3" , "20.18.0" , "24.15.0" ) ) ;
970+ assert ! ( !is_global_package_up_to_date( "5.9.2" , "5.9.3" ) ) ;
975971 }
976972
977973 #[ test]
0 commit comments