Browse Source

Add supports() to the InstallerInterface

Jordi Boggiano 13 years ago
parent
commit
c33fc80d23

+ 2 - 2
bin/composer

@@ -24,8 +24,8 @@ $dm->setDownloader('zip',  new Downloader\ZipDownloader());
 
 // initialize installation manager
 $im = new Installer\InstallationManager();
-$im->setInstaller('library', new Installer\LibraryInstaller('vendor', $dm, $rm->getLocalRepository()));
-$im->setInstaller('symfony-bundle', new Installer\LibraryInstaller('vendor/bundles', $dm, $rm->getLocalRepository()));
+$im->addInstaller(new Installer\LibraryInstaller('vendor', $dm, $rm->getLocalRepository()));
+$im->addInstaller(new Installer\LibraryInstaller('vendor/bundles', $dm, $rm->getLocalRepository(), 'symfony-bundle'));
 
 // load package
 $loader  = new Package\Loader\JsonLoader();

+ 21 - 7
src/Composer/Installer/InstallationManager.php

@@ -22,20 +22,22 @@ use Composer\DependencyResolver\Operation\UninstallOperation;
  * Package operation manager.
  *
  * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ * @author Jordi Boggiano <j.boggiano@seld.be>
  */
 class InstallationManager
 {
     private $installers = array();
+    private $cache = array();
 
     /**
-     * Sets installer for a specific package type.
+     * Adds installer
      *
-     * @param   string              $type       package type (library f.e.)
      * @param   InstallerInterface  $installer  installer instance
      */
-    public function setInstaller($type, InstallerInterface $installer)
+    public function addInstaller(InstallerInterface $installer)
     {
-        $this->installers[$type] = $installer;
+        array_unshift($this->installers, $installer);
+        $this->cache = array();
     }
 
     /**
@@ -49,11 +51,17 @@ class InstallationManager
      */
     public function getInstaller($type)
     {
-        if (!isset($this->installers[$type])) {
-            throw new \InvalidArgumentException('Unknown installer type: '.$type);
+        if (isset($this->cache[$type])) {
+            return $this->cache[$type];
         }
 
-        return $this->installers[$type];
+        foreach ($this->installers as $installer) {
+            if ($installer->supports($type)) {
+                return $this->cache[$type] = $installer;
+            }
+        }
+
+        throw new \InvalidArgumentException('Unknown installer type: '.$type);
     }
 
     /**
@@ -129,6 +137,12 @@ class InstallationManager
         $installer->uninstall($operation->getPackage());
     }
 
+    /**
+     * Returns the installation path of a package
+     *
+     * @param   PackageInterface    $package
+     * @return  string path
+     */
     public function getInstallPath(PackageInterface $package)
     {
         $installer = $this->getInstaller($package->getType());

+ 8 - 0
src/Composer/Installer/InstallerInterface.php

@@ -22,6 +22,14 @@ use Composer\Package\PackageInterface;
  */
 interface InstallerInterface
 {
+    /**
+     * Decides if the installer supports the given type
+     *
+     * @param   string  $packageType
+     * @return  Boolean
+     */
+    function supports($packageType);
+
     /**
      * Checks that provided package is installed.
      *

+ 10 - 1
src/Composer/Installer/LibraryInstaller.php

@@ -35,8 +35,9 @@ class LibraryInstaller implements InstallerInterface
      * @param   string                      $dir        relative path for packages home
      * @param   DownloadManager             $dm         download manager
      * @param   WritableRepositoryInterface $repository repository controller
+     * @param   string                      $type       package type that this installer handles
      */
-    public function __construct($directory, DownloadManager $dm, WritableRepositoryInterface $repository)
+    public function __construct($directory, DownloadManager $dm, WritableRepositoryInterface $repository, $type = 'library')
     {
         $this->directory = $directory;
         $this->downloadManager = $dm;
@@ -57,6 +58,14 @@ class LibraryInstaller implements InstallerInterface
         $this->repository = $repository;
     }
 
+    /**
+     * {@inheritDoc}
+     */
+    public function supports($packageType)
+    {
+        return $packageType === $this->type;
+    }
+
     /**
      * {@inheritDoc}
      */

+ 50 - 11
tests/Composer/Test/Installer/InstallationManagerTest.php

@@ -19,12 +19,20 @@ use Composer\DependencyResolver\Operation\UninstallOperation;
 
 class InstallationManagerTest extends \PHPUnit_Framework_TestCase
 {
-    public function testSetGetInstaller()
+    public function testAddGetInstaller()
     {
         $installer = $this->createInstallerMock();
+
+        $installer
+            ->expects($this->exactly(2))
+            ->method('supports')
+            ->will($this->returnCallback(function ($arg) {
+                return $arg === 'vendor';
+            }));
+
         $manager   = new InstallationManager();
 
-        $manager->setInstaller('vendor', $installer);
+        $manager->addInstaller($installer);
         $this->assertSame($installer, $manager->getInstaller('vendor'));
 
         $this->setExpectedException('InvalidArgumentException');
@@ -65,7 +73,7 @@ class InstallationManagerTest extends \PHPUnit_Framework_TestCase
     {
         $installer = $this->createInstallerMock();
         $manager   = new InstallationManager();
-        $manager->setInstaller('library', $installer);
+        $manager->addInstaller($installer);
 
         $package   = $this->createPackageMock();
         $operation = new InstallOperation($package, 'test');
@@ -75,6 +83,12 @@ class InstallationManagerTest extends \PHPUnit_Framework_TestCase
             ->method('getType')
             ->will($this->returnValue('library'));
 
+        $installer
+            ->expects($this->once())
+            ->method('supports')
+            ->with('library')
+            ->will($this->returnValue(true));
+
         $installer
             ->expects($this->once())
             ->method('install')
@@ -87,7 +101,7 @@ class InstallationManagerTest extends \PHPUnit_Framework_TestCase
     {
         $installer = $this->createInstallerMock();
         $manager   = new InstallationManager();
-        $manager->setInstaller('library', $installer);
+        $manager->addInstaller($installer);
 
         $initial   = $this->createPackageMock();
         $target    = $this->createPackageMock();
@@ -102,6 +116,12 @@ class InstallationManagerTest extends \PHPUnit_Framework_TestCase
             ->method('getType')
             ->will($this->returnValue('library'));
 
+        $installer
+            ->expects($this->once())
+            ->method('supports')
+            ->with('library')
+            ->will($this->returnValue(true));
+
         $installer
             ->expects($this->once())
             ->method('update')
@@ -112,11 +132,11 @@ class InstallationManagerTest extends \PHPUnit_Framework_TestCase
 
     public function testUpdateWithNotEqualTypes()
     {
-        $installer1 = $this->createInstallerMock();
-        $installer2 = $this->createInstallerMock();
+        $libInstaller = $this->createInstallerMock();
+        $bundleInstaller = $this->createInstallerMock();
         $manager    = new InstallationManager();
-        $manager->setInstaller('library', $installer1);
-        $manager->setInstaller('bundles', $installer2);
+        $manager->addInstaller($libInstaller);
+        $manager->addInstaller($bundleInstaller);
 
         $initial   = $this->createPackageMock();
         $target    = $this->createPackageMock();
@@ -131,12 +151,25 @@ class InstallationManagerTest extends \PHPUnit_Framework_TestCase
             ->method('getType')
             ->will($this->returnValue('bundles'));
 
-        $installer1
+        $bundleInstaller
+            ->expects($this->exactly(2))
+            ->method('supports')
+            ->will($this->returnCallback(function ($arg) {
+                return $arg === 'bundles';
+            }));
+
+        $libInstaller
+            ->expects($this->once())
+            ->method('supports')
+            ->with('library')
+            ->will($this->returnValue(true));
+
+        $libInstaller
             ->expects($this->once())
             ->method('uninstall')
             ->with($initial);
 
-        $installer2
+        $bundleInstaller
             ->expects($this->once())
             ->method('install')
             ->with($target);
@@ -148,7 +181,7 @@ class InstallationManagerTest extends \PHPUnit_Framework_TestCase
     {
         $installer = $this->createInstallerMock();
         $manager   = new InstallationManager();
-        $manager->setInstaller('library', $installer);
+        $manager->addInstaller($installer);
 
         $package   = $this->createPackageMock();
         $operation = new UninstallOperation($package, 'test');
@@ -163,6 +196,12 @@ class InstallationManagerTest extends \PHPUnit_Framework_TestCase
             ->method('uninstall')
             ->with($package);
 
+        $installer
+            ->expects($this->once())
+            ->method('supports')
+            ->with('library')
+            ->will($this->returnValue(true));
+
         $manager->uninstall($operation);
     }