@@ -624,10 +624,14 @@ public function get( $args, $assoc_args ) {
624624 }
625625
626626 /**
627- * Updates all installed WP-CLI packages to their latest version.
627+ * Updates installed WP-CLI packages to their latest version.
628+ *
629+ * [<package-name>...]
630+ * : One or more package names to update. If not specified, all packages will be updated.
628631 *
629632 * ## EXAMPLES
630633 *
634+ * # Update all packages.
631635 * $ wp package update
632636 * Using Composer to update packages...
633637 * ---
@@ -641,19 +645,63 @@ public function get( $args, $assoc_args ) {
641645 * Generating autoload files
642646 * ---
643647 * Success: Packages updated.
648+ *
649+ * # Update a specific package.
650+ * $ wp package update wp-cli/server-command
651+ * Using Composer to update packages...
652+ * ---
653+ * Loading composer repositories with package information
654+ * Updating dependencies
655+ * Writing lock file
656+ * Generating autoload files
657+ * ---
658+ * Success: Package updated successfully.
644659 */
645- public function update () {
660+ public function update ( $ args = [] ) {
646661 $ this ->set_composer_auth_env_var ();
662+
663+ // Validate package names if provided
664+ $ packages_to_update = [];
665+ if ( ! empty ( $ args ) ) {
666+ foreach ( $ args as $ package_name ) {
667+ $ package = $ this ->get_installed_package_by_name ( $ package_name );
668+ if ( false === $ package ) {
669+ WP_CLI ::error ( sprintf ( "Package '%s' is not installed. " , $ package_name ) );
670+ }
671+ // Use the package's pretty name (case-sensitive) from composer
672+ $ packages_to_update [] = $ package ->getPrettyName ();
673+ }
674+ }
675+
647676 $ composer = $ this ->get_composer ();
648677
649- // Set up the EventSubscriber
678+ // Set up the EventSubscriber with tracking for updates
679+ $ updated_packages = [];
650680 $ event_subscriber = new PackageManagerEventSubscriber ();
651681 $ composer ->getEventDispatcher ()->addSubscriber ( $ event_subscriber );
652682
683+ // Add a listener to track actual package updates
684+ $ composer ->getEventDispatcher ()->addListener (
685+ 'post-package-update ' ,
686+ function ( $ event ) use ( &$ updated_packages ) {
687+ $ operation = $ event ->getOperation ();
688+ if ( method_exists ( $ operation , 'getTargetPackage ' ) ) {
689+ $ package = $ operation ->getTargetPackage ();
690+ $ updated_packages [] = $ package ->getPrettyName ();
691+ }
692+ }
693+ );
694+
653695 // Set up the installer
654696 $ install = Installer::create ( new ComposerIO (), $ composer );
655697 $ install ->setUpdate ( true ); // Installer class will only override composer.lock with this flag
656698 $ install ->setPreferSource ( true ); // Use VCS when VCS for easier contributions.
699+
700+ // If specific packages are provided, use the allow list
701+ if ( ! empty ( $ packages_to_update ) ) {
702+ $ install ->setUpdateAllowList ( $ packages_to_update );
703+ }
704+
657705 WP_CLI ::log ( 'Using Composer to update packages... ' );
658706 WP_CLI ::log ( '--- ' );
659707 $ res = false ;
@@ -667,7 +715,28 @@ public function update() {
667715 // TODO: The --insecure (to be added here) flag should cause another Composer run with verify disabled.
668716
669717 if ( 0 === $ res ) {
670- WP_CLI ::success ( 'Packages updated. ' );
718+ $ num_packages = count ( $ packages_to_update );
719+ if ( $ num_packages > 0 ) {
720+ // When specific packages were requested, report on actual updates
721+ $ num_updated = count ( $ updated_packages );
722+ if ( 0 === $ num_updated ) {
723+ if ( 1 === $ num_packages ) {
724+ WP_CLI ::success ( 'Package already at latest version. ' );
725+ } else {
726+ WP_CLI ::success ( 'Packages already at latest versions. ' );
727+ }
728+ } elseif ( $ num_updated === $ num_packages ) {
729+ if ( 1 === $ num_packages ) {
730+ WP_CLI ::success ( 'Package updated successfully. ' );
731+ } else {
732+ WP_CLI ::success ( sprintf ( 'All %d packages updated successfully. ' , $ num_packages ) );
733+ }
734+ } else {
735+ WP_CLI ::success ( sprintf ( 'Updated %d of %d packages. ' , $ num_updated , $ num_packages ) );
736+ }
737+ } else {
738+ WP_CLI ::success ( 'Packages updated. ' );
739+ }
671740 } else {
672741 $ res_msg = $ res ? " (Composer return code {$ res }) " : '' ; // $res may be null apparently.
673742 WP_CLI ::error ( "Failed to update packages {$ res_msg }. " );
0 commit comments