From 5ba9a887c2da12db82e1e8fa05f467fab6d36f5d Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Fri, 27 Apr 2012 17:40:59 +0200 Subject: [PATCH 01/14] We do not support any options to keep obsolete packages --- src/Composer/DependencyResolver/Solver.php | 63 +++++++++------------- 1 file changed, 25 insertions(+), 38 deletions(-) diff --git a/src/Composer/DependencyResolver/Solver.php b/src/Composer/DependencyResolver/Solver.php index aa014035c..7e8554a7d 100644 --- a/src/Composer/DependencyResolver/Solver.php +++ b/src/Composer/DependencyResolver/Solver.php @@ -30,7 +30,6 @@ class Solver protected $ruleToJob = array(); protected $addedMap = array(); protected $updateMap = array(); - protected $noObsoletes = array(); protected $watches = array(); protected $removeWatches = array(); protected $decisionMap; @@ -237,50 +236,38 @@ class Solver } // check obsoletes and implicit obsoletes of a package - // if ignoreinstalledsobsoletes is not set, we're also checking - // obsoletes of installed packages (like newer rpm versions) - // - /** TODO if ($this->noInstalledObsoletes) */ - if (true) { - $noObsoletes = isset($this->noObsoletes[$package->getId()]); - $isInstalled = (isset($this->installedMap[$package->getId()])); - - foreach ($package->getReplaces() as $link) { - $obsoleteProviders = $this->pool->whatProvides($link->getTarget(), $link->getConstraint()); - - foreach ($obsoleteProviders as $provider) { - if ($provider === $package) { - continue; - } + $isInstalled = (isset($this->installedMap[$package->getId()])); - $reason = ($isInstalled) ? Rule::RULE_INSTALLED_PACKAGE_OBSOLETES : Rule::RULE_PACKAGE_OBSOLETES; - $this->addRule(RuleSet::TYPE_PACKAGE, $this->createConflictRule($package, $provider, $reason, (string) $link)); - } - } + foreach ($package->getReplaces() as $link) { + $obsoleteProviders = $this->pool->whatProvides($link->getTarget(), $link->getConstraint()); - // check implicit obsoletes - // for installed packages we only need to check installed/installed problems, - // as the others are picked up when looking at the uninstalled package. - if (!$isInstalled) { - $obsoleteProviders = $this->pool->whatProvides($package->getName(), null); + foreach ($obsoleteProviders as $provider) { + if ($provider === $package) { + continue; + } - foreach ($obsoleteProviders as $provider) { - if ($provider === $package) { - continue; - } + $reason = ($isInstalled) ? Rule::RULE_INSTALLED_PACKAGE_OBSOLETES : Rule::RULE_PACKAGE_OBSOLETES; + $this->addRule(RuleSet::TYPE_PACKAGE, $this->createConflictRule($package, $provider, $reason, (string) $link)); + } + } - if ($isInstalled && !isset($this->installedMap[$provider->getId()])) { - continue; - } + // check implicit obsoletes + // for installed packages we only need to check installed/installed problems, + // as the others are picked up when looking at the uninstalled package. + if (!$isInstalled) { + $obsoleteProviders = $this->pool->whatProvides($package->getName(), null); - // obsolete same packages even when noObsoletes - if ($noObsoletes && (!$package->equals($provider))) { - continue; - } + foreach ($obsoleteProviders as $provider) { + if ($provider === $package) { + continue; + } - $reason = ($package->getName() == $provider->getName()) ? Rule::RULE_PACKAGE_SAME_NAME : Rule::RULE_PACKAGE_IMPLICIT_OBSOLETES; - $this->addRule(RuleSet::TYPE_PACKAGE, $rule = $this->createConflictRule($package, $provider, $reason, (string) $package)); + if ($isInstalled && !isset($this->installedMap[$provider->getId()])) { + continue; } + + $reason = ($package->getName() == $provider->getName()) ? Rule::RULE_PACKAGE_SAME_NAME : Rule::RULE_PACKAGE_IMPLICIT_OBSOLETES; + $this->addRule(RuleSet::TYPE_PACKAGE, $rule = $this->createConflictRule($package, $provider, $reason, (string) $package)); } } } From 0e537b9c93c105ad1f8ed21f2acd849357d4bbdf Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Fri, 27 Apr 2012 17:44:42 +0200 Subject: [PATCH 02/14] We won't implement choice rules, you need to edit composer.json to choose --- src/Composer/DependencyResolver/RuleSet.php | 4 +- src/Composer/DependencyResolver/Solver.php | 174 ------------------ .../Test/DependencyResolver/RuleSetTest.php | 1 - 3 files changed, 1 insertion(+), 178 deletions(-) diff --git a/src/Composer/DependencyResolver/RuleSet.php b/src/Composer/DependencyResolver/RuleSet.php index 1f444c788..3278b1a98 100644 --- a/src/Composer/DependencyResolver/RuleSet.php +++ b/src/Composer/DependencyResolver/RuleSet.php @@ -21,15 +21,13 @@ class RuleSet implements \IteratorAggregate, \Countable const TYPE_PACKAGE = 0; const TYPE_JOB = 1; const TYPE_FEATURE = 3; - const TYPE_CHOICE = 4; - const TYPE_LEARNED = 5; + const TYPE_LEARNED = 4; protected static $types = array( -1 => 'UNKNOWN', self::TYPE_PACKAGE => 'PACKAGE', self::TYPE_FEATURE => 'FEATURE', self::TYPE_JOB => 'JOB', - self::TYPE_CHOICE => 'CHOICE', self::TYPE_LEARNED => 'LEARNED', ); diff --git a/src/Composer/DependencyResolver/Solver.php b/src/Composer/DependencyResolver/Solver.php index 7e8554a7d..f2ba5321b 100644 --- a/src/Composer/DependencyResolver/Solver.php +++ b/src/Composer/DependencyResolver/Solver.php @@ -483,174 +483,6 @@ class Solver } } - protected function addChoiceRules() - { - -// void -// solver_addchoicerules(Solver *solv) -// { -// Pool *pool = solv->pool; -// Map m, mneg; -// Rule *r; -// Queue q, qi; -// int i, j, rid, havechoice; -// Id p, d, *pp; -// Id p2, pp2; -// Solvable *s, *s2; -// -// solv->choicerules = solv->nrules; -// if (!pool->installed) -// { -// solv->choicerules_end = solv->nrules; -// return; -// } -// solv->choicerules_ref = sat_calloc(solv->rpmrules_end, sizeof(Id)); -// queue_init(&q); -// queue_init(&qi); -// map_init(&m, pool->nsolvables); -// map_init(&mneg, pool->nsolvables); -// /* set up negative assertion map from infarch and dup rules */ -// for (rid = solv->infarchrules, r = solv->rules + rid; rid < solv->infarchrules_end; rid++, r++) -// if (r->p < 0 && !r->w2 && (r->d == 0 || r->d == -1)) -// MAPSET(&mneg, -r->p); -// for (rid = solv->duprules, r = solv->rules + rid; rid < solv->duprules_end; rid++, r++) -// if (r->p < 0 && !r->w2 && (r->d == 0 || r->d == -1)) -// MAPSET(&mneg, -r->p); -// for (rid = 1; rid < solv->rpmrules_end ; rid++) -// { -// r = solv->rules + rid; -// if (r->p >= 0 || ((r->d == 0 || r->d == -1) && r->w2 < 0)) -// continue; /* only look at requires rules */ -// // solver_printrule(solv, SAT_DEBUG_RESULT, r); -// queue_empty(&q); -// queue_empty(&qi); -// havechoice = 0; -// FOR_RULELITERALS(p, pp, r) -// { -// if (p < 0) -// continue; -// s = pool->solvables + p; -// if (!s->repo) -// continue; -// if (s->repo == pool->installed) -// { -// queue_push(&q, p); -// continue; -// } -// /* check if this package is "blocked" by a installed package */ -// s2 = 0; -// FOR_PROVIDES(p2, pp2, s->name) -// { -// s2 = pool->solvables + p2; -// if (s2->repo != pool->installed) -// continue; -// if (!pool->implicitobsoleteusesprovides && s->name != s2->name) -// continue; -// if (pool->obsoleteusescolors && !pool_colormatch(pool, s, s2)) -// continue; -// break; -// } -// if (p2) -// { -// /* found installed package p2 that we can update to p */ -// if (MAPTST(&mneg, p)) -// continue; -// if (policy_is_illegal(solv, s2, s, 0)) -// continue; -// queue_push(&qi, p2); -// queue_push(&q, p); -// continue; -// } -// if (s->obsoletes) -// { -// Id obs, *obsp = s->repo->idarraydata + s->obsoletes; -// s2 = 0; -// while ((obs = *obsp++) != 0) -// { -// FOR_PROVIDES(p2, pp2, obs) -// { -// s2 = pool->solvables + p2; -// if (s2->repo != pool->installed) -// continue; -// if (!pool->obsoleteusesprovides && !pool_match_nevr(pool, pool->solvables + p2, obs)) -// continue; -// if (pool->obsoleteusescolors && !pool_colormatch(pool, s, s2)) -// continue; -// break; -// } -// if (p2) -// break; -// } -// if (obs) -// { -// /* found installed package p2 that we can update to p */ -// if (MAPTST(&mneg, p)) -// continue; -// if (policy_is_illegal(solv, s2, s, 0)) -// continue; -// queue_push(&qi, p2); -// queue_push(&q, p); -// continue; -// } -// } -// /* package p is independent of the installed ones */ -// havechoice = 1; -// } -// if (!havechoice || !q.count) -// continue; /* no choice */ -// -// /* now check the update rules of the installed package. -// * if all packages of the update rules are contained in -// * the dependency rules, there's no need to set up the choice rule */ -// map_empty(&m); -// FOR_RULELITERALS(p, pp, r) -// if (p > 0) -// MAPSET(&m, p); -// for (i = 0; i < qi.count; i++) -// { -// if (!qi.elements[i]) -// continue; -// Rule *ur = solv->rules + solv->updaterules + (qi.elements[i] - pool->installed->start); -// if (!ur->p) -// ur = solv->rules + solv->featurerules + (qi.elements[i] - pool->installed->start); -// if (!ur->p) -// continue; -// FOR_RULELITERALS(p, pp, ur) -// if (!MAPTST(&m, p)) -// break; -// if (p) -// break; -// for (j = i + 1; j < qi.count; j++) -// if (qi.elements[i] == qi.elements[j]) -// qi.elements[j] = 0; -// } -// if (i == qi.count) -// { -// #if 0 -// printf("skipping choice "); -// solver_printrule(solv, SAT_DEBUG_RESULT, solv->rules + rid); -// #endif -// continue; -// } -// d = q.count ? pool_queuetowhatprovides(pool, &q) : 0; -// solver_addrule(solv, r->p, d); -// queue_push(&solv->weakruleq, solv->nrules - 1); -// solv->choicerules_ref[solv->nrules - 1 - solv->choicerules] = rid; -// #if 0 -// printf("OLD "); -// solver_printrule(solv, SAT_DEBUG_RESULT, solv->rules + rid); -// printf("WEAK CHOICE "); -// solver_printrule(solv, SAT_DEBUG_RESULT, solv->rules + solv->nrules - 1); -// #endif -// } -// queue_free(&q); -// queue_free(&qi); -// map_free(&m); -// map_free(&mneg); -// solv->choicerules_end = solv->nrules; -// } - } - /*********************************************************************** *** *** Policy rule disabling/reenabling @@ -939,8 +771,6 @@ class Solver } } - $this->addChoiceRules(); - foreach ($this->rules as $rule) { $this->addWatchesToRule($rule); } @@ -1523,10 +1353,6 @@ class Solver $why = $lastWeakWhy; } - if ($lastWeakWhy->getType() == RuleSet::TYPE_CHOICE) { - $this->disableChoiceRules($lastWeakWhy); - } - $this->disableProblem($why); /** diff --git a/tests/Composer/Test/DependencyResolver/RuleSetTest.php b/tests/Composer/Test/DependencyResolver/RuleSetTest.php index 54ad88a58..f974732dc 100644 --- a/tests/Composer/Test/DependencyResolver/RuleSetTest.php +++ b/tests/Composer/Test/DependencyResolver/RuleSetTest.php @@ -31,7 +31,6 @@ class RuleSetTest extends TestCase new Rule(array(), 'update1', null), ), RuleSet::TYPE_LEARNED => array(), - RuleSet::TYPE_CHOICE => array(), ); $ruleSet = new RuleSet; From 1a48ebaf577d832819b31ba316a82bd684309964 Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Fri, 27 Apr 2012 17:50:53 +0200 Subject: [PATCH 03/14] Create lookup table for installed packages in only one place --- src/Composer/DependencyResolver/Solver.php | 26 +++++++++++++--------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/Composer/DependencyResolver/Solver.php b/src/Composer/DependencyResolver/Solver.php index f2ba5321b..15b1f46ea 100644 --- a/src/Composer/DependencyResolver/Solver.php +++ b/src/Composer/DependencyResolver/Solver.php @@ -35,6 +35,8 @@ class Solver protected $decisionMap; protected $installedMap; + protected $installedPackages; + protected $packageToFeatureRule = array(); public function __construct(PolicyInterface $policy, Pool $pool, RepositoryInterface $installed) @@ -667,14 +669,20 @@ class Solver } } - public function solve(Request $request) + protected function setupInstalledMap() { - $this->jobs = $request->getJobs(); - $installedPackages = $this->installed->getPackages(); + $this->installedPackages = $this->installed->getPackages(); $this->installedMap = array(); - foreach ($installedPackages as $package) { + foreach ($this->installedPackages as $package) { $this->installedMap[$package->getId()] = $package; } + } + + public function solve(Request $request) + { + $this->jobs = $request->getJobs(); + + $this->setupInstalledMap(); if (version_compare(PHP_VERSION, '5.3.4', '>=')) { $this->decisionMap = new \SplFixedArray($this->pool->getMaxId() + 1); @@ -695,18 +703,18 @@ class Solver switch ($job['cmd']) { case 'update-all': - foreach ($installedPackages as $package) { + foreach ($this->installedMap as $package) { $this->updateMap[$package->getId()] = true; } break; } } - foreach ($installedPackages as $package) { + foreach ($this->installedMap as $package) { $this->addRulesForPackage($package); } - foreach ($installedPackages as $package) { + foreach ($this->installedMap as $package) { $this->addRulesForUpdatePackages($package); } @@ -724,7 +732,7 @@ class Solver // solver_addrpmrulesforweak(solv, &addedmap); - foreach ($installedPackages as $package) { + foreach ($this->installedMap as $package) { $updates = $this->policy->findUpdatePackages($this, $this->pool, $this->installedMap, $package); $rule = $this->createUpdateRule($package, $updates, Rule::RULE_INTERNAL_ALLOW_UPDATE, (string) $package); @@ -1467,8 +1475,6 @@ class Solver $minimizationSteps = 0; $installedPos = 0; - $this->installedPackages = $this->installed->getPackages(); - while (true) { if (1 === $level) { From 2cb2cde096ab2b2f4d3d0b5c36fb406ea6856abe Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Fri, 27 Apr 2012 18:13:37 +0200 Subject: [PATCH 04/14] Installed packages are now always removed unless otherwise requested This means that an update request must always be accompanied by an install request, otherwise the package might be removed rather than updated. --- src/Composer/DependencyResolver/Solver.php | 135 ++---------------- .../Test/DependencyResolver/SolverTest.php | 31 +++- 2 files changed, 39 insertions(+), 127 deletions(-) diff --git a/src/Composer/DependencyResolver/Solver.php b/src/Composer/DependencyResolver/Solver.php index 15b1f46ea..0cb754284 100644 --- a/src/Composer/DependencyResolver/Solver.php +++ b/src/Composer/DependencyResolver/Solver.php @@ -730,14 +730,12 @@ class Solver } } - // solver_addrpmrulesforweak(solv, &addedmap); - foreach ($this->installedMap as $package) { $updates = $this->policy->findUpdatePackages($this, $this->pool, $this->installedMap, $package); $rule = $this->createUpdateRule($package, $updates, Rule::RULE_INTERNAL_ALLOW_UPDATE, (string) $package); $rule->setWeak(true); - $this->addRule(RuleSet::TYPE_FEATURE, $rule); + //$this->addRule(RuleSet::TYPE_FEATURE, $rule); $this->packageToFeatureRule[$package->getId()] = $rule; } @@ -857,6 +855,18 @@ class Solver } } + foreach ($this->decisionMap as $packageId => $decision) { + if ($packageId === 0) { + continue; + } + + if (0 == $decision && isset($this->installedMap[$packageId])) { + $transaction[] = new Operation\UninstallOperation( + $this->pool->packageById($packageId), null + ); + } + } + return array_reverse($transaction); } @@ -1546,125 +1556,6 @@ class Solver } } - // handle installed packages - if ($level < $systemLevel) { - // use two passes if any packages are being updated - // -> better user experience - for ($pass = (count($this->updateMap)) ? 0 : 1; $pass < 2; $pass++) { - $passLevel = $level; - for ($i = $installedPos, $n = 0; $n < count($this->installedPackages); $i++, $n++) { - $repeat = false; - - if ($i == count($this->installedPackages)) { - $i = 0; - } - $literal = new Literal($this->installedPackages[$i], true); - - if ($this->decisionsContain($literal)) { - continue; - } - - // only process updates in first pass - /** TODO: && or || ? **/ - if (0 === $pass && !isset($this->updateMap[$literal->getPackageId()])) { - continue; - } - - $rule = null; - - if (isset($this->packageToFeatureRule[$literal->getPackageId()])) { - $rule = $this->packageToFeatureRule[$literal->getPackageId()]; - } - - if (!$rule || $rule->isDisabled()) { - continue; - } - - $updateRuleLiterals = $rule->getLiterals(); - - $decisionQueue = array(); - if (!isset($this->noUpdate[$literal->getPackageId()]) && ( - $this->decidedRemove($literal->getPackage()) || - isset($this->updateMap[$literal->getPackageId()]) || - !$literal->equals($updateRuleLiterals[0]) - )) { - foreach ($updateRuleLiterals as $ruleLiteral) { - if ($this->decidedInstall($ruleLiteral->getPackage())) { - // already fulfilled - $decisionQueue = array(); - break; - } - if ($this->undecided($ruleLiteral->getPackage())) { - $decisionQueue[] = $ruleLiteral; - } - } - } - - if (sizeof($decisionQueue)) { - $oLevel = $level; - $level = $this->selectAndInstall($level, $decisionQueue, $disableRules, $rule); - - if (0 === $level) { - return; - } - - if ($level <= $oLevel) { - $repeat = true; - } - } else if (!$repeat && $this->undecided($literal->getPackage())) { - // still undecided? keep package. - $oLevel = $level; - if (isset($this->cleanDepsMap[$literal->getPackageId()])) { - // clean deps removes package - $level = $this->setPropagateLearn($level, $literal->invert(), $disableRules, null); - } else { - // ckeeping package - $level = $this->setPropagateLearn($level, $literal, $disableRules, $rule); - } - - - if (0 === $level) { - return; - } - - if ($level <= $oLevel) { - $repeat = true; - } - } - - if ($repeat) { - if (1 === $level || $level < $passLevel) { - // trouble - break; - } - if ($level < $oLevel) { - // redo all - $n = 0; - } - - // repeat - $i--; - $n--; - continue; - } - } - - if ($n < count($this->installedPackages)) { - $installedPos = $i; // retry this problem next time - break; - } - - $installedPos = 0; - } - - $systemLevel = $level + 1; - - if ($pass < 2) { - // had trouble => retry - continue; - } - } - if ($level < $systemLevel) { $systemLevel = $level; } diff --git a/tests/Composer/Test/DependencyResolver/SolverTest.php b/tests/Composer/Test/DependencyResolver/SolverTest.php index 49355a5a4..2bc5a928a 100644 --- a/tests/Composer/Test/DependencyResolver/SolverTest.php +++ b/tests/Composer/Test/DependencyResolver/SolverTest.php @@ -54,6 +54,16 @@ class SolverTest extends TestCase )); } + public function testSolverRemoveIfNotInstalled() + { + $this->repoInstalled->addPackage($packageA = $this->getPackage('A', '1.0')); + $this->reposComplete(); + + $this->checkSolverResult(array( + array('job' => 'remove', 'package' => $packageA), + )); + } + public function testInstallNonExistingPackageFails() { $this->repo->addPackage($this->getPackage('A', '1.0')); @@ -176,6 +186,7 @@ class SolverTest extends TestCase $this->repo->addPackage($newPackageA = $this->getPackage('A', '1.1')); $this->reposComplete(); + $this->request->install('A'); $this->request->update('A'); $this->checkSolverResult(array( @@ -191,6 +202,7 @@ class SolverTest extends TestCase $this->repo->addPackage($newPackageB = $this->getPackage('B', '1.1')); $packageA->setRequires(array(new Link('A', 'B', null, 'requires'))); + $newPackageA->setRequires(array(new Link('A', 'B', null, 'requires'))); $this->reposComplete(); @@ -209,6 +221,7 @@ class SolverTest extends TestCase $this->repo->addPackage($this->getPackage('A', '1.0')); $this->reposComplete(); + $this->request->install('A'); $this->request->update('A'); $this->checkSolverResult(array()); @@ -223,6 +236,8 @@ class SolverTest extends TestCase $this->reposComplete(); + $this->request->install('A'); + $this->request->install('B'); $this->request->update('A'); $this->checkSolverResult(array( @@ -267,7 +282,7 @@ class SolverTest extends TestCase public function testSolverUpdateFullyConstrainedPrunesInstalledPackages() { $this->repoInstalled->addPackage($packageA = $this->getPackage('A', '1.0')); - $this->repoInstalled->addPackage($this->getPackage('B', '1.0')); + $this->repoInstalled->addPackage($packageB = $this->getPackage('B', '1.0')); $this->repo->addPackage($newPackageA = $this->getPackage('A', '1.2')); $this->repo->addPackage($this->getPackage('A', '2.0')); $this->reposComplete(); @@ -275,10 +290,15 @@ class SolverTest extends TestCase $this->request->install('A', $this->getVersionConstraint('<', '2.0.0.0')); $this->request->update('A', $this->getVersionConstraint('=', '1.0.0.0')); - $this->checkSolverResult(array(array( - 'job' => 'update', - 'from' => $packageA, - 'to' => $newPackageA, + $this->checkSolverResult(array( + array( + 'job' => 'remove', + 'package' => $packageB, + ), + array( + 'job' => 'update', + 'from' => $packageA, + 'to' => $newPackageA, ))); } @@ -297,6 +317,7 @@ class SolverTest extends TestCase $this->reposComplete(); $this->request->install('A'); + $this->request->install('C'); $this->request->update('C'); $this->request->remove('D'); From 3618ddacb06ebc3cb01a99634c83bb76c6e8df7a Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Fri, 27 Apr 2012 18:16:34 +0200 Subject: [PATCH 05/14] Remove commented out debug output --- src/Composer/DependencyResolver/Solver.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Composer/DependencyResolver/Solver.php b/src/Composer/DependencyResolver/Solver.php index 0cb754284..6eb57b636 100644 --- a/src/Composer/DependencyResolver/Solver.php +++ b/src/Composer/DependencyResolver/Solver.php @@ -789,9 +789,6 @@ class Solver $installRecommended = 0; $this->runSat(true, $installRecommended); - //$this->printDecisionMap(); - //findrecommendedsuggested(solv); - //solver_prepare_solutions(solv); if ($this->problems) { throw new SolverProblemsException($this->problems); From 6410817c4e36ab5f2cc0bb2f7afdb7a1b8b64bd0 Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Fri, 27 Apr 2012 18:21:25 +0200 Subject: [PATCH 06/14] Policy rules cannot conflict with jobs anymore As we no longer need special feature rules for updating installed packages we don't have policy rules which might conflict with job rules anymore. Everything is driven by jobs now. --- src/Composer/DependencyResolver/Solver.php | 196 --------------------- 1 file changed, 196 deletions(-) diff --git a/src/Composer/DependencyResolver/Solver.php b/src/Composer/DependencyResolver/Solver.php index 6eb57b636..f692a2d22 100644 --- a/src/Composer/DependencyResolver/Solver.php +++ b/src/Composer/DependencyResolver/Solver.php @@ -481,191 +481,6 @@ class Solver } $this->disableProblem($why); - /** TODO solver_reenablepolicyrules(solv, -(v + 1)); */ - } - } - -/*********************************************************************** - *** - *** Policy rule disabling/reenabling - *** - *** Disable all policy rules that conflict with our jobs. If a job - *** gets disabled later on, reenable the involved policy rules again. - *** - *** / - -#define DISABLE_UPDATE 1 -#define DISABLE_INFARCH 2 -#define DISABLE_DUP 3 -*/ - protected function jobToDisableQueue(array $job, array $disableQueue) - { - switch ($job['cmd']) { - case 'install': - foreach ($job['packages'] as $package) { - if (isset($this->installedMap[$package->getId()])) { - $disableQueue[] = array('type' => 'update', 'package' => $package); - } - - /* all job packages obsolete * / - qstart = q->count; - pass = 0; - memset(&omap, 0, sizeof(omap)); - FOR_JOB_SELECT(p, pp, select, what) - { - Id p2, pp2; - - if (pass == 1) - map_grow(&omap, installed->end - installed->start); - s = pool->solvables + p; - if (s->obsoletes) - { - Id obs, *obsp; - obsp = s->repo->idarraydata + s->obsoletes; - while ((obs = *obsp++) != 0) - FOR_PROVIDES(p2, pp2, obs) - { - Solvable *ps = pool->solvables + p2; - if (ps->repo != installed) - continue; - if (!pool->obsoleteusesprovides && !pool_match_nevr(pool, ps, obs)) - continue; - if (pool->obsoleteusescolors && !pool_colormatch(pool, s, ps)) - continue; - if (pass) - MAPSET(&omap, p2 - installed->start); - else - queue_push2(q, DISABLE_UPDATE, p2); - } - } - FOR_PROVIDES(p2, pp2, s->name) - { - Solvable *ps = pool->solvables + p2; - if (ps->repo != installed) - continue; - if (!pool->implicitobsoleteusesprovides && ps->name != s->name) - continue; - if (pool->obsoleteusescolors && !pool_colormatch(pool, s, ps)) - continue; - if (pass) - MAPSET(&omap, p2 - installed->start); - else - queue_push2(q, DISABLE_UPDATE, p2); - } - if (pass) - { - for (i = j = qstart; i < q->count; i += 2) - { - if (MAPTST(&omap, q->elements[i + 1] - installed->start)) - { - MAPCLR(&omap, q->elements[i + 1] - installed->start); - q->elements[j + 1] = q->elements[i + 1]; - j += 2; - } - } - queue_truncate(q, j); - } - if (q->count == qstart) - break; - pass++; - } - if (omap.size) - map_free(&omap); - - if (qstart == q->count) - return; /* nothing to prune * / - if ((set & (SOLVER_SETEVR | SOLVER_SETARCH | SOLVER_SETVENDOR)) == (SOLVER_SETEVR | SOLVER_SETARCH | SOLVER_SETVENDOR)) - return; /* all is set */ - - /* now that we know which installed packages are obsoleted check each of them * / - for (i = j = qstart; i < q->count; i += 2) - { - Solvable *is = pool->solvables + q->elements[i + 1]; - FOR_JOB_SELECT(p, pp, select, what) - { - int illegal = 0; - s = pool->solvables + p; - if ((set & SOLVER_SETEVR) != 0) - illegal |= POLICY_ILLEGAL_DOWNGRADE; /* ignore * / - if ((set & SOLVER_SETARCH) != 0) - illegal |= POLICY_ILLEGAL_ARCHCHANGE; /* ignore * / - if ((set & SOLVER_SETVENDOR) != 0) - illegal |= POLICY_ILLEGAL_VENDORCHANGE; /* ignore * / - illegal = policy_is_illegal(solv, is, s, illegal); - if (illegal && illegal == POLICY_ILLEGAL_DOWNGRADE && (set & SOLVER_SETEV) != 0) - { - /* it's ok if the EV is different * / - if (evrcmp(pool, is->evr, s->evr, EVRCMP_COMPARE_EVONLY) != 0) - illegal = 0; - } - if (illegal) - break; - } - if (!p) - { - /* no package conflicts with the update rule * / - /* thus keep the DISABLE_UPDATE * / - q->elements[j + 1] = q->elements[i + 1]; - j += 2; - } - } - queue_truncate(q, j); - return;*/ - } - break; - - case 'remove': - foreach ($job['packages'] as $package) { - if (isset($this->installedMap[$package->getId()])) { - $disableQueue[] = array('type' => 'update', 'package' => $package); - } - } - break; - } - - return $disableQueue; - } - - protected function disableUpdateRule($package) - { - if (isset($this->packageToFeatureRule[$package->getId()])) { - $this->packageToFeatureRule[$package->getId()]->disable(); - } - } - - /** - * Disables all policy rules that conflict with jobs - */ - protected function disablePolicyRules() - { - $lastJob = null; - $allQueue = array(); - - $iterator = $this->rules->getIteratorFor(RuleSet::TYPE_JOB); - foreach ($iterator as $rule) { - if ($rule->isDisabled()) { - continue; - } - - $job = $this->ruleToJob[$rule->getId()]; - - if ($job === $lastJob) { - continue; - } - - $lastJob = $job; - - $allQueue = $this->jobToDisableQueue($job, $allQueue); - } - - foreach ($allQueue as $disable) { - switch ($disable['type']) { - case 'update': - $this->disableUpdateRule($disable['package']); - break; - default: - throw new \RuntimeException("Unsupported disable type: " . $disable['type']); - } } } @@ -734,8 +549,6 @@ class Solver $updates = $this->policy->findUpdatePackages($this, $this->pool, $this->installedMap, $package); $rule = $this->createUpdateRule($package, $updates, Rule::RULE_INTERNAL_ALLOW_UPDATE, (string) $package); - $rule->setWeak(true); - //$this->addRule(RuleSet::TYPE_FEATURE, $rule); $this->packageToFeatureRule[$package->getId()] = $rule; } @@ -781,9 +594,6 @@ class Solver $this->addWatchesToRule($rule); } - /* disable update rules that conflict with our job */ - $this->disablePolicyRules(); - /* make decisions based on job/update assertions */ $this->makeAssertionRuleDecisions(); @@ -1369,12 +1179,6 @@ class Solver } $this->disableProblem($why); - - /** -@TODO what does v < 0 mean here? ($why == v) - if (v < 0) - solver_reenablepolicyrules(solv, -(v + 1)); -*/ $this->resetSolver(); return true; From 7be4b82ad28d82363ebe787309678ae335f75be1 Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Fri, 27 Apr 2012 18:22:55 +0200 Subject: [PATCH 07/14] Move all solver members to top of the file --- src/Composer/DependencyResolver/Solver.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Composer/DependencyResolver/Solver.php b/src/Composer/DependencyResolver/Solver.php index f692a2d22..b6cbdf4e0 100644 --- a/src/Composer/DependencyResolver/Solver.php +++ b/src/Composer/DependencyResolver/Solver.php @@ -39,6 +39,15 @@ class Solver protected $packageToFeatureRule = array(); + protected $decisionQueue = array(); + protected $decisionQueueWhy = array(); + protected $decisionQueueFree = array(); + protected $propagateIndex; + protected $branches = array(); + protected $problems = array(); + protected $learnedPool = array(); + protected $recommendsIndex; + public function __construct(PolicyInterface $policy, Pool $pool, RepositoryInterface $installed) { $this->policy = $policy; @@ -677,15 +686,6 @@ class Solver return array_reverse($transaction); } - protected $decisionQueue = array(); - protected $decisionQueueWhy = array(); - protected $decisionQueueFree = array(); - protected $propagateIndex; - protected $branches = array(); - protected $problems = array(); - protected $learnedPool = array(); - protected $recommendsIndex; - protected function literalFromId($id) { $package = $this->pool->packageById(abs($id)); From f98ab2e491576212490ba8906f01f517491db09a Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Fri, 27 Apr 2012 18:24:17 +0200 Subject: [PATCH 08/14] An array of installed packages is no longer needed in the solver --- src/Composer/DependencyResolver/Solver.php | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/Composer/DependencyResolver/Solver.php b/src/Composer/DependencyResolver/Solver.php index b6cbdf4e0..d51bbd55d 100644 --- a/src/Composer/DependencyResolver/Solver.php +++ b/src/Composer/DependencyResolver/Solver.php @@ -35,8 +35,6 @@ class Solver protected $decisionMap; protected $installedMap; - protected $installedPackages; - protected $packageToFeatureRule = array(); protected $decisionQueue = array(); @@ -495,9 +493,8 @@ class Solver protected function setupInstalledMap() { - $this->installedPackages = $this->installed->getPackages(); $this->installedMap = array(); - foreach ($this->installedPackages as $package) { + foreach ($this->installed->getPackages() as $package) { $this->installedMap[$package->getId()] = $package; } } @@ -1269,9 +1266,7 @@ class Solver // * here's the main loop: // * 1) propagate new decisions (only needed once) // * 2) fulfill jobs - // * 3) try to keep installed packages // * 4) fulfill all unresolved rules - // * 5) install recommended packages // * 6) minimalize solution if we had choices // * if we encounter a problem, we rewind to a safe level and restart // * with step 1 From d153ab3f8f8c79768b69f129b668abf542be359e Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Fri, 27 Apr 2012 18:25:38 +0200 Subject: [PATCH 09/14] Call feature rules update rules, as there is no difference in composer --- src/Composer/DependencyResolver/Solver.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Composer/DependencyResolver/Solver.php b/src/Composer/DependencyResolver/Solver.php index d51bbd55d..5990fcc59 100644 --- a/src/Composer/DependencyResolver/Solver.php +++ b/src/Composer/DependencyResolver/Solver.php @@ -35,7 +35,7 @@ class Solver protected $decisionMap; protected $installedMap; - protected $packageToFeatureRule = array(); + protected $packageToUpdateRule = array(); protected $decisionQueue = array(); protected $decisionQueueWhy = array(); @@ -555,7 +555,7 @@ class Solver $updates = $this->policy->findUpdatePackages($this, $this->pool, $this->installedMap, $package); $rule = $this->createUpdateRule($package, $updates, Rule::RULE_INTERNAL_ALLOW_UPDATE, (string) $package); - $this->packageToFeatureRule[$package->getId()] = $rule; + $this->packageToUpdateRule[$package->getId()] = $rule; } foreach ($this->jobs as $job) { @@ -625,8 +625,8 @@ class Solver if (!$literal->isWanted() && isset($this->installedMap[$package->getId()])) { $literals = array(); - if (isset($this->packageToFeatureRule[$package->getId()])) { - $literals = array_merge($literals, $this->packageToFeatureRule[$package->getId()]->getLiterals()); + if (isset($this->packageToUpdateRule[$package->getId()])) { + $literals = array_merge($literals, $this->packageToUpdateRule[$package->getId()]->getLiterals()); } foreach ($literals as $updateLiteral) { From f4d5568937a699735a2cf05e94fc2e8ae8a4b9f4 Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Fri, 27 Apr 2012 18:28:18 +0200 Subject: [PATCH 10/14] Rules of type feature are no longer needed --- src/Composer/DependencyResolver/RuleSet.php | 2 -- src/Composer/DependencyResolver/Solver.php | 2 +- .../RuleSetIteratorTest.php | 6 +++--- .../Test/DependencyResolver/RuleSetTest.php | 19 +++++++++---------- 4 files changed, 13 insertions(+), 16 deletions(-) diff --git a/src/Composer/DependencyResolver/RuleSet.php b/src/Composer/DependencyResolver/RuleSet.php index 3278b1a98..9e8ecf29b 100644 --- a/src/Composer/DependencyResolver/RuleSet.php +++ b/src/Composer/DependencyResolver/RuleSet.php @@ -20,13 +20,11 @@ class RuleSet implements \IteratorAggregate, \Countable // highest priority => lowest number const TYPE_PACKAGE = 0; const TYPE_JOB = 1; - const TYPE_FEATURE = 3; const TYPE_LEARNED = 4; protected static $types = array( -1 => 'UNKNOWN', self::TYPE_PACKAGE => 'PACKAGE', - self::TYPE_FEATURE => 'FEATURE', self::TYPE_JOB => 'JOB', self::TYPE_LEARNED => 'LEARNED', ); diff --git a/src/Composer/DependencyResolver/Solver.php b/src/Composer/DependencyResolver/Solver.php index 5990fcc59..afa8f6996 100644 --- a/src/Composer/DependencyResolver/Solver.php +++ b/src/Composer/DependencyResolver/Solver.php @@ -427,7 +427,7 @@ class Solver // push all of our rules (can only be feature or job rules) // asserting this literal on the problem stack - foreach ($this->rules->getIteratorFor(array(RuleSet::TYPE_JOB, RuleSet::TYPE_FEATURE)) as $assertRule) { + foreach ($this->rules->getIteratorFor(RuleSet::TYPE_JOB) as $assertRule) { if ($assertRule->isDisabled() || !$assertRule->isAssertion() || $assertRule->isWeak()) { continue; } diff --git a/tests/Composer/Test/DependencyResolver/RuleSetIteratorTest.php b/tests/Composer/Test/DependencyResolver/RuleSetIteratorTest.php index 28db18131..56084f32a 100644 --- a/tests/Composer/Test/DependencyResolver/RuleSetIteratorTest.php +++ b/tests/Composer/Test/DependencyResolver/RuleSetIteratorTest.php @@ -27,7 +27,7 @@ class ResultSetIteratorTest extends \PHPUnit_Framework_TestCase new Rule(array(), 'job1', null), new Rule(array(), 'job2', null), ), - RuleSet::TYPE_FEATURE => array( + RuleSet::TYPE_LEARNED => array( new Rule(array(), 'update1', null), ), RuleSet::TYPE_PACKAGE => array(), @@ -46,7 +46,7 @@ class ResultSetIteratorTest extends \PHPUnit_Framework_TestCase $expected = array( $this->rules[RuleSet::TYPE_JOB][0], $this->rules[RuleSet::TYPE_JOB][1], - $this->rules[RuleSet::TYPE_FEATURE][0], + $this->rules[RuleSet::TYPE_LEARNED][0], ); $this->assertEquals($expected, $result); @@ -64,7 +64,7 @@ class ResultSetIteratorTest extends \PHPUnit_Framework_TestCase $expected = array( RuleSet::TYPE_JOB, RuleSet::TYPE_JOB, - RuleSet::TYPE_FEATURE, + RuleSet::TYPE_LEARNED, ); $this->assertEquals($expected, $result); diff --git a/tests/Composer/Test/DependencyResolver/RuleSetTest.php b/tests/Composer/Test/DependencyResolver/RuleSetTest.php index f974732dc..f319651ae 100644 --- a/tests/Composer/Test/DependencyResolver/RuleSetTest.php +++ b/tests/Composer/Test/DependencyResolver/RuleSetTest.php @@ -27,16 +27,15 @@ class RuleSetTest extends TestCase new Rule(array(), 'job1', null), new Rule(array(), 'job2', null), ), - RuleSet::TYPE_FEATURE => array( + RuleSet::TYPE_LEARNED => array( new Rule(array(), 'update1', null), ), - RuleSet::TYPE_LEARNED => array(), ); $ruleSet = new RuleSet; $ruleSet->add($rules[RuleSet::TYPE_JOB][0], RuleSet::TYPE_JOB); - $ruleSet->add($rules[RuleSet::TYPE_FEATURE][0], RuleSet::TYPE_FEATURE); + $ruleSet->add($rules[RuleSet::TYPE_LEARNED][0], RuleSet::TYPE_LEARNED); $ruleSet->add($rules[RuleSet::TYPE_JOB][1], RuleSet::TYPE_JOB); $this->assertEquals($rules, $ruleSet->getRules()); @@ -79,7 +78,7 @@ class RuleSetTest extends TestCase $rule1 = new Rule(array(), 'job1', null); $rule2 = new Rule(array(), 'job1', null); $ruleSet->add($rule1, RuleSet::TYPE_JOB); - $ruleSet->add($rule2, RuleSet::TYPE_FEATURE); + $ruleSet->add($rule2, RuleSet::TYPE_LEARNED); $iterator = $ruleSet->getIterator(); @@ -95,9 +94,9 @@ class RuleSetTest extends TestCase $rule2 = new Rule(array(), 'job1', null); $ruleSet->add($rule1, RuleSet::TYPE_JOB); - $ruleSet->add($rule2, RuleSet::TYPE_FEATURE); + $ruleSet->add($rule2, RuleSet::TYPE_LEARNED); - $iterator = $ruleSet->getIteratorFor(RuleSet::TYPE_FEATURE); + $iterator = $ruleSet->getIteratorFor(RuleSet::TYPE_LEARNED); $this->assertSame($rule2, $iterator->current()); } @@ -109,7 +108,7 @@ class RuleSetTest extends TestCase $rule2 = new Rule(array(), 'job1', null); $ruleSet->add($rule1, RuleSet::TYPE_JOB); - $ruleSet->add($rule2, RuleSet::TYPE_FEATURE); + $ruleSet->add($rule2, RuleSet::TYPE_LEARNED); $iterator = $ruleSet->getIteratorWithout(RuleSet::TYPE_JOB); @@ -141,7 +140,7 @@ class RuleSetTest extends TestCase ->method('equal') ->will($this->returnValue(false)); - $ruleSet->add($rule, RuleSet::TYPE_FEATURE); + $ruleSet->add($rule, RuleSet::TYPE_LEARNED); $this->assertTrue($ruleSet->containsEqual($rule)); $this->assertFalse($ruleSet->containsEqual($rule2)); @@ -154,9 +153,9 @@ class RuleSetTest extends TestCase $literal = new Literal($this->getPackage('foo', '2.1'), true); $rule = new Rule(array($literal), 'job1', null); - $ruleSet->add($rule, RuleSet::TYPE_FEATURE); + $ruleSet->add($rule, RuleSet::TYPE_JOB); - $this->assertContains('FEATURE : (+foo-2.1.0.0)', $ruleSet->__toString()); + $this->assertContains('JOB : (+foo-2.1.0.0)', $ruleSet->__toString()); } private function getRuleMock() From b99f9bae6045d87621df4474b4d8b3da2087bbdd Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Fri, 27 Apr 2012 19:23:35 +0200 Subject: [PATCH 11/14] Let the user know a package is being removed --- src/Composer/Downloader/FileDownloader.php | 1 + src/Composer/Downloader/VcsDownloader.php | 1 + 2 files changed, 2 insertions(+) diff --git a/src/Composer/Downloader/FileDownloader.php b/src/Composer/Downloader/FileDownloader.php index 356934514..b11bf7ba6 100644 --- a/src/Composer/Downloader/FileDownloader.php +++ b/src/Composer/Downloader/FileDownloader.php @@ -101,6 +101,7 @@ class FileDownloader implements DownloaderInterface */ public function remove(PackageInterface $package, $path) { + $this->io->write(" - Removing package " . $package->getName() . " (" . $package->getPrettyVersion() . ")"); if (!$this->filesystem->removeDirectory($path)) { throw new \RuntimeException('Could not completely delete '.$path.', aborting.'); } diff --git a/src/Composer/Downloader/VcsDownloader.php b/src/Composer/Downloader/VcsDownloader.php index 2d19bba40..7d3c90c7f 100644 --- a/src/Composer/Downloader/VcsDownloader.php +++ b/src/Composer/Downloader/VcsDownloader.php @@ -77,6 +77,7 @@ abstract class VcsDownloader implements DownloaderInterface public function remove(PackageInterface $package, $path) { $this->enforceCleanDirectory($path); + $this->io->write(" - Removing package " . $package->getName() . " (" . $package->getPrettyVersion() . ")"); if (!$this->filesystem->removeDirectory($path)) { throw new \RuntimeException('Could not completely delete '.$path.', aborting.'); } From 22a825fc07c6e011f0ee1fd90f1f930edd160c93 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Fri, 27 Apr 2012 21:23:07 +0200 Subject: [PATCH 12/14] Clean up vendor dir after a package was removed --- src/Composer/Installer/LibraryInstaller.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Composer/Installer/LibraryInstaller.php b/src/Composer/Installer/LibraryInstaller.php index 0da923654..9be2e1d1d 100644 --- a/src/Composer/Installer/LibraryInstaller.php +++ b/src/Composer/Installer/LibraryInstaller.php @@ -127,6 +127,13 @@ class LibraryInstaller implements InstallerInterface $this->downloadManager->remove($package, $downloadPath); $this->removeBinaries($package); $repo->removePackage($package); + + if (strpos($package->getName(), '/')) { + $packageVendorDir = dirname($downloadPath); + if (is_dir($packageVendorDir) && !glob($packageVendorDir.'/*')) { + @rmdir($packageVendorDir); + } + } } /** From b3659d85f3d51c47bb342c30ba4cc4809197e018 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Fri, 27 Apr 2012 21:24:07 +0200 Subject: [PATCH 13/14] Force platform packages to remain installed --- src/Composer/Installer.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Composer/Installer.php b/src/Composer/Installer.php index 5819e3996..a6094d6e9 100644 --- a/src/Composer/Installer.php +++ b/src/Composer/Installer.php @@ -242,9 +242,11 @@ class Installer } } - // fix the version all installed packages that are not in the current local repo to prevent rogue updates + // fix the version of all installed packages (+ platform) that are not + // in the current local repo to prevent rogue updates (e.g. non-dev + // updating when in dev) foreach ($installedRepo->getPackages() as $package) { - if ($package->getRepository() === $localRepo || $package->getRepository() instanceof PlatformRepository) { + if ($package->getRepository() === $localRepo) { continue; } From d5e35fbe19be36cfdd0121398b5d9b85faf2854b Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Fri, 27 Apr 2012 21:40:46 +0200 Subject: [PATCH 14/14] Clarify output --- src/Composer/Downloader/FileDownloader.php | 4 ++-- src/Composer/Downloader/VcsDownloader.php | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Composer/Downloader/FileDownloader.php b/src/Composer/Downloader/FileDownloader.php index b11bf7ba6..3e15acf80 100644 --- a/src/Composer/Downloader/FileDownloader.php +++ b/src/Composer/Downloader/FileDownloader.php @@ -64,7 +64,7 @@ class FileDownloader implements DownloaderInterface $fileName = $this->getFileName($package, $path); - $this->io->write(" - Package " . $package->getName() . " (" . $package->getPrettyVersion() . ")"); + $this->io->write(" - Installing " . $package->getName() . " (" . $package->getPrettyVersion() . ")"); $processUrl = $this->processUrl($url); @@ -101,7 +101,7 @@ class FileDownloader implements DownloaderInterface */ public function remove(PackageInterface $package, $path) { - $this->io->write(" - Removing package " . $package->getName() . " (" . $package->getPrettyVersion() . ")"); + $this->io->write(" - Removing " . $package->getName() . " (" . $package->getPrettyVersion() . ")"); if (!$this->filesystem->removeDirectory($path)) { throw new \RuntimeException('Could not completely delete '.$path.', aborting.'); } diff --git a/src/Composer/Downloader/VcsDownloader.php b/src/Composer/Downloader/VcsDownloader.php index 7d3c90c7f..cacc74fc4 100644 --- a/src/Composer/Downloader/VcsDownloader.php +++ b/src/Composer/Downloader/VcsDownloader.php @@ -50,7 +50,7 @@ abstract class VcsDownloader implements DownloaderInterface throw new \InvalidArgumentException('Package '.$package->getPrettyName().' is missing reference information'); } - $this->io->write(" - Package " . $package->getName() . " (" . $package->getPrettyVersion() . ")"); + $this->io->write(" - Installing " . $package->getName() . " (" . $package->getPrettyVersion() . ")"); $this->filesystem->removeDirectory($path); $this->doDownload($package, $path); $this->io->write(''); @@ -65,7 +65,7 @@ abstract class VcsDownloader implements DownloaderInterface throw new \InvalidArgumentException('Package '.$target->getPrettyName().' is missing reference information'); } - $this->io->write(" - Package " . $target->getName() . " (" . $target->getPrettyVersion() . ")"); + $this->io->write(" - Installing " . $target->getName() . " (" . $target->getPrettyVersion() . ")"); $this->enforceCleanDirectory($path); $this->doUpdate($initial, $target, $path); $this->io->write(''); @@ -77,7 +77,7 @@ abstract class VcsDownloader implements DownloaderInterface public function remove(PackageInterface $package, $path) { $this->enforceCleanDirectory($path); - $this->io->write(" - Removing package " . $package->getName() . " (" . $package->getPrettyVersion() . ")"); + $this->io->write(" - Removing " . $package->getName() . " (" . $package->getPrettyVersion() . ")"); if (!$this->filesystem->removeDirectory($path)) { throw new \RuntimeException('Could not completely delete '.$path.', aborting.'); }