diff --git a/composer.json b/composer.json index 4827a65c..108e74c1 100644 --- a/composer.json +++ b/composer.json @@ -54,6 +54,7 @@ "plugin path", "plugin search", "plugin status", + "plugin check-update", "plugin toggle", "plugin uninstall", "plugin update", @@ -73,6 +74,7 @@ "theme path", "theme search", "theme status", + "theme check-update", "theme update", "theme mod list" ] diff --git a/features/plugin-check-update.feature b/features/plugin-check-update.feature new file mode 100644 index 00000000..2d01fed0 --- /dev/null +++ b/features/plugin-check-update.feature @@ -0,0 +1,92 @@ +Feature: Check for plugin updates + + @require-wp-5.2 + Scenario: Check for plugin updates with no updates available + Given a WP install + + When I run `wp plugin install wordpress-importer --activate` + Then STDOUT should not be empty + + When I run `wp plugin check-update --all` + Then STDOUT should contain: + """ + Success: All plugins are up to date. + """ + + When I run `wp plugin check-update wordpress-importer` + Then STDOUT should contain: + """ + Success: All plugins are up to date. + """ + + Scenario: Check for plugin updates should throw an error unless --all given + Given a WP install + + When I try `wp plugin check-update` + Then the return code should be 1 + And STDERR should be: + """ + Error: Please specify one or more plugins, or use --all. + """ + And STDOUT should be empty + + @require-wp-5.2 + Scenario: Check for specific plugin updates + Given a WP install + + When I run `wp plugin install wordpress-importer --version=0.5` + Then STDOUT should not be empty + + When I run `wp plugin check-update wordpress-importer --format=csv` + Then STDOUT should contain: + """ + wordpress-importer,inactive,0.5, + """ + + @require-wp-5.2 + Scenario: Check for all plugin updates with --all flag + Given a WP install + + When I run `wp plugin install wordpress-importer --version=0.5 --activate` + Then STDOUT should not be empty + + When I run `wp plugin check-update --all --format=csv` + Then STDOUT should contain: + """ + wordpress-importer,active,0.5, + """ + + @require-wp-5.2 + Scenario: Check for plugin updates in different output formats + Given a WP install + + When I run `wp plugin install wordpress-importer --version=0.5` + Then STDOUT should not be empty + + When I run `wp plugin check-update wordpress-importer --format=json` + Then STDOUT should be JSON containing: + """ + [{"name":"wordpress-importer","status":"inactive","version":"0.5"}] + """ + + When I run `wp plugin check-update wordpress-importer --format=csv` + Then STDOUT should contain: + """ + name,status,version,update_version + """ + And STDOUT should contain: + """ + wordpress-importer,inactive,0.5 + """ + + @require-wp-5.2 + Scenario: Check for plugin updates with custom fields + Given a WP install + + When I run `wp plugin install wordpress-importer --version=0.5` + Then STDOUT should not be empty + + When I run `wp plugin check-update wordpress-importer --fields=name,version` + Then STDOUT should be a table containing rows: + | name | version | + | wordpress-importer | 0.5 | diff --git a/features/theme-check-update.feature b/features/theme-check-update.feature new file mode 100644 index 00000000..e190bc6f --- /dev/null +++ b/features/theme-check-update.feature @@ -0,0 +1,90 @@ +Feature: Check for theme updates + + Scenario: Check for theme updates with no updates available + Given a WP install + + When I run `wp theme install twentytwelve --force` + Then STDOUT should not be empty + + When I run `wp theme check-update --all` + Then STDOUT should contain: + """ + Success: All themes are up to date. + """ + + When I run `wp theme check-update twentytwelve` + Then STDOUT should contain: + """ + Success: All themes are up to date. + """ + + Scenario: Check for theme updates should throw an error unless --all given + Given a WP install + + When I try `wp theme check-update` + Then the return code should be 1 + And STDERR should be: + """ + Error: Please specify one or more themes, or use --all. + """ + And STDOUT should be empty + + Scenario: Check for specific theme updates + Given a WP install + + When I run `wp theme install twentyfourteen --version=1.0 --force` + Then STDOUT should not be empty + + When I run `wp theme install twentytwelve --force` + Then STDOUT should not be empty + + When I run `wp theme check-update twentyfourteen --format=csv` + Then STDOUT should contain: + """ + twentyfourteen,inactive,1.0, + """ + + Scenario: Check for all theme updates with --all flag + Given a WP install + + When I run `wp theme install twentyfourteen --version=1.0 --force` + Then STDOUT should not be empty + + When I run `wp theme check-update --all --format=csv` + Then STDOUT should contain: + """ + twentyfourteen,inactive,1.0, + """ + + Scenario: Check for theme updates in different output formats + Given a WP install + + When I run `wp theme install twentyfourteen --version=1.0 --force` + Then STDOUT should not be empty + + When I run `wp theme check-update twentyfourteen --format=json` + Then STDOUT should be JSON containing: + """ + [{"name":"twentyfourteen","status":"inactive","version":"1.0"}] + """ + + When I run `wp theme check-update twentyfourteen --format=csv` + Then STDOUT should contain: + """ + name,status,version,update_version + """ + And STDOUT should contain: + """ + twentyfourteen,inactive,1.0 + """ + + Scenario: Check for theme updates with custom fields + Given a WP install + + When I run `wp theme install twentyfourteen --version=1.0 --force` + Then STDOUT should not be empty + + When I run `wp theme check-update twentyfourteen --fields=name,version` + Then STDOUT should be a table containing rows: + | name | version | + | twentyfourteen | 1.0 | diff --git a/src/Plugin_Command.php b/src/Plugin_Command.php index ef5b061f..ec4ea59f 100644 --- a/src/Plugin_Command.php +++ b/src/Plugin_Command.php @@ -115,6 +115,108 @@ public function status( $args ) { parent::status( $args ); } + /** + * Checks for plugin updates without performing them. + * + * Lists the available plugin updates. Similar to `wp core check-update`. + * + * ## OPTIONS + * + * [...] + * : One or more plugins to check for updates. + * + * [--all] + * : If set, all plugins will be checked for updates. + * + * [--field=] + * : Prints the value of a single field for each update. + * + * [--fields=] + * : Limit the output to specific object fields. Defaults to name,status,version,update_version. + * + * [--format=] + * : Render output in a particular format. + * --- + * default: table + * options: + * - table + * - csv + * - json + * - yaml + * --- + * + * ## EXAMPLES + * + * # Check for plugin updates + * $ wp plugin check-update + * +-----------+--------+---------+----------------+ + * | name | status | version | update_version | + * +-----------+--------+---------+----------------+ + * | akismet | active | 4.1.0 | 4.1.1 | + * +-----------+--------+---------+----------------+ + * + * # List plugins with available updates in JSON format + * $ wp plugin check-update --format=json + * [{"name":"akismet","status":"active","version":"4.1.0","update_version":"4.1.1"}] + * + * @subcommand check-update + */ + public function check_update( $args, $assoc_args ) { + $all = Utils\get_flag_value( $assoc_args, 'all', false ); + + $args = $this->check_optional_args_and_all( $args, $all ); + if ( ! $args ) { + return; + } + + // Force WordPress to check for updates. + call_user_func( $this->upgrade_refresh ); + + $all = Utils\get_flag_value( $assoc_args, 'all', false ); + + if ( $all ) { + $args = array_map( + function ( $file ) { + return Utils\get_plugin_name( $file ); + }, + array_keys( $this->get_all_plugins() ) + ); + } + + $items = $this->get_item_list(); + + // Filter to only plugins with available updates + $items_with_updates = array_filter( + $items, + function ( $item ) { + return 'available' === $item['update']; + } + ); + + // If specific plugins requested, filter to those + if ( ! empty( $args ) ) { + $items_with_updates = array_filter( + $items_with_updates, + function ( $item ) use ( $args ) { + return in_array( $item['name'], $args, true ); + } + ); + } + + if ( empty( $items_with_updates ) ) { + WP_CLI::success( 'All plugins are up to date.' ); + return; + } + + // Set default fields for check-update output + if ( ! isset( $assoc_args['fields'] ) ) { + $assoc_args['fields'] = 'name,status,version,update_version'; + } + + $formatter = $this->get_formatter( $assoc_args ); + $formatter->display_items( array_values( $items_with_updates ) ); + } + /** * Searches the WordPress.org plugin directory. * diff --git a/src/Theme_Command.php b/src/Theme_Command.php index 5ae8459f..0eda7416 100644 --- a/src/Theme_Command.php +++ b/src/Theme_Command.php @@ -108,6 +108,87 @@ public function status( $args ) { parent::status( $args ); } + /** + * Checks for theme updates without performing them. + * + * Lists the available theme updates. Similar to `wp core check-update`. + * + * ## OPTIONS + * + * [...] + * : One or more themes to check for updates. + * + * [--all] + * : If set, all themes will be checked for updates. + * + * [--field=] + * : Prints the value of a single field for each update. + * + * [--fields=] + * : Limit the output to specific object fields. Defaults to name,status,version,update_version. + * + * [--format=] + * : Render output in a particular format. + * --- + * default: table + * options: + * - table + * - csv + * - json + * - yaml + * --- + * + * ## EXAMPLES + * + * # Check for theme updates + * $ wp theme check-update + * +------------+----------+---------+----------------+ + * | name | status | version | update_version | + * +------------+----------+---------+----------------+ + * | twentytwelve | inactive | 2.0 | 2.1 | + * +------------+----------+---------+----------------+ + * + * # List themes with available updates in JSON format + * $ wp theme check-update --format=json + * [{"name":"twentytwelve","status":"inactive","version":"2.0","update_version":"2.1"}] + * + * @subcommand check-update + */ + public function check_update( $args, $assoc_args ) { + $all = Utils\get_flag_value( $assoc_args, 'all', false ); + + $args = $this->check_optional_args_and_all( $args, $all ); + if ( ! $args ) { + return; + } + + // Force WordPress to check for updates. + call_user_func( $this->upgrade_refresh ); + + $items = $this->get_item_list(); + + // Filter to only themes with available updates + $items_with_updates = array_filter( + $items, + function ( $item ) use ( $args ) { + return in_array( $item['name'], $args, true ) && 'available' === $item['update']; + } + ); + + if ( empty( $items_with_updates ) ) { + WP_CLI::success( 'All themes are up to date.' ); + return; + } + + // Set default fields for check-update output + if ( ! isset( $assoc_args['fields'] ) ) { + $assoc_args['fields'] = 'name,status,version,update_version'; + } + + $formatter = $this->get_formatter( $assoc_args ); + $formatter->display_items( array_values( $items_with_updates ) ); + } + /** * Searches the WordPress.org theme directory. *