Skip to content

Commit 803dd30

Browse files
committed
Merge branch 'main' into copilot/add-package-version-command
2 parents 8143559 + b2b5700 commit 803dd30

6 files changed

Lines changed: 187 additions & 8 deletions

File tree

.github/workflows/copilot-setup-steps.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,17 @@ jobs:
1717

1818
steps:
1919
- name: Checkout code
20-
uses: actions/checkout@v6
20+
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
2121

2222
- name: Check existence of composer.json file
2323
id: check_composer_file
24-
uses: andstor/file-existence-action@v3
24+
uses: andstor/file-existence-action@076e0072799f4942c8bc574a82233e1e4d13e9d6 # v3
2525
with:
2626
files: "composer.json"
2727

2828
- name: Set up PHP environment
2929
if: steps.check_composer_file.outputs.files_exists == 'true'
30-
uses: shivammathur/setup-php@v2
30+
uses: shivammathur/setup-php@44454db4f0199b8b9685a5d763dc37cbf79108e1 # v2
3131
with:
3232
php-version: 'latest'
3333
ini-values: zend.assertions=1, error_reporting=-1, display_errors=On
@@ -38,7 +38,7 @@ jobs:
3838

3939
- name: Install Composer dependencies & cache dependencies
4040
if: steps.check_composer_file.outputs.files_exists == 'true'
41-
uses: ramsey/composer-install@v3
41+
uses: ramsey/composer-install@3cf229dc2919194e9e36783941438d17239e8520 # v3
4242
env:
4343
COMPOSER_ROOT_VERSION: dev-${{ github.event.repository.default_branch }}
4444
with:

.github/workflows/issue-triage.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,13 @@ name: Issue and PR Triage
1313
required: false
1414
type: string
1515

16+
permissions:
17+
issues: write
18+
pull-requests: write
19+
actions: write
20+
contents: read
21+
models: read
22+
1623
jobs:
1724
issue-triage:
1825
uses: wp-cli/.github/.github/workflows/reusable-issue-triage.yml@main

.github/workflows/regenerate-readme.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ on:
1010
- "features/**"
1111
- "README.md"
1212

13+
permissions:
14+
contents: write
15+
pull-requests: write
16+
1317
jobs:
1418
regenerate-readme:
1519
uses: wp-cli/.github/.github/workflows/reusable-regenerate-readme.yml@main

.github/workflows/welcome-new-contributors.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ on:
77
- main
88
- master
99

10+
permissions:
11+
pull-requests: write
12+
1013
jobs:
1114
welcome:
1215
uses: wp-cli/.github/.github/workflows/reusable-welcome-new-contributors.yml@main

features/package-update.feature

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,3 +98,99 @@ Feature: Update WP-CLI packages
9898
"""
9999
Success: Packages updated.
100100
"""
101+
102+
Scenario: Update a specific package by name
103+
Given an empty directory
104+
105+
When I run `wp package install wp-cli-test/updateable-package:v1.0.0`
106+
Then STDOUT should contain:
107+
"""
108+
Success: Package installed.
109+
"""
110+
111+
When I run `wp package install danielbachhuber/wp-cli-reset-post-date-command`
112+
Then STDOUT should contain:
113+
"""
114+
Success: Package installed.
115+
"""
116+
117+
When I run `sed -i.bak s/v1.0.0/\>=1.0.0/g {PACKAGE_PATH}/composer.json`
118+
Then the return code should be 0
119+
120+
When I run `wp package update wp-cli-test/updateable-package`
121+
Then STDOUT should contain:
122+
"""
123+
Using Composer to update packages...
124+
"""
125+
And STDOUT should contain:
126+
"""
127+
Success: Package updated successfully.
128+
"""
129+
130+
When I run `wp package list --fields=name,update`
131+
Then STDOUT should be a table containing rows:
132+
| name | update |
133+
| wp-cli-test/updateable-package | none |
134+
135+
Scenario: Update multiple specific packages by name
136+
Given an empty directory
137+
138+
When I run `wp package install wp-cli-test/updateable-package:v1.0.0`
139+
Then STDOUT should contain:
140+
"""
141+
Success: Package installed.
142+
"""
143+
144+
When I run `wp package install danielbachhuber/wp-cli-reset-post-date-command`
145+
Then STDOUT should contain:
146+
"""
147+
Success: Package installed.
148+
"""
149+
150+
When I run `sed -i.bak s/v1.0.0/\>=1.0.0/g {PACKAGE_PATH}/composer.json`
151+
Then the return code should be 0
152+
153+
When I run `wp package update wp-cli-test/updateable-package danielbachhuber/wp-cli-reset-post-date-command`
154+
Then STDOUT should contain:
155+
"""
156+
Using Composer to update packages...
157+
"""
158+
And STDOUT should contain:
159+
"""
160+
Success: Updated 1 of 2 packages.
161+
"""
162+
163+
Scenario: Update package that is already up to date
164+
Given an empty directory
165+
166+
When I run `wp package install danielbachhuber/wp-cli-reset-post-date-command`
167+
Then STDOUT should contain:
168+
"""
169+
Success: Package installed.
170+
"""
171+
172+
When I run `wp package update danielbachhuber/wp-cli-reset-post-date-command`
173+
Then STDOUT should contain:
174+
"""
175+
Using Composer to update packages...
176+
"""
177+
And STDOUT should contain:
178+
"""
179+
Success: Package already at latest version.
180+
"""
181+
182+
Scenario: Error when trying to update a non-existent package
183+
Given an empty directory
184+
185+
When I run `wp package install danielbachhuber/wp-cli-reset-post-date-command`
186+
Then STDOUT should contain:
187+
"""
188+
Success: Package installed.
189+
"""
190+
191+
When I try `wp package update non-existent/package`
192+
Then STDERR should contain:
193+
"""
194+
Error: Package 'non-existent/package' is not installed.
195+
"""
196+
And the return code should be 1

src/Package_Command.php

Lines changed: 73 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)