$msg = "\n - This package requires ".$packageName.$this->constraintToText($constraint).' but ';
if (defined('HHVM_VERSION') || (count($available) && $packageName === 'hhvm')) {
return $msg . 'your HHVM version does not satisfy that requirement.';
}
if ($packageName === 'hhvm') {
return $msg . 'you are running this with PHP and not HHVM.';
}
return $msg . 'your PHP version ('. $version .') does not satisfy that requirement.';
}
// handle php extensions
if (0 === stripos($packageName, 'ext-')) {
if (false !== strpos($packageName, ' ')) {
return "\n - The requested PHP extension ".$packageName.' should be required as '.str_replace(' ', '-', $packageName).'.';
}
$ext = substr($packageName, 4);
$error = extension_loaded($ext) ? 'has the wrong version ('.(phpversion($ext) ?: '0').') installed' : 'is missing from your system';
return "\n - The requested PHP extension ".$packageName.$this->constraintToText($constraint).' '.$error.'. Install or enable PHP\'s '.$ext.' extension.';
}
// handle linked libs
if (0 === stripos($packageName, 'lib-')) {
if (strtolower($packageName) === 'lib-icu') {
$error = extension_loaded('intl') ? 'has the wrong version installed, try upgrading the intl extension.' : 'is missing from your system, make sure the intl extension is loaded.';
return "\n - The requested linked library ".$packageName.$this->constraintToText($constraint).' '.$error;
}
return "\n - The requested linked library ".$packageName.$this->constraintToText($constraint).' has the wrong version installed or is missing from your system, make sure to load the extension providing it.';
}
if (!preg_match('{^[A-Za-z0-9_./-]+$}', $packageName)) {
return "\n - The requested package ".$packageName.' could not be found, it looks like its name is invalid, "'.$illegalChars.'" is not allowed in package names.';
}
// TODO: The pool doesn't know about these anymore, it has to ask the RepositorySet
return "\n - The requested package ".$packageName.$this->constraintToText($constraint).' is satisfiable by '.$this->getPackageList($providers).' but these conflict with your requirements or minimum-stability.';
}*/
// TODO: The pool doesn't know about these anymore, it has to ask the RepositorySet
return "\n - The requested package ".$packageName.$this->constraintToText($constraint).' exists as '.$this->getPackageList($providers).' but these are rejected by your constraint.';
}*/
return "\n - The requested package ".$packageName.' could not be found in any version, there may be a typo in the package name.';
$msg = "- Root composer.json requires ".$packageName.self::constraintToText($constraint).' but ';
if (defined('HHVM_VERSION') || (count($available) && $packageName === 'hhvm')) {
return array($msg, 'your HHVM version does not satisfy that requirement.');
}
if ($packageName === 'hhvm') {
return array($msg, 'you are running this with PHP and not HHVM.');
}
return array($msg, 'your '.$packageName.' version ('. $version .') does not satisfy that requirement.');
}
// handle php extensions
if (0 === stripos($packageName, 'ext-')) {
if (false !== strpos($packageName, ' ')) {
return array('- ', "PHP extension ".$packageName.' should be required as '.str_replace(' ', '-', $packageName).'.');
}
$ext = substr($packageName, 4);
$error = extension_loaded($ext) ? 'it has the wrong version ('.(phpversion($ext) ?: '0').') installed' : 'it is missing from your system';
return array("- Root composer.json requires PHP extension ".$packageName.self::constraintToText($constraint).' but ', $error.'. Install or enable PHP\'s '.$ext.' extension.');
}
// handle linked libs
if (0 === stripos($packageName, 'lib-')) {
if (strtolower($packageName) === 'lib-icu') {
$error = extension_loaded('intl') ? 'it has the wrong version installed, try upgrading the intl extension.' : 'it is missing from your system, make sure the intl extension is loaded.';
return array("- Root composer.json requires linked library ".$packageName.self::constraintToText($constraint).' but ', 'it has the wrong version installed or is missing from your system, make sure to load the extension providing it.');
}
$fixedPackage = null;
foreach ($request->getFixedPackages() as $package) {
if ($package->getName() === $packageName) {
$fixedPackage = $package;
if ($pool->isUnacceptableFixedPackage($package)) {
return array("- ", $package->getPrettyName().' is fixed to '.$package->getPrettyVersion().' (lock file version) by a partial update but that version is rejected by your minimum-stability. Make sure you whitelist it for update.');
}
break;
}
}
// first check if the actual requested package is found in normal conditions
// if so it must mean it is rejected by another constraint than the one given here
if ($packages = $repositorySet->findPackages($packageName, $constraint)) {
$rootReqs = $repositorySet->getRootRequires();
if (isset($rootReqs[$packageName])) {
$filtered = array_filter($packages, function ($p) use ($rootReqs, $packageName) {
return array("- Root composer.json requires $packageName".self::constraintToText($constraint) . ', ', 'found '.self::getPackageList($packages).' but the package is fixed to '.$fixedPackage->getPrettyVersion().' (lock file version) by a partial update and that version does not match. Make sure you whitelist it for update.');
}
}
return array("- Root composer.json requires $packageName".self::constraintToText($constraint) . ', ', 'found '.self::getPackageList($packages).' but '.(self::hasMultipleNames($packages) ? 'these conflict' : 'it conflicts').' with another require.');
}
// check if the package is found when bypassing stability checks
if ($packages = $repositorySet->findPackages($packageName, $constraint, RepositorySet::ALLOW_UNACCEPTABLE_STABILITIES)) {
return array("- Root composer.json requires $packageName".self::constraintToText($constraint) . ', ', 'found '.self::getPackageList($packages).' but '.(self::hasMultipleNames($packages) ? 'these do' : 'it does').' not match your minimum-stability.');
}
// check if the package is found when bypassing the constraint check
if ($packages = $repositorySet->findPackages($packageName, null)) {
// we must first verify if a valid package would be found in a lower priority repository
if ($allReposPackages = $repositorySet->findPackages($packageName, $constraint, RepositorySet::ALLOW_SHADOWED_REPOSITORIES)) {
if ($nextRepo === null || $nextRepo === $package->getRepository()) {
$nextRepoPackages[] = $package;
$nextRepo = $package->getRepository();
} else {
break;
}
}
return array("- Root composer.json requires $packageName".self::constraintToText($constraint) . ', it is ', 'satisfiable by '.self::getPackageList($nextRepoPackages).' from '.$nextRepo->getRepoName().' but '.self::getPackageList($higherRepoPackages).' from '.reset($higherRepoPackages)->getRepository()->getRepoName().' has higher repository priority. The packages with higher priority do not match your constraint and are therefore not installable.');
}
return array("- Root composer.json requires $packageName".self::constraintToText($constraint) . ', ', 'found '.self::getPackageList($packages).' but '.(self::hasMultipleNames($packages) ? 'these do' : 'it does').' not match your constraint.');
}
if (!preg_match('{^[A-Za-z0-9_./-]+$}', $packageName)) {
return array("- Root composer.json requires $packageName, it ", 'could not be found, it looks like its name is invalid, "'.$illegalChars.'" is not allowed in package names.');
}
return array("- Root composer.json requires $packageName, it ", "could not be found in any version, there may be a typo in the package name.");
}
/**
* @internal
*/
public static function getPackageList(array $packages)
{
$prepared = array();
foreach ($packages as $package) {
@ -207,13 +270,27 @@ class Problem
return implode(', ', $prepared);
}
private static function hasMultipleNames(array $packages)
{
$name = null;
foreach ($packages as $package) {
if ($name === null || $name === $package->getName()) {
$name = $package->getName();
} else {
return true;
}
}
return false;
}
/**
* Turns a constraint into text usable in a sentence describing a request
return $text . ' -> your HHVM version ('.$package->getPrettyVersion().') does not satisfy that requirement.';
} else {
return $text . ' -> you are running this with PHP and not HHVM.';
}
}
if (!($package instanceof CompletePackage)) {
return $text . ' -> your PHP version ('.phpversion().') does not satisfy that requirement.';
}
$extra = $package->getExtra();
if (!empty($extra['config.platform'])) {
$text .= ' -> your PHP version ('.phpversion().') overridden by "config.platform.php" version ('.$package->getPrettyVersion().') does not satisfy that requirement.';
} else {
$text .= ' -> your PHP version ('.$package->getPrettyVersion().') does not satisfy that requirement.';
}
return $text;
}
if (0 === strpos($targetName, 'ext-')) {
// handle php extensions
$ext = substr($targetName, 4);
$error = extension_loaded($ext) ? 'has the wrong version ('.(phpversion($ext) ?: '0').') installed' : 'is missing from your system';
return $text . ' -> the requested linked library '.$lib.' has the wrong version installed or is missing from your system, make sure to have the extension providing it.';
}
// TODO: The pool doesn't know about these anymore, it has to ask the RepositorySet
return $text . ' -> satisfiable by ' . $this->formatPackagesUnique($pool, $providers) .' but these conflict with your requirements or minimum-stability.';
}*/
return $text . ' -> no matching package found.';
return $text . ' -> ' . $reason[1];
}
return $text;
@ -249,7 +200,7 @@ abstract class Rule
$learnedString = '(learned rule, ';
if (isset($learnedPool[$this->reasonData])) {
foreach ($learnedPool[$this->reasonData] as $learnedRule) {
@ -29,6 +29,19 @@ use Composer\Package\Version\StabilityFilter;
*/
class RepositorySet
{
/**
* Packages which replace/provide the given name might be returned as well even if they do not match the name exactly
*/
const ALLOW_PROVIDERS_REPLACERS = 1;
/**
* Packages are returned even though their stability does not match the required stability
*/
const ALLOW_UNACCEPTABLE_STABILITIES = 2;
/**
* Packages will be looked up in all repositories, even after they have been found in a higher prio one
*/
const ALLOW_SHADOWED_REPOSITORIES = 4;
/** @var array */
private $rootAliases;
/** @var array */
@ -39,7 +52,7 @@ class RepositorySet
private $acceptableStabilities;
private $stabilityFlags;
protected $rootRequires;
private $rootRequires;
/** @var Pool */
private $pool;
@ -64,6 +77,11 @@ class RepositorySet
}
}
public function getRootRequires()
{
return $this->rootRequires;
}
/**
* Adds a repository to this repository set
*
@ -96,15 +114,32 @@ class RepositorySet
*
* @param string $name
* @param ConstraintInterface|null $constraint
* @param bool $exactMatch if set to false, packages which replace/provide the given name might be returned as well even if they do not match the name exactly
* @param bool $ignoreStability if set to true, packages are returned even though their stability does not match the required stability
* @param int $flags any of the ALLOW_* constants from this class to tweak what is returned
* @return array
*/
public function findPackages($name, ConstraintInterface $constraint = null, $exactMatch = true, $ignoreStability = false)
public function findPackages($name, ConstraintInterface $constraint = null, $flags = 0)
$this->assertContains('REQUEST : No package found to satisfy root composer.json require foo/bar', $ruleSet->getPrettyString($pool));
$this->assertContains('REQUEST : No package found to satisfy root composer.json require foo/bar', $ruleSet->getPrettyString($repositorySetMock, $requestMock));
@ -82,7 +82,7 @@ class SolverTest extends TestCase
$problems = $e->getProblems();
$this->assertCount(1, $problems);
$this->assertEquals(2, $e->getCode());
$this->assertEquals("\n - The requested package b could not be found in any version, there may be a typo in the package name.", $problems[0]->getPrettyString());
$this->assertEquals("\n - Root composer.json requires b, it could not be found in any version, there may be a typo in the package name.", $problems[0]->getPrettyString($this->repoSet, $this->request));
}
}
@ -682,13 +682,7 @@ class SolverTest extends TestCase
$msg = "\n";
$msg .= " Problem 1\n";
$msg .= " - Root composer.json requires a -> satisfiable by A[1.0].\n";
$msg .= " - A 1.0 requires b >= 2.0 -> no matching package found.\n\n";
$msg .= "Potential causes:\n";
$msg .= " - A typo in the package name\n";
$msg .= " - The package is not available in a stable-enough version according to your minimum-stability setting\n";
$msg .= " see <https://getcomposer.org/doc/04-schema.md#minimum-stability> for more details.\n";
$msg .= " - It's a private package and you forgot to add a custom repository to find it\n\n";
$msg .= "Read <https://getcomposer.org/doc/articles/troubleshooting.md> for further common problems.";
$msg .= " - A 1.0 requires b >= 2.0 -> found B[1.0] but it does not match your constraint.\n";
$this->assertEquals($msg, $e->getMessage());
}
}
@ -895,7 +889,7 @@ class SolverTest extends TestCase
protected function createSolver()
{
$this->solver = new Solver($this->policy, $this->repoSet->createPool($this->request), new NullIO());
$this->solver = new Solver($this->policy, $this->repoSet->createPool($this->request), new NullIO(), $this->repoSet);
}
protected function checkSolverResult(array $expected)
Partial update from lock file should apply lock file and downgrade unstable packages even if not whitelisted
Partial update from lock file should apply lock file and if an unstable package is not allowed anymore by latest composer.json it should fail
--COMPOSER--
{
"repositories": [
@ -59,12 +59,4 @@ Updating dependencies
Your requirements could not be resolved to an installable set of packages.
Problem 1
- The requested package b/unstable could not be found in any version, there may be a typo in the package name.
Potential causes:
- A typo in the package name
- The package is not available in a stable-enough version according to your minimum-stability setting
see <https://getcomposer.org/doc/04-schema.md#minimum-stability> for more details.
- It's a private package and you forgot to add a custom repository to find it
Read <https://getcomposer.org/doc/articles/troubleshooting.md> for further common problems.
- b/unstable is fixed to 1.1.0-alpha (lock file version) by a partial update but that version is rejected by your minimum-stability. Make sure you whitelist it for update.
Your requirements could not be resolved to an installable set of packages.
Problem 1
- The requested package foo/a could not be found in any version, there may be a typo in the package name.
- Root composer.json requires foo/a 2.*, it is satisfiable by foo/a[2.0.0] from package repo (defining 1 package) but foo/a[1.0.0] from package repo (defining 1 package) has higher repository priority. The packages with higher priority do not match your constraint and are therefore not installable.
Potential causes:
- A typo in the package name
- The package is not available in a stable-enough version according to your minimum-stability setting
see <https://getcomposer.org/doc/04-schema.md#minimum-stability> for more details.
- It's a private package and you forgot to add a custom repository to find it
Read <https://getcomposer.org/doc/articles/troubleshooting.md> for further common problems.
Your requirements could not be resolved to an installable set of packages.
Problem 1
- The requested package unstable/package could not be found in any version, there may be a typo in the package name.
- Root composer.json requires unstable/package 2.*, found unstable/package[2.0.0-alpha] but it does not match your minimum-stability.
Problem 2
- The requested package bogus/pkg could not be found in any version, there may be a typo in the package name.
- Root composer.json requires non-existent/pkg, it could not be found in any version, there may be a typo in the package name.
Problem 3
- The requested package stable-requiree-excluded/pkg could not be found in any version, there may be a typo in the package name.
- Root composer.json requires stable-requiree-excluded/pkg 1.0.1, found stable-requiree-excluded/pkg[1.0.1] but the package is fixed to 1.0.0 (lock file version) by a partial update and that version does not match. Make sure you whitelist it for update.
Problem 4
- Root composer.json requires linked library lib-xml 1002.* but it has the wrong version installed or is missing from your system, make sure to load the extension providing it.
Problem 5
- Root composer.json requires linked library lib-icu 1001.* but it has the wrong version installed, try upgrading the intl extension.
Problem 6
- Root composer.json requires PHP extension ext-xml 1002.* but it has the wrong version (%s) installed. Install or enable PHP's xml extension.
Problem 7
- Root composer.json requires php 1 but your php version (%s) does not satisfy that requirement.
Problem 8
- Root composer.json requires package/found 2.* -> satisfiable by package/found[2.0.0].
- package/found 2.0.0 requires unstable/package2 2.* -> found unstable/package2[2.0.0-alpha] but it does not match your minimum-stability.
Problem 9
- Root composer.json requires package/found2 2.* -> satisfiable by package/found2[2.0.0].
- package/found2 2.0.0 requires invalid/💩package * -> could not be found, it looks like its name is invalid, "💩" is not allowed in package names.
Problem 10
- Root composer.json requires package/found3 2.* -> satisfiable by package/found3[2.0.0].
- package/found3 2.0.0 requires unstable/package2 2.* -> found unstable/package2[2.0.0-alpha] but it does not match your minimum-stability.
Problem 11
- Root composer.json requires package/found4 2.* -> satisfiable by package/found4[2.0.0].
- package/found4 2.0.0 requires non-existent/pkg2 1.* -> could not be found in any version, there may be a typo in the package name.
Problem 12
- Root composer.json requires package/found6 2.* -> satisfiable by package/found6[2.0.0].
- package/found6 2.0.0 requires stable-requiree-excluded/pkg2 1.0.1 -> found stable-requiree-excluded/pkg2[1.0.0] but it does not match your constraint.
Problem 13
- Root composer.json requires package/found7 2.* -> satisfiable by package/found7[2.0.0].
- package/found7 2.0.0 requires php-64bit 1.0.1 -> your php-64bit version (%s) does not satisfy that requirement.
Problem 14
- Root composer.json requires requirer/pkg 1.* -> satisfiable by requirer/pkg[1.0.0].