Skip to content

Commit a8725c3

Browse files
authored
Merge pull request #506 from wp-cli/copilot/fix-1570774-87201472-127cd70a-3a52-471a-9dc4-fc27ebad98fc
2 parents 69cbc4b + 2bce3ed commit a8725c3

5 files changed

Lines changed: 93 additions & 4 deletions

File tree

features/plugin-install.feature

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,3 +477,29 @@ Feature: Install WordPress plugins
477477
"""
478478
active-network
479479
"""
480+
481+
Scenario: Install plugin from a zip file with a custom --slug
482+
Given a WP install
483+
484+
When I run `wp plugin install https://github.com/wp-cli-test/generic-example-plugin/archive/refs/heads/master.zip --slug=my-custom-plugin`
485+
Then STDOUT should contain:
486+
"""
487+
Renamed 'generic-example-plugin-master' to 'my-custom-plugin'.
488+
"""
489+
And STDOUT should contain:
490+
"""
491+
Plugin installed successfully.
492+
"""
493+
And the wp-content/plugins/my-custom-plugin directory should exist
494+
And the wp-content/plugins/generic-example-plugin-master directory should not exist
495+
And the return code should be 0
496+
497+
Scenario: Error when --slug is used with multiple plugins
498+
Given a WP install
499+
500+
When I try `wp plugin install hello-dolly akismet --slug=my-plugin`
501+
Then STDERR should contain:
502+
"""
503+
Error: The --slug option can only be used when installing a single item.
504+
"""
505+
And the return code should be 1

features/theme-install.feature

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,3 +186,28 @@ Feature: Install WordPress themes
186186
"""
187187
active
188188
"""
189+
190+
Scenario: Install theme from a zip file with a custom --slug
191+
Given a WP install
192+
193+
When I run `wp theme install https://downloads.wordpress.org/theme/twentytwelve.zip --slug=my-custom-theme`
194+
Then STDOUT should contain:
195+
"""
196+
Renamed 'twentytwelve' to 'my-custom-theme'.
197+
"""
198+
And STDOUT should contain:
199+
"""
200+
Theme installed successfully.
201+
"""
202+
And the wp-content/themes/my-custom-theme directory should exist
203+
And the return code should be 0
204+
205+
Scenario: Error when --slug is used with multiple themes
206+
Given a WP install
207+
208+
When I try `wp theme install twentytwelve twentyeleven --slug=my-theme`
209+
Then STDERR should contain:
210+
"""
211+
Error: The --slug option can only be used when installing a single item.
212+
"""
213+
And the return code should be 1

src/Plugin_Command.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1165,6 +1165,9 @@ protected function filter_item_list( $items, $args ) {
11651165
* [--with-dependencies]
11661166
* : If set, the command will also install all required dependencies of the plugin as specified in the 'Requires Plugins' header.
11671167
*
1168+
* [--slug=<slug>]
1169+
* : Use this as the target directory name when installing from a zip file. Cannot be used when installing multiple plugins.
1170+
*
11681171
* ## EXAMPLES
11691172
*
11701173
* # Install the latest version from wordpress.org and activate

src/Theme_Command.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -612,6 +612,9 @@ protected function filter_item_list( $items, $args ) {
612612
* [--insecure]
613613
* : Retry downloads without certificate validation if TLS handshake fails. Note: This makes the request vulnerable to a MITM attack.
614614
*
615+
* [--slug=<slug>]
616+
* : Use this as the target directory name when installing from a zip file. Cannot be used when installing multiple themes.
617+
*
615618
* ## EXAMPLES
616619
*
617620
* # Install the latest version from wordpress.org and activate

src/WP_CLI/CommandWithUpgrade.php

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -185,8 +185,17 @@ private function show_legend( $items ) {
185185
}
186186

187187
public function install( $args, $assoc_args ) {
188-
$successes = 0;
189-
$errors = 0;
188+
$successes = 0;
189+
$errors = 0;
190+
$custom_slug = Utils\get_flag_value( $assoc_args, 'slug', false );
191+
if ( $custom_slug ) {
192+
$custom_slug = sanitize_file_name( $custom_slug );
193+
}
194+
195+
if ( $custom_slug && count( $args ) > 1 ) {
196+
WP_CLI::error( 'The --slug option can only be used when installing a single item.' );
197+
}
198+
190199
foreach ( $args as $slug ) {
191200

192201
if ( empty( $slug ) ) {
@@ -267,10 +276,33 @@ public function install( $args, $assoc_args ) {
267276
$file_upgrader = $this->get_upgrader( $assoc_args );
268277

269278
$filter = false;
270-
// If a GitHub URL, do some guessing as to the correct plugin/theme directory.
271-
if ( $is_remote && 'github.com' === Utils\parse_url( $slug, PHP_URL_HOST )
279+
if ( $custom_slug ) {
280+
// If --slug is specified, rename the extracted directory to the provided slug.
281+
$filter = function ( $source ) use ( $custom_slug ) {
282+
/**
283+
* @var \WP_Filesystem_Base $wp_filesystem
284+
*/
285+
global $wp_filesystem;
286+
287+
$source_dir = Utils\basename( $source ); // `$source` is trailing-slashed path to the unzipped archive directory.
288+
if ( $source_dir === $custom_slug ) {
289+
return $source;
290+
}
291+
$custom_slug = sanitize_file_name( $custom_slug );
292+
$new_path = substr_replace( $source, $custom_slug, (int) strrpos( $source, $source_dir ), strlen( $source_dir ) );
293+
294+
if ( $wp_filesystem->move( $source, $new_path ) ) {
295+
WP_CLI::log( sprintf( "Renamed '%s' to '%s'.", $source_dir, $custom_slug ) );
296+
return $new_path;
297+
}
298+
299+
return new WP_Error( 'wpcli_install_slug', "Couldn't rename to '{$custom_slug}'." );
300+
};
301+
add_filter( 'upgrader_source_selection', $filter, 10 );
302+
} elseif ( $is_remote && 'github.com' === Utils\parse_url( $slug, PHP_URL_HOST )
272303
// Don't attempt to rename ZIPs uploaded to the releases page or coming from a raw source.
273304
&& ! preg_match( '#github\.com/[^/]+/[^/]+/(?:releases/download|raw)/#', $slug ) ) {
305+
// If a GitHub URL, do some guessing as to the correct plugin/theme directory.
274306

275307
$filter = function ( $source ) use ( $slug ) {
276308
/**

0 commit comments

Comments
 (0)