diff --git a/features/plugin-install.feature b/features/plugin-install.feature index 48941dc37..f8b61ed5a 100644 --- a/features/plugin-install.feature +++ b/features/plugin-install.feature @@ -1,5 +1,8 @@ Feature: Install WordPress plugins + Background: + Given an empty cache + Scenario: Branch names should be removed from Github projects Given a WP install diff --git a/features/upgradables.feature b/features/upgradables.feature index 297781ec4..278f12750 100644 --- a/features/upgradables.feature +++ b/features/upgradables.feature @@ -212,3 +212,35 @@ Feature: Manage WordPress themes and plugins | type | type_name | item | item_title | version | zip_file | file_to_check | | theme | Theme | moina | Moina | 1.1.2 | https://wordpress.org/themes/download/moina.1.1.2.zip | {CONTENT_DIR}/moina/style.css | | plugin | Plugin | category-checklist-tree | Category Checklist Tree | 1.2 | https://downloads.wordpress.org/plugin/category-checklist-tree.1.2.zip | {CONTENT_DIR}/category-checklist-tree/category-checklist-tree.php | + + @require-wp-4.5 + Scenario Outline: Caches certain GitHub URLs + Given a WP install + And I run `wp plugin delete --all` + + When I run `wp plugin install ` + Then STDOUT should contain: + """ + Plugin installed successfully + """ + And STDOUT should not contain: + """ + Using cached file '{SUITE_CACHE_DIR}/plugin/- + """ + + When I run `wp plugin delete --all` + And I run `wp plugin install ` + Then STDOUT should contain: + """ + Plugin installed successfully + """ + And STDOUT should contain: + """ + Using cached file '{SUITE_CACHE_DIR}/plugin/- + """ + + Examples: + | item | version | zip_file | + | one-time-login | 0.4.0 | https://github.com/danielbachhuber/one-time-login/releases/latest | + | preferred-languages | 1.8.0 | https://github.com/swissspidy/preferred-languages/releases/download/1.8.0/preferred-languages.zip | + | generic-example-plugin | 0.1.1 | https://github.com/wp-cli-test/generic-example-plugin/archive/v0.1.1.zip | diff --git a/src/WP_CLI/CommandWithUpgrade.php b/src/WP_CLI/CommandWithUpgrade.php index 1d383f583..5c03ae847 100755 --- a/src/WP_CLI/CommandWithUpgrade.php +++ b/src/WP_CLI/CommandWithUpgrade.php @@ -227,6 +227,9 @@ public function install( $args, $assoc_args ) { add_filter( 'upgrader_source_selection', $filter, 10 ); } + // Add item to cache allowlist if it matches certain URL patterns. + self::maybe_cache( $slug, $this->item_type ); + if ( $file_upgrader->install( $slug ) ) { $slug = $file_upgrader->result['destination_name']; $result = true; @@ -841,6 +844,26 @@ private function parse_url_host_component( $url, $component ) { return function_exists( 'wp_parse_url' ) ? wp_parse_url( $url, $component ) : parse_url( $url, $component ); } + /** + * Add versioned GitHub URLs to cache allowlist. + * + * @param string $url The URL to check. + */ + protected static function maybe_cache( $url, $item_type ) { + $matches = []; + + // cache release URLs like `https://github.com/wp-cli-test/generic-example-plugin/releases/download/v0.1.0/generic-example-plugin.0.1.0.zip` + if ( preg_match( '#github\.com/[^/]+/([^/]+)/releases/download/v?([^/]+)/.+\.zip#', $url, $matches ) ) { + WP_CLI::get_http_cache_manager()->whitelist_package( $url, $item_type, $matches[1], $matches[2] ); + // cache archive URLs like `https://github.com/wp-cli-test/generic-example-plugin/archive/v0.1.0.zip` + } elseif ( preg_match( '#github\.com/[^/]+/([^/]+)/archive/(version/|)v?([^/]+)\.zip#', $url, $matches ) ) { + WP_CLI::get_http_cache_manager()->whitelist_package( $url, $item_type, $matches[1], $matches[3] ); + // cache release URLs like `https://api.github.com/repos/danielbachhuber/one-time-login/zipball/v0.4.0` + } elseif ( preg_match( '#api\.github\.com/repos/[^/]+/([^/]+)/zipball/v?([^/]+)#', $url, $matches ) ) { + WP_CLI::get_http_cache_manager()->whitelist_package( $url, $item_type, $matches[1], $matches[2] ); + } + } + /** * Get the latest package version based on a given repo slug. * @@ -871,6 +894,13 @@ protected function get_the_latest_github_version( $repo_slug ) { ); } + if ( 404 === wp_remote_retrieve_response_code( $response ) ) { + return new \WP_Error( + $decoded_body->status, + $decoded_body->message + ); + } + if ( null === $decoded_body ) { return new \WP_Error( 500, 'Empty response received from GitHub.com API' ); }