Skip to content
Merged
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
44 changes: 44 additions & 0 deletions features/package-install.feature
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,50 @@ Feature: Install WP-CLI packages
wp-cli/google-sitemap-generator-cli
"""

@github-api @shortened
Scenario: Install a package from Git using a shortened package identifier
Given an empty directory

When I run `wp package install wp-cli/google-sitemap-generator-cli`
Then STDOUT should contain:
"""
Installing package wp-cli/google-sitemap-generator-cli (dev-master)
Updating {PACKAGE_PATH}composer.json to require the package...
Registering git@github.com:wp-cli/google-sitemap-generator-cli.git as a VCS repository...
Using Composer to install the package...
"""
And STDOUT should contain:
"""
Success: Package installed.
"""

When I run `wp package list --fields=name`
Then STDOUT should be a table containing rows:
| name |
| wp-cli/google-sitemap-generator-cli |

When I run `wp google-sitemap`
Then STDOUT should contain:
"""
usage: wp google-sitemap rebuild
"""

When I run `wp package uninstall wp-cli/google-sitemap-generator-cli`
Then STDOUT should contain:
"""
Removing require statement from {PACKAGE_PATH}composer.json
"""
And STDOUT should contain:
"""
Success: Uninstalled package.
"""

When I run `wp package list --fields=name`
Then STDOUT should not contain:
"""
wp-cli/google-sitemap-generator-cli
"""

Scenario: Install a package in a local zip
Given an empty directory
And I run `wget -O google-sitemap-generator-cli.zip https://github.com/wp-cli/google-sitemap-generator-cli/archive/master.zip`
Expand Down
35 changes: 31 additions & 4 deletions src/Package_Command.php
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ public function install( $args, $assoc_args ) {

$git_package = $dir_package = false;
$version = 'dev-master';
if ( '.git' === strtolower( substr( $package_name, -4, 4 ) ) ) {
if ( $this->is_git_repository( $package_name ) ) {
$git_package = $package_name;
preg_match( '#([^:\/]+\/[^\/]+)\.git#', $package_name, $matches );
if ( ! empty( $matches[1] ) ) {
Expand Down Expand Up @@ -245,7 +245,10 @@ public function install( $args, $assoc_args ) {
if ( false !== strpos( $package_name, ':' ) ) {
list( $package_name, $version ) = explode( ':', $package_name );
}
$package = $this->get_community_package_by_name( $package_name );
$package = $this->get_package_by_shortened_identifier( $package_name );
if ( $this->is_git_repository( $package ) ) {
$git_package = $package;
}
if ( ! $package ) {
WP_CLI::error( "Invalid package." );
}
Expand Down Expand Up @@ -656,14 +659,27 @@ private function show_packages( $context, $packages, $assoc_args ) {
}

/**
* Get a community package by its name.
* Get a package by its shortened identifier.
*
* A shortened identifier has the form `<vendor>/<package>`.
*
* This method first checks the deprecated package index, for BC reasons,
* and then falls back to the corresponding GitHub URL.
*/
private function get_community_package_by_name( $package_name ) {
private function get_package_by_shortened_identifier( $package_name ) {
// Check the package index first, so we don't break existing behavior.
foreach( $this->get_community_packages() as $package ) {
if ( $package_name == $package->getName() ) {
return $package;
}
}

// Fall back to GitHub URL if we had no match in the package index.
$response = Utils\http_request( 'GET', "https://github.com/{$package_name}.git" );
if ( 20 === (int) substr( $response->status_code, 0, 2 ) ) {
return "git@github.com:{$package_name}.git";
}

return false;
}

Expand Down Expand Up @@ -877,4 +893,15 @@ private function get_pool( Composer $composer ) {
}
return $this->pool;
}

/**
* Check whether a given package is a git repository.
*
* @param string $package Package name to check.
*
* @return bool Whether the package is a git repository.
*/
private function is_git_repository( $package ) {
return '.git' === strtolower( substr( $package, -4, 4 ) );
}
}