diff --git a/features/plugin-update.feature b/features/plugin-update.feature index 617aa8865..6299aa8e4 100644 --- a/features/plugin-update.feature +++ b/features/plugin-update.feature @@ -43,6 +43,33 @@ Feature: Update WordPress plugins Error: --minor and --patch cannot be used together. """ + Scenario: Exclude plugin updates from bulk updates. + Given a WP install + + When I run `wp plugin install akismet --version=3.0.0 --force` + Then STDOUT should contain: + """" + Downloading install package from https://downloads.wordpress.org/plugin/akismet.3.0.0.zip... + """" + + When I run `wp plugin status akismet` + Then STDOUT should contain: + """" + Update available + """" + + When I run `wp plugin update --all --exclude=akismet | grep 'Skipped'` + Then STDOUT should contain: + """ + akismet + """ + + When I run `wp plugin status akismet` + Then STDOUT should contain: + """" + Update available + """" + Scenario: Update a plugin to its latest patch release Given a WP install And I run `wp plugin install --force akismet --version=2.5.4` diff --git a/features/theme.feature b/features/theme.feature index 8e142fb07..5250ec325 100644 --- a/features/theme.feature +++ b/features/theme.feature @@ -108,6 +108,33 @@ Feature: Manage WordPress themes Success: Updated 1 of 1 themes. """ + Scenario: Exclude theme from bulk updates. + Given a WP install + + When I run `wp theme install p2 --version=1.4.1 --force` + Then STDOUT should contain: + """" + Downloading install package from https://downloads.wordpress.org/theme/p2.1.4.1.zip... + """" + + When I run `wp theme status p2` + Then STDOUT should contain: + """" + Update available + """" + + When I run `wp theme update --all --exclude=p2 | grep 'Skipped'` + Then STDOUT should contain: + """ + p2 + """ + + When I run `wp theme status p2` + Then STDOUT should contain: + """" + Update available + """" + Scenario: Get the path of an installed theme Given a WP install diff --git a/src/Plugin_Command.php b/src/Plugin_Command.php index b9a21147d..2778ac284 100644 --- a/src/Plugin_Command.php +++ b/src/Plugin_Command.php @@ -498,6 +498,9 @@ protected function install_from_repo( $slug, $assoc_args ) { * * [--all] * : If set, all plugins that have updates will be updated. + * + * [--exclude=] + * : Comma separated list of plugin 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) @@ -545,6 +548,20 @@ protected function install_from_repo( $slug, $assoc_args ) { * | nginx-cache-controller | 3.1.1 | 3.2.0 | Updated | * +------------------------+-------------+-------------+---------+ * Success: Updated 2 of 2 plugins. + * + * $ wp plugin update --all --exclude=akismet + * Enabling Maintenance mode... + * Downloading update from https://downloads.wordpress.org/plugin/nginx-champuru.3.2.0.zip... + * Unpacking the update... + * Installing the latest version... + * Removing the old version of the plugin... + * Plugin updated successfully. + * Disabling Maintenance mode... + * +------------------------+-------------+-------------+---------+ + * | name | old_version | new_version | status | + * +------------------------+-------------+-------------+---------+ + * | nginx-cache-controller | 3.1.1 | 3.2.0 | Updated | + * +------------------------+-------------+-------------+---------+ * * @alias upgrade */ diff --git a/src/Theme_Command.php b/src/Theme_Command.php index 7cfc748e7..dbb293353 100644 --- a/src/Theme_Command.php +++ b/src/Theme_Command.php @@ -589,6 +589,9 @@ public function get( $args, $assoc_args ) { * * [--all] * : If set, all themes that have updates will be updated. + * + * [--exclude=] + * : Comma separated list of theme names that should be excluded from updating. * * [--format=] * : Output summary as table or summary. Defaults to table. @@ -620,6 +623,26 @@ public function get( $args, $assoc_args ) { * | twentysixteen | 1.1 | 1.2 | Updated | * +---------------+-------------+-------------+---------+ * Success: Updated 2 of 2 themes. + * + * # Exclude themes updates when bulk updating the themes + * $ wp theme update --all --exclude=twentyfifteen + * Downloading update from https://downloads.wordpress.org/theme/astra.1.0.5.1.zip... + * Unpacking the update... + * Installing the latest version... + * Removing the old version of the theme... + * Theme updated successfully. + * Downloading update from https://downloads.wordpress.org/theme/twentyseventeen.1.2.zip... + * Unpacking the update... + * Installing the latest version... + * Removing the old version of the theme... + * Theme updated successfully. + * +-----------------+----------+---------+----------------+ + * | name | status | version | update_version | + * +-----------------+----------+---------+----------------+ + * | astra | inactive | 1.0.1 | 1.0.5.1 | + * | twentyseventeen | inactive | 1.1 | 1.2 | + * +-----------------+----------+---------+----------------+ + * Success: Updated 2 of 2 themes. * * # Update all themes * $ wp theme update --all diff --git a/src/WP_CLI/CommandWithUpgrade.php b/src/WP_CLI/CommandWithUpgrade.php index b9a3877e8..ba86aa09d 100755 --- a/src/WP_CLI/CommandWithUpgrade.php +++ b/src/WP_CLI/CommandWithUpgrade.php @@ -21,6 +21,8 @@ public function __construct() { add_action( 'upgrader_process_complete', function() { remove_action( 'upgrader_process_complete', array( 'Language_Pack_Upgrader', 'async_upgrade' ), 20 ); }, 1 ); + + $this->fetcher = new \WP_CLI\Fetchers\Plugin; } abstract protected function get_upgrader_class( $force ); @@ -301,9 +303,29 @@ protected function update_many( $args, $assoc_args ) { $items_to_update = self::get_minor_or_patch_updates( $items_to_update, $type ); } + $exclude = WP_CLI\Utils\get_flag_value( $assoc_args, 'exclude' ); + if ( isset( $exclude ) ) { + $exclude_items = explode( ',', trim( $assoc_args['exclude'], ',' ) ); + unset( $assoc_args['exclude'] ); + foreach ( $exclude_items as $item ) { + if ( 'plugin' === $this->item_type ) { + $plugin = $this->fetcher->get( $item ); + unset( $items_to_update[ $plugin->file ] ); + } elseif ( 'theme' === $this->item_type ) { + $theme_root = get_theme_root() . '/' . $item; + unset( $items_to_update[ $theme_root ] ); + } + } + } + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'dry-run' ) ) { if ( empty( $items_to_update ) ) { \WP_CLI::log( "No {$this->item_type} updates available." ); + + if ( NULL !== $exclude ) { + \WP_CLI::log( "Skipped updates for: $exclude" ); + } + return; } @@ -319,6 +341,10 @@ protected function update_many( $args, $assoc_args ) { \WP_CLI\Utils\format_items( 'table', $items_to_update, array( 'name', 'status', 'version', 'update_version' ) ); } + if ( NULL !== $exclude ) { + \WP_CLI::log( "Skipped updates for: $exclude" ); + } + return; } @@ -378,6 +404,9 @@ protected function update_many( $args, $assoc_args ) { $total_updated = Utils\get_flag_value( $assoc_args, 'all' ) ? $num_to_update : count( $args ); Utils\report_batch_operation_results( $this->item_type, 'update', $total_updated, $num_updated, $errors ); + if ( NULL !== $exclude ) { + \WP_CLI::log( "Skipped updates for: $exclude" ); + } } protected function _list( $_, $assoc_args ) {