Skip to content
Closed
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
81 changes: 52 additions & 29 deletions src/ComposerIntegration/ComposerIntegrationHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use Composer\Installer;
use Php\Pie\DependencyResolver\Package;
use Php\Pie\DependencyResolver\RequestedPackageAndVersion;
use Php\Pie\ExtensionName;
use Php\Pie\Platform;
use Php\Pie\Platform\TargetPlatform;
use Psr\Container\ContainerInterface;
Expand All @@ -22,8 +23,7 @@ public function __construct(
private readonly ContainerInterface $container,
private readonly QuieterConsoleIO $arrayCollectionIo,
private readonly VendorCleanup $vendorCleanup,
) {
}
) {}

public function runInstall(
Package $package,
Expand Down Expand Up @@ -53,7 +53,6 @@ public function runInstall(
}

// Write the new requirement to pie.json; because we later essentially just do a `composer install` using that file
$pieComposerJson = Platform::getPieJsonFilename($targetPlatform);
$pieJsonEditor = PieJsonEditor::fromTargetPlatform($targetPlatform);
$originalPieJsonContent = $pieJsonEditor->addRequire(
$requestedPackageAndVersion->package,
Expand All @@ -68,33 +67,15 @@ public function runInstall(
$composer->getRepositoryManager()->getLocalRepository()->removePackage($pkg);
}

$composerInstaller = PieComposerInstaller::createWithPhpBinary(
$targetPlatform->phpBinaryPath,
$composerInstaller = $this->createConfiguredInstaller(
$targetPlatform,
$package->extensionName(),
$this->arrayCollectionIo,
$composer,
$requestedPackageAndVersion->package,
$forceInstallPackageVersion,
);
$composerInstaller
->setAllowedTypes(['php-ext', 'php-ext-zend'])
->setInstall(true)
->setIgnoredTypes([])
->setDryRun(false)
->setPlatformRequirementFilter(PlatformRequirementFilterFactory::fromBoolOrList($forceInstallPackageVersion))
->setDownloadOnly(false);

if (file_exists(PieComposerFactory::getLockFile($pieComposerJson))) {
$composerInstaller->setUpdate(true);
$composerInstaller->setUpdateAllowList([$requestedPackageAndVersion->package]);
}

$resultCode = $composerInstaller->run();

if ($resultCode !== Installer::ERROR_NONE) {
// Revert composer.json change
$pieJsonEditor->revert($originalPieJsonContent);

throw ComposerRunFailed::fromExitCode($resultCode);
}
$this->executeComposerInstaller($composerInstaller, $pieJsonEditor, $originalPieJsonContent);

if (! $runCleanup) {
return;
Expand All @@ -110,31 +91,73 @@ public function runUninstall(
RequestedPackageAndVersion $requestedPackageAndVersionToRemove,
): void {
// Write the new requirement to pie.json; because we later essentially just do a `composer install` using that file
$pieComposerJson = Platform::getPieJsonFilename($targetPlatform);
$pieJsonEditor = PieJsonEditor::fromTargetPlatform($targetPlatform);
$originalPieJsonContent = $pieJsonEditor->removeRequire($requestedPackageAndVersionToRemove->package);

// Refresh the Composer instance so it re-reads the updated pie.json
$composer = PieComposerFactory::recreatePieComposer($this->container, $composer);

$composerInstaller = $this->createConfiguredInstaller(
$targetPlatform,
$packageToRemove->extensionName(),
$composer,
$requestedPackageAndVersionToRemove->package,
false,
);

$this->executeComposerInstaller($composerInstaller, $pieJsonEditor, $originalPieJsonContent);
}

/**
* Creates and configures a PieComposerInstaller instance with common settings.
*/
private function createConfiguredInstaller(
TargetPlatform $targetPlatform,
ExtensionName $extensionName,
Composer $composer,
string $packageName,
bool $forceInstallPackageVersion,
): PieComposerInstaller {
$pieComposerJson = Platform::getPieJsonFilename($targetPlatform);

$composerInstaller = PieComposerInstaller::createWithPhpBinary(
$targetPlatform->phpBinaryPath,
$packageToRemove->extensionName(),
$extensionName,
$this->arrayCollectionIo,
$composer,
);

$composerInstaller
->setAllowedTypes(['php-ext', 'php-ext-zend'])
->setInstall(true)
->setIgnoredTypes([])
->setDryRun(false)
->setDownloadOnly(false);

if ($forceInstallPackageVersion) {
$composerInstaller->setPlatformRequirementFilter(
PlatformRequirementFilterFactory::fromBoolOrList(true),
);
}

if (file_exists(PieComposerFactory::getLockFile($pieComposerJson))) {
$composerInstaller->setUpdate(true);
$composerInstaller->setUpdateAllowList([$requestedPackageAndVersionToRemove->package]);
$composerInstaller->setUpdateAllowList([$packageName]);
}

return $composerInstaller;
}

/**
* Executes the Composer installer and handles errors with automatic revert.
*
* @throws ComposerRunFailed
*/
private function executeComposerInstaller(
PieComposerInstaller $composerInstaller,
PieJsonEditor $pieJsonEditor,
string $originalPieJsonContent,
): void {
$resultCode = $composerInstaller->run();

if ($resultCode !== Installer::ERROR_NONE) {
Expand Down
Loading