diff --git a/doc/03-cli.md b/doc/03-cli.md
index 043ce1801..2d5ad54a3 100644
--- a/doc/03-cli.md
+++ b/doc/03-cli.md
@@ -76,6 +76,8 @@ resolution.
* **--dev:** By default composer will only install required packages. By
passing this option you can also make it install packages referenced by
`require-dev`.
+* **--no-dev:** Skip installing packages listed in `require-dev` (this is
+ the default for `install`).
* **--no-scripts:** Skips execution of scripts defined in `composer.json`.
* **--no-custom-installers:** Disables custom installers.
* **--no-progress:** Removes the progress display that can mess with some
@@ -107,7 +109,8 @@ You can also use wildcards to update a bunch of packages at once:
* **--prefer-source:** Install packages from `source` when available.
* **--prefer-dist:** Install packages from `dist` when available.
* **--dry-run:** Simulate the command without actually doing anything.
-* **--dev:** Install packages listed in `require-dev`.
+* **--dev:** Install packages listed in `require-dev` (this is the default for `update`).
+* **--no-dev:** Skip installing packages listed in `require-dev`.
* **--no-scripts:** Skips execution of scripts defined in `composer.json`.
* **--no-custom-installers:** Disables custom installers.
* **--no-progress:** Removes the progress display that can mess with some
@@ -190,7 +193,6 @@ specific version.
* **--installed (-i):** List the packages that are installed.
* **--platform (-p):** List only platform packages (php & extensions).
* **--self (-s):** List the root package info.
-* **--dev:** Include dev-required packages when combined with **--installed** or **--platform**.
## depends
diff --git a/doc/04-schema.md b/doc/04-schema.md
index ed585b76d..74c7510de 100644
--- a/doc/04-schema.md
+++ b/doc/04-schema.md
@@ -296,17 +296,7 @@ unless those requirements can be met.
Lists packages required for developing this package, or running
tests, etc. The dev requirements of the root package only will be installed
-if `install` or `update` is ran with `--dev`.
-
-Packages listed here and their dependencies can not overrule the resolution
-found with the packages listed in require. This is even true if a different
-version of a package would be installable and solve the conflict. The reason
-is that `install --dev` produces the exact same state as just `install`, apart
-from the additional dev packages.
-
-If you run into such a conflict, you can specify the conflicting package in
-the require section and require the right version number to resolve the
-conflict.
+if `install` is run with `--dev` or if `update` is run without `--no-dev`.
#### conflict
diff --git a/src/Composer/Command/DependsCommand.php b/src/Composer/Command/DependsCommand.php
index fe42387b1..6dc1a7e44 100644
--- a/src/Composer/Command/DependsCommand.php
+++ b/src/Composer/Command/DependsCommand.php
@@ -50,13 +50,11 @@ EOT
protected function execute(InputInterface $input, OutputInterface $output)
{
- $repos = $this->getComposer()->getRepositoryManager()->getLocalRepositories();
+ $repo = $this->getComposer()->getRepositoryManager()->getLocalRepository();
$needle = $input->getArgument('package');
$pool = new Pool();
- foreach ($repos as $repo) {
- $pool->addRepository($repo);
- }
+ $pool->addRepository($repo);
$packages = $pool->whatProvides($needle);
if (empty($packages)) {
@@ -75,22 +73,20 @@ EOT
}, $input->getOption('link-type'));
$messages = array();
- foreach ($repos as $repo) {
- $repo->filterPackages(function ($package) use ($needle, $types, $linkTypes, &$messages) {
- static $outputPackages = array();
+ $repo->filterPackages(function ($package) use ($needle, $types, $linkTypes, &$messages) {
+ static $outputPackages = array();
- foreach ($types as $type) {
- foreach ($package->{'get'.$linkTypes[$type][0]}() as $link) {
- if ($link->getTarget() === $needle) {
- if (!isset($outputPackages[$package->getName()])) {
- $messages[] = ''.$package->getPrettyName() . ' ' . $linkTypes[$type][1] . ' ' . $needle .' (' . $link->getPrettyConstraint() . ')';
- $outputPackages[$package->getName()] = true;
- }
+ foreach ($types as $type) {
+ foreach ($package->{'get'.$linkTypes[$type][0]}() as $link) {
+ if ($link->getTarget() === $needle) {
+ if (!isset($outputPackages[$package->getName()])) {
+ $messages[] = ''.$package->getPrettyName() . ' ' . $linkTypes[$type][1] . ' ' . $needle .' (' . $link->getPrettyConstraint() . ')';
+ $outputPackages[$package->getName()] = true;
}
}
}
- });
- }
+ }
+ });
if ($messages) {
sort($messages);
diff --git a/src/Composer/Command/DumpAutoloadCommand.php b/src/Composer/Command/DumpAutoloadCommand.php
index aa01aecbb..e3687899e 100755
--- a/src/Composer/Command/DumpAutoloadCommand.php
+++ b/src/Composer/Command/DumpAutoloadCommand.php
@@ -45,10 +45,10 @@ EOT
$composer = $this->getComposer();
$installationManager = $composer->getInstallationManager();
- $localRepos = new CompositeRepository($composer->getRepositoryManager()->getLocalRepositories());
+ $localRepo = $composer->getRepositoryManager()->getLocalRepository();
$package = $composer->getPackage();
$config = $composer->getConfig();
- $composer->getAutoloadGenerator()->dump($config, $localRepos, $package, $installationManager, 'composer', $input->getOption('optimize'));
+ $composer->getAutoloadGenerator()->dump($config, $localRepo, $package, $installationManager, 'composer', $input->getOption('optimize'));
}
}
diff --git a/src/Composer/Command/InstallCommand.php b/src/Composer/Command/InstallCommand.php
index 0d8ffce2d..c578a308c 100644
--- a/src/Composer/Command/InstallCommand.php
+++ b/src/Composer/Command/InstallCommand.php
@@ -33,7 +33,8 @@ class InstallCommand extends Command
new InputOption('prefer-source', null, InputOption::VALUE_NONE, 'Forces installation from package sources when possible, including VCS information.'),
new InputOption('prefer-dist', null, InputOption::VALUE_NONE, 'Forces installation from package dist even for dev versions.'),
new InputOption('dry-run', null, InputOption::VALUE_NONE, 'Outputs the operations but will not execute anything (implicitly enables --verbose).'),
- new InputOption('dev', null, InputOption::VALUE_NONE, 'Enables installation of dev-require packages.'),
+ new InputOption('dev', null, InputOption::VALUE_NONE, 'Enables installation of require-dev packages.'),
+ new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Disables installation of require-dev packages (enabled by default, only present for sanity).'),
new InputOption('no-custom-installers', null, InputOption::VALUE_NONE, 'Disables all custom installers.'),
new InputOption('no-scripts', null, InputOption::VALUE_NONE, 'Skips the execution of all scripts defined in composer.json file.'),
new InputOption('no-progress', null, InputOption::VALUE_NONE, 'Do not output download progress.'),
diff --git a/src/Composer/Command/ShowCommand.php b/src/Composer/Command/ShowCommand.php
index d5ec48dfe..c05517398 100644
--- a/src/Composer/Command/ShowCommand.php
+++ b/src/Composer/Command/ShowCommand.php
@@ -45,7 +45,6 @@ class ShowCommand extends Command
new InputOption('platform', 'p', InputOption::VALUE_NONE, 'List platform packages only'),
new InputOption('available', 'a', InputOption::VALUE_NONE, 'List available packages only'),
new InputOption('self', 's', InputOption::VALUE_NONE, 'Show the root package information'),
- new InputOption('dev', null, InputOption::VALUE_NONE, 'Enables display of dev-require packages.'),
new InputOption('name-only', 'N', InputOption::VALUE_NONE, 'List package names only'),
))
->setHelp(<<getRepositoryManager();
- $repos = new CompositeRepository(array($manager->getLocalRepository()));
- if ($dev) {
- $repos->addRepository($manager->getLocalDevRepository());
- }
-
- return $repos;
- };
if ($input->getOption('self')) {
$package = $this->getComposer(false)->getPackage();
@@ -79,7 +69,7 @@ EOT
} elseif ($input->getOption('platform')) {
$repos = $installedRepo = $platformRepo;
} elseif ($input->getOption('installed')) {
- $repos = $installedRepo = $getRepositories($this->getComposer(), $input->getOption('dev'));
+ $repos = $installedRepo = $this->getComposer()->getRepositoryManager()->getLocalRepository();
} elseif ($input->getOption('available')) {
$installedRepo = $platformRepo;
if ($composer = $this->getComposer(false)) {
@@ -90,7 +80,7 @@ EOT
$output->writeln('No composer.json found in the current directory, showing available packages from ' . implode(', ', array_keys($defaultRepos)));
}
} elseif ($composer = $this->getComposer(false)) {
- $localRepo = $getRepositories($composer, $input->getOption('dev'));
+ $localRepo = $composer = $this->getComposer()->getRepositoryManager()->getLocalRepository();
$installedRepo = new CompositeRepository(array($localRepo, $platformRepo));
$repos = new CompositeRepository(array_merge(array($installedRepo), $composer->getRepositoryManager()->getRepositories()));
} else {
diff --git a/src/Composer/Command/UpdateCommand.php b/src/Composer/Command/UpdateCommand.php
index a6aa3a476..f1ac08f28 100644
--- a/src/Composer/Command/UpdateCommand.php
+++ b/src/Composer/Command/UpdateCommand.php
@@ -33,7 +33,8 @@ class UpdateCommand extends Command
new InputOption('prefer-source', null, InputOption::VALUE_NONE, 'Forces installation from package sources when possible, including VCS information.'),
new InputOption('prefer-dist', null, InputOption::VALUE_NONE, 'Forces installation from package dist even for dev versions.'),
new InputOption('dry-run', null, InputOption::VALUE_NONE, 'Outputs the operations but will not execute anything (implicitly enables --verbose).'),
- new InputOption('dev', null, InputOption::VALUE_NONE, 'Enables installation of dev-require packages.'),
+ new InputOption('dev', null, InputOption::VALUE_NONE, 'Enables installation of require-dev packages (enabled by default, only present for sanity).'),
+ new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Disables installation of require-dev packages.'),
new InputOption('no-custom-installers', null, InputOption::VALUE_NONE, 'Disables all custom installers.'),
new InputOption('no-scripts', null, InputOption::VALUE_NONE, 'Skips the execution of all scripts defined in composer.json file.'),
new InputOption('no-progress', null, InputOption::VALUE_NONE, 'Do not output download progress.'),
@@ -68,7 +69,7 @@ EOT
->setVerbose($input->getOption('verbose'))
->setPreferSource($input->getOption('prefer-source'))
->setPreferDist($input->getOption('prefer-dist'))
- ->setDevMode($input->getOption('dev'))
+ ->setDevMode(!$input->getOption('no-dev'))
->setRunScripts(!$input->getOption('no-scripts'))
->setOptimizeAutoloader($input->getOption('optimize-autoloader'))
->setUpdate(true)
diff --git a/src/Composer/Factory.php b/src/Composer/Factory.php
index 64ea0724f..5014b3724 100644
--- a/src/Composer/Factory.php
+++ b/src/Composer/Factory.php
@@ -291,7 +291,6 @@ class Factory
protected function addLocalRepository(RepositoryManager $rm, $vendorDir)
{
$rm->setLocalRepository(new Repository\InstalledFilesystemRepository(new JsonFile($vendorDir.'/composer/installed.json')));
- $rm->setLocalDevRepository(new Repository\InstalledFilesystemRepository(new JsonFile($vendorDir.'/composer/installed_dev.json')));
}
/**
@@ -345,12 +344,10 @@ class Factory
*/
protected function purgePackages(Repository\RepositoryManager $rm, Installer\InstallationManager $im)
{
- foreach ($rm->getLocalRepositories() as $repo) {
- /* @var $repo Repository\WritableRepositoryInterface */
- foreach ($repo->getPackages() as $package) {
- if (!$im->isPackageInstalled($repo, $package)) {
- $repo->removePackage($package);
- }
+ $repo = $rm->getLocalRepository();
+ foreach ($repo->getPackages() as $package) {
+ if (!$im->isPackageInstalled($repo, $package)) {
+ $repo->removePackage($package);
}
}
}
diff --git a/src/Composer/Installer.php b/src/Composer/Installer.php
index ac7838537..dad53d023 100644
--- a/src/Composer/Installer.php
+++ b/src/Composer/Installer.php
@@ -15,6 +15,7 @@ namespace Composer;
use Composer\Autoload\AutoloadGenerator;
use Composer\DependencyResolver\DefaultPolicy;
use Composer\DependencyResolver\Operation\UpdateOperation;
+use Composer\DependencyResolver\Operation\UninstallOperation;
use Composer\DependencyResolver\Pool;
use Composer\DependencyResolver\Request;
use Composer\DependencyResolver\Solver;
@@ -24,6 +25,7 @@ use Composer\Installer\InstallationManager;
use Composer\Config;
use Composer\Installer\NoopInstaller;
use Composer\IO\IOInterface;
+use Composer\Json\JsonFile;
use Composer\Package\AliasPackage;
use Composer\Package\Link;
use Composer\Package\LinkConstraint\VersionConstraint;
@@ -32,6 +34,7 @@ use Composer\Package\PackageInterface;
use Composer\Package\RootPackageInterface;
use Composer\Repository\CompositeRepository;
use Composer\Repository\InstalledArrayRepository;
+use Composer\Repository\InstalledFilesystemRepository;
use Composer\Repository\PlatformRepository;
use Composer\Repository\RepositoryInterface;
use Composer\Repository\RepositoryManager;
@@ -148,6 +151,20 @@ class Installer
$this->mockLocalRepositories($this->repositoryManager);
}
+ // TODO remove this BC feature at some point
+ // purge old require-dev packages to avoid conflicts with the new way of handling dev requirements
+ $devRepo = new InstalledFilesystemRepository(new JsonFile($this->config->get('vendor-dir').'/composer/installed_dev.json'));
+ if ($devRepo->getPackages()) {
+ $this->io->write('BC Notice: Removing old dev packages to migrate to the new require-dev handling.');
+ foreach ($devRepo->getPackages() as $package) {
+ if ($this->installationManager->isPackageInstalled($devRepo, $package)) {
+ $this->installationManager->uninstall($devRepo, new UninstallOperation($package));
+ }
+ }
+ }
+ unset($devRepo, $package);
+ // end BC
+
if ($this->preferSource) {
$this->downloadManager->setPreferSource(true);
}
@@ -160,13 +177,12 @@ class Installer
$installedRootPackage->setRequires(array());
$installedRootPackage->setDevRequires(array());
+ $localRepo = $this->repositoryManager->getLocalRepository();
$platformRepo = new PlatformRepository();
- $repos = array_merge(
- $this->repositoryManager->getLocalRepositories(),
- array(
- new InstalledArrayRepository(array($installedRootPackage)),
- $platformRepo,
- )
+ $repos = array(
+ $localRepo,
+ new InstalledArrayRepository(array($installedRootPackage)),
+ $platformRepo,
);
$installedRepo = new CompositeRepository($repos);
if ($this->additionalInstalledRepository) {
@@ -184,14 +200,9 @@ class Installer
try {
$this->suggestedPackages = array();
- if (!$this->doInstall($this->repositoryManager->getLocalRepository(), $installedRepo, $aliases)) {
+ if (!$this->doInstall($localRepo, $installedRepo, $platformRepo, $aliases, $this->devMode)) {
return false;
}
- if ($this->devMode) {
- if (!$this->doInstall($this->repositoryManager->getLocalDevRepository(), $installedRepo, $aliases, true)) {
- return false;
- }
- }
} catch (\Exception $e) {
$this->installationManager->notifyInstalls();
@@ -214,9 +225,34 @@ class Installer
if (!$this->dryRun) {
// write lock
if ($this->update || !$this->locker->isLocked()) {
+ $devPackages = $this->devMode ? array() : null;
+ $localRepo->reload();
+
+ // split dev and non-dev requirements by checking what would be removed if we update without the dev requirements
+ if ($this->devMode && $this->package->getDevRequires()) {
+ $policy = new DefaultPolicy();
+ $pool = $this->createPool();
+ $pool->addRepository($installedRepo, $aliases);
+
+ // creating requirements request
+ $request = $this->createRequest($pool, $this->package, $platformRepo);
+ $request->updateAll();
+ foreach ($this->package->getRequires() as $link) {
+ $request->install($link->getTarget(), $link->getConstraint());
+ }
+
+ $solver = new Solver($policy, $pool, $installedRepo);
+ $ops = $solver->solve($request);
+ foreach ($ops as $op) {
+ if ($op->getJobType() === 'uninstall') {
+ $devPackages[] = $op->getPackage();
+ }
+ }
+ }
+
$updatedLock = $this->locker->setLockData(
- $this->repositoryManager->getLocalRepository()->getPackages(),
- $this->devMode ? $this->repositoryManager->getLocalDevRepository()->getPackages() : null,
+ array_diff($localRepo->getPackages(), (array) $devPackages),
+ $devPackages,
$aliases,
$this->package->getMinimumStability(),
$this->package->getStabilityFlags()
@@ -228,8 +264,7 @@ class Installer
// write autoloader
$this->io->write('Generating autoload files');
- $localRepos = new CompositeRepository($this->repositoryManager->getLocalRepositories());
- $this->autoloadGenerator->dump($this->config, $localRepos, $this->package, $this->installationManager, 'composer', $this->optimizeAutoloader);
+ $this->autoloadGenerator->dump($this->config, $localRepo, $this->package, $this->installationManager, 'composer', $this->optimizeAutoloader);
if ($this->runScripts) {
// dispatch post event
@@ -241,27 +276,22 @@ class Installer
return true;
}
- protected function doInstall($localRepo, $installedRepo, $aliases, $devMode = false)
+ protected function doInstall($localRepo, $installedRepo, $platformRepo, $aliases, $withDevReqs)
{
- $minimumStability = $this->package->getMinimumStability();
- $stabilityFlags = $this->package->getStabilityFlags();
-
// init vars
$lockedRepository = null;
$repositories = null;
// initialize locker to create aliased packages
$installFromLock = false;
- if (!$this->update && $this->locker->isLocked($devMode)) {
+ if (!$this->update && $this->locker->isLocked()) {
$installFromLock = true;
- $lockedRepository = $this->locker->getLockedRepository($devMode);
- $minimumStability = $this->locker->getMinimumStability();
- $stabilityFlags = $this->locker->getStabilityFlags();
+ $lockedRepository = $this->locker->getLockedRepository($withDevReqs);
}
$this->whitelistUpdateDependencies(
$localRepo,
- $devMode,
+ $withDevReqs,
$this->package->getRequires(),
$this->package->getDevRequires()
);
@@ -270,13 +300,13 @@ class Installer
// creating repository pool
$policy = new DefaultPolicy();
- $pool = new Pool($minimumStability, $stabilityFlags);
+ $pool = $this->createPool();
$pool->addRepository($installedRepo, $aliases);
if ($installFromLock) {
$pool->addRepository($lockedRepository, $aliases);
}
- if (!$installFromLock || !$this->locker->isCompleteFormat($devMode)) {
+ if (!$installFromLock || !$this->locker->isCompleteFormat()) {
$repositories = $this->repositoryManager->getRepositories();
foreach ($repositories as $repository) {
$pool->addRepository($repository, $aliases);
@@ -284,30 +314,30 @@ class Installer
}
// creating requirements request
- $request = new Request($pool);
-
- $constraint = new VersionConstraint('=', $this->package->getVersion());
- $constraint->setPrettyString($this->package->getPrettyVersion());
- $request->install($this->package->getName(), $constraint);
+ $request = $this->createRequest($pool, $this->package, $platformRepo);
if ($this->update) {
- $this->io->write('Updating '.($devMode ? 'dev ': '').'dependencies');
+ $this->io->write('Updating dependencies'.($withDevReqs?' (including require-dev)':'').'');
$request->updateAll();
- $links = $devMode ? $this->package->getDevRequires() : $this->package->getRequires();
+ if ($withDevReqs) {
+ $links = array_merge($this->package->getRequires(), $this->package->getDevRequires());
+ } else {
+ $links = $this->package->getRequires();
+ }
foreach ($links as $link) {
$request->install($link->getTarget(), $link->getConstraint());
}
} elseif ($installFromLock) {
- $this->io->write('Installing '.($devMode ? 'dev ': '').'dependencies from lock file');
+ $this->io->write('Installing dependencies'.($withDevReqs?' (including require-dev)':'').' from lock file');
- if (!$this->locker->isCompleteFormat($devMode)) {
+ if (!$this->locker->isCompleteFormat($withDevReqs)) {
$this->io->write('Warning: Your lock file is in a deprecated format. It will most likely take a *long* time for composer to install dependencies, and may cause dependency solving issues.');
}
- if (!$this->locker->isFresh() && !$devMode) {
+ if (!$this->locker->isFresh()) {
$this->io->write('Warning: The lock file is not up to date with the latest changes in composer.json. You may be getting outdated dependencies. Run update to update them.');
}
@@ -321,40 +351,24 @@ class Installer
$request->install($package->getName(), $constraint);
}
} else {
- $this->io->write('Installing '.($devMode ? 'dev ': '').'dependencies');
+ $this->io->write('Installing dependencies'.($withDevReqs?' (including require-dev)':'').'');
- $links = $devMode ? $this->package->getDevRequires() : $this->package->getRequires();
+ if ($withDevReqs) {
+ $links = array_merge($this->package->getRequires(), $this->package->getDevRequires());
+ } else {
+ $links = $this->package->getRequires();
+ }
foreach ($links as $link) {
$request->install($link->getTarget(), $link->getConstraint());
}
}
- // fix the version of all installed packages (+ platform) that are not
- // in the current local repo to prevent rogue updates (e.g. non-dev
- // updating when in dev)
- foreach ($installedRepo->getPackages() as $package) {
- if ($package->getRepository() === $localRepo) {
- continue;
- }
-
- $constraint = new VersionConstraint('=', $package->getVersion());
- $constraint->setPrettyString($package->getPrettyVersion());
-
- if (!($package->getRepository() instanceof PlatformRepository)
- || !($provided = $this->package->getProvides())
- || !isset($provided[$package->getName()])
- || !$provided[$package->getName()]->getConstraint()->matches($constraint)
- ) {
- $request->install($package->getName(), $constraint);
- }
- }
-
// if the updateWhitelist is enabled, packages not in it are also fixed
// to the version specified in the lock, or their currently installed version
if ($this->update && $this->updateWhitelist) {
- if ($this->locker->isLocked($devMode)) {
- $currentPackages = $this->locker->getLockedRepository($devMode)->getPackages();
+ if ($this->locker->isLocked()) {
+ $currentPackages = $this->locker->getLockedRepository($withDevReqs)->getPackages();
} else {
$currentPackages = $installedRepo->getPackages();
}
@@ -397,19 +411,6 @@ class Installer
return false;
}
- if ($devMode) {
- // remove bogus operations that the solver creates for stuff that was force-updated in the non-dev pass
- // TODO this should not be necessary ideally, but it seems to work around the problem quite well
- foreach ($operations as $index => $op) {
- if ('update' === $op->getJobType() && $op->getInitialPackage()->getUniqueName() === $op->getTargetPackage()->getUniqueName()
- && $op->getInitialPackage()->getSourceReference() === $op->getTargetPackage()->getSourceReference()
- && $op->getInitialPackage()->getDistReference() === $op->getTargetPackage()->getDistReference()
- ) {
- unset($operations[$index]);
- }
- }
- }
-
// force dev packages to be updated if we update or install from a (potentially new) lock
$operations = $this->processDevPackages($localRepo, $pool, $policy, $repositories, $lockedRepository, $installFromLock, 'force-updates', $operations);
@@ -472,6 +473,45 @@ class Installer
return true;
}
+ private function createPool()
+ {
+ $minimumStability = $this->package->getMinimumStability();
+ $stabilityFlags = $this->package->getStabilityFlags();
+
+ if (!$this->update && $this->locker->isLocked()) {
+ $minimumStability = $this->locker->getMinimumStability();
+ $stabilityFlags = $this->locker->getStabilityFlags();
+ }
+
+ return new Pool($minimumStability, $stabilityFlags);
+ }
+
+ private function createRequest(Pool $pool, RootPackageInterface $rootPackage, PlatformRepository $platformRepo)
+ {
+ $request = new Request($pool);
+
+ $constraint = new VersionConstraint('=', $rootPackage->getVersion());
+ $constraint->setPrettyString($rootPackage->getPrettyVersion());
+ $request->install($rootPackage->getName(), $constraint);
+
+ // fix the version of all installed packages (+ platform) that are not
+ // in the current local repo to prevent rogue updates (e.g. non-dev
+ // updating when in dev)
+ foreach ($platformRepo->getPackages() as $package) {
+ $constraint = new VersionConstraint('=', $package->getVersion());
+ $constraint->setPrettyString($package->getPrettyVersion());
+
+ if (!($provided = $rootPackage->getProvides())
+ || !isset($provided[$package->getName()])
+ || !$provided[$package->getName()]->getConstraint()->matches($constraint)
+ ) {
+ $request->install($package->getName(), $constraint);
+ }
+ }
+
+ return $request;
+ }
+
private function processDevPackages($localRepo, $pool, $policy, $repositories, $lockedRepository, $installFromLock, $task, array $operations = null)
{
if ($task === 'force-updates' && null === $operations) {
@@ -732,18 +772,6 @@ class Installer
$rm->setLocalRepository(
new InstalledArrayRepository($packages)
);
-
- $packages = array_map(function ($p) {
- return clone $p;
- }, $rm->getLocalDevRepository()->getPackages());
- foreach ($packages as $key => $package) {
- if ($package instanceof AliasPackage) {
- unset($packages[$key]);
- }
- }
- $rm->setLocalDevRepository(
- new InstalledArrayRepository($packages)
- );
}
/**
diff --git a/src/Composer/Installer/InstallerInstaller.php b/src/Composer/Installer/InstallerInstaller.php
index dd2b63cec..5a41d4e96 100644
--- a/src/Composer/Installer/InstallerInstaller.php
+++ b/src/Composer/Installer/InstallerInstaller.php
@@ -41,11 +41,10 @@ class InstallerInstaller extends LibraryInstaller
parent::__construct($io, $composer, 'composer-installer');
$this->installationManager = $composer->getInstallationManager();
- foreach ($composer->getRepositoryManager()->getLocalRepositories() as $repo) {
- foreach ($repo->getPackages() as $package) {
- if ('composer-installer' === $package->getType()) {
- $this->registerInstaller($package);
- }
+ $repo = $composer->getRepositoryManager()->getLocalRepository();
+ foreach ($repo->getPackages() as $package) {
+ if ('composer-installer' === $package->getType()) {
+ $this->registerInstaller($package);
}
}
}
diff --git a/src/Composer/Package/Locker.php b/src/Composer/Package/Locker.php
index e867860fc..424983787 100644
--- a/src/Composer/Package/Locker.php
+++ b/src/Composer/Package/Locker.php
@@ -58,19 +58,15 @@ class Locker
/**
* Checks whether locker were been locked (lockfile found).
*
- * @param bool $dev true to check if dev packages are locked
* @return bool
*/
- public function isLocked($dev = false)
+ public function isLocked()
{
if (!$this->lockFile->exists()) {
return false;
}
$data = $this->getLockData();
- if ($dev) {
- return isset($data['packages-dev']);
- }
return isset($data['packages']);
}
@@ -90,13 +86,12 @@ class Locker
/**
* Checks whether the lock file is in the new complete format or not
*
- * @param bool $dev true to check in dev mode
* @return bool
*/
- public function isCompleteFormat($dev)
+ public function isCompleteFormat()
{
$lockData = $this->getLockData();
- $lockedPackages = $dev ? $lockData['packages-dev'] : $lockData['packages'];
+ $lockedPackages = $lockData['packages'];
if (empty($lockedPackages) || isset($lockedPackages[0]['name'])) {
return true;
@@ -108,15 +103,22 @@ class Locker
/**
* Searches and returns an array of locked packages, retrieved from registered repositories.
*
- * @param bool $dev true to retrieve the locked dev packages
+ * @param bool $withDevReqs true to retrieve the locked dev packages
* @return \Composer\Repository\RepositoryInterface
*/
- public function getLockedRepository($dev = false)
+ public function getLockedRepository($withDevReqs = false)
{
$lockData = $this->getLockData();
$packages = new ArrayRepository();
- $lockedPackages = $dev ? $lockData['packages-dev'] : $lockData['packages'];
+ $lockedPackages = $lockData['packages'];
+ if ($withDevReqs) {
+ if (isset($lockData['packages-dev'])) {
+ $lockedPackages = array_merge($lockedPackages, $lockData['packages-dev']);
+ } else {
+ throw new \RuntimeException('The lock file does not contain require-dev information, run install without --dev or run update to install those packages.');
+ }
+ }
if (empty($lockedPackages)) {
return $packages;
@@ -131,7 +133,7 @@ class Locker
}
// legacy lock file support
- $repo = $dev ? $this->repositoryManager->getLocalDevRepository() : $this->repositoryManager->getLocalRepository();
+ $repo = $this->repositoryManager->getLocalRepository();
foreach ($lockedPackages as $info) {
$resolvedVersion = !empty($info['alias-version']) ? $info['alias-version'] : $info['version'];
diff --git a/src/Composer/Repository/RepositoryManager.php b/src/Composer/Repository/RepositoryManager.php
index ea0dca137..461783fd5 100644
--- a/src/Composer/Repository/RepositoryManager.php
+++ b/src/Composer/Repository/RepositoryManager.php
@@ -25,7 +25,6 @@ use Composer\Config;
class RepositoryManager
{
private $localRepository;
- private $localDevRepository;
private $repositories = array();
private $repositoryClasses = array();
private $io;
@@ -143,33 +142,16 @@ class RepositoryManager
return $this->localRepository;
}
- /**
- * Sets localDev repository for the project.
- *
- * @param RepositoryInterface $repository repository instance
- */
- public function setLocalDevRepository(RepositoryInterface $repository)
- {
- $this->localDevRepository = $repository;
- }
-
- /**
- * Returns localDev repository for the project.
- *
- * @return RepositoryInterface
- */
- public function getLocalDevRepository()
- {
- return $this->localDevRepository;
- }
-
/**
* Returns all local repositories for the project.
*
+ * @deprecated getLocalDevRepository is gone, so this is useless now, just use getLocalRepository instead
* @return array[WritableRepositoryInterface]
*/
public function getLocalRepositories()
{
- return array($this->localRepository, $this->localDevRepository);
+ trigger_error('This method is deprecated, use getLocalRepository instead since the getLocalDevRepository is now gone', E_USER_DEPRECATED);
+
+ return array($this->localRepository);
}
}
diff --git a/src/Composer/Script/EventDispatcher.php b/src/Composer/Script/EventDispatcher.php
index c24ea21ae..88b08e2d8 100644
--- a/src/Composer/Script/EventDispatcher.php
+++ b/src/Composer/Script/EventDispatcher.php
@@ -155,10 +155,7 @@ class EventDispatcher
}
$generator = $this->composer->getAutoloadGenerator();
- $packages = array_merge(
- $this->composer->getRepositoryManager()->getLocalRepository()->getPackages(),
- $this->composer->getRepositoryManager()->getLocalDevRepository()->getPackages()
- );
+ $packages = $this->composer->getRepositoryManager()->getLocalRepository()->getPackages();
$packageMap = $generator->buildPackageMap($this->composer->getInstallationManager(), $package, $packages);
$map = $generator->parseAutoloads($packageMap, $package);
$this->loader = $generator->createLoader($map);
diff --git a/tests/Composer/Test/CacheTest.php b/tests/Composer/Test/CacheTest.php
index a07f35e2f..ba2ea77ad 100644
--- a/tests/Composer/Test/CacheTest.php
+++ b/tests/Composer/Test/CacheTest.php
@@ -29,7 +29,7 @@ class CacheTest extends TestCase
file_put_contents("{$this->root}/cached.file{$i}.zip", $zeros);
$this->files[] = new \SplFileInfo("{$this->root}/cached.file{$i}.zip");
}
- $this->finder = $this->getMock('Symfony\Component\Finder\Finder');
+ $this->finder = $this->getMockBuilder('Symfony\Component\Finder\Finder')->disableOriginalConstructor()->getMock();
$io = $this->getMock('Composer\IO\IOInterface');
$this->cache = $this->getMock(
@@ -65,7 +65,7 @@ class CacheTest extends TestCase
public function testRemoveFilesWhenCacheIsTooLarge()
{
- $emptyFinder = $this->getMock('Symfony\Component\Finder\Finder');
+ $emptyFinder = $this->getMockBuilder('Symfony\Component\Finder\Finder')->disableOriginalConstructor()->getMock();
$emptyFinder
->expects($this->once())
->method('getIterator')
diff --git a/tests/Composer/Test/Fixtures/installer/update-all.test b/tests/Composer/Test/Fixtures/installer/update-all.test
index 35a2e9337..ad5e1d3be 100644
--- a/tests/Composer/Test/Fixtures/installer/update-all.test
+++ b/tests/Composer/Test/Fixtures/installer/update-all.test
@@ -30,10 +30,7 @@ Updates updateable packages
--INSTALLED--
[
{ "name": "a/a", "version": "1.0.0" },
- { "name": "a/c", "version": "1.0.0" }
-]
---INSTALLED-DEV--
-[
+ { "name": "a/c", "version": "1.0.0" },
{ "name": "a/b", "version": "1.0.0" }
]
--RUN--
diff --git a/tests/Composer/Test/Installer/InstallerInstallerTest.php b/tests/Composer/Test/Installer/InstallerInstallerTest.php
index a53ad467c..c61182389 100644
--- a/tests/Composer/Test/Installer/InstallerInstallerTest.php
+++ b/tests/Composer/Test/Installer/InstallerInstallerTest.php
@@ -51,8 +51,8 @@ class InstallerInstallerTest extends \PHPUnit_Framework_TestCase
->disableOriginalConstructor()
->getMock();
$rm->expects($this->any())
- ->method('getLocalRepositories')
- ->will($this->returnValue(array($this->repository)));
+ ->method('getLocalRepository')
+ ->will($this->returnValue($this->repository));
$this->io = $this->getMock('Composer\IO\IOInterface');
diff --git a/tests/Composer/Test/InstallerTest.php b/tests/Composer/Test/InstallerTest.php
index 951e81397..69b292b7a 100644
--- a/tests/Composer/Test/InstallerTest.php
+++ b/tests/Composer/Test/InstallerTest.php
@@ -29,6 +29,19 @@ use Symfony\Component\Console\Output\StreamOutput;
class InstallerTest extends TestCase
{
+ protected $prevCwd;
+
+ public function setUp()
+ {
+ $this->prevCwd = getcwd();
+ chdir(__DIR__);
+ }
+
+ public function tearDown()
+ {
+ chdir($this->prevCwd);
+ }
+
/**
* @dataProvider provideInstaller
*/
@@ -41,7 +54,6 @@ class InstallerTest extends TestCase
$repositoryManager = new RepositoryManager($io, $config);
$repositoryManager->setLocalRepository(new WritableRepositoryMock());
- $repositoryManager->setLocalDevRepository(new WritableRepositoryMock());
if (!is_array($repositories)) {
$repositories = array($repositories);
@@ -124,7 +136,7 @@ class InstallerTest extends TestCase
/**
* @dataProvider getIntegrationTests
*/
- public function testIntegration($file, $message, $condition, $composerConfig, $lock, $installed, $installedDev, $run, $expectLock, $expectOutput, $expect)
+ public function testIntegration($file, $message, $condition, $composerConfig, $lock, $installed, $run, $expectLock, $expectOutput, $expect)
{
if ($condition) {
eval('$res = '.$condition.';');
@@ -151,17 +163,8 @@ class InstallerTest extends TestCase
->method('exists')
->will($this->returnValue(true));
- $devJsonMock = $this->getMockBuilder('Composer\Json\JsonFile')->disableOriginalConstructor()->getMock();
- $devJsonMock->expects($this->any())
- ->method('read')
- ->will($this->returnValue($installedDev));
- $devJsonMock->expects($this->any())
- ->method('exists')
- ->will($this->returnValue(true));
-
$repositoryManager = $composer->getRepositoryManager();
$repositoryManager->setLocalRepository(new InstalledFilesystemRepositoryMock($jsonMock));
- $repositoryManager->setLocalDevRepository(new InstalledFilesystemRepositoryMock($devJsonMock));
$lockJsonMock = $this->getMockBuilder('Composer\Json\JsonFile')->disableOriginalConstructor()->getMock();
$lockJsonMock->expects($this->any())
@@ -253,7 +256,6 @@ class InstallerTest extends TestCase
--COMPOSER--\s*(?P'.$content.')\s*
(?:--LOCK--\s*(?P'.$content.'))?\s*
(?:--INSTALLED--\s*(?P'.$content.'))?\s*
- (?:--INSTALLED-DEV--\s*(?P'.$content.'))?\s*
--RUN--\s*(?P.*?)\s*
(?:--EXPECT-LOCK--\s*(?P'.$content.'))?\s*
(?:--EXPECT-OUTPUT--\s*(?P'.$content.'))?\s*
@@ -279,9 +281,6 @@ class InstallerTest extends TestCase
if (!empty($match['installed'])) {
$installed = JsonFile::parseJson($match['installed']);
}
- if (!empty($match['installedDev'])) {
- $installedDev = JsonFile::parseJson($match['installedDev']);
- }
$run = $match['run'];
if (!empty($match['expectLock'])) {
$expectLock = JsonFile::parseJson($match['expectLock']);
@@ -295,7 +294,7 @@ class InstallerTest extends TestCase
die(sprintf('Test "%s" is not valid, did not match the expected format.', str_replace($fixturesDir.'/', '', $file)));
}
- $tests[] = array(str_replace($fixturesDir.'/', '', $file), $message, $condition, $composer, $lock, $installed, $installedDev, $run, $expectLock, $expectOutput, $expect);
+ $tests[] = array(str_replace($fixturesDir.'/', '', $file), $message, $condition, $composer, $lock, $installed, $run, $expectLock, $expectOutput, $expect);
}
return $tests;
diff --git a/tests/Composer/Test/Mock/InstallationManagerMock.php b/tests/Composer/Test/Mock/InstallationManagerMock.php
index b643df728..0ecca1e2a 100644
--- a/tests/Composer/Test/Mock/InstallationManagerMock.php
+++ b/tests/Composer/Test/Mock/InstallationManagerMock.php
@@ -13,6 +13,7 @@ namespace Composer\Test\Mock;
use Composer\Installer\InstallationManager;
use Composer\Repository\RepositoryInterface;
+use Composer\Repository\InstalledRepositoryInterface;
use Composer\Package\PackageInterface;
use Composer\DependencyResolver\Operation\InstallOperation;
use Composer\DependencyResolver\Operation\UpdateOperation;