From e1370be7a0a86dd52241c2bf37105654d7e4a61e Mon Sep 17 00:00:00 2001 From: Beau Simensen Date: Thu, 26 Jan 2012 19:53:32 -0800 Subject: [PATCH] Continued refactoring of install() method, mainly by way of adding Composite Repository * Rewritten `install()` method now takes a repository instead of a list of packages (per @nadermen) * Added Composite Repository * Added tests for Composite Repository * Removed "local repository" concept from Platform Repository * Removed some `use` statements for Platform Repository where it was not actually being used --- src/Composer/Command/DebugPackagesCommand.php | 3 +- src/Composer/Command/InstallCommand.php | 15 +- src/Composer/Command/SearchCommand.php | 1 - src/Composer/Command/ValidateCommand.php | 1 - .../Repository/CompositeRepository.php | 120 ++++++++++++++++ .../Repository/PlatformRepository.php | 11 -- .../Repository/CompositeRepositoryTest.php | 128 ++++++++++++++++++ 7 files changed, 257 insertions(+), 22 deletions(-) create mode 100644 src/Composer/Repository/CompositeRepository.php create mode 100644 tests/Composer/Test/Repository/CompositeRepositoryTest.php diff --git a/src/Composer/Command/DebugPackagesCommand.php b/src/Composer/Command/DebugPackagesCommand.php index d7c2acdfa..e3d196466 100644 --- a/src/Composer/Command/DebugPackagesCommand.php +++ b/src/Composer/Command/DebugPackagesCommand.php @@ -18,6 +18,7 @@ use Composer\DependencyResolver\Pool; use Composer\DependencyResolver\Request; use Composer\DependencyResolver\Operation; use Composer\Package\LinkConstraint\VersionConstraint; +use Composer\Repository\CompositeRepository; use Composer\Repository\PlatformRepository; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; @@ -52,7 +53,7 @@ EOT // create local repo, this contains all packages that are installed in the local project $localRepo = $composer->getRepositoryManager()->getLocalRepository(); // create installed repo, this contains all local packages + platform packages (php & extensions) - $installedRepo = new PlatformRepository($localRepo); + $installedRepo = new CompositeRepository(array($localRepo, new PlatformRepository())); if ($input->getOption('local')) { foreach ($localRepo->getPackages() as $package) { diff --git a/src/Composer/Command/InstallCommand.php b/src/Composer/Command/InstallCommand.php index 97f7b4b89..0bc45a0a9 100644 --- a/src/Composer/Command/InstallCommand.php +++ b/src/Composer/Command/InstallCommand.php @@ -23,7 +23,9 @@ use Composer\DependencyResolver\Operation; use Composer\Package\MemoryPackage; use Composer\Package\LinkConstraint\VersionConstraint; use Composer\Package\PackageInterface; +use Composer\Repository\CompositeRepository; use Composer\Repository\PlatformRepository; +use Composer\Repository\RepositoryInterface; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; @@ -79,7 +81,7 @@ EOT ); } - public function install(Composer $composer, EventDispatcher $eventDispatcher, InputInterface $input, OutputInterface $output, $update, $preferSource, $dryRun, $verbose, $noInstallRecommends, $installSuggests, $internallyInstalledPackages = null) + public function install(Composer $composer, EventDispatcher $eventDispatcher, InputInterface $input, OutputInterface $output, $update, $preferSource, $dryRun, $verbose, $noInstallRecommends, $installSuggests, RepositoryInterface $additionalInstalledRepository = null) { if ($dryRun) { $verbose = true; @@ -90,14 +92,11 @@ EOT } // create local repo, this contains all packages that are installed in the local project - $localRepo = $composer->getRepositoryManager()->getLocalRepository(); + $localRepo = $composer->getRepositoryManager()->getLocalRepository(); // create installed repo, this contains all local packages + platform packages (php & extensions) - $installedRepo = new PlatformRepository($localRepo); - - if ($internallyInstalledPackages) { - foreach ($internallyInstalledPackages as $package) { - $installedRepo->addPackage(new MemoryPackage($package->getName(), $package->getVersion(), $package->getPrettyVersion())); - } + $installedRepo = new CompositeRepository(array($localRepo, new PlatformRepository())); + if ($additionalInstalledRepository) { + $installedRepo->addRepository($additionalInstalledRepository); } // creating repository pool diff --git a/src/Composer/Command/SearchCommand.php b/src/Composer/Command/SearchCommand.php index c7c6ebd3d..4a937539d 100644 --- a/src/Composer/Command/SearchCommand.php +++ b/src/Composer/Command/SearchCommand.php @@ -12,7 +12,6 @@ namespace Composer\Command; -use Composer\Repository\PlatformRepository; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Output\OutputInterface; diff --git a/src/Composer/Command/ValidateCommand.php b/src/Composer/Command/ValidateCommand.php index 692b6a323..d862a2b61 100644 --- a/src/Composer/Command/ValidateCommand.php +++ b/src/Composer/Command/ValidateCommand.php @@ -12,7 +12,6 @@ namespace Composer\Command; -use Composer\Repository\PlatformRepository; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Output\OutputInterface; diff --git a/src/Composer/Repository/CompositeRepository.php b/src/Composer/Repository/CompositeRepository.php new file mode 100644 index 000000000..7af8cffad --- /dev/null +++ b/src/Composer/Repository/CompositeRepository.php @@ -0,0 +1,120 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Repository; + +use Composer\Package\PackageInterface; + +/** + * Composite repository. + * + * @author Beau Simensen + */ +class CompositeRepository implements RepositoryInterface +{ + + /** + * List of repositories + * @var array + */ + private $repositories; + + /** + * Constructor + * @param array $repositories + */ + public function __construct(array $repositories) + { + $this->repositories = $repositories; + } + + /** + * (non-PHPdoc) + * @see Composer\Repository.RepositoryInterface::hasPackage() + */ + public function hasPackage(PackageInterface $package) + { + foreach ($this->repositories as $repository) { + /* @var $repository RepositoryInterface */ + if ($repository->hasPackage($package)) { + return true; + } + } + return false; + } + + /** + * (non-PHPdoc) + * @see Composer\Repository.RepositoryInterface::findPackage() + */ + public function findPackage($name, $version) { + foreach ($this->repositories as $repository) { + /* @var $repository RepositoryInterface */ + $package = $repository->findPackage($name, $version); + if (null !== $package) { + return $package; + } + } + return null; + } + + /** + * (non-PHPdoc) + * @see Composer\Repository.RepositoryInterface::findPackagesByName() + */ + public function findPackagesByName($name) + { + $packages = array(); + foreach ($this->repositories as $repository) { + /* @var $repository RepositoryInterface */ + $packages[] = $repository->findPackagesByName($name); + } + return call_user_func_array('array_merge', $packages); + } + + /** + * (non-PHPdoc) + * @see Composer\Repository.RepositoryInterface::getPackages() + */ + public function getPackages() + { + $packages = array(); + foreach ($this->repositories as $repository) { + /* @var $repository RepositoryInterface */ + $packages[] = $repository->getPackages(); + } + return call_user_func_array('array_merge', $packages); + } + + /** + * Add a repository. + * @param RepositoryInterface $repository + */ + public function addRepository(RepositoryInterface $repository) + { + $this->repositories[] = $repository; + } + + /** + * (non-PHPdoc) + * @see Countable::count() + */ + public function count() + { + $total = 0; + foreach ($this->repositories as $repository) { + /* @var $repository RepositoryInterface */ + $total += $repository->count(); + } + return $total; + } +} diff --git a/src/Composer/Repository/PlatformRepository.php b/src/Composer/Repository/PlatformRepository.php index b9747fb37..12d5a6aa8 100644 --- a/src/Composer/Repository/PlatformRepository.php +++ b/src/Composer/Repository/PlatformRepository.php @@ -20,12 +20,6 @@ use Composer\Package\Version\VersionParser; */ class PlatformRepository extends ArrayRepository { - private $localRepository; - - public function __construct(RepositoryInterface $localRepository) - { - $this->localRepository = $localRepository; - } protected function initialize() { @@ -62,9 +56,4 @@ class PlatformRepository extends ArrayRepository parent::addPackage($ext); } } - - public function getPackages() - { - return array_merge(parent::getPackages(), $this->localRepository->getPackages()); - } } diff --git a/tests/Composer/Test/Repository/CompositeRepositoryTest.php b/tests/Composer/Test/Repository/CompositeRepositoryTest.php new file mode 100644 index 000000000..49e017d18 --- /dev/null +++ b/tests/Composer/Test/Repository/CompositeRepositoryTest.php @@ -0,0 +1,128 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Test\Repository; + +use Composer\Repository\CompositeRepository; +use Composer\Repository\ArrayRepository; +use Composer\Test\TestCase; + +class CompositeRepositoryTest extends TestCase +{ + public function testHasPackage() + { + $arrayRepoOne = new ArrayRepository; + $arrayRepoOne->addPackage($this->getPackage('foo', '1')); + + $arrayRepoTwo = new ArrayRepository; + $arrayRepoTwo->addPackage($this->getPackage('bar', '1')); + + $repo = new CompositeRepository(array($arrayRepoOne, $arrayRepoTwo)); + + $this->assertTrue($repo->hasPackage($this->getPackage('foo', '1')), "Should have package 'foo/1'"); + $this->assertTrue($repo->hasPackage($this->getPackage('bar', '1')), "Should have package 'bar/1'"); + + $this->assertFalse($repo->hasPackage($this->getPackage('foo', '2')), "Should not have package 'foo/2'"); + $this->assertFalse($repo->hasPackage($this->getPackage('bar', '2')), "Should not have package 'bar/2'"); + } + + public function testFindPackage() + { + $arrayRepoOne = new ArrayRepository; + $arrayRepoOne->addPackage($this->getPackage('foo', '1')); + + $arrayRepoTwo = new ArrayRepository; + $arrayRepoTwo->addPackage($this->getPackage('bar', '1')); + + $repo = new CompositeRepository(array($arrayRepoOne, $arrayRepoTwo)); + + $this->assertEquals('foo', $repo->findPackage('foo', '1')->getName(), "Should find package 'foo/1' and get name of 'foo'"); + $this->assertEquals('1', $repo->findPackage('foo', '1')->getPrettyVersion(), "Should find package 'foo/1' and get pretty version of '1'"); + $this->assertEquals('bar', $repo->findPackage('bar', '1')->getName(), "Should find package 'bar/1' and get name of 'bar'"); + $this->assertEquals('1', $repo->findPackage('bar', '1')->getPrettyVersion(), "Should find package 'bar/1' and get pretty version of '1'"); + $this->assertNull($repo->findPackage('foo', '2'), "Should not find package 'foo/2'"); + } + + public function testFindPackagesByName() + { + $arrayRepoOne = new ArrayRepository; + $arrayRepoOne->addPackage($this->getPackage('foo', '1')); + $arrayRepoOne->addPackage($this->getPackage('foo', '2')); + $arrayRepoOne->addPackage($this->getPackage('bat', '1')); + + $arrayRepoTwo = new ArrayRepository; + $arrayRepoTwo->addPackage($this->getPackage('bar', '1')); + $arrayRepoTwo->addPackage($this->getPackage('bar', '2')); + $arrayRepoTwo->addPackage($this->getPackage('foo', '3')); + + $repo = new CompositeRepository(array($arrayRepoOne, $arrayRepoTwo)); + + $bats = $repo->findPackagesByName('bat'); + $this->assertCount(1, $bats, "Should find one instance of 'bats' (defined in just one repository)"); + $this->assertEquals('bat', $bats[0]->getName(), "Should find packages named 'bat'"); + + $bars = $repo->findPackagesByName('bar'); + $this->assertCount(2, $bars, "Should find two instances of 'bar' (both defined in the same repository)"); + $this->assertEquals('bar', $bars[0]->getName(), "Should find packages named 'bar'"); + + $foos = $repo->findPackagesByName('foo'); + $this->assertCount(3, $foos, "Should find three instances of 'foo' (two defined in one repository, the third in the other)"); + $this->assertEquals('foo', $foos[0]->getName(), "Should find packages named 'foo'"); + } + + public function testGetPackages() + { + $arrayRepoOne = new ArrayRepository; + $arrayRepoOne->addPackage($this->getPackage('foo', '1')); + + $arrayRepoTwo = new ArrayRepository; + $arrayRepoTwo->addPackage($this->getPackage('bar', '1')); + + $repo = new CompositeRepository(array($arrayRepoOne, $arrayRepoTwo)); + + $packages = $repo->getPackages(); + $this->assertCount(2, $packages, "Should get two packages"); + $this->assertEquals("foo", $packages[0]->getName(), "First package should have name of 'foo'"); + $this->assertEquals("1", $packages[0]->getPrettyVersion(), "First package should have pretty version of '1'"); + $this->assertEquals("bar", $packages[1]->getName(), "Second package should have name of 'bar'"); + $this->assertEquals("1", $packages[1]->getPrettyVersion(), "Second package should have pretty version of '1'"); + } + + public function testAddRepository() + { + $arrayRepoOne = new ArrayRepository; + $arrayRepoOne->addPackage($this->getPackage('foo', '1')); + + $arrayRepoTwo = new ArrayRepository; + $arrayRepoTwo->addPackage($this->getPackage('bar', '1')); + $arrayRepoTwo->addPackage($this->getPackage('bar', '2')); + $arrayRepoTwo->addPackage($this->getPackage('bar', '3')); + + $repo = new CompositeRepository(array($arrayRepoOne)); + $this->assertCount(1, $repo, "Composite repository should have just one package before addRepository() is called"); + $repo->addRepository($arrayRepoTwo); + $this->assertCount(4, $repo, "Composite repository should have four packages after addRepository() is called"); + } + + public function testCount() + { + $arrayRepoOne = new ArrayRepository; + $arrayRepoOne->addPackage($this->getPackage('foo', '1')); + + $arrayRepoTwo = new ArrayRepository; + $arrayRepoTwo->addPackage($this->getPackage('bar', '1')); + + $repo = new CompositeRepository(array($arrayRepoOne, $arrayRepoTwo)); + + $this->assertEquals(2, count($repo), "Should return '2' for count(\$repo)"); + } +}