Skip to content
Closed
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
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ function (OperationInterface $operation): void {
$packageReleaseAssets = $this->container->get(PackageReleaseAssets::class);

try {
$url = $packageReleaseAssets->findMatchingReleaseAssetUrl(
$releaseAsset = $packageReleaseAssets->findMatchingReleaseAsset(
$targetPlatform,
$piePackage,
new HttpDownloader($this->io, $this->composer->getConfig()),
Expand All @@ -147,8 +147,28 @@ function (OperationInterface $operation): void {
continue;
}

$this->composerRequest->pieOutput->write('Found prebuilt archive: ' . $url);
$composerPackage->setDistUrl($url);
$this->composerRequest->pieOutput->write('Found prebuilt archive: ' . $releaseAsset->url);
$composerPackage->setDistUrl($releaseAsset->url);

if ($releaseAsset->headers !== []) {
$transportOptions = $composerPackage->getTransportOptions();
$httpOptions = $transportOptions['http'] ?? [];
if (! is_array($httpOptions)) {
$httpOptions = [];
}

$headers = $httpOptions['header'] ?? [];
if (! is_array($headers)) {
$headers = [];
}

$httpOptions['header'] = [
...$headers,
...$releaseAsset->headers,
];
$transportOptions['http'] = $httpOptions;
$composerPackage->setTransportOptions($transportOptions);
}

// Composer's dist-sha was computed against the original
// Packagist URL; once we swap to a release-asset URL the
Expand All @@ -159,7 +179,7 @@ function (OperationInterface $operation): void {
'<warning>Note: dist-sha integrity check is not available for prebuilt-binary URLs; HTTPS to the release-asset origin is the only integrity guarantee.</warning>',
);

if (pathinfo($url, PATHINFO_EXTENSION) === 'tgz') {
if (pathinfo($releaseAsset->name, PATHINFO_EXTENSION) === 'tgz') {
$composerPackage->setDistType('tar');
}

Expand Down
22 changes: 13 additions & 9 deletions src/Downloading/GithubPackageReleaseAssets.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,15 @@ public function __construct(
/**
* @param non-empty-list<non-empty-string> $possibleReleaseAssetNames
*
* @return non-empty-string
* @return ReleaseAsset
*/
public function findMatchingReleaseAssetUrl(
public function findMatchingReleaseAsset(
TargetPlatform $targetPlatform,
Package $package,
HttpDownloader $httpDownloader,
DownloadUrlMethod $downloadUrlMethod,
array $possibleReleaseAssetNames,
): string {
): ReleaseAsset {
$releaseAsset = $this->selectMatchingReleaseAsset(
$targetPlatform,
$package,
Expand All @@ -42,16 +42,20 @@ public function findMatchingReleaseAssetUrl(
$possibleReleaseAssetNames,
);

return $releaseAsset['browser_download_url'];
return new ReleaseAsset(
$releaseAsset['url'],
$releaseAsset['name'],
['Accept: application/octet-stream'],
);
}

/** @link https://github.com/squizlabs/PHP_CodeSniffer/issues/3734 */
// phpcs:disable Squiz.Commenting.FunctionComment.MissingParamName
/**
* @param list<array{name: non-empty-string, browser_download_url: non-empty-string, ...}> $releaseAssets
* @param list<array{name: non-empty-string, url: non-empty-string, ...}> $releaseAssets
* @param non-empty-list<non-empty-string> $possibleReleaseAssetNames
*
* @return array{name: non-empty-string, browser_download_url: non-empty-string, ...}
* @return array{name: non-empty-string, url: non-empty-string, ...}
*/
// phpcs:enable
private function selectMatchingReleaseAsset(
Expand All @@ -70,7 +74,7 @@ private function selectMatchingReleaseAsset(
throw Exception\CouldNotFindReleaseAsset::forPackage($targetPlatform, $package, $downloadUrlMethod, $possibleReleaseAssetNames);
}

/** @return list<array{name: non-empty-string, browser_download_url: non-empty-string, ...}> */
/** @return list<array{name: non-empty-string, url: non-empty-string, ...}> */
private function getReleaseAssetsForPackage(
Package $package,
HttpDownloader $httpDownloader,
Expand Down Expand Up @@ -106,8 +110,8 @@ private function getReleaseAssetsForPackage(
static function (array $asset): array {
Assert::keyExists($asset, 'name');
Assert::stringNotEmpty($asset['name']);
Assert::keyExists($asset, 'browser_download_url');
Assert::stringNotEmpty($asset['browser_download_url']);
Assert::keyExists($asset, 'url');
Assert::stringNotEmpty($asset['url']);

return $asset;
},
Expand Down
6 changes: 3 additions & 3 deletions src/Downloading/PackageReleaseAssets.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ interface PackageReleaseAssets
/**
* @param non-empty-list<non-empty-string> $possibleReleaseAssetNames
*
* @return non-empty-string
* @return ReleaseAsset
*/
public function findMatchingReleaseAssetUrl(
public function findMatchingReleaseAsset(
TargetPlatform $targetPlatform,
Package $package,
HttpDownloader $httpDownloader,
DownloadUrlMethod $downloadUrlMethod,
array $possibleReleaseAssetNames,
): string;
): ReleaseAsset;
}
21 changes: 21 additions & 0 deletions src/Downloading/ReleaseAsset.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

declare(strict_types=1);

namespace Php\Pie\Downloading;

/** @internal This is not public API for PIE, so should not be depended upon unless you accept the risk of BC breaks */
final class ReleaseAsset
{
/**
* @param non-empty-string $url
* @param non-empty-string $name
* @param list<non-empty-string> $headers
*/
public function __construct(
public readonly string $url,
public readonly string $name,
public readonly array $headers = [],
) {
}
}
11 changes: 8 additions & 3 deletions test/integration/Downloading/GithubPackageReleaseAssetsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use Php\Pie\DependencyResolver\Package;
use Php\Pie\Downloading\DownloadUrlMethod;
use Php\Pie\Downloading\GithubPackageReleaseAssets;
use Php\Pie\Downloading\ReleaseAsset;
use Php\Pie\ExtensionName;
use Php\Pie\ExtensionType;
use Php\Pie\Platform\Architecture;
Expand Down Expand Up @@ -60,10 +61,14 @@ public function testDeterminingReleaseAssetUrlForWindows(): void
$config = Factory::createConfig();
$io->loadConfiguration($config);

self::assertSame(
'https://github.com/asgrim/example-pie-extension/releases/download/2.0.2/php_example_pie_extension-2.0.2-8.3-ts-vs16-x86_64.zip',
self::assertEquals(
new ReleaseAsset(
'https://api.github.com/repos/asgrim/example-pie-extension/releases/assets/197867674',
'php_example_pie_extension-2.0.2-8.3-ts-vs16-x86_64.zip',
['Accept: application/octet-stream'],
),
(new GithubPackageReleaseAssets('https://api.github.com'))
->findMatchingReleaseAssetUrl(
->findMatchingReleaseAsset(
$targetPlatform,
$package,
new HttpDownloader($io, $config),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
use Php\Pie\Downloading\DownloadUrlMethod;
use Php\Pie\Downloading\Exception\CouldNotFindReleaseAsset;
use Php\Pie\Downloading\PackageReleaseAssets;
use Php\Pie\Downloading\ReleaseAsset;
use Php\Pie\Platform\Architecture;
use Php\Pie\Platform\OperatingSystem;
use Php\Pie\Platform\OperatingSystemFamily;
Expand Down Expand Up @@ -283,8 +284,8 @@ public function testDistUrlIsUpdatedForWindowsInstallers(): void
$packageReleaseAssets = $this->createMock(PackageReleaseAssets::class);
$packageReleaseAssets
->expects(self::once())
->method('findMatchingReleaseAssetUrl')
->willReturn('https://example.com/windows-download-url');
->method('findMatchingReleaseAsset')
->willReturn(new ReleaseAsset('https://example.com/windows-download-url', 'windows-download-url.zip', ['Accept: application/octet-stream']));

$this->container
->method('get')
Expand Down Expand Up @@ -319,6 +320,15 @@ public function testDistUrlIsUpdatedForWindowsInstallers(): void
$composerPackage->getDistUrl(),
);
self::assertSame(DownloadUrlMethod::WindowsBinaryDownload, DownloadUrlMethod::fromComposerPackage($composerPackage));
$transportOptions = $composerPackage->getTransportOptions();
self::assertArrayHasKey('http', $transportOptions);
self::assertIsArray($transportOptions['http']);
$httpOptions = $transportOptions['http'];
self::assertArrayHasKey('header', $httpOptions);
self::assertSame(
['Accept: application/octet-stream'],
$httpOptions['header'],
);
}

public function testDistUrlIsUpdatedForPrePackagedTgzSource(): void
Expand All @@ -343,8 +353,8 @@ public function testDistUrlIsUpdatedForPrePackagedTgzSource(): void
$packageReleaseAssets = $this->createMock(PackageReleaseAssets::class);
$packageReleaseAssets
->expects(self::once())
->method('findMatchingReleaseAssetUrl')
->willReturn('https://example.com/pre-packaged-source-download-url.tgz');
->method('findMatchingReleaseAsset')
->willReturn(new ReleaseAsset('https://example.com/pre-packaged-source-download-url.tgz', 'pre-packaged-source-download-url.tgz'));

$this->container
->method('get')
Expand Down Expand Up @@ -404,8 +414,8 @@ public function testDistUrlIsUpdatedForPrePackagedTgzBinaryWhenBinaryIsFound():
$packageReleaseAssets = $this->createMock(PackageReleaseAssets::class);
$packageReleaseAssets
->expects(self::once())
->method('findMatchingReleaseAssetUrl')
->willReturn('https://example.com/pre-packaged-binary-download-url.tgz');
->method('findMatchingReleaseAsset')
->willReturn(new ReleaseAsset('https://example.com/pre-packaged-binary-download-url.tgz', 'pre-packaged-binary-download-url.tgz'));

$this->container
->method('get')
Expand Down Expand Up @@ -465,7 +475,7 @@ public function testDistUrlIsUpdatedForPrePackagedTgzBinaryWhenBinaryIsNotFound(
$packageReleaseAssets = $this->createMock(PackageReleaseAssets::class);
$packageReleaseAssets
->expects(self::once())
->method('findMatchingReleaseAssetUrl')
->method('findMatchingReleaseAsset')
->willThrowException(new CouldNotFindReleaseAsset('nope not found'));

$this->container
Expand Down Expand Up @@ -583,8 +593,8 @@ public function testDistUrlIsUpdatedForWindowsInstallersOnUpdateOperations(): vo
$packageReleaseAssets = $this->createMock(PackageReleaseAssets::class);
$packageReleaseAssets
->expects(self::once())
->method('findMatchingReleaseAssetUrl')
->willReturn('https://example.com/windows-download-url');
->method('findMatchingReleaseAsset')
->willReturn(new ReleaseAsset('https://example.com/windows-download-url', 'windows-download-url.zip'));

$this->container
->method('get')
Expand Down Expand Up @@ -643,7 +653,7 @@ public function testNoSelectedDownloadUrlMethodWillThrowException(): void
$packageReleaseAssets = $this->createMock(PackageReleaseAssets::class);
$packageReleaseAssets
->expects(self::once())
->method('findMatchingReleaseAssetUrl')
->method('findMatchingReleaseAsset')
->willThrowException(new CouldNotFindReleaseAsset('nope not found'));

$this->container
Expand Down
24 changes: 13 additions & 11 deletions test/unit/Downloading/GithubPackageReleaseAssetsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use Php\Pie\Downloading\DownloadUrlMethod;
use Php\Pie\Downloading\Exception\CouldNotFindReleaseAsset;
use Php\Pie\Downloading\GithubPackageReleaseAssets;
use Php\Pie\Downloading\ReleaseAsset;
use Php\Pie\ExtensionName;
use Php\Pie\ExtensionType;
use Php\Pie\Platform\Architecture;
Expand All @@ -28,6 +29,7 @@
use function uniqid;

#[CoversClass(GithubPackageReleaseAssets::class)]
#[CoversClass(ReleaseAsset::class)]
final class GithubPackageReleaseAssetsTest extends TestCase
{
public function testUrlIsReturnedWhenFindingWindowsDownloadUrl(): void
Expand Down Expand Up @@ -56,11 +58,11 @@ public function testUrlIsReturnedWhenFindingWindowsDownloadUrl(): void
'assets' => [
[
'name' => 'php_foo-1.2.3-8.3-vc14-nts-x86.zip',
'browser_download_url' => 'wrong_download_url',
'url' => 'wrong_download_url',
],
[
'name' => 'php_foo-1.2.3-8.3-vc14-ts-x86.zip',
'browser_download_url' => 'actual_download_url',
'url' => 'actual_download_url',
],
],
]);
Expand All @@ -82,9 +84,9 @@ public function testUrlIsReturnedWhenFindingWindowsDownloadUrl(): void

$releaseAssets = new GithubPackageReleaseAssets('https://test-github-api-base-url.thephp.foundation');

self::assertSame(
'actual_download_url',
$releaseAssets->findMatchingReleaseAssetUrl(
self::assertEquals(
new ReleaseAsset('actual_download_url', 'php_foo-1.2.3-8.3-vc14-ts-x86.zip', ['Accept: application/octet-stream']),
$releaseAssets->findMatchingReleaseAsset(
$targetPlatform,
$package,
$httpDownloader,
Expand Down Expand Up @@ -123,11 +125,11 @@ public function testUrlIsReturnedWhenFindingWindowsDownloadUrlWithCompilerAndThr
'assets' => [
[
'name' => 'php_foo-1.2.3-8.3-nts-vc14-x86.zip',
'browser_download_url' => 'wrong_download_url',
'url' => 'wrong_download_url',
],
[
'name' => 'php_foo-1.2.3-8.3-ts-vc14-x86.zip',
'browser_download_url' => 'actual_download_url',
'url' => 'actual_download_url',
],
],
]);
Expand All @@ -149,9 +151,9 @@ public function testUrlIsReturnedWhenFindingWindowsDownloadUrlWithCompilerAndThr

$releaseAssets = new GithubPackageReleaseAssets('https://test-github-api-base-url.thephp.foundation');

self::assertSame(
'actual_download_url',
$releaseAssets->findMatchingReleaseAssetUrl(
self::assertEquals(
new ReleaseAsset('actual_download_url', 'php_foo-1.2.3-8.3-ts-vc14-x86.zip', ['Accept: application/octet-stream']),
$releaseAssets->findMatchingReleaseAsset(
$targetPlatform,
$package,
$httpDownloader,
Expand Down Expand Up @@ -198,7 +200,7 @@ public function testFindWindowsDownloadUrlForPackageThrowsExceptionWhenAssetNotF
$releaseAssets = new GithubPackageReleaseAssets('https://test-github-api-base-url.thephp.foundation');

$this->expectException(CouldNotFindReleaseAsset::class);
$releaseAssets->findMatchingReleaseAssetUrl(
$releaseAssets->findMatchingReleaseAsset(
$targetPlatform,
$package,
$httpDownloader,
Expand Down