Browse Source

Add installer events

François Pluchino 10 years ago
parent
commit
1067ce4f96

+ 24 - 0
src/Composer/EventDispatcher/EventDispatcher.php

@@ -12,9 +12,14 @@
 
 namespace Composer\EventDispatcher;
 
+use Composer\DependencyResolver\PolicyInterface;
+use Composer\DependencyResolver\Pool;
+use Composer\DependencyResolver\Request;
+use Composer\Installer\InstallerEvent;
 use Composer\IO\IOInterface;
 use Composer\Composer;
 use Composer\DependencyResolver\Operation\OperationInterface;
+use Composer\Repository\CompositeRepository;
 use Composer\Script;
 use Composer\Script\CommandEvent;
 use Composer\Script\PackageEvent;
@@ -113,6 +118,25 @@ class EventDispatcher
         return $this->doDispatch(new CommandEvent($eventName, $this->composer, $this->io, $devMode, $additionalArgs));
     }
 
+
+    /**
+     * Dispatch a installer event.
+     *
+     * @param string              $eventName     The constant in InstallerEvents
+     * @param PolicyInterface     $policy        The policy
+     * @param Pool                $pool          The pool
+     * @param CompositeRepository $installedRepo The installed repository
+     * @param Request             $request       The request
+     * @param array               $operations    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, PolicyInterface $policy, Pool $pool, CompositeRepository $installedRepo, Request $request, array $operations = array())
+    {
+        return $this->doDispatch(new InstallerEvent($eventName, $this->composer, $this->io, $policy, $pool, $installedRepo, $request, $operations));
+    }
+
     /**
      * Triggers the listeners of an event.
      *

+ 5 - 0
src/Composer/Installer.php

@@ -26,6 +26,7 @@ use Composer\DependencyResolver\SolverProblemsException;
 use Composer\Downloader\DownloadManager;
 use Composer\EventDispatcher\EventDispatcher;
 use Composer\Installer\InstallationManager;
+use Composer\Installer\InstallerEvents;
 use Composer\Installer\NoopInstaller;
 use Composer\IO\IOInterface;
 use Composer\Json\JsonFile;
@@ -260,8 +261,10 @@ class Installer
                         $request->install($link->getTarget(), $link->getConstraint());
                     }
 
+                    $this->eventDispatcher->dispatchInstallerEvent(InstallerEvents::PRE_SOLVE_DEPENDENCIES, $policy, $pool, $installedRepo, $request);
                     $solver = new Solver($policy, $pool, $installedRepo);
                     $ops = $solver->solve($request);
+                    $this->eventDispatcher->dispatchInstallerEvent(InstallerEvents::POST_SOLVE_DEPENDENCIES, $policy, $pool, $installedRepo, $request, $ops);
                     foreach ($ops as $op) {
                         if ($op->getJobType() === 'uninstall') {
                             $devPackages[] = $op->getPackage();
@@ -464,9 +467,11 @@ class Installer
         $this->processDevPackages($localRepo, $pool, $policy, $repositories, $lockedRepository, $installFromLock, 'force-links');
 
         // solve dependencies
+        $this->eventDispatcher->dispatchInstallerEvent(InstallerEvents::PRE_SOLVE_DEPENDENCIES, $policy, $pool, $installedRepo, $request);
         $solver = new Solver($policy, $pool, $installedRepo);
         try {
             $operations = $solver->solve($request);
+            $this->eventDispatcher->dispatchInstallerEvent(InstallerEvents::POST_SOLVE_DEPENDENCIES, $policy, $pool, $installedRepo, $request, $operations);
         } catch (SolverProblemsException $e) {
             $this->io->write('<error>Your requirements could not be resolved to an installable set of packages.</error>');
             $this->io->write($e->getMessage());

+ 146 - 0
src/Composer/Installer/InstallerEvent.php

@@ -0,0 +1,146 @@
+<?php
+
+/*
+ * This file is part of Composer.
+ *
+ * (c) Nils Adermann <naderman@naderman.de>
+ *     Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Composer\Installer;
+
+use Composer\Composer;
+use Composer\DependencyResolver\PolicyInterface;
+use Composer\DependencyResolver\Operation\OperationInterface;
+use Composer\DependencyResolver\Pool;
+use Composer\DependencyResolver\Request;
+use Composer\EventDispatcher\Event;
+use Composer\IO\IOInterface;
+use Composer\Repository\CompositeRepository;
+
+/**
+ * An event for all installer.
+ *
+ * @author François Pluchino <francois.pluchino@gmail.com>
+ */
+class InstallerEvent extends Event
+{
+    /**
+     * @var Composer
+     */
+    private $composer;
+
+    /**
+     * @var IOInterface
+     */
+    private $io;
+
+    /**
+     * @var PolicyInterface
+     */
+    private $policy;
+
+    /**
+     * @var Pool
+     */
+    private $pool;
+
+    /**
+     * @var CompositeRepository
+     */
+    private $installedRepo;
+
+    /**
+     * @var Request
+     */
+    private $request;
+
+    /**
+     * @var OperationInterface[]
+     */
+    private $operations;
+
+    /**
+     * Constructor.
+     *
+     * @param string               $eventName
+     * @param Composer             $composer
+     * @param IOInterface          $io
+     * @param PolicyInterface      $policy
+     * @param Pool                 $pool
+     * @param CompositeRepository  $installedRepo
+     * @param Request              $request
+     * @param OperationInterface[] $operations
+     */
+    public function __construct($eventName, Composer $composer, IOInterface $io, PolicyInterface $policy, Pool $pool, CompositeRepository $installedRepo, Request $request, array $operations = array())
+    {
+        parent::__construct($eventName);
+
+        $this->composer = $composer;
+        $this->io = $io;
+        $this->policy = $policy;
+        $this->pool = $pool;
+        $this->installedRepo = $installedRepo;
+        $this->request = $request;
+        $this->operations = $operations;
+    }
+
+    /**
+     * @return Composer
+     */
+    public function getComposer()
+    {
+        return $this->composer;
+    }
+
+    /**
+     * @return IOInterface
+     */
+    public function getIO()
+    {
+        return $this->io;
+    }
+
+    /**
+     * @return PolicyInterface
+     */
+    public function getPolicy()
+    {
+        return $this->policy;
+    }
+
+    /**
+     * @return Pool
+     */
+    public function getPool()
+    {
+        return $this->pool;
+    }
+
+    /**
+     * @return CompositeRepository
+     */
+    public function getInstalledRepo()
+    {
+        return $this->installedRepo;
+    }
+
+    /**
+     * @return Request
+     */
+    public function getRequest()
+    {
+        return $this->request;
+    }
+
+    /**
+     * @return OperationInterface[]
+     */
+    public function getOperations()
+    {
+        return $this->operations;
+    }
+}

+ 43 - 0
src/Composer/Installer/InstallerEvents.php

@@ -0,0 +1,43 @@
+<?php
+
+/*
+ * This file is part of Composer.
+ *
+ * (c) Nils Adermann <naderman@naderman.de>
+ *     Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Composer\Installer;
+
+/**
+ * The Installer Events.
+ *
+ * @author François Pluchino <francois.pluchino@gmail.com>
+ */
+class InstallerEvents
+{
+    /**
+     * The PRE_SOLVE_DEPENDENCIES event occurs as a installer begins
+     * resolve operations.
+     *
+     * The event listener method receives a
+     * Composer\Installer\InstallerEvent instance.
+     *
+     * @var string
+     */
+    const PRE_SOLVE_DEPENDENCIES = 'pre-solve-dependencies';
+
+    /**
+     * The POST_SOLVE_DEPENDENCIES event occurs as a installer after
+     * resolve operations.
+     *
+     * The event listener method receives a
+     * Composer\Installer\InstallerEvent instance.
+     *
+     * @var string
+     */
+    const POST_SOLVE_DEPENDENCIES = 'post-solve-dependencies';
+}

+ 25 - 0
tests/Composer/Test/EventDispatcher/EventDispatcherTest.php

@@ -174,6 +174,31 @@ class EventDispatcherTest extends TestCase
         $dispatcher->dispatchCommandEvent("post-install-cmd", false);
     }
 
+    public function testDispatcherInstallerEvents()
+    {
+        $process = $this->getMock('Composer\Util\ProcessExecutor');
+        $dispatcher = $this->getMockBuilder('Composer\EventDispatcher\EventDispatcher')
+            ->setConstructorArgs(array(
+                    $this->getMock('Composer\Composer'),
+                    $this->getMock('Composer\IO\IOInterface'),
+                    $process,
+                ))
+            ->setMethods(array('getListeners'))
+            ->getMock();
+
+        $dispatcher->expects($this->atLeastOnce())
+            ->method('getListeners')
+            ->will($this->returnValue(array()));
+
+        $policy = $this->getMock('Composer\DependencyResolver\PolicyInterface');
+        $pool = $this->getMockBuilder('Composer\DependencyResolver\Pool')->disableOriginalConstructor()->getMock();
+        $installedRepo = $this->getMockBuilder('Composer\Repository\CompositeRepository')->disableOriginalConstructor()->getMock();
+        $request = $this->getMockBuilder('Composer\DependencyResolver\Request')->disableOriginalConstructor()->getMock();
+
+        $dispatcher->dispatchInstallerEvent("pre-solve-dependencies", $policy, $pool, $installedRepo, $request);
+        $dispatcher->dispatchInstallerEvent("post-solve-dependencies", $policy, $pool, $installedRepo, $request, array());
+    }
+
     public static function call()
     {
         throw new \RuntimeException();

+ 39 - 0
tests/Composer/Test/Installer/InstallerEventTest.php

@@ -0,0 +1,39 @@
+<?php
+
+/*
+ * This file is part of Composer.
+ *
+ * (c) Nils Adermann <naderman@naderman.de>
+ *     Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Composer\Test\Installer;
+
+use Composer\Installer\InstallerEvent;
+
+class InstallerEventTest extends \PHPUnit_Framework_TestCase
+{
+    public function testGetter()
+    {
+        $composer = $this->getMock('Composer\Composer');
+        $io = $this->getMock('Composer\IO\IOInterface');
+        $policy = $this->getMock('Composer\DependencyResolver\PolicyInterface');
+        $pool = $this->getMockBuilder('Composer\DependencyResolver\Pool')->disableOriginalConstructor()->getMock();
+        $installedRepo = $this->getMockBuilder('Composer\Repository\CompositeRepository')->disableOriginalConstructor()->getMock();
+        $request = $this->getMockBuilder('Composer\DependencyResolver\Request')->disableOriginalConstructor()->getMock();
+        $operations = array($this->getMock('Composer\DependencyResolver\Operation\OperationInterface'));
+        $event = new InstallerEvent('EVENT_NAME', $composer, $io, $policy, $pool, $installedRepo, $request, $operations);
+
+        $this->assertSame('EVENT_NAME', $event->getName());
+        $this->assertInstanceOf('Composer\Composer', $event->getComposer());
+        $this->assertInstanceOf('Composer\IO\IOInterface', $event->getIO());
+        $this->assertInstanceOf('Composer\DependencyResolver\PolicyInterface', $event->getPolicy());
+        $this->assertInstanceOf('Composer\DependencyResolver\Pool', $event->getPool());
+        $this->assertInstanceOf('Composer\Repository\CompositeRepository', $event->getInstalledRepo());
+        $this->assertInstanceOf('Composer\DependencyResolver\Request', $event->getRequest());
+        $this->assertCount(1, $event->getOperations());
+    }
+}