1
0
Fork 0

Implement getProviders on reposet for all repo types and add replacers

This way errors during require dev extraction make more sense
pull/8684/head
Nils Adermann 2020-03-11 17:38:16 +01:00
parent ddb1e79bef
commit 1f467046d7
5 changed files with 64 additions and 9 deletions

View File

@ -248,7 +248,7 @@ class Problem
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.');
}
if ($providers = $repositorySet->getProviders($packageName)) {
if ($providers = $repositorySet->getProvidersAndReplacers($packageName)) {
$maxProviders = 20;
$providersStr = implode(array_map(function ($p) {
return " - ${p['name']} ".substr($p['description'], 0, 100)."\n";

View File

@ -31,7 +31,7 @@ class SolverProblemsException extends \RuntimeException
parent::__construct('Failed resolving dependencies with '.count($problems).' problems, call getPrettyString to get formatted details', 2);
}
public function getPrettyString(RepositorySet $repositorySet, Request $request, Pool $pool)
public function getPrettyString(RepositorySet $repositorySet, Request $request, Pool $pool, $isDevExtraction = false)
{
$installedMap = $request->getPresentMap(true);
$text = "\n";
@ -44,7 +44,7 @@ class SolverProblemsException extends \RuntimeException
}
}
if (strpos($text, 'could not be found') || strpos($text, 'no matching package found')) {
if (!$isDevExtraction && (strpos($text, 'could not be found') || strpos($text, 'no matching package found'))) {
$text .= "\nPotential causes:\n - A typo in the package name\n - The package is not available in a stable-enough version according to your minimum-stability setting\n see <https://getcomposer.org/doc/04-schema.md#minimum-stability> for more details.\n - It's a private package and you forgot to add a custom repository to find it\n\nRead <https://getcomposer.org/doc/articles/troubleshooting.md> for further common problems.";
}

View File

@ -573,8 +573,9 @@ class Installer
$solver = null;
} catch (SolverProblemsException $e) {
$this->io->writeError('<error>Unable to find a compatible set of packages based on your non-dev requirements alone.</error>', true, IOInterface::QUIET);
$this->io->writeError('Your requirements can be successfully resolved when require-dev packages are present.');
$this->io->writeError($e->getPrettyString($repositorySet, $request, $pool));
$this->io->writeError('Your requirements can be resolved successfully when require-dev packages are present.');
$this->io->writeError('You may need to move packages from require-dev or some of their dependencies to require.');
$this->io->writeError($e->getPrettyString($repositorySet, $request, $pool, true));
return max(1, $e->getCode());
}

View File

@ -163,17 +163,31 @@ class RepositorySet
return $candidates;
}
public function getProviders($packageName)
public function getProvidersAndReplacers($packageName)
{
$providers = array();
foreach ($this->repositories as $repository) {
if ($repository instanceof ComposerRepository) {
if ($providers = $repository->getProviders($packageName)) {
return $providers;
if ($repoProviders = $repository->getProviders($packageName)) {
$providers = array_merge($providers, $repoProviders);
}
} else {
foreach ($repository->getPackages() as $candidate) {
foreach (array_merge($candidate->getProvides(), $candidate->getReplaces()) as $link) {
if ($packageName === $link->getTarget()) {
$providers[] = array(
'name' => $candidate->getName(),
'description' => $candidate->getDescription(),
'type' => $candidate->getType(),
);
continue 2;
}
}
}
}
}
return array();
return $providers;
}
public function isPackageAcceptable($names, $stability)

View File

@ -0,0 +1,40 @@
--TEST--
Test that an appropriate error is thrown if a requirement is only satisfied by a package provided by a dependency of a dev requirement.
--COMPOSER--
{
"repositories": [
{
"type": "package",
"package": [
{"name": "provider/requirer", "version": "1.0.0", "type": "metapackage", "require": {"b/b": "1.0.0"}},
{"name": "b/b", "version": "1.0.0", "type": "metapackage", "provide": {"provided/pkg": "1.0.0"}}
]
}
],
"require": {
"provided/pkg": "1.0.0"
},
"require-dev": {
"provider/requirer": "1.0.0"
}
}
--RUN--
update
--EXPECT-EXIT-CODE--
2
--EXPECT-OUTPUT--
Loading composer repositories with package information
Updating dependencies
Unable to find a compatible set of packages based on your non-dev requirements alone.
Your requirements can be resolved successfully when require-dev packages are present.
You may need to move packages from require-dev or some of their dependencies to require.
Problem 1
- Root composer.json requires provided/pkg 1.0.0, it could not be found in any version, but the following packages provide it:
- b/b
Consider requiring one of these to satisfy the provided/pkg requirement.
--EXPECT--