1
0
Fork 0

add --prefer-lowest-stable to update command

pull/3450/head
Nicolas Grekas 2014-11-21 14:01:01 +01:00
parent 2264a80a7d
commit 4a0feb0189
6 changed files with 85 additions and 4 deletions

View File

@ -47,6 +47,7 @@ class UpdateCommand extends Command
new InputOption('verbose', 'v|vv|vvv', InputOption::VALUE_NONE, 'Shows more details including new commits pulled in when updating packages.'), new InputOption('verbose', 'v|vv|vvv', InputOption::VALUE_NONE, 'Shows more details including new commits pulled in when updating packages.'),
new InputOption('optimize-autoloader', 'o', InputOption::VALUE_NONE, 'Optimize autoloader during autoloader dump.'), new InputOption('optimize-autoloader', 'o', InputOption::VALUE_NONE, 'Optimize autoloader during autoloader dump.'),
new InputOption('ignore-platform-reqs', null, InputOption::VALUE_NONE, 'Ignore platform requirements (php & ext- packages).'), new InputOption('ignore-platform-reqs', null, InputOption::VALUE_NONE, 'Ignore platform requirements (php & ext- packages).'),
new InputOption('prefer-lowest-stable', null, InputOption::VALUE_NONE, 'Forces all packages to their lowest stable version.'),
)) ))
->setHelp(<<<EOT ->setHelp(<<<EOT
The <info>update</info> command reads the composer.json file from the The <info>update</info> command reads the composer.json file from the
@ -121,6 +122,7 @@ EOT
->setUpdateWhitelist($input->getOption('lock') ? array('lock') : $input->getArgument('packages')) ->setUpdateWhitelist($input->getOption('lock') ? array('lock') : $input->getArgument('packages'))
->setWhitelistDependencies($input->getOption('with-dependencies')) ->setWhitelistDependencies($input->getOption('with-dependencies'))
->setIgnorePlatformRequirements($input->getOption('ignore-platform-reqs')) ->setIgnorePlatformRequirements($input->getOption('ignore-platform-reqs'))
->setPreferLowestStable($input->getOption('prefer-lowest-stable'))
; ;
if ($input->getOption('no-plugins')) { if ($input->getOption('no-plugins')) {

View File

@ -24,10 +24,12 @@ use Composer\Package\LinkConstraint\VersionConstraint;
class DefaultPolicy implements PolicyInterface class DefaultPolicy implements PolicyInterface
{ {
private $preferStable; private $preferStable;
private $preferLowest;
public function __construct($preferStable = false) public function __construct($preferStable = false, $preferLowest = false)
{ {
$this->preferStable = $preferStable; $this->preferStable = $preferStable;
$this->preferLowest = $preferLowest;
} }
public function versionCompare(PackageInterface $a, PackageInterface $b, $operator) public function versionCompare(PackageInterface $a, PackageInterface $b, $operator)
@ -195,6 +197,7 @@ class DefaultPolicy implements PolicyInterface
protected function pruneToBestVersion(Pool $pool, $literals) protected function pruneToBestVersion(Pool $pool, $literals)
{ {
$operator = $this->preferLowest ? '<' : '>';
$bestLiterals = array($literals[0]); $bestLiterals = array($literals[0]);
$bestPackage = $pool->literalToPackage($literals[0]); $bestPackage = $pool->literalToPackage($literals[0]);
foreach ($literals as $i => $literal) { foreach ($literals as $i => $literal) {
@ -204,7 +207,7 @@ class DefaultPolicy implements PolicyInterface
$package = $pool->literalToPackage($literal); $package = $pool->literalToPackage($literal);
if ($this->versionCompare($package, $bestPackage, '>')) { if ($this->versionCompare($package, $bestPackage, $operator)) {
$bestPackage = $package; $bestPackage = $package;
$bestLiterals = array($literal); $bestLiterals = array($literal);
} elseif ($this->versionCompare($package, $bestPackage, '==')) { } elseif ($this->versionCompare($package, $bestPackage, '==')) {

View File

@ -107,6 +107,7 @@ class Installer
protected $update = false; protected $update = false;
protected $runScripts = true; protected $runScripts = true;
protected $ignorePlatformReqs = false; protected $ignorePlatformReqs = false;
protected $preferLowestStable = false;
/** /**
* Array of package names/globs flagged for update * Array of package names/globs flagged for update
* *
@ -693,6 +694,7 @@ class Installer
private function createPolicy() private function createPolicy()
{ {
$preferLowest = false;
$preferStable = null; $preferStable = null;
if (!$this->update && $this->locker->isLocked()) { if (!$this->update && $this->locker->isLocked()) {
$preferStable = $this->locker->getPreferStable(); $preferStable = $this->locker->getPreferStable();
@ -700,10 +702,14 @@ class Installer
// old lock file without prefer stable will return null // old lock file without prefer stable will return null
// so in this case we use the composer.json info // so in this case we use the composer.json info
if (null === $preferStable) { if (null === $preferStable) {
if ($this->preferLowestStable) {
$preferStable = $preferLowest = true;
} else {
$preferStable = $this->package->getPreferStable(); $preferStable = $this->package->getPreferStable();
} }
}
return new DefaultPolicy($preferStable); return new DefaultPolicy($preferStable, $preferLowest);
} }
private function createRequest(Pool $pool, RootPackageInterface $rootPackage, PlatformRepository $platformRepo) private function createRequest(Pool $pool, RootPackageInterface $rootPackage, PlatformRepository $platformRepo)
@ -1244,6 +1250,19 @@ class Installer
return $this; return $this;
} }
/**
* Should packages be forced to their lowest stable version when updating?
*
* @param boolean $preferLowestStable
* @return Installer
*/
public function setPreferLowestStable($preferLowestStable = true)
{
$this->preferLowestStable = (boolean) $preferLowestStable;
return $this;
}
/** /**
* Disables plugins. * Disables plugins.
* *

View File

@ -247,4 +247,20 @@ class DefaultPolicyTest extends TestCase
return $map; return $map;
} }
public function testSelectLowest()
{
$policy = new DefaultPolicy(false, true);
$this->repo->addPackage($packageA1 = $this->getPackage('A', '1.0'));
$this->repo->addPackage($packageA2 = $this->getPackage('A', '2.0'));
$this->pool->addRepository($this->repo);
$literals = array($packageA1->getId(), $packageA2->getId());
$expected = array($packageA1->getId());
$selected = $policy->selectPreferedPackages($this->pool, array(), $literals);
$this->assertEquals($expected, $selected);
}
} }

View File

@ -0,0 +1,40 @@
--TEST--
Updates packages to their lowest stable version
--COMPOSER--
{
"repositories": [
{
"type": "package",
"package": [
{ "name": "a/a", "version": "1.0.0-rc1" },
{ "name": "a/a", "version": "1.0.1" },
{ "name": "a/a", "version": "1.1.0" },
{ "name": "a/b", "version": "1.0.0" },
{ "name": "a/b", "version": "1.0.1" },
{ "name": "a/b", "version": "2.0.0" },
{ "name": "a/c", "version": "1.0.0" },
{ "name": "a/c", "version": "2.0.0" }
]
}
],
"require": {
"a/a": "~1.0@dev",
"a/c": "2.*"
},
"require-dev": {
"a/b": "*"
}
}
--INSTALLED--
[
{ "name": "a/a", "version": "1.0.0-rc1" },
{ "name": "a/c", "version": "2.0.0" },
{ "name": "a/b", "version": "1.0.1" }
]
--RUN--
update --prefer-lowest-stable
--EXPECT--
Updating a/a (1.0.0-rc1) to a/a (1.0.1)
Updating a/b (1.0.1) to a/b (1.0.0)

View File

@ -217,6 +217,7 @@ class InstallerTest extends TestCase
->setDryRun($input->getOption('dry-run')) ->setDryRun($input->getOption('dry-run'))
->setUpdateWhitelist($input->getArgument('packages')) ->setUpdateWhitelist($input->getArgument('packages'))
->setWhitelistDependencies($input->getOption('with-dependencies')) ->setWhitelistDependencies($input->getOption('with-dependencies'))
->setPreferLowestStable($input->getOption('prefer-lowest-stable'))
->setIgnorePlatformRequirements($input->getOption('ignore-platform-reqs')); ->setIgnorePlatformRequirements($input->getOption('ignore-platform-reqs'));
return $installer->run(); return $installer->run();