1
0
Fork 0
mirror of https://github.com/composer/composer synced 2025-05-10 17:12:51 +00:00

Make VersionSelector prefer stable by default and allow specifying a PHP version that must be matched, fixes #4318

This commit is contained in:
Jordi Boggiano 2015-10-27 14:43:04 +00:00
parent 4f934d9282
commit 507415e404
5 changed files with 107 additions and 20 deletions

View file

@ -321,7 +321,7 @@ EOT
return $this->repos;
}
protected function determineRequirements(InputInterface $input, OutputInterface $output, $requires = array())
protected function determineRequirements(InputInterface $input, OutputInterface $output, $requires = array(), $phpVersion = null)
{
if ($requires) {
$requires = $this->normalizeRequirements($requires);
@ -331,7 +331,7 @@ EOT
foreach ($requires as $requirement) {
if (!isset($requirement['version'])) {
// determine the best version automatically
$version = $this->findBestVersionForPackage($input, $requirement['name']);
$version = $this->findBestVersionForPackage($input, $requirement['name'], $phpVersion);
$requirement['version'] = $version;
$io->writeError(sprintf(
@ -426,7 +426,7 @@ EOT
);
if (false === $constraint) {
$constraint = $this->findBestVersionForPackage($input, $package);
$constraint = $this->findBestVersionForPackage($input, $package, $phpVersion);
$io->writeError(sprintf(
'Using version <info>%s</info> for <info>%s</info>',
@ -591,14 +591,15 @@ EOT
*
* @param InputInterface $input
* @param string $name
* @param string $phpVersion
* @throws \InvalidArgumentException
* @return string
*/
private function findBestVersionForPackage(InputInterface $input, $name)
private function findBestVersionForPackage(InputInterface $input, $name, $phpVersion)
{
// find the latest version allowed in this pool
$versionSelector = new VersionSelector($this->getPool($input));
$package = $versionSelector->findBestCandidate($name);
$package = $versionSelector->findBestCandidate($name, null, $phpVersion);
if (!$package) {
throw new \InvalidArgumentException(sprintf(

View file

@ -96,12 +96,18 @@ EOT
$composer = $this->getComposer();
$repos = $composer->getRepositoryManager()->getRepositories();
$platformOverrides = $composer->getConfig()->get('platform') ?: array();
// initialize $this->repos as it is used by the parent InitCommand
$this->repos = new CompositeRepository(array_merge(
array(new PlatformRepository),
array(new PlatformRepository(array(), $platformOverrides)),
$repos
));
$requirements = $this->determineRequirements($input, $output, $input->getArgument('packages'));
$phpPackages = $this->repos->findPackages('php');
$phpPackage = reset($phpPackages);
$phpVersion = $phpPackage->getVersion();
unset($phpPackage, $phpPackages);
$requirements = $this->determineRequirements($input, $output, $input->getArgument('packages'), $phpVersion);
$requireKey = $input->getOption('dev') ? 'require-dev' : 'require';
$removeKey = $input->getOption('dev') ? 'require' : 'require-dev';

View file

@ -223,6 +223,11 @@ abstract class BasePackage implements PackageInterface
return $this->getPrettyVersion() . ' ' . $this->getSourceReference();
}
public function getStabilityPriority()
{
return self::$stabilities[$this->getStability()];
}
public function __clone()
{
$this->repository = null;

View file

@ -17,6 +17,8 @@ use Composer\Package\PackageInterface;
use Composer\Package\Loader\ArrayLoader;
use Composer\Package\Dumper\ArrayDumper;
use Composer\Semver\VersionParser as SemverVersionParser;
use Composer\Semver\Semver;
use Composer\Semver\Constraint\Constraint;
/**
* Selects the best possible version for a package
@ -41,13 +43,22 @@ class VersionSelector
*
* @param string $packageName
* @param string $targetPackageVersion
* @param string $targetPhpVersion
* @return PackageInterface|bool
*/
public function findBestCandidate($packageName, $targetPackageVersion = null)
public function findBestCandidate($packageName, $targetPackageVersion = null, $targetPhpVersion = null, $preferStable = true)
{
$constraint = $targetPackageVersion ? $this->getParser()->parseConstraints($targetPackageVersion) : null;
$candidates = $this->pool->whatProvides(strtolower($packageName), $constraint, true);
if ($targetPhpVersion) {
$phpConstraint = new Constraint('==', $this->getParser()->normalize($targetPhpVersion));
$candidates = array_filter($candidates, function ($pkg) use ($phpConstraint) {
$reqs = $pkg->getRequires();
return !isset($reqs['php']) || $reqs['php']->getConstraint()->matches($phpConstraint);
});
}
if (!$candidates) {
return false;
}
@ -55,6 +66,9 @@ class VersionSelector
// select highest version if we have many
$package = reset($candidates);
foreach ($candidates as $candidate) {
if ($preferStable && $package->getStabilityPriority() < $candidate->getStabilityPriority()) {
continue;
}
if (version_compare($package->getVersion(), $candidate->getVersion(), '<')) {
$package = $candidate;
}