Skip to content

Commit 985563f

Browse files
Copilotswissspidy
andauthored
Default package installation to @stable instead of default branch (#219)
Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Pascal Birchler <pascalb@google.com>
1 parent 44d9152 commit 985563f

2 files changed

Lines changed: 45 additions & 18 deletions

File tree

features/package-install.feature

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,7 @@ Feature: Install WP-CLI packages
374374
Scenario: Install a package from a GitLab URL without .git suffix and nested groups
375375
Given an empty directory
376376

377-
When I run `wp package install https://gitlab.com/wp-cli/wp-cli-test/test-command`
377+
When I try `wp package install https://gitlab.com/wp-cli/wp-cli-test/test-command`
378378
Then STDOUT should contain:
379379
"""
380380
Installing package wp-cli-test/test-command
@@ -387,6 +387,10 @@ Feature: Install WP-CLI packages
387387
"""
388388
Success: Package installed.
389389
"""
390+
And STDERR should contain:
391+
"""
392+
Could not guess stable version from GitHub repository, falling back to master branch
393+
"""
390394

391395
When I run `wp package uninstall wp-cli-test/test-command`
392396
Then STDOUT should contain:

src/Package_Command.php

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,9 @@
4040
* | wp-cli/server-command | Daniel Bachhuber | dev-main | available | 2.x-dev |
4141
* +-----------------------+------------------+----------+-----------+----------------+
4242
*
43-
* # Install the latest development version of the package.
43+
* # Install the latest stable version of the package.
4444
* $ wp package install wp-cli/server-command
45-
* Installing package wp-cli/server-command (dev-main)
45+
* Installing package wp-cli/server-command (^2.0)
4646
* Updating /home/person/.wp-cli/packages/composer.json to require the package...
4747
* Using Composer to install the package...
4848
* ---
@@ -204,10 +204,10 @@ public function browse( $_, $assoc_args ) {
204204
*
205205
* ## EXAMPLES
206206
*
207-
* # Install a package hosted at a git URL.
207+
* # Install the latest stable version of a package.
208208
* $ wp package install runcommand/hook
209209
*
210-
* # Install the latest stable version.
210+
* # Install the latest stable version (explicitly specified).
211211
* $ wp package install wp-cli/server-command:@stable
212212
*
213213
* # Install a package hosted at a GitLab.com URL.
@@ -239,16 +239,21 @@ public function install( $args, $assoc_args ) {
239239
}
240240
if ( $this->is_git_repository( $package_name ) ) {
241241
if ( '' === $version ) {
242+
$version = '@stable';
242243
if ( preg_match( '#^(?:https?://github\.com/|git@github\.com:)#i', $package_name ) ) {
243244
$version = "dev-{$this->get_github_default_branch( $package_name, $insecure )}";
244245
} else {
245-
$version = 'dev-master';
246+
$version = '@stable';
246247
}
247248
}
248249
$git_package = $package_name;
249250
$matches = [];
250251
if ( preg_match( '#([^:\/]+\/[^\/]+)\.git#', $package_name, $matches ) ) {
251-
$package_name = $this->check_git_package_name( $matches[1], $package_name, $version, $insecure );
252+
$extracted_package_name = $matches[1];
253+
if ( '@stable' === $version ) {
254+
$version = $this->resolve_stable_version( $extracted_package_name, $insecure );
255+
}
256+
$package_name = $this->check_git_package_name( $extracted_package_name, $package_name, $version, $insecure );
252257
} else {
253258
WP_CLI::error( "Couldn't parse package name from expected path '<name>/<package>'." );
254259
}
@@ -320,12 +325,11 @@ public function install( $args, $assoc_args ) {
320325
$git_package = $package;
321326

322327
if ( '' === $version ) {
323-
$version = "dev-{$this->get_github_default_branch( $package_name, $insecure )}";
328+
$version = '@stable';
324329
}
325330

326331
if ( '@stable' === $version ) {
327-
$tag = $this->get_github_latest_release_tag( $package_name, $insecure );
328-
$version = $this->guess_version_constraint_from_tag( $tag );
332+
$version = $this->resolve_stable_version( $package_name, $insecure );
329333
}
330334
$package_name = $this->check_github_package_name( $package_name, $version, $insecure );
331335
}
@@ -1502,26 +1506,45 @@ private function get_raw_git_version( $version ) {
15021506
return str_replace( [ '^', '~' ], '', $version );
15031507
}
15041508

1509+
/**
1510+
* Resolves '@stable' version to an actual version constraint.
1511+
*
1512+
* @param string $package_name Name of the repository.
1513+
* @param bool $insecure Whether to retry downloads without certificate validation if TLS handshake fails.
1514+
*
1515+
* @return string Version constraint.
1516+
*/
1517+
private function resolve_stable_version( $package_name, $insecure ) {
1518+
$tag = $this->get_github_latest_release_tag( $package_name, $insecure );
1519+
return $this->guess_version_constraint_from_tag( $tag );
1520+
}
1521+
15051522
/**
15061523
* Gets the release tag for the latest stable release of a GitHub repository.
15071524
*
1525+
* If there is no release, falls back to the default branch prefixed with 'dev-'.
1526+
*
15081527
* @param string $package_name Name of the repository.
1528+
* @param bool $insecure Whether to retry downloads without certificate validation if TLS handshake fails.
15091529
*
1510-
* @return string Release tag.
1530+
* @return string Release tag or 'dev-{default_branch}' if no release exists.
15111531
*/
15121532
private function get_github_latest_release_tag( $package_name, $insecure ) {
15131533
$url = "https://api.github.com/repos/{$package_name}/releases/latest";
15141534
$options = [ 'insecure' => $insecure ];
15151535
$response = Utils\http_request( 'GET', $url, null, [], $options );
1516-
if ( 20 !== (int) substr( (string) $response->status_code, 0, 2 ) ) {
1517-
WP_CLI::warning( 'Could not guess stable version from GitHub repository, falling back to master branch' );
1518-
return 'master';
1519-
}
15201536

1537+
// Check for successful response and valid JSON
15211538
$package_data = json_decode( $response->body );
1522-
if ( JSON_ERROR_NONE !== json_last_error() ) {
1523-
WP_CLI::warning( 'Could not guess stable version from GitHub repository, falling back to master branch' );
1524-
return 'master';
1539+
1540+
if ( 20 !== (int) substr( (string) $response->status_code, 0, 2 )
1541+
|| JSON_ERROR_NONE !== json_last_error()
1542+
|| null === $package_data
1543+
|| ! isset( $package_data->tag_name ) ) {
1544+
1545+
$default_branch = $this->get_github_default_branch( $package_name, $insecure );
1546+
WP_CLI::warning( "Could not guess stable version from GitHub repository, falling back to {$default_branch} branch" );
1547+
return "dev-{$default_branch}";
15251548
}
15261549

15271550
$tag = $package_data->tag_name;

0 commit comments

Comments
 (0)