diff --git a/src/Composer/DependencyResolver/Operation/InstallOperation.php b/src/Composer/DependencyResolver/Operation/InstallOperation.php index 69f042159..89ab5bd85 100644 --- a/src/Composer/DependencyResolver/Operation/InstallOperation.php +++ b/src/Composer/DependencyResolver/Operation/InstallOperation.php @@ -46,16 +46,6 @@ class InstallOperation extends SolverOperation return $this->package; } - /** - * Returns installer type to be used with this operation. - * - * @return string - */ - public function getInstallerType() - { - return $this->package->getType(); - } - /** * Returns job type. * diff --git a/src/Composer/DependencyResolver/Operation/OperationInterface.php b/src/Composer/DependencyResolver/Operation/OperationInterface.php index 7cb943440..704de2d5d 100644 --- a/src/Composer/DependencyResolver/Operation/OperationInterface.php +++ b/src/Composer/DependencyResolver/Operation/OperationInterface.php @@ -28,13 +28,6 @@ interface OperationInterface */ function getJobType(); - /** - * Returns installer type to be used with this operation. - * - * @return string - */ - function getInstallerType(); - /** * Returns operation reason. * diff --git a/src/Composer/DependencyResolver/Operation/UninstallOperation.php b/src/Composer/DependencyResolver/Operation/UninstallOperation.php index 71bfc088f..3731f3181 100644 --- a/src/Composer/DependencyResolver/Operation/UninstallOperation.php +++ b/src/Composer/DependencyResolver/Operation/UninstallOperation.php @@ -46,16 +46,6 @@ class UninstallOperation extends SolverOperation return $this->package; } - /** - * Returns installer type to be used with this operation. - * - * @return string - */ - public function getInstallerType() - { - return $this->package->getType(); - } - /** * Returns job type. * diff --git a/src/Composer/DependencyResolver/Operation/UpdateOperation.php b/src/Composer/DependencyResolver/Operation/UpdateOperation.php index 5caadd881..c9d75c7b4 100644 --- a/src/Composer/DependencyResolver/Operation/UpdateOperation.php +++ b/src/Composer/DependencyResolver/Operation/UpdateOperation.php @@ -59,17 +59,6 @@ class UpdateOperation extends SolverOperation return $this->targetPackage; } - /** - * Returns installer type to be used with this operation. - * - * @return string - */ - public function getInstallerType() - { - return $this->targetPackage->getType(); - } - - /** * Returns job type. * diff --git a/src/Composer/Installer/InstallationManager.php b/src/Composer/Installer/InstallationManager.php new file mode 100644 index 000000000..e27f1c52e --- /dev/null +++ b/src/Composer/Installer/InstallationManager.php @@ -0,0 +1,131 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Installer; + +use Composer\Package\PackageInterface; +use Composer\DependencyResolver\Operation\OperationInterface; +use Composer\DependencyResolver\Operation\InstallOperation; +use Composer\DependencyResolver\Operation\UpdateOperation; +use Composer\DependencyResolver\Operation\UninstallOperation; + +/** + * Package operation manager. + * + * @author Konstantin Kudryashov + */ +class InstallationManager +{ + private $installers = array(); + + /** + * Sets installer for a specific package type. + * + * @param string $type package type (library f.e.) + * @param InstallerInterface $installer installer instance + */ + public function setInstaller($type, InstallerInterface $installer) + { + $this->installers[$type] = $installer; + } + + /** + * Returns installer for a specific package type. + * + * @param string $type package type + * + * @return InstallerInterface + * + * @throws InvalidArgumentException if installer for provided type is not registered + */ + public function getInstaller($type) + { + if (!isset($this->installers[$type])) { + throw new \InvalidArgumentException('Unknown installer type: '.$type); + } + + return $this->installers[$type]; + } + + /** + * Checks whether provided package is installed in one of the registered installers. + * + * @param PackageInterface $package package instance + * + * @return Boolean + */ + public function isPackageInstalled(PackageInterface $package) + { + foreach ($this->installers as $installer) { + if ($installer->isInstalled($package)) { + return true; + } + } + + return false; + } + + /** + * Executes solver operation. + * + * @param OperationInterface $operation operation instance + */ + public function execute(OperationInterface $operation) + { + $method = $operation->getJobType(); + $this->$method($operation); + } + + /** + * Executes install operation. + * + * @param InstallOperation $operation operation instance + */ + public function install(InstallOperation $operation) + { + $installer = $this->getInstaller($operation->getPackage()->getType()); + $installer->install($operation->getPackage()); + } + + /** + * Executes update operation. + * + * @param InstallOperation $operation operation instance + */ + public function update(UpdateOperation $operation) + { + $initial = $operation->getInitialPackage(); + $target = $operation->getTargetPackage(); + + $initialType = $initial->getType(); + $targetType = $target->getType(); + + if ($initialType === $targetType) { + $installer = $this->getInstaller($initialType); + $installer->update($initial, $target); + } else { + $this->getInstaller($initialType)->uninstall($initial); + $this->getInstaller($targetType)->install($target); + } + } + + /** + * Uninstalls package. + * + * @param UninstallOperation $operation operation instance + */ + public function uninstall(UninstallOperation $operation) + { + $installer = $this->getInstaller($operation->getPackage()->getType()); + $installer->uninstall($operation->getPackage()); + } +} diff --git a/src/Composer/Installer/InstallerInterface.php b/src/Composer/Installer/InstallerInterface.php index 96af2bc93..9fbacbc36 100644 --- a/src/Composer/Installer/InstallerInterface.php +++ b/src/Composer/Installer/InstallerInterface.php @@ -22,13 +22,6 @@ use Composer\Package\PackageInterface; */ interface InstallerInterface { - /** - * Executes specific solver operation. - * - * @param OperationInterface $operation solver operation instance - */ - function executeOperation(OperationInterface $operation); - /** * Checks that provided package is installed. * diff --git a/src/Composer/Installer/LibraryInstaller.php b/src/Composer/Installer/LibraryInstaller.php index 75cb4d92a..59d546da2 100644 --- a/src/Composer/Installer/LibraryInstaller.php +++ b/src/Composer/Installer/LibraryInstaller.php @@ -57,22 +57,6 @@ class LibraryInstaller implements InstallerInterface $this->repository = $repository; } - /** - * Executes specific solver operation. - * - * @param OperationInterface $operation solver operation instance - */ - public function executeOperation(OperationInterface $operation) - { - $method = $operation->getJobType(); - - if ('update' === $method) { - $this->$method($operation->getInitialPackage(), $operation->getTargetPackage()); - } else { - $this->$method($operation->getPackage()); - } - } - /** * Checks that specific package is installed. * diff --git a/tests/Composer/Test/Installer/InstallationManagerTest.php b/tests/Composer/Test/Installer/InstallationManagerTest.php new file mode 100644 index 000000000..a8b1a9818 --- /dev/null +++ b/tests/Composer/Test/Installer/InstallationManagerTest.php @@ -0,0 +1,180 @@ + + * Jordi Boggiano + * + * 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\InstallationManager; +use Composer\DependencyResolver\Operation\InstallOperation; +use Composer\DependencyResolver\Operation\UpdateOperation; +use Composer\DependencyResolver\Operation\UninstallOperation; + +class InstallationManagerTest extends \PHPUnit_Framework_TestCase +{ + public function testSetGetInstaller() + { + $installer = $this->createInstallerMock(); + $manager = new InstallationManager(); + + $manager->setInstaller('vendor', $installer); + $this->assertSame($installer, $manager->getInstaller('vendor')); + + $this->setExpectedException('InvalidArgumentException'); + $manager->getInstaller('unregistered'); + } + + public function testExecute() + { + $manager = $this->getMockBuilder('Composer\Installer\InstallationManager') + ->setMethods(array('install', 'update', 'uninstall')) + ->getMock(); + + $installOperation = new InstallOperation($this->createPackageMock()); + $removeOperation = new UninstallOperation($this->createPackageMock()); + $updateOperation = new UpdateOperation( + $this->createPackageMock(), $this->createPackageMock() + ); + + $manager + ->expects($this->once()) + ->method('install') + ->with($installOperation); + $manager + ->expects($this->once()) + ->method('uninstall') + ->with($removeOperation); + $manager + ->expects($this->once()) + ->method('update') + ->with($updateOperation); + + $manager->execute($installOperation); + $manager->execute($removeOperation); + $manager->execute($updateOperation); + } + + public function testInstall() + { + $installer = $this->createInstallerMock(); + $manager = new InstallationManager(); + $manager->setInstaller('library', $installer); + + $package = $this->createPackageMock(); + $operation = new InstallOperation($package, 'test'); + + $package + ->expects($this->once()) + ->method('getType') + ->will($this->returnValue('library')); + + $installer + ->expects($this->once()) + ->method('install') + ->with($package); + + $manager->install($operation); + } + + public function testUpdateWithEqualTypes() + { + $installer = $this->createInstallerMock(); + $manager = new InstallationManager(); + $manager->setInstaller('library', $installer); + + $initial = $this->createPackageMock(); + $target = $this->createPackageMock(); + $operation = new UpdateOperation($initial, $target, 'test'); + + $initial + ->expects($this->once()) + ->method('getType') + ->will($this->returnValue('library')); + $target + ->expects($this->once()) + ->method('getType') + ->will($this->returnValue('library')); + + $installer + ->expects($this->once()) + ->method('update') + ->with($initial, $target); + + $manager->update($operation); + } + + public function testUpdateWithNotEqualTypes() + { + $installer1 = $this->createInstallerMock(); + $installer2 = $this->createInstallerMock(); + $manager = new InstallationManager(); + $manager->setInstaller('library', $installer1); + $manager->setInstaller('bundles', $installer2); + + $initial = $this->createPackageMock(); + $target = $this->createPackageMock(); + $operation = new UpdateOperation($initial, $target, 'test'); + + $initial + ->expects($this->once()) + ->method('getType') + ->will($this->returnValue('library')); + $target + ->expects($this->once()) + ->method('getType') + ->will($this->returnValue('bundles')); + + $installer1 + ->expects($this->once()) + ->method('uninstall') + ->with($initial); + + $installer2 + ->expects($this->once()) + ->method('install') + ->with($target); + + $manager->update($operation); + } + + public function testUninstall() + { + $installer = $this->createInstallerMock(); + $manager = new InstallationManager(); + $manager->setInstaller('library', $installer); + + $package = $this->createPackageMock(); + $operation = new UninstallOperation($package, 'test'); + + $package + ->expects($this->once()) + ->method('getType') + ->will($this->returnValue('library')); + + $installer + ->expects($this->once()) + ->method('uninstall') + ->with($package); + + $manager->uninstall($operation); + } + + private function createInstallerMock() + { + return $this->getMockBuilder('Composer\Installer\InstallerInterface') + ->getMock(); + } + + private function createPackageMock() + { + return $this->getMockBuilder('Composer\Package\PackageInterface') + ->getMock(); + } +} diff --git a/tests/Composer/Test/Installer/LibraryInstallerTest.php b/tests/Composer/Test/Installer/LibraryInstallerTest.php index 6069b2cd8..c5be9cbb6 100644 --- a/tests/Composer/Test/Installer/LibraryInstallerTest.php +++ b/tests/Composer/Test/Installer/LibraryInstallerTest.php @@ -50,38 +50,6 @@ class LibraryInstallerTest extends \PHPUnit_Framework_TestCase $library = new LibraryInstaller($file, $this->dm, $this->repository); } - public function testExecuteOperation() - { - $library = $this->getMockBuilder('Composer\Installer\LibraryInstaller') - ->setConstructorArgs(array($this->dir, $this->dm, $this->repository)) - ->setMethods(array('install', 'update', 'uninstall')) - ->getMock(); - - $packageToInstall = $this->createPackageMock(); - $packageToRemove = $this->createPackageMock(); - $packageToUpdate = $this->createPackageMock(); - $updatedPackage = $this->createPackageMock(); - - $library - ->expects($this->once()) - ->method('install') - ->with($packageToInstall); - - $library - ->expects($this->once()) - ->method('uninstall') - ->with($packageToRemove); - - $library - ->expects($this->once()) - ->method('update') - ->with($packageToUpdate, $updatedPackage); - - $library->executeOperation(new Operation\InstallOperation($packageToInstall)); - $library->executeOperation(new Operation\UninstallOperation($packageToRemove)); - $library->executeOperation(new Operation\UpdateOperation($packageToUpdate, $updatedPackage)); - } - public function testIsInstalled() { $library = new LibraryInstaller($this->dir, $this->dm, $this->repository);