Merge pull request #321 from naderman/error-reporting
Basic error reporting for solver problemspull/325/merge
commit
c97a33577b
|
@ -1035,6 +1035,10 @@ class Solver
|
|||
//findrecommendedsuggested(solv);
|
||||
//solver_prepare_solutions(solv);
|
||||
|
||||
if ($this->problems) {
|
||||
throw new SolverProblemsException($this->problems, $this->learnedPool);
|
||||
}
|
||||
|
||||
return $this->createTransaction();
|
||||
}
|
||||
|
||||
|
@ -1113,6 +1117,8 @@ class Solver
|
|||
|
||||
protected function addDecision(Literal $l, $level)
|
||||
{
|
||||
assert($this->decisionMap[$l->getPackageId()] == 0);
|
||||
|
||||
if ($l->isWanted()) {
|
||||
$this->decisionMap[$l->getPackageId()] = $level;
|
||||
} else {
|
||||
|
@ -1123,6 +1129,9 @@ class Solver
|
|||
protected function addDecisionId($literalId, $level)
|
||||
{
|
||||
$packageId = abs($literalId);
|
||||
|
||||
assert($this->decisionMap[$packageId] == 0);
|
||||
|
||||
if ($literalId > 0) {
|
||||
$this->decisionMap[$packageId] = $level;
|
||||
} else {
|
||||
|
@ -1165,8 +1174,8 @@ class Solver
|
|||
{
|
||||
$packageId = abs($literalId);
|
||||
return (
|
||||
$this->decisionMap[$packageId] > 0 && !($literalId < 0) ||
|
||||
$this->decisionMap[$packageId] < 0 && $literalId > 0
|
||||
($this->decisionMap[$packageId] > 0 && $literalId < 0) ||
|
||||
($this->decisionMap[$packageId] < 0 && $literalId > 0)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Composer.
|
||||
*
|
||||
* (c) Nils Adermann <naderman@naderman.de>
|
||||
* Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Composer\DependencyResolver;
|
||||
|
||||
/**
|
||||
* @author Nils Adermann <naderman@naderman.de>
|
||||
*/
|
||||
class SolverProblemsException extends \RuntimeException
|
||||
{
|
||||
protected $problems;
|
||||
|
||||
public function __construct(array $problems, array $learnedPool)
|
||||
{
|
||||
$message = '';
|
||||
foreach ($problems as $i => $problem) {
|
||||
$message .= '[';
|
||||
foreach ($problem as $why) {
|
||||
|
||||
if (is_int($why) && isset($learnedPool[$why])) {
|
||||
$rules = $learnedPool[$why];
|
||||
} else {
|
||||
$rules = $why;
|
||||
}
|
||||
|
||||
if (isset($rules['packages'])) {
|
||||
$message .= $this->jobToText($rules);
|
||||
} else {
|
||||
$message .= '(';
|
||||
foreach ($rules as $rule) {
|
||||
if ($rule instanceof Rule) {
|
||||
if ($rule->getType() == RuleSet::TYPE_LEARNED) {
|
||||
$message .= 'learned: ';
|
||||
}
|
||||
$message .= $rule . ', ';
|
||||
} else {
|
||||
$message .= 'String(' . $rule . '), ';
|
||||
}
|
||||
}
|
||||
$message .= ')';
|
||||
}
|
||||
$message .= ', ';
|
||||
}
|
||||
$message .= "]\n";
|
||||
}
|
||||
|
||||
parent::__construct($message);
|
||||
}
|
||||
|
||||
public function jobToText($job)
|
||||
{
|
||||
//$output = serialize($job);
|
||||
$output = 'Job(cmd='.$job['cmd'].', target='.$job['packageName'].', packages=['.implode(', ', $job['packages']).'])';
|
||||
return $output;
|
||||
}
|
||||
}
|
|
@ -19,6 +19,7 @@ use Composer\DependencyResolver\DefaultPolicy;
|
|||
use Composer\DependencyResolver\Pool;
|
||||
use Composer\DependencyResolver\Request;
|
||||
use Composer\DependencyResolver\Solver;
|
||||
use Composer\DependencyResolver\SolverProblemsException;
|
||||
use Composer\Package\Link;
|
||||
use Composer\Package\LinkConstraint\VersionConstraint;
|
||||
use Composer\Test\TestCase;
|
||||
|
@ -484,6 +485,49 @@ class SolverTest extends TestCase
|
|||
));
|
||||
}
|
||||
|
||||
public function testConflictResultEmpty()
|
||||
{
|
||||
$this->repo->addPackage($packageA = $this->getPackage('A', '1.0'));
|
||||
$this->repo->addPackage($packageB = $this->getPackage('B', '1.0'));;
|
||||
|
||||
$packageA->setConflicts(array(
|
||||
new Link('A', 'B', new VersionConstraint('>=', '1.0'), 'conflicts'),
|
||||
));
|
||||
|
||||
$this->reposComplete();
|
||||
|
||||
$this->request->install('A');
|
||||
$this->request->install('B');
|
||||
|
||||
try {
|
||||
$transaction = $this->solver->solve($this->request);
|
||||
$this->fail('Unsolvable conflict did not resolve in exception.');
|
||||
} catch (SolverProblemsException $e) {
|
||||
// @todo: assert problem properties
|
||||
}
|
||||
}
|
||||
|
||||
public function testUnsatisfiableRequires()
|
||||
{
|
||||
$this->repo->addPackage($packageA = $this->getPackage('A', '1.0'));
|
||||
$this->repo->addPackage($packageB = $this->getPackage('B', '1.0'));
|
||||
|
||||
$packageA->setRequires(array(
|
||||
new Link('A', 'B', new VersionConstraint('>=', '2.0'), 'requires'),
|
||||
));
|
||||
|
||||
$this->reposComplete();
|
||||
|
||||
$this->request->install('A');
|
||||
|
||||
try {
|
||||
$transaction = $this->solver->solve($this->request);
|
||||
$this->fail('Unsolvable conflict did not resolve in exception.');
|
||||
} catch (SolverProblemsException $e) {
|
||||
// @todo: assert problem properties
|
||||
}
|
||||
}
|
||||
|
||||
protected function reposComplete()
|
||||
{
|
||||
$this->pool->addRepository($this->repoInstalled);
|
||||
|
@ -513,5 +557,4 @@ class SolverTest extends TestCase
|
|||
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue