Skip to content

Commit

Permalink
Merge pull request #153 from asgrim/150-fix-ext-conflict
Browse files Browse the repository at this point in the history
Fix conflict trying to install an ext that is already enabled
  • Loading branch information
asgrim authored Dec 11, 2024
2 parents ee7c603 + 1da8baf commit c987ee8
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 4 deletions.
7 changes: 6 additions & 1 deletion src/ComposerIntegration/ComposerIntegrationHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,12 @@ public function __invoke(Package $package, Composer $composer, TargetPlatform $t
$composer->getRepositoryManager()->getLocalRepository()->removePackage($pkg);
}

$composerInstaller = Installer::create($this->arrayCollectionIo, $composer);
$composerInstaller = PieComposerInstaller::createWithPhpBinary(
$targetPlatform->phpBinaryPath,
$package->extensionName,
$this->arrayCollectionIo,
$composer,
);
$composerInstaller
->setAllowedTypes(['php-ext', 'php-ext-zend'])
->setInstall(true)
Expand Down
13 changes: 12 additions & 1 deletion src/ComposerIntegration/PhpBinaryPathBasedPlatformRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Composer\Pcre\Preg;
use Composer\Repository\PlatformRepository;
use Composer\Semver\VersionParser;
use Php\Pie\ExtensionName;
use Php\Pie\Platform\TargetPhp\PhpBinaryPath;
use UnexpectedValueException;

Expand All @@ -19,7 +20,7 @@ class PhpBinaryPathBasedPlatformRepository extends PlatformRepository
{
private VersionParser $versionParser;

public function __construct(PhpBinaryPath $phpBinaryPath)
public function __construct(PhpBinaryPath $phpBinaryPath, ExtensionName|null $extensionBeingInstalled)
{
$this->versionParser = new VersionParser();
$this->packages = [];
Expand All @@ -32,6 +33,16 @@ public function __construct(PhpBinaryPath $phpBinaryPath)
$extVersions = $phpBinaryPath->extensions();

foreach ($extVersions as $extension => $extensionVersion) {
/**
* If the extension we're trying to exclude is not excluded from this list if it is already installed
* and enabled, it conflicts when running {@see ComposerIntegrationHandler}.
*
* @link https://github.com/php/pie/issues/150
*/
if ($extensionBeingInstalled !== null && $extension === $extensionBeingInstalled->name()) {
continue;
}

$this->addPackage($this->packageForExtension($extension, $extensionVersion));
}

Expand Down
57 changes: 57 additions & 0 deletions src/ComposerIntegration/PieComposerInstaller.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php

declare(strict_types=1);

namespace Php\Pie\ComposerIntegration;

use Composer\Composer;
use Composer\Installer;
use Composer\IO\IOInterface;
use Composer\Repository\PlatformRepository;
use Php\Pie\ExtensionName;
use Php\Pie\Platform\TargetPhp\PhpBinaryPath;
use Webmozart\Assert\Assert;

/**
* @internal This is not public API for PIE, so should not be depended upon unless you accept the risk of BC breaks
*
* @psalm-suppress PropertyNotSetInConstructor Property $fixedRootPackage is defined in parent
*/
class PieComposerInstaller extends Installer
{
private PhpBinaryPath|null $phpBinaryPath = null;
private ExtensionName|null $extensionBeingInstalled = null;

protected function createPlatformRepo(bool $forUpdate): PlatformRepository
{
Assert::notNull($this->phpBinaryPath, '$phpBinaryPath was not set, maybe createWithPhpBinary was not used?');
Assert::notNull($this->extensionBeingInstalled, '$extensionBeingInstalled was not set, maybe createWithPhpBinary was not used?');

return new PhpBinaryPathBasedPlatformRepository($this->phpBinaryPath, $this->extensionBeingInstalled);
}

public static function createWithPhpBinary(
PhpBinaryPath $php,
ExtensionName $extensionBeingInstalled,
IOInterface $io,
Composer $composer,
): self {
/** @psalm-suppress InvalidArgument some kind of unrelated type mismatch, defined in parent */
$composerInstaller = new self(
$io,
$composer->getConfig(),
$composer->getPackage(),
$composer->getDownloadManager(),
$composer->getRepositoryManager(),
$composer->getLocker(),
$composer->getInstallationManager(),
$composer->getEventDispatcher(),
$composer->getAutoloadGenerator(),
);

$composerInstaller->phpBinaryPath = $php;
$composerInstaller->extensionBeingInstalled = $extensionBeingInstalled;

return $composerInstaller;
}
}
2 changes: 1 addition & 1 deletion src/ComposerIntegration/VersionSelectorFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public static function make(
): VersionSelector {
return new VersionSelector(
self::factoryRepositorySet($composer, $requestedPackageAndVersion->version),
new PhpBinaryPathBasedPlatformRepository($targetPlatform->phpBinaryPath),
new PhpBinaryPathBasedPlatformRepository($targetPlatform->phpBinaryPath, null),
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use Composer\Package\PackageInterface;
use Php\Pie\ComposerIntegration\PhpBinaryPathBasedPlatformRepository;
use Php\Pie\ExtensionName;
use Php\Pie\Platform\TargetPhp\PhpBinaryPath;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\TestCase;
Expand All @@ -30,7 +31,7 @@ public function testPlatformRepositoryContainsExpectedPacakges(): void
'another' => '1.2.3-alpha.34',
]);

$platformRepository = new PhpBinaryPathBasedPlatformRepository($phpBinaryPath);
$platformRepository = new PhpBinaryPathBasedPlatformRepository($phpBinaryPath, null);

self::assertSame(
[
Expand All @@ -46,4 +47,33 @@ public function testPlatformRepositoryContainsExpectedPacakges(): void
),
);
}

public function testPlatformRepositoryExcludesExtensionBeingInstalled(): void
{
$extensionBeingInstalled = ExtensionName::normaliseFromString('extension_being_installed');

$phpBinaryPath = $this->createMock(PhpBinaryPath::class);
$phpBinaryPath->expects(self::once())
->method('version')
->willReturn('8.1.0');
$phpBinaryPath->expects(self::once())
->method('extensions')
->willReturn([
'foo' => '8.1.0',
'extension_being_installed' => '1.2.3',
]);

$platformRepository = new PhpBinaryPathBasedPlatformRepository($phpBinaryPath, $extensionBeingInstalled);

self::assertSame(
[
'php:8.1.0',
'ext-foo:8.1.0',
],
array_map(
static fn (PackageInterface $package): string => $package->getName() . ':' . $package->getPrettyVersion(),
$platformRepository->getPackages(),
),
);
}
}

0 comments on commit c987ee8

Please sign in to comment.