From 759a3a9300c02b739d8731aa4564144b2757a5b1 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Thu, 14 Oct 2021 15:41:44 +0200 Subject: [PATCH] Fix require reverting changes even though dependency resolution succeeded if when something fails afterwards, closes #10118 --- src/Composer/Command/RequireCommand.php | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/Composer/Command/RequireCommand.php b/src/Composer/Command/RequireCommand.php index 8f511a015..54a2794e6 100644 --- a/src/Composer/Command/RequireCommand.php +++ b/src/Composer/Command/RequireCommand.php @@ -20,6 +20,7 @@ use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; use Composer\Factory; use Composer\Installer; +use Composer\Installer\InstallerEvents; use Composer\Json\JsonFile; use Composer\Json\JsonManipulator; use Composer\Package\Version\VersionParser; @@ -52,6 +53,8 @@ class RequireCommand extends InitCommand private $lock; /** @var ?string contents before modification if the lock file exists */ private $lockBackup; + /** @var bool */ + private $dependencyResolutionCompleted = false; protected function configure() { @@ -270,7 +273,9 @@ EOT try { return $this->doUpdate($input, $output, $io, $requirements, $requireKey, $removeKey); } catch (\Exception $e) { - $this->revertComposerFile(false); + if (!$this->dependencyResolutionCompleted) { + $this->revertComposerFile(false); + } throw $e; } } @@ -311,6 +316,14 @@ EOT ); } + /** + * @private + */ + public function markSolverComplete() + { + $this->dependencyResolutionCompleted = true; + } + private function doUpdate(InputInterface $input, OutputInterface $output, IOInterface $io, array $requirements, $requireKey, $removeKey) { // Update packages @@ -318,6 +331,9 @@ EOT $composer = $this->getComposer(true, $input->getOption('no-plugins')); $composer->getEventDispatcher()->setRunScripts(!$input->getOption('no-scripts')); + $this->dependencyResolutionCompleted = false; + $composer->getEventDispatcher()->addListener(InstallerEvents::PRE_OPERATIONS_EXEC, [$this, 'markSolverComplete'], 10000); + if ($input->getOption('dry-run')) { $rootPackage = $composer->getPackage(); $links = array(