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
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
use Psr\Container\ContainerInterface;
use Throwable;

use function array_merge_recursive;
use function array_walk;
use function in_array;
use function pathinfo;
Expand Down Expand Up @@ -134,7 +135,7 @@ function (OperationInterface $operation): void {
$packageReleaseAssets = $this->container->get(PackageReleaseAssets::class);

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

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

$composerPackage->setTransportOptions(array_merge_recursive(
$composerPackage->getTransportOptions(),
['http' => ['header' => ['Accept: application/octet-stream']]],
));

// Composer's dist-sha was computed against the original
// Packagist URL; once we swap to a release-asset URL the
Expand All @@ -159,7 +165,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($matchedReleaseAsset->filename, PATHINFO_EXTENSION) === 'tgz') {
$composerPackage->setDistType('tar');
}

Expand Down
22 changes: 9 additions & 13 deletions src/Downloading/GithubPackageReleaseAssets.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,14 @@ public function __construct(
) {
}

/**
* @param non-empty-list<non-empty-string> $possibleReleaseAssetNames
*
* @return non-empty-string
*/
public function findMatchingReleaseAssetUrl(
/** @param non-empty-list<non-empty-string> $possibleReleaseAssetNames */
public function findMatchingReleaseAsset(
TargetPlatform $targetPlatform,
Package $package,
HttpDownloader $httpDownloader,
DownloadUrlMethod $downloadUrlMethod,
array $possibleReleaseAssetNames,
): string {
): MatchedReleaseAsset {
$releaseAsset = $this->selectMatchingReleaseAsset(
$targetPlatform,
$package,
Expand All @@ -42,16 +38,16 @@ public function findMatchingReleaseAssetUrl(
$possibleReleaseAssetNames,
);

return $releaseAsset['browser_download_url'];
return new MatchedReleaseAsset($releaseAsset['url'], $releaseAsset['name']);
}

/** @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 +66,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 +102,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
23 changes: 23 additions & 0 deletions src/Downloading/MatchedReleaseAsset.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?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
*
* @immutable
*/
final class MatchedReleaseAsset
{
/**
* @param non-empty-string $url
* @param non-empty-string $filename
*/
public function __construct(
public readonly string $url,
public readonly string $filename,
) {
}
}
10 changes: 3 additions & 7 deletions src/Downloading/PackageReleaseAssets.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,12 @@
/** @internal This is not public API for PIE, so should not be depended upon unless you accept the risk of BC breaks */
interface PackageReleaseAssets
{
/**
* @param non-empty-list<non-empty-string> $possibleReleaseAssetNames
*
* @return non-empty-string
*/
public function findMatchingReleaseAssetUrl(
/** @param non-empty-list<non-empty-string> $possibleReleaseAssetNames */
public function findMatchingReleaseAsset(
TargetPlatform $targetPlatform,
Package $package,
HttpDownloader $httpDownloader,
DownloadUrlMethod $downloadUrlMethod,
array $possibleReleaseAssetNames,
): string;
): MatchedReleaseAsset;
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,10 @@ 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::assertMatchesRegularExpression(
'~^https://api\.github\.com/repos/asgrim/example-pie-extension/releases/assets/\d+$~',
(new GithubPackageReleaseAssets('https://api.github.com'))
->findMatchingReleaseAssetUrl(
->findMatchingReleaseAsset(
$targetPlatform,
$package,
new HttpDownloader($io, $config),
Expand All @@ -72,7 +72,7 @@ public function testDeterminingReleaseAssetUrlForWindows(): void
$targetPlatform,
$package,
),
),
)->url,
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
use Php\Pie\DependencyResolver\RequestedPackageAndVersion;
use Php\Pie\Downloading\DownloadUrlMethod;
use Php\Pie\Downloading\Exception\CouldNotFindReleaseAsset;
use Php\Pie\Downloading\MatchedReleaseAsset;
use Php\Pie\Downloading\PackageReleaseAssets;
use Php\Pie\Platform\Architecture;
use Php\Pie\Platform\OperatingSystem;
Expand Down Expand Up @@ -283,8 +284,11 @@ 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 MatchedReleaseAsset(
'https://api.github.com/repos/foo/bar/releases/assets/11111',
'php_foo-1.2.3-8.3-vc14-ts-x86.zip',
));

$this->container
->method('get')
Expand Down Expand Up @@ -315,10 +319,11 @@ public function testDistUrlIsUpdatedForWindowsInstallers(): void
))($installerEvent);

self::assertSame(
'https://example.com/windows-download-url',
'https://api.github.com/repos/foo/bar/releases/assets/11111',
$composerPackage->getDistUrl(),
);
self::assertSame(DownloadUrlMethod::WindowsBinaryDownload, DownloadUrlMethod::fromComposerPackage($composerPackage));
self::assertSame(['http' => ['header' => ['Accept: application/octet-stream']]], $composerPackage->getTransportOptions());
}

public function testDistUrlIsUpdatedForPrePackagedTgzSource(): void
Expand All @@ -343,8 +348,11 @@ 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 MatchedReleaseAsset(
'https://api.github.com/repos/foo/bar/releases/assets/22222',
'php_foobar-1.2.3-src.tgz',
));

$this->container
->method('get')
Expand Down Expand Up @@ -375,7 +383,7 @@ public function testDistUrlIsUpdatedForPrePackagedTgzSource(): void
))($installerEvent);

self::assertSame(
'https://example.com/pre-packaged-source-download-url.tgz',
'https://api.github.com/repos/foo/bar/releases/assets/22222',
$composerPackage->getDistUrl(),
);
self::assertSame(DownloadUrlMethod::PrePackagedSourceDownload, DownloadUrlMethod::fromComposerPackage($composerPackage));
Expand Down Expand Up @@ -404,8 +412,11 @@ 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 MatchedReleaseAsset(
'https://api.github.com/repos/foo/bar/releases/assets/12345',
'php_foobar-1.2.3_php8.3-x86_64-linux-glibc-zts.tgz',
));

$this->container
->method('get')
Expand Down Expand Up @@ -436,11 +447,12 @@ public function testDistUrlIsUpdatedForPrePackagedTgzBinaryWhenBinaryIsFound():
))($installerEvent);

self::assertSame(
'https://example.com/pre-packaged-binary-download-url.tgz',
'https://api.github.com/repos/foo/bar/releases/assets/12345',
$composerPackage->getDistUrl(),
);
self::assertSame(DownloadUrlMethod::PrePackagedBinary, DownloadUrlMethod::fromComposerPackage($composerPackage));
self::assertSame('tar', $composerPackage->getDistType());
self::assertSame(['http' => ['header' => ['Accept: application/octet-stream']]], $composerPackage->getTransportOptions());
}

public function testDistUrlIsUpdatedForPrePackagedTgzBinaryWhenBinaryIsNotFound(): void
Expand All @@ -465,7 +477,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 +595,11 @@ 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 MatchedReleaseAsset(
'https://api.github.com/repos/foo/bar/releases/assets/33333',
'php_foo-1.2.3-8.3-vc14-ts-x86.zip',
));

$this->container
->method('get')
Expand Down Expand Up @@ -615,7 +630,7 @@ public function testDistUrlIsUpdatedForWindowsInstallersOnUpdateOperations(): vo
))($installerEvent);

self::assertSame(
'https://example.com/windows-download-url',
'https://api.github.com/repos/foo/bar/releases/assets/33333',
$targetPackage->getDistUrl(),
);
self::assertSame(DownloadUrlMethod::WindowsBinaryDownload, DownloadUrlMethod::fromComposerPackage($targetPackage));
Expand Down Expand Up @@ -643,7 +658,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
18 changes: 9 additions & 9 deletions test/unit/Downloading/GithubPackageReleaseAssetsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,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 @@ -84,7 +84,7 @@ public function testUrlIsReturnedWhenFindingWindowsDownloadUrl(): void

self::assertSame(
'actual_download_url',
$releaseAssets->findMatchingReleaseAssetUrl(
$releaseAssets->findMatchingReleaseAsset(
$targetPlatform,
$package,
$httpDownloader,
Expand All @@ -93,7 +93,7 @@ public function testUrlIsReturnedWhenFindingWindowsDownloadUrl(): void
$targetPlatform,
$package,
),
),
)->url,
);
}

Expand Down Expand Up @@ -123,11 +123,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 @@ -151,7 +151,7 @@ public function testUrlIsReturnedWhenFindingWindowsDownloadUrlWithCompilerAndThr

self::assertSame(
'actual_download_url',
$releaseAssets->findMatchingReleaseAssetUrl(
$releaseAssets->findMatchingReleaseAsset(
$targetPlatform,
$package,
$httpDownloader,
Expand All @@ -160,7 +160,7 @@ public function testUrlIsReturnedWhenFindingWindowsDownloadUrlWithCompilerAndThr
$targetPlatform,
$package,
),
),
)->url,
);
}

Expand Down Expand Up @@ -198,7 +198,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