From c94d867c072432b63a311d459b1be4400fa93aca Mon Sep 17 00:00:00 2001 From: Beau Simensen Date: Wed, 18 Jan 2012 22:08:27 -0800 Subject: [PATCH 1/7] Make install method self contained Experimental: Updated `install()` method to accept its Composer and input option dependencies as method arguments. --- src/Composer/Command/InstallCommand.php | 48 +++++++++++++++---------- src/Composer/Command/UpdateCommand.php | 17 ++++++++- 2 files changed, 46 insertions(+), 19 deletions(-) diff --git a/src/Composer/Command/InstallCommand.php b/src/Composer/Command/InstallCommand.php index 9e212af10..3c338590e 100644 --- a/src/Composer/Command/InstallCommand.php +++ b/src/Composer/Command/InstallCommand.php @@ -15,6 +15,7 @@ namespace Composer\Command; use Composer\Script\ScriptEvents; use Composer\Script\EventDispatcher; use Composer\Autoload\AutoloadGenerator; +use Composer\Composer; use Composer\DependencyResolver; use Composer\DependencyResolver\Pool; use Composer\DependencyResolver\Request; @@ -60,17 +61,28 @@ EOT protected function execute(InputInterface $input, OutputInterface $output) { - return $this->install($input, $output); - } - - public function install(InputInterface $input, OutputInterface $output, $update = false) - { - $preferSource = (Boolean) $input->getOption('dev'); - $dryRun = (Boolean) $input->getOption('dry-run'); - $verbose = $dryRun || $input->getOption('verbose'); $composer = $this->getComposer(); $io = $this->getApplication()->getIO(); - $dispatcher = new EventDispatcher($this->getComposer(), $io); + $eventDispatcher = new EventDispatcher($composer, $io); + return $this->install( + $composer, + $eventDispatcher, + $input, + $output, + false, + (Boolean)$input->getOption('dev'), + (Boolean)$input->getOption('dry-run'), + (Boolean)$input->getOption('verbose'), + (Boolean)$input->getOption('no-install-recommends'), + (Boolean)$input->getOption('install-suggests') + ); + } + + public function install(Composer $composer, EventDispatcher $eventDispatcher, InputInterface $input, OutputInterface $output, $update, $preferSource, $dryRun, $verbose, $noInstallRecommends, $installSuggests) + { + if ($dryRun) { + $verbose = true; + } if ($preferSource) { $composer->getDownloadManager()->setPreferSource(true); @@ -91,7 +103,7 @@ EOT // dispatch pre event if (!$dryRun) { $eventName = $update ? ScriptEvents::PRE_UPDATE_CMD : ScriptEvents::PRE_INSTALL_CMD; - $dispatcher->dispatchCommandEvent($eventName); + $eventDispatcher->dispatchCommandEvent($eventName); } // creating requirements request @@ -99,7 +111,7 @@ EOT if ($update) { $output->writeln('Updating dependencies'); $installedPackages = $installedRepo->getPackages(); - $links = $this->collectLinks($input, $composer->getPackage()); + $links = $this->collectLinks($input, $composer->getPackage(), $noInstallRecommends, $installSuggests); foreach ($links as $link) { foreach ($installedPackages as $package) { @@ -125,7 +137,7 @@ EOT } else { $output->writeln('Installing dependencies'); - $links = $this->collectLinks($input, $composer->getPackage()); + $links = $this->collectLinks($input, $composer->getPackage(), $noInstallRecommends, $installSuggests); foreach ($links as $link) { $request->install($link->getTarget(), $link->getConstraint()); @@ -177,9 +189,9 @@ EOT $output->writeln((string) $operation); } if (!$dryRun) { - $dispatcher->dispatchPackageEvent(constant('Composer\Script\ScriptEvents::PRE_PACKAGE_'.strtoupper($operation->getJobType())), $operation); + $eventDispatcher->dispatchPackageEvent(constant('Composer\Script\ScriptEvents::PRE_PACKAGE_'.strtoupper($operation->getJobType())), $operation); $installationManager->execute($operation); - $dispatcher->dispatchPackageEvent(constant('Composer\Script\ScriptEvents::POST_PACKAGE_'.strtoupper($operation->getJobType())), $operation); + $eventDispatcher->dispatchPackageEvent(constant('Composer\Script\ScriptEvents::POST_PACKAGE_'.strtoupper($operation->getJobType())), $operation); } } @@ -197,19 +209,19 @@ EOT // dispatch post event $eventName = $update ? ScriptEvents::POST_UPDATE_CMD : ScriptEvents::POST_INSTALL_CMD; - $dispatcher->dispatchCommandEvent($eventName); + $eventDispatcher->dispatchCommandEvent($eventName); } } - private function collectLinks(InputInterface $input, PackageInterface $package) + private function collectLinks(InputInterface $input, PackageInterface $package, $noInstallRecommends, $installSuggests) { $links = $package->getRequires(); - if (!$input->getOption('no-install-recommends')) { + if (!$noInstallRecommends) { $links = array_merge($links, $package->getRecommends()); } - if ($input->getOption('install-suggests')) { + if ($installSuggests) { $links = array_merge($links, $package->getSuggests()); } diff --git a/src/Composer/Command/UpdateCommand.php b/src/Composer/Command/UpdateCommand.php index 6b46199c0..faeeb33fc 100644 --- a/src/Composer/Command/UpdateCommand.php +++ b/src/Composer/Command/UpdateCommand.php @@ -19,6 +19,7 @@ use Composer\DependencyResolver\Request; use Composer\DependencyResolver\Operation; use Composer\Package\LinkConstraint\VersionConstraint; use Composer\Repository\PlatformRepository; +use Composer\Script\EventDispatcher; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; @@ -54,7 +55,21 @@ EOT protected function execute(InputInterface $input, OutputInterface $output) { $installCommand = $this->getApplication()->find('install'); + $composer = $this->getComposer(); + $io = $this->getApplication()->getIO(); + $eventDispatcher = new EventDispatcher($composer, $io); - return $installCommand->install($input, $output, true); + return $installCommand->install( + $composer, + $eventDispatcher, + $input, + $output, + true, + (Boolean)$input->getOption('dev'), + (Boolean)$input->getOption('dry-run'), + (Boolean)$input->getOption('verbose'), + (Boolean)$input->getOption('no-install-recommends'), + (Boolean)$input->getOption('install-suggests') + ); } } From c1ba2be345bd2556efa44891df9b9d7f296fae00 Mon Sep 17 00:00:00 2001 From: Beau Simensen Date: Tue, 24 Jan 2012 22:09:41 -0800 Subject: [PATCH 2/7] Provide the ability to specify internally installed packages (i.e., embedded in phar) --- src/Composer/Command/InstallCommand.php | 33 ++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/src/Composer/Command/InstallCommand.php b/src/Composer/Command/InstallCommand.php index 3c338590e..d8dedb40e 100644 --- a/src/Composer/Command/InstallCommand.php +++ b/src/Composer/Command/InstallCommand.php @@ -78,7 +78,7 @@ EOT ); } - public function install(Composer $composer, EventDispatcher $eventDispatcher, InputInterface $input, OutputInterface $output, $update, $preferSource, $dryRun, $verbose, $noInstallRecommends, $installSuggests) + public function install(Composer $composer, EventDispatcher $eventDispatcher, InputInterface $input, OutputInterface $output, $update, $preferSource, $dryRun, $verbose, $noInstallRecommends, $installSuggests, $internallyInstalledPackages = null) { if ($dryRun) { $verbose = true; @@ -108,12 +108,31 @@ EOT // creating requirements request $request = new Request($pool); + $internallyInstalledPackagesMap = array(); + if ($internallyInstalledPackages) { + foreach ($internallyInstalledPackages as $package) { + $request->install($package->getName(), new VersionConstraint('=', $package->getVersion())); + $internallyInstalledPackagesMap[$package->getName()] = $package; + } + } if ($update) { $output->writeln('Updating dependencies'); $installedPackages = $installedRepo->getPackages(); $links = $this->collectLinks($input, $composer->getPackage(), $noInstallRecommends, $installSuggests); foreach ($links as $link) { + if (isset($internallyInstalledPackagesMap[$link->getTarget()])) { + $package = $internallyInstalledPackagesMap[$link->getTarget()]; + if (!$link->getConstraint()->matches(new VersionConstraint('=', $package->getVersion()))) { + // Solver was not handling this well so we will + // handle it here where we can do something + // nice in the way of output. + throw new \UnexpectedValueException('Package '.$package->getName().' can not be updated because its version constraint ('.$link->getPrettyConstraint().') is not compatible with previously installed version ('.$package->getPrettyVersion().')'); + } + // This package is installed internally, no need to + // install it again. + continue; + } foreach ($installedPackages as $package) { if ($package->getName() === $link->getTarget()) { $request->update($package->getName(), new VersionConstraint('=', $package->getVersion())); @@ -140,6 +159,18 @@ EOT $links = $this->collectLinks($input, $composer->getPackage(), $noInstallRecommends, $installSuggests); foreach ($links as $link) { + if (isset($internallyInstalledPackagesMap[$link->getTarget()])) { + $package = $internallyInstalledPackagesMap[$link->getTarget()]; + if (!$link->getConstraint()->matches(new VersionConstraint('=', $package->getVersion()))) { + // Solver was not handling this well so we will + // handle it here where we can do something + // nice in the way of output. + throw new \UnexpectedValueException('Package '.$package->getName().' can not be installed because its version constraint ('.$link->getPrettyConstraint().') is not compatible with previously installed version ('.$package->getPrettyVersion().')'); + } + // This package is installed internally, no need to + // install it again. + continue; + } $request->install($link->getTarget(), $link->getConstraint()); } } From 57ffc9d59b2af7c910e4de32200f10e746c1027b Mon Sep 17 00:00:00 2001 From: Beau Simensen Date: Wed, 25 Jan 2012 13:46:46 -0800 Subject: [PATCH 3/7] Changed some variable names, continue 2, locked install changed Changed some some instances of the $package variable name to be able to be consistent in all branches of the "add to request" section of code. Updated an instance of "break" to "continue 2" as it was resulting in the same package getting both update() and install() called on request. Seems like this is probably not needed, should be just one or the other? (could be way wrong on this) Gave "locked" branch of the update/locked/install code some logic to handle internally installed packages. --- src/Composer/Command/InstallCommand.php | 39 +++++++++++++++---------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/src/Composer/Command/InstallCommand.php b/src/Composer/Command/InstallCommand.php index d8dedb40e..a06e70a8e 100644 --- a/src/Composer/Command/InstallCommand.php +++ b/src/Composer/Command/InstallCommand.php @@ -122,21 +122,20 @@ EOT foreach ($links as $link) { if (isset($internallyInstalledPackagesMap[$link->getTarget()])) { - $package = $internallyInstalledPackagesMap[$link->getTarget()]; - if (!$link->getConstraint()->matches(new VersionConstraint('=', $package->getVersion()))) { + $internallyInstalledPackage = $internallyInstalledPackagesMap[$link->getTarget()]; + if (!$link->getConstraint()->matches(new VersionConstraint('=', $internallyInstalledPackage->getVersion()))) { // Solver was not handling this well so we will - // handle it here where we can do something - // nice in the way of output. - throw new \UnexpectedValueException('Package '.$package->getName().' can not be updated because its version constraint ('.$link->getPrettyConstraint().') is not compatible with previously installed version ('.$package->getPrettyVersion().')'); + // handle it here. + throw new \UnexpectedValueException('Package '.$internallyInstalledPackage->getName().' can not be updated because its version constraint ('.$link->getPrettyConstraint().') is not compatible with internally installed version ('.$internallyInstalledPackage->getPrettyVersion().')'); } - // This package is installed internally, no need to - // install it again. + // This package is installed internally and has already + // been added to the request. continue; } foreach ($installedPackages as $package) { if ($package->getName() === $link->getTarget()) { $request->update($package->getName(), new VersionConstraint('=', $package->getVersion())); - break; + continue 2; } } @@ -151,6 +150,17 @@ EOT foreach ($composer->getLocker()->getLockedPackages() as $package) { $constraint = new VersionConstraint('=', $package->getVersion()); + if (isset($internallyInstalledPackagesMap[$package->getName()])) { + $internallyInstalledPackage = $internallyInstalledPackagesMap[$package->getName()]; + if (!$constraint->matches(new VersionConstraint('=', $internallyInstalledPackage->getVersion()))) { + // Solver was not handling this well so we will + // handle it here. + throw new \UnexpectedValueException('Package '.$package->getName().' can not be installed because its version constraint ('.$package->getPrettyVersion().') is not compatible with internally installed version ('.$internallyInstalledPackage->getPrettyVersion().')'); + } + // This package is installed internally and has already + // been added to the request. + continue; + } $request->install($package->getName(), $constraint); } } else { @@ -160,15 +170,14 @@ EOT foreach ($links as $link) { if (isset($internallyInstalledPackagesMap[$link->getTarget()])) { - $package = $internallyInstalledPackagesMap[$link->getTarget()]; - if (!$link->getConstraint()->matches(new VersionConstraint('=', $package->getVersion()))) { + $internallyInstalledPackage = $internallyInstalledPackagesMap[$link->getTarget()]; + if (!$link->getConstraint()->matches(new VersionConstraint('=', $internallyInstalledPackage->getVersion()))) { // Solver was not handling this well so we will - // handle it here where we can do something - // nice in the way of output. - throw new \UnexpectedValueException('Package '.$package->getName().' can not be installed because its version constraint ('.$link->getPrettyConstraint().') is not compatible with previously installed version ('.$package->getPrettyVersion().')'); + // handle it here. + throw new \UnexpectedValueException('Package '.$internallyInstalledPackage->getName().' can not be installed because its version constraint ('.$link->getPrettyConstraint().') is not compatible with internally installed version ('.$internallyInstalledPackage->getPrettyVersion().')'); } - // This package is installed internally, no need to - // install it again. + // This package is installed internally and has already + // been added to the request. continue; } $request->install($link->getTarget(), $link->getConstraint()); From df72919ba3ea74c8303adc5fef7d0d213cd1af38 Mon Sep 17 00:00:00 2001 From: Beau Simensen Date: Wed, 25 Jan 2012 19:25:42 -0800 Subject: [PATCH 4/7] @naderman says this is wrong. --- src/Composer/Command/InstallCommand.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Composer/Command/InstallCommand.php b/src/Composer/Command/InstallCommand.php index a06e70a8e..fdedfce45 100644 --- a/src/Composer/Command/InstallCommand.php +++ b/src/Composer/Command/InstallCommand.php @@ -135,7 +135,7 @@ EOT foreach ($installedPackages as $package) { if ($package->getName() === $link->getTarget()) { $request->update($package->getName(), new VersionConstraint('=', $package->getVersion())); - continue 2; + break; } } From 473f127ff111c8fe627342b31a6e59b411075fed Mon Sep 17 00:00:00 2001 From: Beau Simensen Date: Wed, 25 Jan 2012 20:27:06 -0800 Subject: [PATCH 5/7] Super simplified, works, but needs refactoring w/ Composer Repository --- src/Composer/Command/InstallCommand.php | 47 ++++--------------------- 1 file changed, 7 insertions(+), 40 deletions(-) diff --git a/src/Composer/Command/InstallCommand.php b/src/Composer/Command/InstallCommand.php index fdedfce45..97f7b4b89 100644 --- a/src/Composer/Command/InstallCommand.php +++ b/src/Composer/Command/InstallCommand.php @@ -20,6 +20,7 @@ use Composer\DependencyResolver; use Composer\DependencyResolver\Pool; use Composer\DependencyResolver\Request; use Composer\DependencyResolver\Operation; +use Composer\Package\MemoryPackage; use Composer\Package\LinkConstraint\VersionConstraint; use Composer\Package\PackageInterface; use Composer\Repository\PlatformRepository; @@ -93,6 +94,12 @@ EOT // 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())); + } + } + // creating repository pool $pool = new Pool; $pool->addRepository($installedRepo); @@ -108,30 +115,12 @@ EOT // creating requirements request $request = new Request($pool); - $internallyInstalledPackagesMap = array(); - if ($internallyInstalledPackages) { - foreach ($internallyInstalledPackages as $package) { - $request->install($package->getName(), new VersionConstraint('=', $package->getVersion())); - $internallyInstalledPackagesMap[$package->getName()] = $package; - } - } if ($update) { $output->writeln('Updating dependencies'); $installedPackages = $installedRepo->getPackages(); $links = $this->collectLinks($input, $composer->getPackage(), $noInstallRecommends, $installSuggests); foreach ($links as $link) { - if (isset($internallyInstalledPackagesMap[$link->getTarget()])) { - $internallyInstalledPackage = $internallyInstalledPackagesMap[$link->getTarget()]; - if (!$link->getConstraint()->matches(new VersionConstraint('=', $internallyInstalledPackage->getVersion()))) { - // Solver was not handling this well so we will - // handle it here. - throw new \UnexpectedValueException('Package '.$internallyInstalledPackage->getName().' can not be updated because its version constraint ('.$link->getPrettyConstraint().') is not compatible with internally installed version ('.$internallyInstalledPackage->getPrettyVersion().')'); - } - // This package is installed internally and has already - // been added to the request. - continue; - } foreach ($installedPackages as $package) { if ($package->getName() === $link->getTarget()) { $request->update($package->getName(), new VersionConstraint('=', $package->getVersion())); @@ -150,17 +139,6 @@ EOT foreach ($composer->getLocker()->getLockedPackages() as $package) { $constraint = new VersionConstraint('=', $package->getVersion()); - if (isset($internallyInstalledPackagesMap[$package->getName()])) { - $internallyInstalledPackage = $internallyInstalledPackagesMap[$package->getName()]; - if (!$constraint->matches(new VersionConstraint('=', $internallyInstalledPackage->getVersion()))) { - // Solver was not handling this well so we will - // handle it here. - throw new \UnexpectedValueException('Package '.$package->getName().' can not be installed because its version constraint ('.$package->getPrettyVersion().') is not compatible with internally installed version ('.$internallyInstalledPackage->getPrettyVersion().')'); - } - // This package is installed internally and has already - // been added to the request. - continue; - } $request->install($package->getName(), $constraint); } } else { @@ -169,17 +147,6 @@ EOT $links = $this->collectLinks($input, $composer->getPackage(), $noInstallRecommends, $installSuggests); foreach ($links as $link) { - if (isset($internallyInstalledPackagesMap[$link->getTarget()])) { - $internallyInstalledPackage = $internallyInstalledPackagesMap[$link->getTarget()]; - if (!$link->getConstraint()->matches(new VersionConstraint('=', $internallyInstalledPackage->getVersion()))) { - // Solver was not handling this well so we will - // handle it here. - throw new \UnexpectedValueException('Package '.$internallyInstalledPackage->getName().' can not be installed because its version constraint ('.$link->getPrettyConstraint().') is not compatible with internally installed version ('.$internallyInstalledPackage->getPrettyVersion().')'); - } - // This package is installed internally and has already - // been added to the request. - continue; - } $request->install($link->getTarget(), $link->getConstraint()); } } From e1370be7a0a86dd52241c2bf37105654d7e4a61e Mon Sep 17 00:00:00 2001 From: Beau Simensen Date: Thu, 26 Jan 2012 19:53:32 -0800 Subject: [PATCH 6/7] 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)"); + } +} From d05f0a6e40886edf4156ba33edea6635f9472afa Mon Sep 17 00:00:00 2001 From: Beau Simensen Date: Fri, 27 Jan 2012 06:40:24 -0800 Subject: [PATCH 7/7] Addressed coding standard issues reported by @stof --- .../Repository/CompositeRepository.php | 39 ++++++++----------- 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/src/Composer/Repository/CompositeRepository.php b/src/Composer/Repository/CompositeRepository.php index 7af8cffad..eccf5f230 100644 --- a/src/Composer/Repository/CompositeRepository.php +++ b/src/Composer/Repository/CompositeRepository.php @@ -21,7 +21,6 @@ use Composer\Package\PackageInterface; */ class CompositeRepository implements RepositoryInterface { - /** * List of repositories * @var array @@ -38,8 +37,7 @@ class CompositeRepository implements RepositoryInterface } /** - * (non-PHPdoc) - * @see Composer\Repository.RepositoryInterface::hasPackage() + * {@inheritdoc} */ public function hasPackage(PackageInterface $package) { @@ -53,10 +51,10 @@ class CompositeRepository implements RepositoryInterface } /** - * (non-PHPdoc) - * @see Composer\Repository.RepositoryInterface::findPackage() + * {@inheritdoc} */ - public function findPackage($name, $version) { + public function findPackage($name, $version) + { foreach ($this->repositories as $repository) { /* @var $repository RepositoryInterface */ $package = $repository->findPackage($name, $version); @@ -68,8 +66,7 @@ class CompositeRepository implements RepositoryInterface } /** - * (non-PHPdoc) - * @see Composer\Repository.RepositoryInterface::findPackagesByName() + * {@inheritdoc} */ public function findPackagesByName($name) { @@ -82,8 +79,7 @@ class CompositeRepository implements RepositoryInterface } /** - * (non-PHPdoc) - * @see Composer\Repository.RepositoryInterface::getPackages() + * {@inheritdoc} */ public function getPackages() { @@ -96,17 +92,7 @@ class CompositeRepository implements RepositoryInterface } /** - * Add a repository. - * @param RepositoryInterface $repository - */ - public function addRepository(RepositoryInterface $repository) - { - $this->repositories[] = $repository; - } - - /** - * (non-PHPdoc) - * @see Countable::count() + * {@inheritdoc} */ public function count() { @@ -117,4 +103,13 @@ class CompositeRepository implements RepositoryInterface } return $total; } -} + + /** + * Add a repository. + * @param RepositoryInterface $repository + */ + public function addRepository(RepositoryInterface $repository) + { + $this->repositories[] = $repository; + } +} \ No newline at end of file