diff --git a/src/Command/SelfUpdateCommand.php b/src/Command/SelfUpdateCommand.php
index ea9a1529..b60860fa 100644
--- a/src/Command/SelfUpdateCommand.php
+++ b/src/Command/SelfUpdateCommand.php
@@ -13,6 +13,7 @@
use Php\Pie\File\FullPathToSelf;
use Php\Pie\File\SudoFilePut;
use Php\Pie\SelfManage\Update\FetchPieReleaseFromGitHub;
+use Php\Pie\SelfManage\Update\PiePharMissingFromLatestRelease;
use Php\Pie\SelfManage\Update\ReleaseMetadata;
use Php\Pie\SelfManage\Verify\FailedToVerifyRelease;
use Php\Pie\SelfManage\Verify\VerifyPieReleaseUsingAttestation;
@@ -92,8 +93,15 @@ public function execute(InputInterface $input, OutputInterface $output): int
$output->writeln('Downloading the latest nightly release.');
} else {
- $latestRelease = $fetchLatestPieRelease->latestReleaseMetadata();
- $pieVersion = PieVersion::get();
+ try {
+ $latestRelease = $fetchLatestPieRelease->latestReleaseMetadata();
+ } catch (PiePharMissingFromLatestRelease $piePharMissingFromLatestRelease) {
+ $output->writeln(sprintf('%s', $piePharMissingFromLatestRelease->getMessage()));
+
+ return Command::FAILURE;
+ }
+
+ $pieVersion = PieVersion::get();
if (preg_match('/^(?.+)@(?[a-f0-9]{7})$/', $pieVersion, $matches)) {
// Have to change the version to something the Semver library understands
diff --git a/src/Downloading/GithubPackageReleaseAssets.php b/src/Downloading/GithubPackageReleaseAssets.php
index 89b26c9a..5b10942e 100644
--- a/src/Downloading/GithubPackageReleaseAssets.php
+++ b/src/Downloading/GithubPackageReleaseAssets.php
@@ -79,7 +79,7 @@ private function getReleaseAssetsForPackage(
Assert::notNull($package->downloadUrl());
try {
- $decodedRepsonse = $httpDownloader->get(
+ $decodedResponse = $httpDownloader->get(
$this->githubApiBaseUrl . '/repos/' . $package->githubOrgAndRepository() . '/releases/tags/' . $package->version(),
[
'retry-auth-failure' => true,
@@ -98,9 +98,9 @@ private function getReleaseAssetsForPackage(
throw $t;
}
- Assert::isArray($decodedRepsonse);
- Assert::keyExists($decodedRepsonse, 'assets');
- Assert::isList($decodedRepsonse['assets']);
+ Assert::isArray($decodedResponse);
+ Assert::keyExists($decodedResponse, 'assets');
+ Assert::isList($decodedResponse['assets']);
return array_map(
static function (array $asset): array {
@@ -111,7 +111,7 @@ static function (array $asset): array {
return $asset;
},
- $decodedRepsonse['assets'],
+ $decodedResponse['assets'],
);
}
}
diff --git a/src/SelfManage/Update/FetchPieRelease.php b/src/SelfManage/Update/FetchPieRelease.php
index ef02be0e..3ec78c7e 100644
--- a/src/SelfManage/Update/FetchPieRelease.php
+++ b/src/SelfManage/Update/FetchPieRelease.php
@@ -9,6 +9,7 @@
/** @internal This is not public API for PIE, so should not be depended upon unless you accept the risk of BC breaks */
interface FetchPieRelease
{
+ /** @throws PiePharMissingFromLatestRelease */
public function latestReleaseMetadata(): ReleaseMetadata;
/** Download the given pie.phar and return the filename (should be a temp file) */
diff --git a/src/SelfManage/Update/FetchPieReleaseFromGitHub.php b/src/SelfManage/Update/FetchPieReleaseFromGitHub.php
index e56ce9ed..efba02ad 100644
--- a/src/SelfManage/Update/FetchPieReleaseFromGitHub.php
+++ b/src/SelfManage/Update/FetchPieReleaseFromGitHub.php
@@ -12,6 +12,7 @@
use function array_filter;
use function array_map;
+use function count;
use function file_put_contents;
use function reset;
use function sys_get_temp_dir;
@@ -34,7 +35,7 @@ public function latestReleaseMetadata(): ReleaseMetadata
{
$url = $this->githubApiBaseUrl . self::PIE_LATEST_RELEASE_URL;
- $decodedRepsonse = $this->httpDownloader->get(
+ $decodedResponse = $this->httpDownloader->get(
$url,
[
'retry-auth-failure' => true,
@@ -45,11 +46,11 @@ public function latestReleaseMetadata(): ReleaseMetadata
],
)->decodeJson();
- Assert::isArray($decodedRepsonse);
- Assert::keyExists($decodedRepsonse, 'tag_name');
- Assert::stringNotEmpty($decodedRepsonse['tag_name']);
- Assert::keyExists($decodedRepsonse, 'assets');
- Assert::isList($decodedRepsonse['assets']);
+ Assert::isArray($decodedResponse);
+ Assert::keyExists($decodedResponse, 'tag_name');
+ Assert::stringNotEmpty($decodedResponse['tag_name']);
+ Assert::keyExists($decodedResponse, 'assets');
+ Assert::isList($decodedResponse['assets']);
$assetsNamedPiePhar = array_filter(
array_map(
@@ -62,16 +63,21 @@ static function (array $asset): array {
return $asset;
},
- $decodedRepsonse['assets'],
+ $decodedResponse['assets'],
),
static function (array $asset): bool {
return $asset['name'] === self::PIE_PHAR_NAME;
},
);
+
+ if (! count($assetsNamedPiePhar)) {
+ throw PiePharMissingFromLatestRelease::fromRelease($decodedResponse['tag_name']);
+ }
+
$firstAssetNamedPiePhar = reset($assetsNamedPiePhar);
return new ReleaseMetadata(
- $decodedRepsonse['tag_name'],
+ $decodedResponse['tag_name'],
$firstAssetNamedPiePhar['browser_download_url'],
);
}
diff --git a/src/SelfManage/Update/PiePharMissingFromLatestRelease.php b/src/SelfManage/Update/PiePharMissingFromLatestRelease.php
new file mode 100644
index 00000000..20cd5ff5
--- /dev/null
+++ b/src/SelfManage/Update/PiePharMissingFromLatestRelease.php
@@ -0,0 +1,21 @@
+downloadUrl);
}
+ public function testLatestReleaseNotHavingPiePharThrowsException(): void
+ {
+ $httpDownloader = $this->createMock(HttpDownloader::class);
+ $authHelper = $this->createMock(AuthHelper::class);
+
+ $url = self::TEST_GITHUB_URL . '/repos/php/pie/releases/latest';
+ $authHelper
+ ->method('addAuthenticationHeader')
+ ->willReturn(['Authorization: Bearer fake-token']);
+ $httpDownloader->expects(self::once())
+ ->method('get')
+ ->with(
+ $url,
+ [
+ 'retry-auth-failure' => true,
+ 'http' => [
+ 'method' => 'GET',
+ 'header' => ['Authorization: Bearer fake-token'],
+ ],
+ ],
+ )
+ ->willReturn(
+ new Response(
+ ['url' => $url],
+ 200,
+ [],
+ json_encode([
+ 'tag_name' => '1.2.3',
+ 'assets' => [
+ [
+ 'name' => 'not-pie.phar',
+ 'browser_download_url' => self::TEST_GITHUB_URL . '/do/not/download/this',
+ ],
+ ],
+ ]),
+ ),
+ );
+
+ $fetch = new FetchPieReleaseFromGitHub(self::TEST_GITHUB_URL, $httpDownloader, $authHelper);
+
+ $this->expectException(PiePharMissingFromLatestRelease::class);
+ $fetch->latestReleaseMetadata();
+ }
+
public function testDownloadContent(): void
{
$url = self::TEST_GITHUB_URL . '/path/to/pie.phar';