From d52ce3c37fdfd78baa86fc20019f0b47f6d5eb92 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Wed, 12 Feb 2020 14:35:31 +0100 Subject: [PATCH] Replace pre/post-dependencies-solving by a pre-operations-exec event happening only on install from lock --- doc/articles/scripts.md | 4 +- .../EventDispatcher/EventDispatcher.php | 15 ++-- src/Composer/Installer.php | 29 +++----- src/Composer/Installer/InstallerEvent.php | 68 +++---------------- src/Composer/Installer/InstallerEvents.php | 25 ++----- .../EventDispatcher/EventDispatcherTest.php | 7 +- .../Test/Installer/InstallerEventTest.php | 11 +-- 7 files changed, 34 insertions(+), 125 deletions(-) diff --git a/doc/articles/scripts.md b/doc/articles/scripts.md index c16977003..8977aa32d 100644 --- a/doc/articles/scripts.md +++ b/doc/articles/scripts.md @@ -43,8 +43,8 @@ Composer fires the following named events during its execution process: ### Installer Events -- **pre-dependencies-solving**: occurs before the dependencies are resolved. -- **post-dependencies-solving**: occurs after the dependencies have been resolved. +- **pre-operations-exec**: occurs before the install/upgrade/.. operations + are executed when installing a lock file. ### Package Events diff --git a/src/Composer/EventDispatcher/EventDispatcher.php b/src/Composer/EventDispatcher/EventDispatcher.php index 34a1981a9..fda5c29fd 100644 --- a/src/Composer/EventDispatcher/EventDispatcher.php +++ b/src/Composer/EventDispatcher/EventDispatcher.php @@ -119,20 +119,17 @@ class EventDispatcher /** * Dispatch a installer event. * - * @param string $eventName The constant in InstallerEvents - * @param bool $devMode Whether or not we are in dev mode - * @param PolicyInterface $policy The policy - * @param RepositorySet $repositorySet The repository set - * @param RepositoryInterface $localRepo The installed repository - * @param Request $request The request - * @param array $operations The list of operations + * @param string $eventName The constant in InstallerEvents + * @param bool $devMode Whether or not we are in dev mode + * @param bool $executeOperations True if operations will be executed, false in --dry-run + * @param Transaction $transaction The transaction contains the list of operations * * @return int return code of the executed script if any, for php scripts a false return * value is changed to 1, anything else to 0 */ - public function dispatchInstallerEvent($eventName, $devMode, RepositorySet $repositorySet, Pool $pool, Request $request, PolicyInterface $policy, Transaction $transaction = null) + public function dispatchInstallerEvent($eventName, $devMode, $executeOperations, Transaction $transaction) { - return $this->doDispatch(new InstallerEvent($eventName, $this->composer, $this->io, $devMode, $repositorySet, $pool, $request, $policy, $transaction)); + return $this->doDispatch(new InstallerEvent($eventName, $this->composer, $this->io, $devMode, $executeOperations, $transaction)); } /** diff --git a/src/Composer/Installer.php b/src/Composer/Installer.php index b7ee247db..a1f93695d 100644 --- a/src/Composer/Installer.php +++ b/src/Composer/Installer.php @@ -382,7 +382,6 @@ class Installer } $pool = $repositorySet->createPool($request, $this->eventDispatcher); - $this->eventDispatcher->dispatchInstallerEvent(InstallerEvents::PRE_DEPENDENCIES_SOLVING, $this->devMode, $repositorySet, $pool, $request, $policy); // solve dependencies $solver = new Solver($policy, $pool, $this->io, $repositorySet); @@ -400,9 +399,6 @@ class Installer return max(1, $e->getCode()); } - // TODO should we warn people / error if plugins in vendor folder do not match contents of lock file before update? - $this->eventDispatcher->dispatchInstallerEvent(InstallerEvents::POST_DEPENDENCIES_SOLVING, $this->devMode, $repositorySet, $pool, $request, $policy, $lockTransaction); - $this->io->writeError("Analyzed ".count($pool)." packages to resolve dependencies", true, IOInterface::VERBOSE); $this->io->writeError("Analyzed ".$ruleSetSize." rules to resolve dependencies", true, IOInterface::VERBOSE); @@ -524,11 +520,9 @@ class Installer $pool = $repositorySet->createPool($request, $this->eventDispatcher); - $this->eventDispatcher->dispatchInstallerEvent(InstallerEvents::PRE_DEPENDENCIES_SOLVING, false, $repositorySet, $pool, $request, $policy); $solver = new Solver($policy, $pool, $this->io, $repositorySet); try { $nonDevLockTransaction = $solver->solve($request, $this->ignorePlatformReqs); - $this->eventDispatcher->dispatchInstallerEvent(InstallerEvents::POST_DEPENDENCIES_SOLVING, false, $repositorySet, $pool, $request, $policy, $nonDevLockTransaction); $solver = null; } catch (SolverProblemsException $e) { $this->io->writeError('Unable to find a compatible set of packages based on your non-dev requirements alone.', true, IOInterface::QUIET); @@ -547,22 +541,22 @@ class Installer */ protected function doInstall(RepositoryInterface $localRepo, $alreadySolved = false) { - $platformRepo = $this->createPlatformRepo(false); - $lockedRepository = $this->locker->getLockedRepository($this->devMode); - - // creating repository set - $policy = $this->createPolicy(false); - // use aliases from lock file only, so empty root aliases here - $repositorySet = $this->createRepositorySet(false, $platformRepo, array(), $lockedRepository); - $repositorySet->addRepository($lockedRepository); - $this->io->writeError('Installing dependencies from lock file'.($this->devMode ? ' (including require-dev)' : '').''); + $lockedRepository = $this->locker->getLockedRepository($this->devMode); + // verify that the lock file works with the current platform repository // we can skip this part if we're doing this as the second step after an update if (!$alreadySolved) { $this->io->writeError('Verifying lock file contents can be installed on current platform.'); + $platformRepo = $this->createPlatformRepo(false); + // creating repository set + $policy = $this->createPolicy(false); + // use aliases from lock file only, so empty root aliases here + $repositorySet = $this->createRepositorySet(false, $platformRepo, array(), $lockedRepository); + $repositorySet->addRepository($lockedRepository); + // creating requirements request $request = $this->createRequest($this->fixedRootPackage, $platformRepo, $lockedRepository); @@ -579,7 +573,6 @@ class Installer } $pool = $repositorySet->createPool($request, $this->eventDispatcher); - $this->eventDispatcher->dispatchInstallerEvent(InstallerEvents::PRE_DEPENDENCIES_SOLVING, $this->devMode, $repositorySet, $pool, $request, $policy); // solve dependencies $solver = new Solver($policy, $pool, $this->io, $repositorySet); @@ -599,13 +592,11 @@ class Installer return max(1, $e->getCode()); } - - // TODO should we warn people / error if plugins in vendor folder do not match contents of lock file before update? - $this->eventDispatcher->dispatchInstallerEvent(InstallerEvents::POST_DEPENDENCIES_SOLVING, $this->devMode, $repositorySet, $pool, $request, $policy, $lockTransaction); } // TODO in how far do we need to do anything here to ensure dev packages being updated to latest in lock without version change are treated correctly? $localRepoTransaction = new LocalRepoTransaction($lockedRepository, $localRepo); + $this->eventDispatcher->dispatchInstallerEvent(InstallerEvents::PRE_OPERATIONS_EXEC, $this->devMode, $this->executeOperations, $localRepoTransaction); if (!$localRepoTransaction->getOperations()) { $this->io->writeError('Nothing to install, update or remove'); diff --git a/src/Composer/Installer/InstallerEvent.php b/src/Composer/Installer/InstallerEvent.php index 7fc5fe746..1b8f03de4 100644 --- a/src/Composer/Installer/InstallerEvent.php +++ b/src/Composer/Installer/InstallerEvent.php @@ -21,11 +21,6 @@ use Composer\EventDispatcher\Event; use Composer\IO\IOInterface; use Composer\Repository\RepositorySet; -/** - * An event for all installer. - * - * @author François Pluchino - */ class InstallerEvent extends Event { /** @@ -44,27 +39,12 @@ class InstallerEvent extends Event private $devMode; /** - * @var RepositorySet - */ - private $repositorySet; - - /** - * @var Pool - */ - private $pool; - - /** - * @var Request - */ - private $request; - - /** - * @var PolicyInterface + * @var bool */ - private $policy; + private $executeOperations; /** - * @var Transaction|null + * @var Transaction */ private $transaction; @@ -75,23 +55,17 @@ class InstallerEvent extends Event * @param Composer $composer * @param IOInterface $io * @param bool $devMode - * @param RepositorySet $repositorySet - * @param Pool $pool - * @param Request $request - * @param PolicyInterface $policy + * @param bool $executeOperations * @param Transaction $transaction */ - public function __construct($eventName, Composer $composer, IOInterface $io, $devMode, RepositorySet $repositorySet, Pool $pool, Request $request, PolicyInterface $policy, Transaction $transaction = null) + public function __construct($eventName, Composer $composer, IOInterface $io, $devMode, $executeOperations, Transaction $transaction) { parent::__construct($eventName); $this->composer = $composer; $this->io = $io; $this->devMode = $devMode; - $this->repositorySet = $repositorySet; - $this->pool = $pool; - $this->request = $request; - $this->policy = $policy; + $this->executeOperations = $executeOperations; $this->transaction = $transaction; } @@ -120,35 +94,11 @@ class InstallerEvent extends Event } /** - * @return PolicyInterface - */ - public function getPolicy() - { - return $this->policy; - } - - /** - * @return RepositorySet - */ - public function getRepositorySet() - { - return $this->repositorySet; - } - - /** - * @return Pool - */ - public function getPool() - { - return $this->pool; - } - - /** - * @return Request + * @return bool */ - public function getRequest() + public function isExecutingOperations() { - return $this->request; + return $this->executeOperations; } /** diff --git a/src/Composer/Installer/InstallerEvents.php b/src/Composer/Installer/InstallerEvents.php index e05c92587..f75b8bdd4 100644 --- a/src/Composer/Installer/InstallerEvents.php +++ b/src/Composer/Installer/InstallerEvents.php @@ -12,32 +12,15 @@ namespace Composer\Installer; -/** - * The Installer Events. - * - * @author François Pluchino - */ class InstallerEvents { /** - * The PRE_DEPENDENCIES_SOLVING event occurs as a installer begins - * resolve operations. - * - * The event listener method receives a - * Composer\Installer\InstallerEvent instance. - * - * @var string - */ - const PRE_DEPENDENCIES_SOLVING = 'pre-dependencies-solving'; - - /** - * The POST_DEPENDENCIES_SOLVING event occurs as a installer after - * resolve operations. + * The PRE_OPERATIONS_EXEC event occurs before the lock file gets + * installed and operations are executed. * - * The event listener method receives a - * Composer\Installer\InstallerEvent instance. + * The event listener method receives an Composer\Installer\InstallerEvent instance. * * @var string */ - const POST_DEPENDENCIES_SOLVING = 'post-dependencies-solving'; + const PRE_OPERATIONS_EXEC = 'pre-operations-exec'; } diff --git a/tests/Composer/Test/EventDispatcher/EventDispatcherTest.php b/tests/Composer/Test/EventDispatcher/EventDispatcherTest.php index 65a5ae62f..c038681da 100644 --- a/tests/Composer/Test/EventDispatcher/EventDispatcherTest.php +++ b/tests/Composer/Test/EventDispatcher/EventDispatcherTest.php @@ -565,14 +565,9 @@ class EventDispatcherTest extends TestCase ->method('getListeners') ->will($this->returnValue(array())); - $policy = $this->getMockBuilder('Composer\DependencyResolver\PolicyInterface')->getMock(); - $repositorySet = $this->getMockBuilder('Composer\Repository\RepositorySet')->disableOriginalConstructor()->getMock(); - $pool = $this->getMockBuilder('Composer\DependencyResolver\Pool')->disableOriginalConstructor()->getMock(); $transaction = $this->getMockBuilder('Composer\DependencyResolver\LockTransaction')->disableOriginalConstructor()->getMock(); - $request = $this->getMockBuilder('Composer\DependencyResolver\Request')->disableOriginalConstructor()->getMock(); - $dispatcher->dispatchInstallerEvent(InstallerEvents::PRE_DEPENDENCIES_SOLVING, true, $repositorySet, $pool, $request, $policy); - $dispatcher->dispatchInstallerEvent(InstallerEvents::POST_DEPENDENCIES_SOLVING, true, $repositorySet, $pool, $request, $policy, $transaction); + $dispatcher->dispatchInstallerEvent(InstallerEvents::PRE_OPERATIONS_EXEC, true, true, $transaction); } public static function call() diff --git a/tests/Composer/Test/Installer/InstallerEventTest.php b/tests/Composer/Test/Installer/InstallerEventTest.php index 52c7baa96..6c0689844 100644 --- a/tests/Composer/Test/Installer/InstallerEventTest.php +++ b/tests/Composer/Test/Installer/InstallerEventTest.php @@ -21,21 +21,14 @@ class InstallerEventTest extends TestCase { $composer = $this->getMockBuilder('Composer\Composer')->getMock(); $io = $this->getMockBuilder('Composer\IO\IOInterface')->getMock(); - $policy = $this->getMockBuilder('Composer\DependencyResolver\PolicyInterface')->getMock(); - $repositorySet = $this->getMockBuilder('Composer\Repository\RepositorySet')->disableOriginalConstructor()->getMock(); - $pool = $this->getMockBuilder('Composer\DependencyResolver\Pool')->disableOriginalConstructor()->getMock(); $transaction = $this->getMockBuilder('Composer\DependencyResolver\LockTransaction')->disableOriginalConstructor()->getMock(); - $request = $this->getMockBuilder('Composer\DependencyResolver\Request')->disableOriginalConstructor()->getMock(); - $event = new InstallerEvent('EVENT_NAME', $composer, $io, true, $repositorySet, $pool, $request, $policy, $transaction); + $event = new InstallerEvent('EVENT_NAME', $composer, $io, true, true, $transaction); $this->assertSame('EVENT_NAME', $event->getName()); $this->assertInstanceOf('Composer\Composer', $event->getComposer()); $this->assertInstanceOf('Composer\IO\IOInterface', $event->getIO()); $this->assertTrue($event->isDevMode()); - $this->assertInstanceOf('Composer\DependencyResolver\PolicyInterface', $event->getPolicy()); - $this->assertInstanceOf('Composer\Repository\RepositorySet', $event->getRepositorySet()); - $this->assertInstanceOf('Composer\DependencyResolver\Pool', $event->getPool()); - $this->assertInstanceOf('Composer\DependencyResolver\Request', $event->getRequest()); + $this->assertTrue($event->isExecutingOperations()); $this->assertInstanceOf('Composer\DependencyResolver\Transaction', $event->getTransaction()); } }