Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1378,6 +1378,12 @@ wp theme update [<theme>...] [--all] [--exclude=<theme-names>] [--format=<format
[--exclude=<theme-names>]
Comma separated list of theme names that should be excluded from updating.

[--minor]
Only perform updates for minor releases (e.g. from 1.3 to 1.4 instead of 2.0)

[--patch]
Only perform updates for patch releases (e.g. from 1.3 to 1.3.3 instead of 1.4)

[--format=<format>]
Render output in a particular format.
---
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
],
"require": {
"composer/semver": "^1.4 || ^2 || ^3",
"wp-cli/wp-cli": "^2.5.1"
"wp-cli/wp-cli": "^2.10"
},
"require-dev": {
"wp-cli/cache-command": "^2.0",
Expand Down
42 changes: 42 additions & 0 deletions features/theme-update.feature
Original file line number Diff line number Diff line change
Expand Up @@ -113,3 +113,45 @@ Feature: Update WordPress themes
"""
Error: Can't find the requested theme's version 1.4.2 in the WordPress.org theme repository (HTTP code 404).
"""

Scenario: Error when both --minor and --patch are provided
Given a WP install

When I try `wp theme update --patch --minor --all`
Then STDERR should be:
"""
Error: --minor and --patch cannot be used together.
"""
And the return code should be 1

Scenario: Update a theme to its latest minor release
Given a WP install
And I run `wp theme install --force twentytwelve --version=3.0`

When I run `wp theme update twentytwelve --minor`
Then STDOUT should contain:
"""
Success: Updated 1 of 1 themes.
"""

When I run `wp theme get twentytwelve --field=version`
Then STDOUT should be:
"""
3.9
"""

Scenario: Update a theme to its latest patch release
Given a WP install
And I run `wp theme install --force twentytwelve --version=1.1`

When I run `wp theme update twentytwelve --patch`
Then STDOUT should contain:
"""
Success: Updated 1 of 1 themes.
"""

When I run `wp theme get twentytwelve --field=version`
Then STDOUT should be:
"""
1.1.1
"""
8 changes: 7 additions & 1 deletion src/Theme_Command.php
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,7 @@ protected function get_item_list() {
protected function filter_item_list( $items, $args ) {
$theme_files = array();
foreach ( $args as $arg ) {
$theme_files[] = $this->fetcher->get_check( $arg )->get_stylesheet_directory();
$theme_files[] = $this->fetcher->get_check( $arg )->get_stylesheet();
}

return Utils\pick_fields( $items, $theme_files );
Expand Down Expand Up @@ -589,6 +589,12 @@ public function get( $args, $assoc_args ) {
* [--exclude=<theme-names>]
* : Comma separated list of theme names that should be excluded from updating.
*
* [--minor]
* : Only perform updates for minor releases (e.g. from 1.3 to 1.4 instead of 2.0)
*
* [--patch]
* : Only perform updates for patch releases (e.g. from 1.3 to 1.3.3 instead of 1.4)
*
* [--format=<format>]
* : Render output in a particular format.
* ---
Expand Down
40 changes: 27 additions & 13 deletions src/WP_CLI/CommandWithUpgrade.php
Original file line number Diff line number Diff line change
Expand Up @@ -348,12 +348,14 @@ protected function update_many( $args, $assoc_args ) {
$minor = (bool) Utils\get_flag_value( $assoc_args, 'minor', false );
$patch = (bool) Utils\get_flag_value( $assoc_args, 'patch', false );

if ( 'plugin' === $this->item_type
&& ( $minor || $patch ) ) {
if (
in_array( $this->item_type, [ 'plugin', 'theme' ], true ) &&
( $minor || $patch )
) {
$type = $minor ? 'minor' : 'patch';
$insecure = (bool) Utils\get_flag_value( $assoc_args, 'insecure', false );

$items_to_update = self::get_minor_or_patch_updates( $items_to_update, $type, $insecure, true );
$items_to_update = self::get_minor_or_patch_updates( $items_to_update, $type, $insecure, true, $this->item_type );
}

$exclude = Utils\get_flag_value( $assoc_args, 'exclude' );
Expand All @@ -368,11 +370,10 @@ protected function update_many( $args, $assoc_args ) {
}
unset( $items_to_update[ $plugin->file ] );
} elseif ( 'theme' === $this->item_type ) {
$theme_root = get_theme_root() . '/' . $item;
if ( ! is_dir( $theme_root ) ) {
continue;
$theme = wp_get_theme( $item );
if ( $theme->exists() ) {
unset( $items_to_update[ $theme->get_stylesheet() ] );
}
unset( $items_to_update[ $theme_root ] );
}
}
}
Expand Down Expand Up @@ -429,8 +430,13 @@ protected function update_many( $args, $assoc_args ) {
$transient_filter = function ( $transient ) use ( $items_to_update ) {
foreach ( $items_to_update as $name => $item_data ) {
if ( isset( $transient->response[ $name ] ) ) {
$transient->response[ $name ]->new_version = $item_data['update_version'];
$transient->response[ $name ]->package = $item_data['update_package'];
if ( is_object( $transient->response[ $name ] ) ) {
$transient->response[ $name ]->new_version = $item_data['update_version'];
$transient->response[ $name ]->package = $item_data['update_package'];
} else {
$transient->response[ $name ]['new_version'] = $item_data['update_version'];
$transient->response[ $name ]['package'] = $item_data['update_package'];
}
}
}
return $transient;
Expand Down Expand Up @@ -611,19 +617,27 @@ private function get_color( $status ) {
}

/**
* Get the minor or patch version for plugins with available updates
* Get the minor or patch version for plugins and themes with available updates
*
* @param array $items Plugins with updates.
* @param array $items Items with updates.
* @param string $type Either 'minor' or 'patch'.
* @param bool $insecure Whether to retry without certificate validation on TLS handshake failure.
* @param bool $require_stable Whether to require stable version when comparing versions.
* @param string $item_type Item type, either 'plugin' or 'theme'.
* @return array
*/
private function get_minor_or_patch_updates( $items, $type, $insecure, $require_stable ) {
private function get_minor_or_patch_updates( $items, $type, $insecure, $require_stable, $item_type ) {
$wp_org_api = new WpOrgApi( [ 'insecure' => $insecure ] );
foreach ( $items as $i => $item ) {
try {
$data = $wp_org_api->get_plugin_info( $item['name'] );
$data = call_user_func(
[ $wp_org_api, "get_{$item_type}_info" ],
$item['name'],
// The default.
'en_US',
// We are only interested in the versions field.
[ 'versions' => true ]
);
} catch ( Exception $exception ) {
unset( $items[ $i ] );
continue;
Expand Down
20 changes: 10 additions & 10 deletions src/WP_CLI/ParseThemeNameInput.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,38 +76,38 @@ private function get_all_themes() {
}

foreach ( wp_get_themes() as $key => $theme ) {
$file = $theme->get_stylesheet_directory();
$stylesheet = $theme->get_stylesheet();

$update_info = ( isset( $all_update_info->response[ $theme->get_stylesheet() ] ) && null !== $all_update_info->response[ $theme->get_stylesheet() ] ) ? (array) $all_update_info->response[ $theme->get_stylesheet() ] : null;
$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;

$items[ $file ] = [
$items[ $stylesheet ] = [
'name' => $key,
'status' => $this->get_status( $theme ),
'update' => (bool) $update_info,
'update_version' => isset( $update_info['new_version'] ) ? $update_info['new_version'] : null,
'update_package' => isset( $update_info['package'] ) ? $update_info['package'] : null,
'version' => $theme->get( 'Version' ),
'update_id' => $theme->get_stylesheet(),
'update_id' => $stylesheet,
'title' => $theme->get( 'Name' ),
'description' => wordwrap( $theme->get( 'Description' ) ),
'author' => $theme->get( 'Author' ),
'auto_update' => in_array( $theme->get_stylesheet(), $auto_updates, true ),
'auto_update' => in_array( $stylesheet, $auto_updates, true ),
];

// Compare version and update information in theme list.
if ( isset( $theme_version_info[ $key ] ) && false === $theme_version_info[ $key ] ) {
$items[ $file ]['update'] = 'version higher than expected';
$items[ $stylesheet ]['update'] = 'version higher than expected';
}

if ( is_multisite() ) {
if ( ! empty( $site_enabled[ $key ] ) && ! empty( $network_enabled[ $key ] ) ) {
$items[ $file ]['enabled'] = 'network,site';
$items[ $stylesheet ]['enabled'] = 'network,site';
} elseif ( ! empty( $network_enabled[ $key ] ) ) {
$items[ $file ]['enabled'] = 'network';
$items[ $stylesheet ]['enabled'] = 'network';
} elseif ( ! empty( $site_enabled[ $key ] ) ) {
$items[ $file ]['enabled'] = 'site';
$items[ $stylesheet ]['enabled'] = 'site';
} else {
$items[ $file ]['enabled'] = 'no';
$items[ $stylesheet ]['enabled'] = 'no';
}
}
}
Expand Down