Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions features/plugin-install.feature
Original file line number Diff line number Diff line change
Expand Up @@ -472,3 +472,29 @@ Feature: Install WordPress plugins
"""
active-network
"""

Scenario: Install plugin from a zip file with a custom --slug
Given a WP install

When I run `wp plugin install https://github.com/wp-cli-test/generic-example-plugin/archive/refs/heads/master.zip --slug=my-custom-plugin`
Then STDOUT should contain:
"""
Renamed 'generic-example-plugin-master' to 'my-custom-plugin'.
"""
And STDOUT should contain:
"""
Plugin installed successfully.
"""
And the wp-content/plugins/my-custom-plugin directory should exist
And the wp-content/plugins/generic-example-plugin-master directory should not exist
And the return code should be 0

Scenario: Error when --slug is used with multiple plugins
Given a WP install

When I try `wp plugin install hello-dolly akismet --slug=my-plugin`
Then STDERR should contain:
"""
Error: The --slug option can only be used when installing a single item.
"""
And the return code should be 1
26 changes: 26 additions & 0 deletions features/theme-install.feature
Original file line number Diff line number Diff line change
Expand Up @@ -186,3 +186,29 @@ Feature: Install WordPress themes
"""
active
"""

Scenario: Install theme from a zip file with a custom --slug
Given a WP install

When I run `wp theme install https://github.com/wp-cli-test/generic-example-theme/archive/refs/heads/master.zip --slug=my-custom-theme`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This repo does not exist yet and needs to be created first

Then STDOUT should contain:
"""
Renamed 'generic-example-theme-master' to 'my-custom-theme'.
"""
And STDOUT should contain:
"""
Theme installed successfully.
"""
And the wp-content/themes/my-custom-theme directory should exist
And the wp-content/themes/generic-example-theme-master directory should not exist
And the return code should be 0

Scenario: Error when --slug is used with multiple themes
Given a WP install

When I try `wp theme install twentytwelve twentyeleven --slug=my-theme`
Then STDERR should contain:
"""
Error: The --slug option can only be used when installing a single item.
"""
And the return code should be 1
3 changes: 3 additions & 0 deletions src/Plugin_Command.php
Original file line number Diff line number Diff line change
Expand Up @@ -1165,6 +1165,9 @@ protected function filter_item_list( $items, $args ) {
* [--with-dependencies]
* : If set, the command will also install all required dependencies of the plugin as specified in the 'Requires Plugins' header.
*
* [--slug=<slug>]
* : Use this as the target directory name when installing from a zip file. Cannot be used when installing multiple plugins.
*
* ## EXAMPLES
*
* # Install the latest version from wordpress.org and activate
Expand Down
3 changes: 3 additions & 0 deletions src/Theme_Command.php
Original file line number Diff line number Diff line change
Expand Up @@ -612,6 +612,9 @@ protected function filter_item_list( $items, $args ) {
* [--insecure]
* : Retry downloads without certificate validation if TLS handshake fails. Note: This makes the request vulnerable to a MITM attack.
*
* [--slug=<slug>]
* : Use this as the target directory name when installing from a zip file. Cannot be used when installing multiple themes.
*
* ## EXAMPLES
*
* # Install the latest version from wordpress.org and activate
Expand Down
36 changes: 32 additions & 4 deletions src/WP_CLI/CommandWithUpgrade.php
Original file line number Diff line number Diff line change
Expand Up @@ -185,8 +185,14 @@ private function show_legend( $items ) {
}

public function install( $args, $assoc_args ) {
$successes = 0;
$errors = 0;
$successes = 0;
$errors = 0;
$custom_slug = Utils\get_flag_value( $assoc_args, 'slug', false );

if ( $custom_slug && count( $args ) > 1 ) {
WP_CLI::error( 'The --slug option can only be used when installing a single item.' );
}

foreach ( $args as $slug ) {

if ( empty( $slug ) ) {
Expand Down Expand Up @@ -263,10 +269,32 @@ public function install( $args, $assoc_args ) {
$file_upgrader = $this->get_upgrader( $assoc_args );

$filter = false;
// If a GitHub URL, do some guessing as to the correct plugin/theme directory.
if ( $is_remote && 'github.com' === Utils\parse_url( $slug, PHP_URL_HOST )
if ( $custom_slug ) {
// If --slug is specified, rename the extracted directory to the provided slug.
$filter = function ( $source ) use ( $custom_slug ) {
/**
* @var \WP_Filesystem_Base $wp_filesystem
*/
global $wp_filesystem;

$source_dir = Utils\basename( $source ); // `$source` is trailing-slashed path to the unzipped archive directory.
if ( $source_dir === $custom_slug ) {
return $source;
}
$new_path = substr_replace( $source, $custom_slug, (int) strrpos( $source, $source_dir ), strlen( $source_dir ) );

if ( $wp_filesystem->move( $source, $new_path ) ) {
WP_CLI::log( sprintf( "Renamed '%s' to '%s'.", $source_dir, $custom_slug ) );
return $new_path;
}

return new WP_Error( 'wpcli_install_slug', "Couldn't rename to '{$custom_slug}'." );
};
add_filter( 'upgrader_source_selection', $filter, 10 );
} elseif ( $is_remote && 'github.com' === Utils\parse_url( $slug, PHP_URL_HOST )
// Don't attempt to rename ZIPs uploaded to the releases page or coming from a raw source.
&& ! preg_match( '#github\.com/[^/]+/[^/]+/(?:releases/download|raw)/#', $slug ) ) {
// If a GitHub URL, do some guessing as to the correct plugin/theme directory.

$filter = function ( $source ) use ( $slug ) {
/**
Expand Down
Loading