Skip to content
Draft
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
34 changes: 22 additions & 12 deletions src/Package_Command.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@
* | wp-cli/server-command | Daniel Bachhuber | dev-main | available | 2.x-dev |
* +-----------------------+------------------+----------+-----------+----------------+
*
* # Install the latest development version of the package.
* # Install the latest stable version of the package.
* $ wp package install wp-cli/server-command
* Installing package wp-cli/server-command (dev-main)
* Installing package wp-cli/server-command (^2.0)
* Updating /home/person/.wp-cli/packages/composer.json to require the package...
* Using Composer to install the package...
* ---
Expand Down Expand Up @@ -201,10 +201,10 @@ public function browse( $_, $assoc_args ) {
*
* ## EXAMPLES
*
* # Install a package hosted at a git URL.
* # Install the latest stable version of a package.
* $ wp package install runcommand/hook
*
* # Install the latest stable version.
* # Install the latest stable version (explicitly specified).
* $ wp package install wp-cli/server-command:@stable
*
* # Install a package hosted at a GitLab.com URL.
Expand All @@ -224,12 +224,17 @@ public function install( $args, $assoc_args ) {
$version = '';
if ( $this->is_git_repository( $package_name ) ) {
if ( '' === $version ) {
$version = "dev-{$this->get_github_default_branch( $package_name, $insecure )}";
$version = '@stable';
}
$git_package = $package_name;
$matches = [];
if ( preg_match( '#([^:\/]+\/[^\/]+)\.git#', $package_name, $matches ) ) {
$package_name = $this->check_git_package_name( $matches[1], $package_name, $version, $insecure );
$extracted_package_name = $matches[1];
if ( '@stable' === $version ) {
$tag = $this->get_github_latest_release_tag( $extracted_package_name, $insecure );
$version = $this->guess_version_constraint_from_tag( $tag );
}
$package_name = $this->check_git_package_name( $extracted_package_name, $package_name, $version, $insecure );
Comment on lines +232 to +237

Choose a reason for hiding this comment

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

medium

There's some code duplication here. The logic to resolve the @stable version is repeated here and again on lines 312-315 for shortened identifiers.

To improve maintainability and follow the DRY (Don't Repeat Yourself) principle, you could extract this logic into a private helper method. For example, a method like resolve_stable_version_constraint(\$package_name, \$insecure) could encapsulate this logic, making the code cleaner and easier to manage.

} else {
WP_CLI::error( "Couldn't parse package name from expected path '<name>/<package>'." );
}
Expand Down Expand Up @@ -301,7 +306,7 @@ public function install( $args, $assoc_args ) {
$git_package = $package;

if ( '' === $version ) {
$version = "dev-{$this->get_github_default_branch( $package_name, $insecure )}";
$version = '@stable';
}

if ( '@stable' === $version ) {
Expand Down Expand Up @@ -1352,23 +1357,28 @@ private function get_raw_git_version( $version ) {
/**
* Gets the release tag for the latest stable release of a GitHub repository.
*
* If there is no release, falls back to the default branch prefixed with 'dev-'.
*
* @param string $package_name Name of the repository.
* @param bool $insecure Whether to retry downloads without certificate validation if TLS handshake fails.
*
* @return string Release tag.
* @return string Release tag or 'dev-{default_branch}' if no release exists.
*/
private function get_github_latest_release_tag( $package_name, $insecure ) {
$url = "https://api.github.com/repos/{$package_name}/releases/latest";
$options = [ 'insecure' => $insecure ];
$response = Utils\http_request( 'GET', $url, null, [], $options );
if ( 20 !== (int) substr( $response->status_code, 0, 2 ) ) {
WP_CLI::warning( 'Could not guess stable version from GitHub repository, falling back to master branch' );
return 'master';
$default_branch = $this->get_github_default_branch( $package_name, $insecure );
WP_CLI::warning( "Could not guess stable version from GitHub repository, falling back to {$default_branch} branch" );
return "dev-{$default_branch}";
}

$package_data = json_decode( $response->body );
if ( JSON_ERROR_NONE !== json_last_error() ) {
WP_CLI::warning( 'Could not guess stable version from GitHub repository, falling back to master branch' );
return 'master';
$default_branch = $this->get_github_default_branch( $package_name, $insecure );
WP_CLI::warning( "Could not guess stable version from GitHub repository, falling back to {$default_branch} branch" );
return "dev-{$default_branch}";
}
Comment on lines 1371 to 1382

Choose a reason for hiding this comment

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

medium

The fallback logic to get the default branch is duplicated in the case of an HTTP error and a JSON parsing error. You can refactor this to avoid repetition and make the code cleaner by combining the checks. This also provides an opportunity to make the check for a valid response object more robust.

		$package_data = null;
		if ( 20 === (int) substr( $response->status_code, 0, 2 ) ) {
			$package_data = json_decode( $response->body );
		}

		if ( ! is_object( $package_data ) || JSON_ERROR_NONE !== json_last_error() ) {
			$default_branch = $this->get_github_default_branch( $package_name, $insecure );
			WP_CLI::warning( "Could not guess stable version from GitHub repository, falling back to {$default_branch} branch" );
			return "dev-{$default_branch}";
		}


$tag = $package_data->tag_name;
Expand Down