From e2f61ef324b2d3dd0c19188f2bd7db82bdbdde80 Mon Sep 17 00:00:00 2001 From: James Titcumb Date: Fri, 2 Aug 2024 11:40:16 +0100 Subject: [PATCH] Make requiring specific commit hashes work --- .../ResolveDependencyWithComposer.php | 13 ++++++ .../Command/DownloadCommandTest.php | 27 +++++++----- .../ResolveDependencyWithComposerTest.php | 43 +++++++++++-------- 3 files changed, 56 insertions(+), 27 deletions(-) diff --git a/src/DependencyResolver/ResolveDependencyWithComposer.php b/src/DependencyResolver/ResolveDependencyWithComposer.php index be36001..6872f5c 100644 --- a/src/DependencyResolver/ResolveDependencyWithComposer.php +++ b/src/DependencyResolver/ResolveDependencyWithComposer.php @@ -59,6 +59,19 @@ final class ResolveDependencyWithComposer implements DependencyResolver throw UnableToResolveRequirement::fromRequirement($packageName, $requestedVersion); } + /** + * If a specific commit hash is requested, override the references in the package. This is approximately what + * Composer does anyway: + * + * > ArrayLoader::parseLinks is in charge of this, it drops commit refs, for package resolution purposes we + * > only use dev-main, but we ensure in the PoolBuilder that root references (#...) are set so the dev-main + * > package has its source and dist refs overridden to be whatever you specify and that applies at install + * > time then but package metadata is only read from the branch's head + */ + if ($requestedVersion !== null && preg_match('/#([a-f0-9]{40})$/', $requestedVersion, $matches)) { + $package->setSourceDistReferences($matches[1]); + } + if (! ExtensionType::isValid($package->getType())) { throw UnableToResolveRequirement::toPhpOrZendExtension($package, $packageName, $requestedVersion); } diff --git a/test/integration/Command/DownloadCommandTest.php b/test/integration/Command/DownloadCommandTest.php index 45b2bec..76eab39 100644 --- a/test/integration/Command/DownloadCommandTest.php +++ b/test/integration/Command/DownloadCommandTest.php @@ -39,19 +39,20 @@ class DownloadCommandTest extends TestCase * please see {@see \Php\PieIntegrationTest\DependencyResolver\ResolveDependencyWithComposerTest}, which is much * faster to execute! * - * @return array + * @return array * * @psalm-suppress PossiblyUnusedMethod https://github.com/psalm/psalm-plugin-phpunit/issues/131 */ public static function validVersionsList(): array { $versionsAndExpected = [ - [self::TEST_PACKAGE, self::TEST_PACKAGE . ':1.0.1'], - [self::TEST_PACKAGE . ':^1.0', self::TEST_PACKAGE . ':1.0.1'], - [self::TEST_PACKAGE . ':1.0.1-alpha.3@alpha', self::TEST_PACKAGE . ':1.0.1-alpha.3'], - [self::TEST_PACKAGE . ':*', self::TEST_PACKAGE . ':1.0.1'], - [self::TEST_PACKAGE . ':~1.0.0@alpha', self::TEST_PACKAGE . ':1.0.1'], - [self::TEST_PACKAGE . ':~1.0.0', self::TEST_PACKAGE . ':1.0.1'], + [self::TEST_PACKAGE, self::TEST_PACKAGE . ':1.0.1', '769f906'], + [self::TEST_PACKAGE . ':^1.0', self::TEST_PACKAGE . ':1.0.1', '769f906'], + [self::TEST_PACKAGE . ':1.0.1-alpha.3@alpha', self::TEST_PACKAGE . ':1.0.1-alpha.3', '115f8f8'], + [self::TEST_PACKAGE . ':*', self::TEST_PACKAGE . ':1.0.1', '769f906'], + [self::TEST_PACKAGE . ':~1.0.0@alpha', self::TEST_PACKAGE . ':1.0.1', '769f906'], + [self::TEST_PACKAGE . ':~1.0.0', self::TEST_PACKAGE . ':1.0.1', '769f906'], + [self::TEST_PACKAGE . ':dev-main#9b5e6c80a1e05556e4e6824f0c112a4992cee001', self::TEST_PACKAGE . ':dev-main', '9b5e6c8'], ]; return array_combine( @@ -61,8 +62,11 @@ class DownloadCommandTest extends TestCase } #[DataProvider('validVersionsList')] - public function testDownloadCommandWillDownloadCompatibleExtension(string $requestedVersion, string $expectedVersion): void - { + public function testDownloadCommandWillDownloadCompatibleExtension( + string $requestedVersion, + string $expectedVersion, + string $expectedSha, + ): void { if (PHP_VERSION_ID < 80300 || PHP_VERSION_ID >= 80400) { self::markTestSkipped('This test can only run on PHP 8.3 - you are running ' . PHP_VERSION); } @@ -73,7 +77,10 @@ class DownloadCommandTest extends TestCase $outputString = $this->commandTester->getDisplay(); self::assertStringContainsString('Found package: ' . $expectedVersion . ' which provides', $outputString); - self::assertStringContainsString('Extracted ' . $expectedVersion . ' source to', $outputString); + self::assertStringMatchesFormat( + '%AExtracted ' . $expectedVersion . ' source to: /tmp/%s/asgrim-example-pie-extension-' . $expectedSha . '%A', + $outputString, + ); } #[DataProvider('validVersionsList')] diff --git a/test/integration/DependencyResolver/ResolveDependencyWithComposerTest.php b/test/integration/DependencyResolver/ResolveDependencyWithComposerTest.php index 5281b7a..3be4074 100644 --- a/test/integration/DependencyResolver/ResolveDependencyWithComposerTest.php +++ b/test/integration/DependencyResolver/ResolveDependencyWithComposerTest.php @@ -22,28 +22,32 @@ use const PHP_VERSION_ID; #[CoversClass(ResolveDependencyWithComposer::class)] final class ResolveDependencyWithComposerTest extends TestCase { + private const DOWNLOAD_URL_ANY = 'https://api.github.com/repos/asgrim/example-pie-extension/zipball/%s'; + private const DOWNLOAD_URL_1_0_1_ALPHA_3 = 'https://api.github.com/repos/asgrim/example-pie-extension/zipball/115f8f8e01ee098a18ec2f47af4852be51ebece7'; + private const DOWNLOAD_URL_1_0_1 = 'https://api.github.com/repos/asgrim/example-pie-extension/zipball/769f906413d6d1e12152f6d34134cbcd347ca253'; + private const DOWNLOAD_URL_1_1_0_BETA_1 = 'https://api.github.com/repos/asgrim/example-pie-extension/zipball/b8cec47269dc607b3111fbebd2c47f5b5112595e'; + /** - * @return array + * @return array * * @psalm-suppress PossiblyUnusedMethod https://github.com/psalm/psalm-plugin-phpunit/issues/131 */ public static function validVersionsList(): array { $versionsAndExpected = [ - [null, '1.0.1'], - ['*', '1.0.1'], - ['1.0.1-alpha.3@alpha', '1.0.1-alpha.3'], - ['^1.0', '1.0.1'], - ['^1.1.0@alpha', '1.1.0-beta.1'], - ['^1.0@beta', '1.0.1'], - ['^1.1@beta', '1.1.0-beta.1'], - ['~1.0.0', '1.0.1'], - ['~1.0.0@alpha', '1.0.1'], - ['~1.0.0@beta', '1.0.1'], - ['~1.0@beta', '1.0.1'], - ['dev-main', 'dev-main'], - // @todo this is resolving simply to `dev-main`, but we should be able to download a specific commit -// ['dev-769f906413d6d1e12152f6d34134cbcd347ca253#769f906413d6d1e12152f6d34134cbcd347ca253@dev', ''], + [null, '1.0.1', self::DOWNLOAD_URL_ANY], + ['*', '1.0.1', self::DOWNLOAD_URL_ANY], + ['1.0.1-alpha.3@alpha', '1.0.1-alpha.3', self::DOWNLOAD_URL_1_0_1_ALPHA_3], + ['^1.0', '1.0.1', self::DOWNLOAD_URL_1_0_1], + ['^1.1.0@alpha', '1.1.0-beta.1', self::DOWNLOAD_URL_1_1_0_BETA_1], + ['^1.0@beta', '1.0.1', self::DOWNLOAD_URL_1_0_1], + ['^1.1@beta', '1.1.0-beta.1', self::DOWNLOAD_URL_1_1_0_BETA_1], + ['~1.0.0', '1.0.1', self::DOWNLOAD_URL_1_0_1], + ['~1.0.0@alpha', '1.0.1', self::DOWNLOAD_URL_1_0_1], + ['~1.0.0@beta', '1.0.1', self::DOWNLOAD_URL_1_0_1], + ['~1.0@beta', '1.0.1', self::DOWNLOAD_URL_1_0_1], + ['dev-main', 'dev-main', self::DOWNLOAD_URL_ANY], + ['dev-main#769f906413d6d1e12152f6d34134cbcd347ca253', 'dev-main', self::DOWNLOAD_URL_1_0_1], ]; return array_combine( @@ -53,8 +57,11 @@ final class ResolveDependencyWithComposerTest extends TestCase } #[DataProvider('validVersionsList')] - public function testDependenciesAreResolvedToExpectedVersions(string|null $requestedVersion, string $expectedVersion): void - { + public function testDependenciesAreResolvedToExpectedVersions( + string|null $requestedVersion, + string $expectedVersion, + string $expectedDownloadUrl, + ): void { if (PHP_VERSION_ID < 80300 || PHP_VERSION_ID >= 80400) { self::markTestSkipped('This test can only run on PHP 8.3 - you are running ' . PHP_VERSION); } @@ -69,5 +76,7 @@ final class ResolveDependencyWithComposerTest extends TestCase ); self::assertSame($expectedVersion, $package->version); + self::assertNotNull($package->downloadUrl); + self::assertStringMatchesFormat($expectedDownloadUrl, $package->downloadUrl); } }