@@ -512,10 +512,16 @@ public function path( $args ) {
512512 }
513513
514514 /**
515- * Updates all installed WP-CLI packages to their latest version.
515+ * Updates installed WP-CLI packages to their latest version.
516+ *
517+ * ## OPTIONS
518+ *
519+ * [<package-name>...]
520+ * : One or more package names to update. If not specified, all packages will be updated.
516521 *
517522 * ## EXAMPLES
518523 *
524+ * # Update all packages.
519525 * $ wp package update
520526 * Using Composer to update packages...
521527 * ---
@@ -529,19 +535,63 @@ public function path( $args ) {
529535 * Generating autoload files
530536 * ---
531537 * Success: Packages updated.
538+ *
539+ * # Update a specific package.
540+ * $ wp package update wp-cli/server-command
541+ * Using Composer to update packages...
542+ * ---
543+ * Loading composer repositories with package information
544+ * Updating dependencies
545+ * Writing lock file
546+ * Generating autoload files
547+ * ---
548+ * Success: Package updated successfully.
532549 */
533- public function update () {
550+ public function update ( $ args = [] ) {
534551 $ this ->set_composer_auth_env_var ();
552+
553+ // Validate package names if provided
554+ $ packages_to_update = [];
555+ if ( ! empty ( $ args ) ) {
556+ foreach ( $ args as $ package_name ) {
557+ $ package = $ this ->get_installed_package_by_name ( $ package_name );
558+ if ( false === $ package ) {
559+ WP_CLI ::error ( sprintf ( "Package '%s' is not installed. " , $ package_name ) );
560+ }
561+ // Use the package's pretty name (case-sensitive) from composer
562+ $ packages_to_update [] = $ package ->getPrettyName ();
563+ }
564+ }
565+
535566 $ composer = $ this ->get_composer ();
536567
537- // Set up the EventSubscriber
568+ // Set up the EventSubscriber with tracking for updates
569+ $ updated_packages = [];
538570 $ event_subscriber = new PackageManagerEventSubscriber ();
539571 $ composer ->getEventDispatcher ()->addSubscriber ( $ event_subscriber );
540572
573+ // Add a listener to track actual package updates
574+ $ composer ->getEventDispatcher ()->addListener (
575+ 'post-package-update ' ,
576+ function ( $ event ) use ( &$ updated_packages ) {
577+ $ operation = $ event ->getOperation ();
578+ if ( method_exists ( $ operation , 'getTargetPackage ' ) ) {
579+ $ package = $ operation ->getTargetPackage ();
580+ $ updated_packages [] = $ package ->getPrettyName ();
581+ }
582+ }
583+ );
584+
541585 // Set up the installer
542586 $ install = Installer::create ( new ComposerIO (), $ composer );
543587 $ install ->setUpdate ( true ); // Installer class will only override composer.lock with this flag
544588 $ install ->setPreferSource ( true ); // Use VCS when VCS for easier contributions.
589+
590+ // If specific packages are provided, use the allow list
591+ if ( ! empty ( $ packages_to_update ) ) {
592+ $ install ->setUpdateAllowList ( $ packages_to_update );
593+ }
594+
545595 WP_CLI ::log ( 'Using Composer to update packages... ' );
546596 WP_CLI ::log ( '--- ' );
547597 $ res = false ;
@@ -555,7 +605,28 @@ public function update() {
555605 // TODO: The --insecure (to be added here) flag should cause another Composer run with verify disabled.
556606
557607 if ( 0 === $ res ) {
558- WP_CLI ::success ( 'Packages updated. ' );
608+ $ num_packages = count ( $ packages_to_update );
609+ if ( $ num_packages > 0 ) {
610+ // When specific packages were requested, report on actual updates
611+ $ num_updated = count ( $ updated_packages );
612+ if ( 0 === $ num_updated ) {
613+ if ( 1 === $ num_packages ) {
614+ WP_CLI ::success ( 'Package already at latest version. ' );
615+ } else {
616+ WP_CLI ::success ( 'Packages already at latest versions. ' );
617+ }
618+ } elseif ( $ num_updated === $ num_packages ) {
619+ if ( 1 === $ num_packages ) {
620+ WP_CLI ::success ( 'Package updated successfully. ' );
621+ } else {
622+ WP_CLI ::success ( sprintf ( 'All %d packages updated successfully. ' , $ num_packages ) );
623+ }
624+ } else {
625+ WP_CLI ::success ( sprintf ( 'Updated %d of %d packages. ' , $ num_updated , $ num_packages ) );
626+ }
627+ } else {
628+ WP_CLI ::success ( 'Packages updated. ' );
629+ }
559630 } else {
560631 $ res_msg = $ res ? " (Composer return code {$ res }) " : '' ; // $res may be null apparently.
561632 WP_CLI ::error ( "Failed to update packages {$ res_msg }. " );
0 commit comments