Skip to content

Commit c987ee8

Browse files
authored
Merge pull request #153 from asgrim/150-fix-ext-conflict
Fix conflict trying to install an ext that is already enabled
2 parents ee7c603 + 1da8baf commit c987ee8

File tree

5 files changed

+107
-4
lines changed

5 files changed

+107
-4
lines changed

src/ComposerIntegration/ComposerIntegrationHandler.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,12 @@ public function __invoke(Package $package, Composer $composer, TargetPlatform $t
5353
$composer->getRepositoryManager()->getLocalRepository()->removePackage($pkg);
5454
}
5555

56-
$composerInstaller = Installer::create($this->arrayCollectionIo, $composer);
56+
$composerInstaller = PieComposerInstaller::createWithPhpBinary(
57+
$targetPlatform->phpBinaryPath,
58+
$package->extensionName,
59+
$this->arrayCollectionIo,
60+
$composer,
61+
);
5762
$composerInstaller
5863
->setAllowedTypes(['php-ext', 'php-ext-zend'])
5964
->setInstall(true)

src/ComposerIntegration/PhpBinaryPathBasedPlatformRepository.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use Composer\Pcre\Preg;
99
use Composer\Repository\PlatformRepository;
1010
use Composer\Semver\VersionParser;
11+
use Php\Pie\ExtensionName;
1112
use Php\Pie\Platform\TargetPhp\PhpBinaryPath;
1213
use UnexpectedValueException;
1314

@@ -19,7 +20,7 @@ class PhpBinaryPathBasedPlatformRepository extends PlatformRepository
1920
{
2021
private VersionParser $versionParser;
2122

22-
public function __construct(PhpBinaryPath $phpBinaryPath)
23+
public function __construct(PhpBinaryPath $phpBinaryPath, ExtensionName|null $extensionBeingInstalled)
2324
{
2425
$this->versionParser = new VersionParser();
2526
$this->packages = [];
@@ -32,6 +33,16 @@ public function __construct(PhpBinaryPath $phpBinaryPath)
3233
$extVersions = $phpBinaryPath->extensions();
3334

3435
foreach ($extVersions as $extension => $extensionVersion) {
36+
/**
37+
* If the extension we're trying to exclude is not excluded from this list if it is already installed
38+
* and enabled, it conflicts when running {@see ComposerIntegrationHandler}.
39+
*
40+
* @link https://github.com/php/pie/issues/150
41+
*/
42+
if ($extensionBeingInstalled !== null && $extension === $extensionBeingInstalled->name()) {
43+
continue;
44+
}
45+
3546
$this->addPackage($this->packageForExtension($extension, $extensionVersion));
3647
}
3748

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Php\Pie\ComposerIntegration;
6+
7+
use Composer\Composer;
8+
use Composer\Installer;
9+
use Composer\IO\IOInterface;
10+
use Composer\Repository\PlatformRepository;
11+
use Php\Pie\ExtensionName;
12+
use Php\Pie\Platform\TargetPhp\PhpBinaryPath;
13+
use Webmozart\Assert\Assert;
14+
15+
/**
16+
* @internal This is not public API for PIE, so should not be depended upon unless you accept the risk of BC breaks
17+
*
18+
* @psalm-suppress PropertyNotSetInConstructor Property $fixedRootPackage is defined in parent
19+
*/
20+
class PieComposerInstaller extends Installer
21+
{
22+
private PhpBinaryPath|null $phpBinaryPath = null;
23+
private ExtensionName|null $extensionBeingInstalled = null;
24+
25+
protected function createPlatformRepo(bool $forUpdate): PlatformRepository
26+
{
27+
Assert::notNull($this->phpBinaryPath, '$phpBinaryPath was not set, maybe createWithPhpBinary was not used?');
28+
Assert::notNull($this->extensionBeingInstalled, '$extensionBeingInstalled was not set, maybe createWithPhpBinary was not used?');
29+
30+
return new PhpBinaryPathBasedPlatformRepository($this->phpBinaryPath, $this->extensionBeingInstalled);
31+
}
32+
33+
public static function createWithPhpBinary(
34+
PhpBinaryPath $php,
35+
ExtensionName $extensionBeingInstalled,
36+
IOInterface $io,
37+
Composer $composer,
38+
): self {
39+
/** @psalm-suppress InvalidArgument some kind of unrelated type mismatch, defined in parent */
40+
$composerInstaller = new self(
41+
$io,
42+
$composer->getConfig(),
43+
$composer->getPackage(),
44+
$composer->getDownloadManager(),
45+
$composer->getRepositoryManager(),
46+
$composer->getLocker(),
47+
$composer->getInstallationManager(),
48+
$composer->getEventDispatcher(),
49+
$composer->getAutoloadGenerator(),
50+
);
51+
52+
$composerInstaller->phpBinaryPath = $php;
53+
$composerInstaller->extensionBeingInstalled = $extensionBeingInstalled;
54+
55+
return $composerInstaller;
56+
}
57+
}

src/ComposerIntegration/VersionSelectorFactory.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public static function make(
3535
): VersionSelector {
3636
return new VersionSelector(
3737
self::factoryRepositorySet($composer, $requestedPackageAndVersion->version),
38-
new PhpBinaryPathBasedPlatformRepository($targetPlatform->phpBinaryPath),
38+
new PhpBinaryPathBasedPlatformRepository($targetPlatform->phpBinaryPath, null),
3939
);
4040
}
4141
}

test/unit/ComposerIntegration/PhpBinaryPathBasedPlatformRepositoryTest.php

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use Composer\Package\PackageInterface;
88
use Php\Pie\ComposerIntegration\PhpBinaryPathBasedPlatformRepository;
9+
use Php\Pie\ExtensionName;
910
use Php\Pie\Platform\TargetPhp\PhpBinaryPath;
1011
use PHPUnit\Framework\Attributes\CoversClass;
1112
use PHPUnit\Framework\TestCase;
@@ -30,7 +31,7 @@ public function testPlatformRepositoryContainsExpectedPacakges(): void
3031
'another' => '1.2.3-alpha.34',
3132
]);
3233

33-
$platformRepository = new PhpBinaryPathBasedPlatformRepository($phpBinaryPath);
34+
$platformRepository = new PhpBinaryPathBasedPlatformRepository($phpBinaryPath, null);
3435

3536
self::assertSame(
3637
[
@@ -46,4 +47,33 @@ public function testPlatformRepositoryContainsExpectedPacakges(): void
4647
),
4748
);
4849
}
50+
51+
public function testPlatformRepositoryExcludesExtensionBeingInstalled(): void
52+
{
53+
$extensionBeingInstalled = ExtensionName::normaliseFromString('extension_being_installed');
54+
55+
$phpBinaryPath = $this->createMock(PhpBinaryPath::class);
56+
$phpBinaryPath->expects(self::once())
57+
->method('version')
58+
->willReturn('8.1.0');
59+
$phpBinaryPath->expects(self::once())
60+
->method('extensions')
61+
->willReturn([
62+
'foo' => '8.1.0',
63+
'extension_being_installed' => '1.2.3',
64+
]);
65+
66+
$platformRepository = new PhpBinaryPathBasedPlatformRepository($phpBinaryPath, $extensionBeingInstalled);
67+
68+
self::assertSame(
69+
[
70+
'php:8.1.0',
71+
'ext-foo:8.1.0',
72+
],
73+
array_map(
74+
static fn (PackageInterface $package): string => $package->getName() . ':' . $package->getPrettyVersion(),
75+
$platformRepository->getPackages(),
76+
),
77+
);
78+
}
4979
}

0 commit comments

Comments
 (0)