Merge pull request #8684 from naderman/dev-require-errors
Handle dev extraction exit codes instead of completing broken lock with errorspull/8557/head
commit
d09daa8d5a
|
@ -251,12 +251,13 @@ class Problem
|
||||||
if ($providers = $repositorySet->getProviders($packageName)) {
|
if ($providers = $repositorySet->getProviders($packageName)) {
|
||||||
$maxProviders = 20;
|
$maxProviders = 20;
|
||||||
$providersStr = implode(array_map(function ($p) {
|
$providersStr = implode(array_map(function ($p) {
|
||||||
return " - ${p['name']} ".substr($p['description'], 0, 100)."\n";
|
$description = $p['description'] ? ' '.substr($p['description'], 0, 100) : '';
|
||||||
|
return " - ${p['name']}".$description."\n";
|
||||||
}, count($providers) > $maxProviders+1 ? array_slice($providers, 0, $maxProviders) : $providers));
|
}, count($providers) > $maxProviders+1 ? array_slice($providers, 0, $maxProviders) : $providers));
|
||||||
if (count($providers) > $maxProviders+1) {
|
if (count($providers) > $maxProviders+1) {
|
||||||
$providersStr .= ' ... and '.(count($providers)-$maxProviders).' more.'."\n";
|
$providersStr .= ' ... and '.(count($providers)-$maxProviders).' more.'."\n";
|
||||||
}
|
}
|
||||||
return array("- Root composer.json requires $packageName".self::constraintToText($constraint).", it ", "could not be found in any version, but the following packages provide it: \n".$providersStr." Consider requiring one of these to satisfy the $packageName requirement.");
|
return array("- Root composer.json requires $packageName".self::constraintToText($constraint).", it ", "could not be found in any version, but the following packages provide it:\n".$providersStr." Consider requiring one of these to satisfy the $packageName requirement.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return array("- Root composer.json requires $packageName, it ", "could not be found in any version, there may be a typo in the package name.");
|
return array("- Root composer.json requires $packageName, it ", "could not be found in any version, there may be a typo in the package name.");
|
||||||
|
|
|
@ -31,7 +31,7 @@ class SolverProblemsException extends \RuntimeException
|
||||||
parent::__construct('Failed resolving dependencies with '.count($problems).' problems, call getPrettyString to get formatted details', 2);
|
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);
|
$installedMap = $request->getPresentMap(true);
|
||||||
$text = "\n";
|
$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.";
|
$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.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -429,7 +429,10 @@ class Installer
|
||||||
$this->io->writeError('Nothing to modify in lock file');
|
$this->io->writeError('Nothing to modify in lock file');
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->extractDevPackages($lockTransaction, $platformRepo, $aliases, $policy);
|
$exitCode = $this->extractDevPackages($lockTransaction, $platformRepo, $aliases, $policy);
|
||||||
|
if ($exitCode !== 0) {
|
||||||
|
return $exitCode;
|
||||||
|
}
|
||||||
|
|
||||||
// write lock
|
// write lock
|
||||||
$platformReqs = $this->extractPlatformRequirements($this->package->getRequires());
|
$platformReqs = $this->extractPlatformRequirements($this->package->getRequires());
|
||||||
|
@ -542,7 +545,7 @@ class Installer
|
||||||
protected function extractDevPackages(LockTransaction $lockTransaction, $platformRepo, $aliases, $policy)
|
protected function extractDevPackages(LockTransaction $lockTransaction, $platformRepo, $aliases, $policy)
|
||||||
{
|
{
|
||||||
if (!$this->package->getDevRequires()) {
|
if (!$this->package->getDevRequires()) {
|
||||||
return array();
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
$resultRepo = new ArrayRepository(array());
|
$resultRepo = new ArrayRepository(array());
|
||||||
|
@ -562,7 +565,7 @@ class Installer
|
||||||
$request->requireName($link->getTarget(), $link->getConstraint());
|
$request->requireName($link->getTarget(), $link->getConstraint());
|
||||||
}
|
}
|
||||||
|
|
||||||
$pool = $repositorySet->createPool($request, $this->eventDispatcher);
|
$pool = $repositorySet->createPoolWithAllPackages();
|
||||||
|
|
||||||
$solver = new Solver($policy, $pool, $this->io, $repositorySet);
|
$solver = new Solver($policy, $pool, $this->io, $repositorySet);
|
||||||
try {
|
try {
|
||||||
|
@ -570,12 +573,16 @@ class Installer
|
||||||
$solver = null;
|
$solver = null;
|
||||||
} catch (SolverProblemsException $e) {
|
} 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('<error>Unable to find a compatible set of packages based on your non-dev requirements alone.</error>', true, IOInterface::QUIET);
|
||||||
$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());
|
return max(1, $e->getCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
$lockTransaction->setNonDevPackages($nonDevLockTransaction);
|
$lockTransaction->setNonDevPackages($nonDevLockTransaction);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -422,11 +422,13 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
|
||||||
public function getProviders($packageName)
|
public function getProviders($packageName)
|
||||||
{
|
{
|
||||||
if (!$this->providersApiUrl) {
|
if (!$this->providersApiUrl) {
|
||||||
|
// TODO should this return the info based on getPackages in other cases?
|
||||||
return array();
|
return array();
|
||||||
}
|
}
|
||||||
|
|
||||||
$result = $this->httpDownloader->get(str_replace('%package%', $packageName, $this->providersApiUrl), $this->options)->decodeJson();
|
$result = $this->httpDownloader->get(str_replace('%package%', $packageName, $this->providersApiUrl), $this->options)->decodeJson();
|
||||||
|
|
||||||
|
// TODO filter packageName out here?
|
||||||
return $result['providers'];
|
return $result['providers'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -165,15 +165,29 @@ class RepositorySet
|
||||||
|
|
||||||
public function getProviders($packageName)
|
public function getProviders($packageName)
|
||||||
{
|
{
|
||||||
|
$providers = array();
|
||||||
foreach ($this->repositories as $repository) {
|
foreach ($this->repositories as $repository) {
|
||||||
if ($repository instanceof ComposerRepository) {
|
if ($repository instanceof ComposerRepository) {
|
||||||
if ($providers = $repository->getProviders($packageName)) {
|
if ($repoProviders = $repository->getProviders($packageName)) {
|
||||||
return $providers;
|
$providers = array_merge($providers, $repoProviders);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
foreach ($repository->getPackages() as $candidate) {
|
||||||
|
foreach ($candidate->getProvides() 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)
|
public function isPackageAcceptable($names, $stability)
|
||||||
|
@ -201,6 +215,28 @@ class RepositorySet
|
||||||
return $poolBuilder->buildPool($this->repositories, $request);
|
return $poolBuilder->buildPool($this->repositories, $request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a pool for dependency resolution from the packages in this repository set.
|
||||||
|
*
|
||||||
|
* @return Pool
|
||||||
|
*/
|
||||||
|
public function createPoolWithAllPackages()
|
||||||
|
{
|
||||||
|
foreach ($this->repositories as $repo) {
|
||||||
|
if (($repo instanceof InstalledRepositoryInterface || $repo instanceof InstalledRepository) && !$this->allowInstalledRepositories) {
|
||||||
|
throw new \LogicException('The pool can not accept packages from an installed repository');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->locked = true;
|
||||||
|
|
||||||
|
$packages = array();
|
||||||
|
foreach ($this->repositories as $repository) {
|
||||||
|
$packages = array_merge($packages, $repository->getPackages());
|
||||||
|
}
|
||||||
|
return new Pool($packages);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO unify this with above in some simpler version without "request"?
|
// TODO unify this with above in some simpler version without "request"?
|
||||||
public function createPoolForPackage($packageName, LockArrayRepository $lockedRepo = null)
|
public function createPoolForPackage($packageName, LockArrayRepository $lockedRepo = null)
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
--TEST--
|
||||||
|
Test that a requirement can be satisfied by a providing package required in require-dev.
|
||||||
|
--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 --no-dev
|
||||||
|
|
||||||
|
--EXPECT-LOCK--
|
||||||
|
{
|
||||||
|
"packages": [
|
||||||
|
{
|
||||||
|
"name": "b/b",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"type": "metapackage",
|
||||||
|
"provide": {"provided/pkg": "1.0.0"}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"packages-dev": [
|
||||||
|
{
|
||||||
|
"name": "provider/requirer",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"type": "metapackage",
|
||||||
|
"require": {"b/b": "1.0.0"}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"aliases": [],
|
||||||
|
"minimum-stability": "stable",
|
||||||
|
"stability-flags": [],
|
||||||
|
"prefer-stable": false,
|
||||||
|
"prefer-lowest": false,
|
||||||
|
"platform": [],
|
||||||
|
"platform-dev": []
|
||||||
|
}
|
||||||
|
--EXPECT--
|
||||||
|
Installing b/b (1.0.0)
|
Loading…
Reference in New Issue