1
0
Fork 0

Merge pull request #1740 from Seldaek/preferstable

Add prefer-stable flag to pick stable package over unstable ones when possible
pull/1760/merge
Jordi Boggiano 2013-04-02 09:46:33 -07:00
commit 79100bea81
7 changed files with 83 additions and 2 deletions

View File

@ -493,6 +493,13 @@ a given package can be done in `require` or `require-dev` (see
Available options (in order of stability) are `dev`, `alpha`, `beta`, `RC`, Available options (in order of stability) are `dev`, `alpha`, `beta`, `RC`,
and `stable`. and `stable`.
### prefer-stable <span>(root-only)</span>
When this is enabled, Composer will prefer more stable packages over unstable
ones when finding compatible stable packages is possible. If you require a
dev version or only alphas are available for a package, those will still be
selected granted that the minimum-stability allows for it.
### repositories <span>(root-only)</span> ### repositories <span>(root-only)</span>
Custom package repositories to use. Custom package repositories to use.

View File

@ -221,6 +221,10 @@
"type": ["string"], "type": ["string"],
"description": "The minimum stability the packages must have to be install-able. Possible values are: dev, alpha, beta, RC, stable." "description": "The minimum stability the packages must have to be install-able. Possible values are: dev, alpha, beta, RC, stable."
}, },
"prefer-stable": {
"type": ["boolean"],
"description": "If set to true, stable packages will be prefered to dev packages when possible, even if the minimum-stability allows unstable packages."
},
"bin": { "bin": {
"type": ["array"], "type": ["array"],
"description": "A set of files that should be treated as binaries and symlinked into bin-dir (from config).", "description": "A set of files that should be treated as binaries and symlinked into bin-dir (from config).",

View File

@ -14,15 +14,28 @@ namespace Composer\DependencyResolver;
use Composer\Package\PackageInterface; use Composer\Package\PackageInterface;
use Composer\Package\AliasPackage; use Composer\Package\AliasPackage;
use Composer\Package\BasePackage;
use Composer\Package\LinkConstraint\VersionConstraint; use Composer\Package\LinkConstraint\VersionConstraint;
/** /**
* @author Nils Adermann <naderman@naderman.de> * @author Nils Adermann <naderman@naderman.de>
* @author Jordi Boggiano <j.boggiano@seld.be>
*/ */
class DefaultPolicy implements PolicyInterface class DefaultPolicy implements PolicyInterface
{ {
private $preferStable;
public function __construct($preferStable = false)
{
$this->preferStable = $preferStable;
}
public function versionCompare(PackageInterface $a, PackageInterface $b, $operator) public function versionCompare(PackageInterface $a, PackageInterface $b, $operator)
{ {
if ($this->preferStable && ($stabA = $a->getStability()) !== ($stabB = $b->getStability())) {
return BasePackage::$stabilities[$stabA] < BasePackage::$stabilities[$stabB];
}
$constraint = new VersionConstraint($operator, $b->getVersion()); $constraint = new VersionConstraint($operator, $b->getVersion());
$version = new VersionConstraint('==', $a->getVersion()); $version = new VersionConstraint('==', $a->getVersion());

View File

@ -234,7 +234,7 @@ class Installer
// split dev and non-dev requirements by checking what would be removed if we update without the dev requirements // 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()) { if ($this->devMode && $this->package->getDevRequires()) {
$policy = new DefaultPolicy(); $policy = $this->createPolicy();
$pool = $this->createPool(); $pool = $this->createPool();
$pool->addRepository($installedRepo, $aliases); $pool->addRepository($installedRepo, $aliases);
@ -308,7 +308,7 @@ class Installer
$this->io->write('<info>Loading composer repositories with package information</info>'); $this->io->write('<info>Loading composer repositories with package information</info>');
// creating repository pool // creating repository pool
$policy = new DefaultPolicy(); $policy = $this->createPolicy();
$pool = $this->createPool(); $pool = $this->createPool();
$pool->addRepository($installedRepo, $aliases); $pool->addRepository($installedRepo, $aliases);
if ($installFromLock) { if ($installFromLock) {
@ -513,6 +513,11 @@ class Installer
return new Pool($minimumStability, $stabilityFlags); return new Pool($minimumStability, $stabilityFlags);
} }
private function createPolicy()
{
return new DefaultPolicy($this->package->getPreferStable());
}
private function createRequest(Pool $pool, RootPackageInterface $rootPackage, PlatformRepository $platformRepo) private function createRequest(Pool $pool, RootPackageInterface $rootPackage, PlatformRepository $platformRepo)
{ {
$request = new Request($pool); $request = new Request($pool);

View File

@ -91,6 +91,10 @@ class RootPackageLoader extends ArrayLoader
$package->setMinimumStability(VersionParser::normalizeStability($config['minimum-stability'])); $package->setMinimumStability(VersionParser::normalizeStability($config['minimum-stability']));
} }
if (isset($config['prefer-stable'])) {
$package->setPreferStable((bool) $config['prefer-stable']);
}
$repos = Factory::createDefaultRepositories(null, $this->config, $this->manager); $repos = Factory::createDefaultRepositories(null, $this->config, $this->manager);
foreach ($repos as $repo) { foreach ($repos as $repo) {
$this->manager->addRepository($repo); $this->manager->addRepository($repo);

View File

@ -20,6 +20,7 @@ namespace Composer\Package;
class RootPackage extends CompletePackage implements RootPackageInterface class RootPackage extends CompletePackage implements RootPackageInterface
{ {
protected $minimumStability = 'stable'; protected $minimumStability = 'stable';
protected $preferStable = false;
protected $stabilityFlags = array(); protected $stabilityFlags = array();
protected $references = array(); protected $references = array();
@ -59,6 +60,24 @@ class RootPackage extends CompletePackage implements RootPackageInterface
return $this->stabilityFlags; return $this->stabilityFlags;
} }
/**
* Set the preferStable
*
* @param bool $preferStable
*/
public function setPreferStable($preferStable)
{
$this->preferStable = $preferStable;
}
/**
* {@inheritDoc}
*/
public function getPreferStable()
{
return $this->preferStable;
}
/** /**
* Set the references * Set the references
* *

View File

@ -65,6 +65,35 @@ class DefaultPolicyTest extends TestCase
$this->assertEquals($expected, $selected); $this->assertEquals($expected, $selected);
} }
public function testSelectNewestPicksLatest()
{
$this->repo->addPackage($packageA1 = $this->getPackage('A', '1.0.0'));
$this->repo->addPackage($packageA2 = $this->getPackage('A', '1.0.1-alpha'));
$this->pool->addRepository($this->repo);
$literals = array($packageA1->getId(), $packageA2->getId());
$expected = array($packageA2->getId());
$selected = $this->policy->selectPreferedPackages($this->pool, array(), $literals);
$this->assertEquals($expected, $selected);
}
public function testSelectNewestPicksLatestStableWithPreferStable()
{
$this->repo->addPackage($packageA1 = $this->getPackage('A', '1.0.0'));
$this->repo->addPackage($packageA2 = $this->getPackage('A', '1.0.1-alpha'));
$this->pool->addRepository($this->repo);
$literals = array($packageA1->getId(), $packageA2->getId());
$expected = array($packageA1->getId());
$policy = new DefaultPolicy(true);
$selected = $policy->selectPreferedPackages($this->pool, array(), $literals);
$this->assertEquals($expected, $selected);
}
public function testSelectNewestOverInstalled() public function testSelectNewestOverInstalled()
{ {
$this->repo->addPackage($packageA = $this->getPackage('A', '2.0')); $this->repo->addPackage($packageA = $this->getPackage('A', '2.0'));