Skip to content

Commit 2ecec9a

Browse files
authored
Merge pull request #81 from wp-cli/issue-80-github-url-misread-archive
For Github archive URLs use the Github project name as the plugin directory.
2 parents 052ffc8 + 6c9092c commit 2ecec9a

File tree

3 files changed

+62
-41
lines changed

3 files changed

+62
-41
lines changed

features/plugin-install.feature

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ Feature: Install WordPress plugins
55

66
When I run `wp plugin install https://github.com/runcommand/one-time-login/archive/master.zip --activate`
77
Then STDOUT should contain:
8-
""""
8+
"""
99
Downloading install
10-
""""
10+
"""
1111
And STDOUT should contain:
1212
"""
1313
package from https://github.com/runcommand/one-time-login/archive/master.zip
@@ -20,7 +20,6 @@ Feature: Install WordPress plugins
2020
"""
2121
Plugin installed successfully.
2222
"""
23-
And STDERR should be empty
2423
And the wp-content/plugins/one-time-login directory should exist
2524
And the wp-content/plugins/one-time-login-master directory should not exist
2625

@@ -45,6 +44,20 @@ Feature: Install WordPress plugins
4544
And the wp-content/plugins/one-time-login directory should exist
4645
And the wp-content/plugins/one-time-login-master directory should not exist
4746

47+
# However if the plugin slug ('modern-framework') does not match the project name then it's downloaded to wrong directory.
48+
When I run `wp plugin install https://github.com/Miller-Media/modern-wordpress/archive/master.zip`
49+
Then STDOUT should contain:
50+
"""
51+
Plugin installed successfully.
52+
"""
53+
And STDOUT should contain:
54+
"""
55+
Renamed Github-based project from 'modern-wordpress-master' to 'modern-wordpress'.
56+
"""
57+
# Wrong directory.
58+
And the wp-content/plugins/modern-wordpress directory should exist
59+
And the wp-content/plugins/modern-framework directory should not exist
60+
4861
Scenario: Don't attempt to rename ZIPs uploaded to GitHub's releases page
4962
Given a WP install
5063

@@ -55,9 +68,8 @@ Feature: Install WordPress plugins
5568
"""
5669
And STDOUT should not contain:
5770
"""
58-
Renamed Github-based project from
71+
Renamed Github-based project from 'one-time-login.0.1.2' to 'one-time-login'.
5972
"""
60-
And STDERR should be empty
6173
And the wp-content/plugins/one-time-login directory should exist
6274

6375
Scenario: Don't attempt to rename ZIPs coming from a GitHub raw source
@@ -70,9 +82,8 @@ Feature: Install WordPress plugins
7082
"""
7183
And STDOUT should not contain:
7284
"""
73-
Renamed Github-based project from
85+
Renamed Github-based project from 'modern-framework-stable' to 'modern-framework'.
7486
"""
75-
And STDERR should be empty
7687
And the wp-content/plugins/modern-framework directory should exist
7788

7889
Scenario: Installing respects WP_PROXY_HOST and WP_PROXY_PORT
@@ -101,7 +112,6 @@ Feature: Install WordPress plugins
101112
"""
102113
Plugin installed successfully.
103114
"""
104-
And STDERR should be empty
105115

106116
Scenario: Return code is 1 when one or more plugin installations fail
107117
Given a WP install
@@ -161,7 +171,7 @@ Feature: Install WordPress plugins
161171
"""
162172
And the return code should be 1
163173

164-
Scenario: Don't attempt to rename ZIPs coming from a GitHub archive release/tag
174+
Scenario: For Github archive URLs use the Github project name as the plugin directory
165175
Given a WP install
166176

167177
When I run `wp plugin install https://github.com/wp-cli-test/generic-example-plugin/archive/v0.1.0.zip`
@@ -177,11 +187,23 @@ Feature: Install WordPress plugins
177187
"""
178188
Renamed Github-based project from 'generic-example-plugin-0.1.0' to 'generic-example-plugin'.
179189
"""
180-
And STDOUT should contain:
181-
"""
182-
Plugin installed successfully.
183-
"""
184-
And STDERR should be empty
185190
And the wp-content/plugins/generic-example-plugin directory should exist
186191
And the wp-content/plugins/generic-example-plugi directory should not exist
187192
And the wp-content/plugins/generic-example-plugin-0.1.0 directory should not exist
193+
194+
When I run `wp plugin install https://github.com/Automattic/sensei/archive/version/1.9.19.zip`
195+
Then STDOUT should contain:
196+
"""
197+
Plugin installed successfully.
198+
"""
199+
And STDOUT should contain:
200+
"""
201+
package from https://github.com/Automattic/sensei/archive/version/1.9.19.zip
202+
"""
203+
And STDOUT should contain:
204+
"""
205+
Renamed Github-based project from 'sensei-version-1.9.19' to 'sensei'.
206+
"""
207+
And the wp-content/plugins/sensei directory should exist
208+
And the wp-content/plugins/archive directory should not exist
209+
And the wp-content/plugins/sensei-version-1.9.19 directory should not exist

features/plugin.feature

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -491,7 +491,7 @@ Feature: Manage WordPress plugins
491491
When I try `wp plugin install ''`
492492
Then STDERR should contain:
493493
"""
494-
Warning: Ignoring ambigious empty slug value.
494+
Warning: Ignoring ambiguous empty slug value.
495495
"""
496496
And STDOUT should not contain:
497497
"""

src/WP_CLI/CommandWithUpgrade.php

Lines changed: 25 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -128,53 +128,52 @@ public function install( $args, $assoc_args ) {
128128
foreach ( $args as $slug ) {
129129

130130
if ( empty( $slug ) ) {
131-
WP_CLI::warning( "Ignoring ambigious empty slug value." );
131+
WP_CLI::warning( "Ignoring ambiguous empty slug value." );
132132
continue;
133133
}
134134

135-
$local_or_remote_zip_file = false;
136135
$result = false;
137136

138-
// Check if a URL to a remote or local zip has been specified
139-
if ( strpos( $slug, '://' ) !== false || ( pathinfo( $slug, PATHINFO_EXTENSION ) === 'zip' && is_file( $slug ) ) ) {
140-
$local_or_remote_zip_file = $slug;
141-
}
137+
$is_remote = false !== strpos( $slug, '://' );
142138

143-
if ( $local_or_remote_zip_file ) {
139+
// Check if a URL to a remote or local zip has been specified
140+
if ( $is_remote || ( pathinfo( $slug, PATHINFO_EXTENSION ) === 'zip' && is_file( $slug ) ) ) {
144141
// Install from local or remote zip file
145142
$file_upgrader = $this->get_upgrader( $assoc_args );
146143

147144
$filter = false;
148-
if ( strpos( $local_or_remote_zip_file, '://' ) !== false
149-
&& 'github.com' === parse_url( $local_or_remote_zip_file, PHP_URL_HOST ) ) {
150-
$filter = function( $source, $remote_source, $upgrader ) use ( $local_or_remote_zip_file ) {
151-
// Don't attempt to rename ZIPs uploaded to the releases page
152-
if ( preg_match( '#github\.com/([^/]+)/([^/]+)/releases/download/#', $local_or_remote_zip_file ) || preg_match( '#github\.com/([^/]+)/([^/]+)/raw/#', $local_or_remote_zip_file ) ) {
153-
return $source;
154-
}
145+
// If a Github URL, do some guessing as to the correct plugin/theme directory.
146+
if ( $is_remote && 'github.com' === parse_url( $slug, PHP_URL_HOST )
147+
// Don't attempt to rename ZIPs uploaded to the releases page or coming from a raw source.
148+
&& ! preg_match( '#github\.com/[^/]+/[^/]+/(?:releases/download|raw)/#', $slug ) ) {
155149

156-
$branch_name = pathinfo( $local_or_remote_zip_file, PATHINFO_FILENAME );
150+
$filter = function( $source, $remote_source, $upgrader ) use ( $slug ) {
157151

158-
// Always be attached "archive" into release tag and tag on github.
159-
if ( preg_match( '#github\.com/([^/]+)/([^/]+)/archive/#', $local_or_remote_zip_file ) ) {
160-
$path_array = explode( "/", pathinfo( $local_or_remote_zip_file, PATHINFO_DIRNAME) );
161-
array_pop( $path_array );
162-
$branch_name = end( $path_array );
152+
$slug_dir = Utils\basename( parse_url( $slug, PHP_URL_PATH ), '.zip' );
153+
154+
// Don't use the zip name if archive attached to release, as name likely to contain version tag/branch.
155+
if ( preg_match( '#github\.com/[^/]+/([^/]+)/archive/#', $slug, $matches ) ) {
156+
// Note this will be wrong if the project name isn't the same as the plugin/theme slug name.
157+
$slug_dir = $matches[1];
163158
}
164159

165-
$new_path = str_replace( pathinfo( $source, PATHINFO_BASENAME ), $branch_name, $source );
160+
$source_dir = Utils\basename( $source ); // `$source` is trailing-slashed path to the unzipped archive directory, so basename returns the unslashed directory.
161+
if ( $source_dir === $slug_dir ) {
162+
return $source;
163+
}
164+
$new_path = substr_replace( $source, $slug_dir, strrpos( $source, $source_dir ), strlen( $source_dir ) );
165+
166166
if ( $GLOBALS['wp_filesystem']->move( $source, $new_path ) ) {
167-
WP_CLI::log( "Renamed Github-based project from '" . Utils\basename( $source ) . "' to '" . Utils\basename( $new_path ) . "'." );
167+
WP_CLI::log( sprintf( "Renamed Github-based project from '%s' to '%s'.", $source_dir, $slug_dir ) );
168168
return $new_path;
169-
} else {
170-
return new \WP_Error( 'wpcli_install_github', "Couldn't move Github-based project to appropriate directory." );
171169
}
172-
return $source;
170+
171+
return new \WP_Error( 'wpcli_install_github', "Couldn't move Github-based project to appropriate directory." );
173172
};
174173
add_filter( 'upgrader_source_selection', $filter, 10, 3 );
175174
}
176175

177-
if ( $file_upgrader->install( $local_or_remote_zip_file ) ) {
176+
if ( $file_upgrader->install( $slug ) ) {
178177
$slug = $file_upgrader->result['destination_name'];
179178
$result = true;
180179
if ( $filter ) {

0 commit comments

Comments
 (0)