@@ -554,6 +554,23 @@ impl PackageManagerCommand {
554554/// Package manager subcommands (`vp pm <subcommand>`).
555555#[ derive( Subcommand , Debug , Clone ) ]
556556pub enum PmCommands {
557+ /// Approve dependency lifecycle scripts (install/postinstall) to run
558+ #[ command( name = "approve-builds" ) ]
559+ ApproveBuilds {
560+ /// Packages to approve. Prefix with `!` to deny (pnpm >= 11.0.0 only).
561+ /// Omit to launch interactive mode (pnpm only).
562+ packages : Vec < String > ,
563+
564+ /// Approve every package currently pending approval (pnpm >= 10.32.0).
565+ /// Mutually exclusive with positional packages.
566+ #[ arg( long, conflicts_with = "packages" ) ]
567+ all : bool ,
568+
569+ /// Additional arguments to pass through to the package manager
570+ #[ arg( last = true , allow_hyphen_values = true ) ]
571+ pass_through_args : Option < Vec < String > > ,
572+ } ,
573+
557574 /// Remove unnecessary packages
558575 Prune {
559576 /// Remove devDependencies
@@ -1182,4 +1199,56 @@ mod tests {
11821199
11831200 assert_eq ! ( error. kind( ) , clap:: error:: ErrorKind :: ValueValidation ) ;
11841201 }
1202+
1203+ #[ test]
1204+ fn approve_builds_all_conflicts_with_packages ( ) {
1205+ let error = parse_pm_command ( & [ "vp" , "pm" , "approve-builds" , "--all" , "esbuild" ] )
1206+ . expect_err ( "expected --all + positional to fail" ) ;
1207+
1208+ assert_eq ! ( error. kind( ) , clap:: error:: ErrorKind :: ArgumentConflict ) ;
1209+ }
1210+
1211+ #[ test]
1212+ fn approve_builds_all_conflicts_with_deny_packages ( ) {
1213+ let error = parse_pm_command ( & [ "vp" , "pm" , "approve-builds" , "--all" , "!core-js" ] )
1214+ . expect_err ( "expected --all + !pkg to fail" ) ;
1215+
1216+ assert_eq ! ( error. kind( ) , clap:: error:: ErrorKind :: ArgumentConflict ) ;
1217+ }
1218+
1219+ #[ test]
1220+ fn approve_builds_all_alone_parses ( ) {
1221+ let command = parse_pm_command ( & [ "vp" , "pm" , "approve-builds" , "--all" ] )
1222+ . expect ( "--all alone should parse" ) ;
1223+
1224+ assert ! ( matches!(
1225+ command,
1226+ PackageManagerCommand :: Pm ( PmCommands :: ApproveBuilds { all: true , .. } )
1227+ ) ) ;
1228+ }
1229+
1230+ #[ test]
1231+ fn approve_builds_packages_alone_parses ( ) {
1232+ let command = parse_pm_command ( & [ "vp" , "pm" , "approve-builds" , "esbuild" , "fsevents" ] )
1233+ . expect ( "positional packages should parse" ) ;
1234+
1235+ assert ! ( matches!(
1236+ command,
1237+ PackageManagerCommand :: Pm ( PmCommands :: ApproveBuilds { all: false , .. } )
1238+ ) ) ;
1239+ }
1240+
1241+ #[ test]
1242+ fn approve_builds_pass_through_args_capture ( ) {
1243+ let command =
1244+ parse_pm_command ( & [ "vp" , "pm" , "approve-builds" , "esbuild" , "--" , "--workspace-root" ] )
1245+ . expect ( "pass-through args should parse" ) ;
1246+
1247+ let PackageManagerCommand :: Pm ( PmCommands :: ApproveBuilds { pass_through_args, .. } ) =
1248+ command
1249+ else {
1250+ panic ! ( "expected ApproveBuilds variant" ) ;
1251+ } ;
1252+ assert_eq ! ( pass_through_args, Some ( vec![ "--workspace-root" . to_string( ) ] ) ) ;
1253+ }
11851254}
0 commit comments