Skip to content

Commit a6ef00a

Browse files
authored
Merge pull request #495 from wp-cli/copilot/add-plugin-update-identification
Add --auto-update-indicated flag to `plugin update` and `theme update` commands
2 parents 4a1978c + c2a172b commit a6ef00a

File tree

6 files changed

+257
-4
lines changed

6 files changed

+257
-4
lines changed

features/plugin-update.feature

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,94 @@ Feature: Update WordPress plugins
268268
Success: Updated 1 of 1 plugins (1 skipped).
269269
"""
270270

271+
# Tests for --auto-update-indicated feature
272+
# Note: These tests verify the flag handling and error cases.
273+
# The actual update behavior when autoupdate is true from the server
274+
# cannot be easily tested as it requires mocking WordPress.org API responses.
275+
# The update functionality itself is handled by the existing update_many method.
276+
277+
@require-wp-5.2
278+
Scenario: Show auto_update_indicated field in plugin list
279+
Given a WP install
280+
281+
When I run `wp plugin install wordpress-importer --version=0.5 --force`
282+
Then STDOUT should not be empty
283+
284+
When I run `wp plugin list --fields=name,version,update,auto_update_indicated`
285+
Then STDOUT should be a table containing rows:
286+
| name | version | update | auto_update_indicated |
287+
| wordpress-importer | 0.5 | available | no |
288+
289+
@require-wp-5.2
290+
Scenario: Using --auto-update-indicated flag when no plugins have auto-update indicated
291+
Given a WP install
292+
293+
When I run `wp plugin install wordpress-importer --version=0.5 --force`
294+
Then STDOUT should not be empty
295+
296+
When I run `wp plugin update --auto-update-indicated`
297+
Then STDOUT should be:
298+
"""
299+
Success: No plugins with server-indicated automatic updates available.
300+
"""
301+
302+
@require-wp-5.2
303+
Scenario: Error when using --version with --auto-update-indicated
304+
Given a WP install
305+
306+
When I try `wp plugin update --auto-update-indicated --version=1.0.0`
307+
Then STDERR should be:
308+
"""
309+
Error: Cannot use --version with --auto-update-indicated. The version is determined by the server.
310+
"""
311+
And the return code should be 1
312+
313+
@require-wp-5.2
314+
Scenario: Error when using --minor with --auto-update-indicated
315+
Given a WP install
316+
317+
When I try `wp plugin update --auto-update-indicated --minor`
318+
Then STDERR should be:
319+
"""
320+
Error: Cannot use --minor or --patch with --auto-update-indicated. The version is determined by the server.
321+
"""
322+
And the return code should be 1
323+
324+
@require-wp-5.2
325+
Scenario: Error when using --patch with --auto-update-indicated
326+
Given a WP install
327+
328+
When I try `wp plugin update --auto-update-indicated --patch`
329+
Then STDERR should be:
330+
"""
331+
Error: Cannot use --minor or --patch with --auto-update-indicated. The version is determined by the server.
332+
"""
333+
And the return code should be 1
334+
335+
@require-wp-5.2
336+
Scenario: Error when specifying plugin names with --auto-update-indicated
337+
Given a WP install
338+
339+
When I try `wp plugin update akismet --auto-update-indicated`
340+
Then STDERR should be:
341+
"""
342+
Error: Cannot specify plugin names with --auto-update-indicated. This flag updates all plugins with server-indicated automatic updates.
343+
"""
344+
And the return code should be 1
345+
346+
@require-wp-5.2
347+
Scenario: Preview updates with --auto-update-indicated and --dry-run
348+
Given a WP install
349+
350+
When I run `wp plugin install wordpress-importer --version=0.5 --force`
351+
Then STDOUT should not be empty
352+
353+
When I run `wp plugin update --auto-update-indicated --dry-run`
354+
Then STDOUT should be:
355+
"""
356+
Success: No plugins with server-indicated automatic updates available.
357+
"""
358+
271359
@require-wp-5.2
272360
Scenario: Updating all plugins should show the name of each plugin as it is updated
273361
Given a WP install

features/theme-update.feature

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,87 @@ Feature: Update WordPress themes
155155
1.1.1
156156
"""
157157

158+
# Tests for --auto-update-indicated feature
159+
# Note: These tests verify the flag handling and error cases.
160+
# The actual update behavior when autoupdate is true from the server
161+
# cannot be easily tested as it requires mocking WordPress.org API responses.
162+
# The update functionality itself is handled by the existing update_many method.
163+
164+
Scenario: Show auto_update_indicated field in theme list
165+
Given a WP install
166+
167+
When I run `wp theme install twentytwelve --version=3.0 --force`
168+
Then STDOUT should not be empty
169+
170+
When I run `wp theme list --fields=name,version,update,auto_update_indicated`
171+
Then STDOUT should be a table containing rows:
172+
| name | version | update | auto_update_indicated |
173+
| twentytwelve | 3.0 | available | no |
174+
175+
Scenario: Using --auto-update-indicated flag when no themes have auto-update indicated
176+
Given a WP install
177+
178+
When I run `wp theme install twentytwelve --version=3.0 --force`
179+
Then STDOUT should not be empty
180+
181+
When I run `wp theme update --auto-update-indicated`
182+
Then STDOUT should be:
183+
"""
184+
Success: No themes with server-indicated automatic updates available.
185+
"""
186+
187+
Scenario: Error when using --version with --auto-update-indicated
188+
Given a WP install
189+
190+
When I try `wp theme update --auto-update-indicated --version=1.0.0`
191+
Then STDERR should be:
192+
"""
193+
Error: Cannot use --version with --auto-update-indicated. The version is determined by the server.
194+
"""
195+
And the return code should be 1
196+
197+
Scenario: Error when using --minor with --auto-update-indicated
198+
Given a WP install
199+
200+
When I try `wp theme update --auto-update-indicated --minor`
201+
Then STDERR should be:
202+
"""
203+
Error: Cannot use --minor or --patch with --auto-update-indicated. The version is determined by the server.
204+
"""
205+
And the return code should be 1
206+
207+
Scenario: Error when using --patch with --auto-update-indicated
208+
Given a WP install
209+
210+
When I try `wp theme update --auto-update-indicated --patch`
211+
Then STDERR should be:
212+
"""
213+
Error: Cannot use --minor or --patch with --auto-update-indicated. The version is determined by the server.
214+
"""
215+
And the return code should be 1
216+
217+
Scenario: Error when specifying theme names with --auto-update-indicated
218+
Given a WP install
219+
220+
When I try `wp theme update twentytwelve --auto-update-indicated`
221+
Then STDERR should be:
222+
"""
223+
Error: Cannot specify theme names with --auto-update-indicated. This flag updates all themes with server-indicated automatic updates.
224+
"""
225+
And the return code should be 1
226+
227+
Scenario: Preview updates with --auto-update-indicated and --dry-run
228+
Given a WP install
229+
230+
When I run `wp theme install twentytwelve --version=3.0 --force`
231+
Then STDOUT should not be empty
232+
233+
When I run `wp theme update --auto-update-indicated --dry-run`
234+
Then STDOUT should be:
235+
"""
236+
Success: No themes with server-indicated automatic updates available.
237+
"""
238+
158239
@require-wp-4.5
159240
Scenario: Updating all themes should show the name of each theme as it is updated
160241
Given a WP install

src/Plugin_Command.php

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -728,6 +728,9 @@ protected function install_from_repo( $slug, $assoc_args ) {
728728
* [--insecure]
729729
* : Retry downloads without certificate validation if TLS handshake fails. Note: This makes the request vulnerable to a MITM attack.
730730
*
731+
* [--auto-update-indicated]
732+
* : Only update plugins where the server response indicates an automatic update. Updates to the version indicated by the server, not necessarily the latest version. Cannot be used with `--version`, `--minor`, or `--patch`.
733+
*
731734
* ## EXAMPLES
732735
*
733736
* $ wp plugin update bbpress --version=dev
@@ -779,6 +782,11 @@ protected function install_from_repo( $slug, $assoc_args ) {
779782
public function update( $args, $assoc_args ) {
780783
$all = Utils\get_flag_value( $assoc_args, 'all', false );
781784

785+
// Handle --auto-update-indicated flag if present.
786+
if ( $this->handle_auto_update_indicated( $args, $assoc_args ) ) {
787+
return;
788+
}
789+
782790
$args = $this->check_optional_args_and_all( $args, $all );
783791
if ( ! $args ) {
784792
return;
@@ -827,8 +835,9 @@ protected function get_item_list() {
827835
$duplicate_names[ $name ] = array();
828836
}
829837

830-
$requires = isset( $update_info ) && isset( $update_info['requires'] ) ? $update_info['requires'] : null;
831-
$requires_php = isset( $update_info ) && isset( $update_info['requires_php'] ) ? $update_info['requires_php'] : null;
838+
$requires = isset( $update_info ) && isset( $update_info['requires'] ) ? $update_info['requires'] : null;
839+
$requires_php = isset( $update_info ) && isset( $update_info['requires_php'] ) ? $update_info['requires_php'] : null;
840+
$auto_update_indicated = isset( $update_info ) && isset( $update_info['autoupdate'] ) ? (bool) $update_info['autoupdate'] : false;
832841

833842
// If an update has requires_php set, check to see if the local version of PHP meets that requirement
834843
// The plugins update API already filters out plugins that don't meet WordPress requirements, but does not
@@ -870,6 +879,7 @@ protected function get_item_list() {
870879
'description' => wordwrap( $details['Description'] ),
871880
'file' => $file,
872881
'auto_update' => in_array( $file, $auto_updates, true ),
882+
'auto_update_indicated' => $auto_update_indicated,
873883
'author' => $details['Author'],
874884
'tested_up_to' => '',
875885
'requires' => $requires,
@@ -1796,6 +1806,7 @@ public function delete( $args, $assoc_args ) {
17961806
* * requires_php
17971807
* * wporg_status
17981808
* * wporg_last_updated
1809+
* * auto_update_indicated
17991810
*
18001811
* ## EXAMPLES
18011812
*

src/Theme_Command.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -691,6 +691,9 @@ public function get( $args, $assoc_args ) {
691691
* [--insecure]
692692
* : Retry downloads without certificate validation if TLS handshake fails. Note: This makes the request vulnerable to a MITM attack.
693693
*
694+
* [--auto-update-indicated]
695+
* : Only update themes where the server response indicates an automatic update. Updates to the version indicated by the server, not necessarily the latest version. Cannot be used with `--version`, `--minor`, or `--patch`.
696+
*
694697
* ## EXAMPLES
695698
*
696699
* # Update multiple themes
@@ -741,6 +744,11 @@ public function get( $args, $assoc_args ) {
741744
public function update( $args, $assoc_args ) {
742745
$all = Utils\get_flag_value( $assoc_args, 'all', false );
743746

747+
// Handle --auto-update-indicated flag if present.
748+
if ( $this->handle_auto_update_indicated( $args, $assoc_args ) ) {
749+
return;
750+
}
751+
744752
$args = $this->check_optional_args_and_all( $args, $all );
745753
if ( ! $args ) {
746754
return;
@@ -945,6 +953,7 @@ public function delete( $args, $assoc_args ) {
945953
* * update_id
946954
* * title
947955
* * description
956+
* * auto_update_indicated
948957
*
949958
* ## EXAMPLES
950959
*

src/WP_CLI/CommandWithUpgrade.php

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,62 @@ protected function get_upgrader( $assoc_args ) {
562562
return Utils\get_upgrader( $upgrader_class, $insecure, new ExtensionUpgraderSkin() );
563563
}
564564

565+
/**
566+
* Handles the --auto-update-indicated flag logic for both plugins and themes.
567+
*
568+
* This method validates flag combinations, filters items by auto_update_indicated,
569+
* and processes updates if any items are found.
570+
*
571+
* @param array $args Positional arguments (item names).
572+
* @param array $assoc_args Associative arguments (flags).
573+
* @return bool Returns true if auto-update-indicated was handled, false otherwise.
574+
*/
575+
protected function handle_auto_update_indicated( $args, $assoc_args ) {
576+
$auto_update_indicated = Utils\get_flag_value( $assoc_args, 'auto-update-indicated', false );
577+
578+
if ( ! $auto_update_indicated ) {
579+
return false;
580+
}
581+
582+
// Don't allow --version to be set with --auto-update-indicated, as the version comes from the server.
583+
if ( isset( $assoc_args['version'] ) ) {
584+
WP_CLI::error( 'Cannot use --version with --auto-update-indicated. The version is determined by the server.' );
585+
}
586+
587+
// Don't allow --minor or --patch to be set with --auto-update-indicated, as the version comes from the server.
588+
if ( isset( $assoc_args['minor'] ) || isset( $assoc_args['patch'] ) ) {
589+
WP_CLI::error( 'Cannot use --minor or --patch with --auto-update-indicated. The version is determined by the server.' );
590+
}
591+
592+
// Don't allow item names to be specified with --auto-update-indicated.
593+
if ( ! empty( $args ) ) {
594+
WP_CLI::error( "Cannot specify {$this->item_type} names with --auto-update-indicated. This flag updates all {$this->item_type}s with server-indicated automatic updates." );
595+
}
596+
597+
// Get all items with their update info.
598+
$items = $this->get_item_list();
599+
600+
// Filter to only include items where auto_update_indicated is true.
601+
$auto_update_items = array_filter(
602+
$items,
603+
function ( $item ) {
604+
return ! empty( $item['auto_update_indicated'] );
605+
}
606+
);
607+
608+
// Get the item names to update.
609+
$args = array_values( wp_list_pluck( $auto_update_items, 'name' ) );
610+
611+
if ( empty( $args ) ) {
612+
WP_CLI::success( "No {$this->item_type}s with server-indicated automatic updates available." );
613+
return true;
614+
}
615+
616+
// Process the updates.
617+
$this->update_many( $args, $assoc_args );
618+
return true;
619+
}
620+
565621
protected function update_many( $args, $assoc_args ) {
566622
call_user_func( $this->upgrade_refresh );
567623

@@ -812,6 +868,12 @@ function ( $value ) {
812868
} elseif ( false === $value ) {
813869
$value = 'off';
814870
}
871+
} elseif ( 'auto_update_indicated' === $field ) {
872+
if ( true === $value ) {
873+
$value = 'yes';
874+
} elseif ( false === $value ) {
875+
$value = 'no';
876+
}
815877
}
816878
}
817879

src/WP_CLI/ParseThemeNameInput.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,9 @@ private function get_all_themes() {
9090
}
9191

9292
foreach ( wp_get_themes( [ 'errors' => null ] ) as $key => $theme ) {
93-
$stylesheet = $theme->get_stylesheet();
94-
$update_info = ( isset( $all_update_info->response[ $stylesheet ] ) && null !== $all_update_info->response[ $theme->get_stylesheet() ] ) ? (array) $all_update_info->response[ $theme->get_stylesheet() ] : null;
93+
$stylesheet = $theme->get_stylesheet();
94+
$update_info = ( isset( $all_update_info->response[ $stylesheet ] ) && null !== $all_update_info->response[ $theme->get_stylesheet() ] ) ? (array) $all_update_info->response[ $theme->get_stylesheet() ] : null;
95+
$auto_update_indicated = isset( $update_info ) && isset( $update_info['autoupdate'] ) ? (bool) $update_info['autoupdate'] : false;
9596

9697
// Unlike plugin update responses, the wordpress.org API does not seem to check and filter themes that don't meet
9798
// WordPress version requirements into a separate no_updates array
@@ -149,6 +150,7 @@ private function get_all_themes() {
149150
'description' => wordwrap( $theme->get( 'Description' ) ),
150151
'author' => $theme->get( 'Author' ),
151152
'auto_update' => in_array( $stylesheet, $auto_updates, true ),
153+
'auto_update_indicated' => $auto_update_indicated,
152154
'requires' => $requires,
153155
'requires_php' => $requires_php,
154156
'update_unavailable_reason' => isset( $update_unavailable_reason ) ? $update_unavailable_reason : '',

0 commit comments

Comments
 (0)