1
0
Fork 0

Completely move loading of packages from composer repo to pool

pull/3994/head
Nils Adermann 2015-05-05 19:08:33 +02:00
parent 9b9ad9d0fe
commit 090711b21c
3 changed files with 105 additions and 136 deletions

View File

@ -102,9 +102,21 @@ class Pool
$repo->resetPackageIds(); $repo->resetPackageIds();
} else { } else {
foreach ($repo->getPackages() as $package) { foreach ($repo->getPackages() as $package) {
$this->loadPackage($package, $rootAliases, $exempt);
}
}
}
}
private function loadPackage(PackageInterface $package, array $rootAliases, $acceptableExemption = false)
{
$names = $package->getNames(); $names = $package->getNames();
$stability = $package->getStability(); $stability = $package->getStability();
if ($exempt || $this->isPackageAcceptable($names, $stability)) {
if (!$acceptableExemption && !$this->isPackageAcceptable($names, $stability)) {
return;
}
$package->setId($this->id++); $package->setId($this->id++);
$this->packages[] = $package; $this->packages[] = $package;
$this->packageByExactName[$package->getName()][$package->id] = $package; $this->packageByExactName[$package->getName()][$package->id] = $package;
@ -133,10 +145,6 @@ class Pool
} }
} }
} }
}
}
}
}
public function getPriority(RepositoryInterface $repo) public function getPriority(RepositoryInterface $repo)
{ {
@ -160,11 +168,32 @@ class Pool
return $this->packages[$id - 1]; return $this->packages[$id - 1];
} }
public function ensureLoaded($constrainedNames) public function loadRecursively(array $packageNames, $loadDev)
{ {
$loadedMap = array();
do {
$newPackageNames = array();
$loadedCount = count($loadedMap);
foreach ($this->providerRepos as $repo) { foreach ($this->providerRepos as $repo) {
$repo->ensureLoaded($this, $constrainedNames); $packages = $repo->loadRecursively(
$packageNames,
$loadDev,
array($this, 'isPackageAcceptable')
);
foreach ($packages as $package) {
$name = $package->getName();
if (!isset($loadedMap[$name])) {
$loadedMap[$name] = true;
$newPackageNames[] = $name;
} }
$this->loadPackage($package, $repo->getRootAliases());
}
}
$packageNames = $newPackageNames;
} while (count($loadedMap) > $loadedCount);
} }
/** /**
@ -193,7 +222,7 @@ class Pool
private function computeWhatProvides($name, $constraint, $mustMatchName = false) private function computeWhatProvides($name, $constraint, $mustMatchName = false)
{ {
$candidates = array(); $candidates = array();
/*
foreach ($this->providerRepos as $repo) { foreach ($this->providerRepos as $repo) {
foreach ($repo->whatProvides($this, $name) as $candidate) { foreach ($repo->whatProvides($this, $name) as $candidate) {
$candidates[] = $candidate; $candidates[] = $candidate;
@ -202,7 +231,7 @@ class Pool
$this->packages[$this->id - 2] = $candidate; $this->packages[$this->id - 2] = $candidate;
} }
} }
} }*/
if ($mustMatchName) { if ($mustMatchName) {
$candidates = array_filter($candidates, function ($candidate) use ($name) { $candidates = array_filter($candidates, function ($candidate) use ($name) {

View File

@ -170,19 +170,16 @@ class Solver
$this->setupInstalledMap(); $this->setupInstalledMap();
$constrainedNames = array(); $packageNames = array();
foreach ($this->jobs as $job) { foreach ($this->jobs as $job) {
switch ($job['cmd']) { switch ($job['cmd']) {
case 'install': case 'install':
$constrainedNames[] = array( $packageNames[] = $job['packageName'];
'name' => $job['packageName'],
'constraint' => $job['constraint'],
);
break; break;
} }
} }
$this->pool->ensureLoaded($constrainedNames); $this->pool->loadRecursively($packageNames, true);
$this->rules = $this->ruleSetGenerator->getRulesFor($this->jobs, $this->installedMap, $ignorePlatformReqs); $this->rules = $this->ruleSetGenerator->getRulesFor($this->jobs, $this->installedMap, $ignorePlatformReqs);
$this->checkForRootRequireProblems($ignorePlatformReqs); $this->checkForRootRequireProblems($ignorePlatformReqs);

View File

@ -43,10 +43,9 @@ class ComposerRepository extends ArrayRepository
protected $searchUrl; protected $searchUrl;
protected $hasProviders = false; protected $hasProviders = false;
protected $providersUrl; protected $providersUrl;
protected $loadedMap = array();
protected $lazyProvidersUrl; protected $lazyProvidersUrl;
protected $providerListing; protected $providerListing;
protected $providers = array();
protected $providersByUid = array();
protected $loader; protected $loader;
protected $rootAliases; protected $rootAliases;
protected $allowSslDowngrade = false; protected $allowSslDowngrade = false;
@ -96,38 +95,47 @@ class ComposerRepository extends ArrayRepository
$this->rootAliases = $rootAliases; $this->rootAliases = $rootAliases;
} }
public function ensureLoaded($pool, array $constrainedNames) public function getRootAliases()
{
return $this->rootAliases;
}
public function loadRecursively(array $packageNames, $loadDev, $acceptableCallback)
{ {
$workQueue = new \SplQueue; $workQueue = new \SplQueue;
foreach ($constrainedNames as $packageSpec) { foreach ($packageNames as $packageName) {
$workQueue->enqueue($packageSpec); $workQueue->enqueue($packageName);
} }
$loadedMap = array(); $loadedPackages = array();
while (!$workQueue->isEmpty()) { while (!$workQueue->isEmpty()) {
$packageSpec = $workQueue->dequeue(); $packageName = $workQueue->dequeue();
if (isset($this->loadedMap[$packageSpec['name']])) { if (isset($this->loadedMap[$packageName])) {
continue; continue;
} }
$this->loadedMap[$packageSpec['name']] = true; $this->loadedMap[$packageName] = true;
$packages = $this->loadName($pool, $packageSpec['name']); $packages = $this->loadName($packageName, $acceptableCallback);
foreach ($packages as $package) { foreach ($packages as $package) {
foreach ($package->getRequires() as $link) { $loadedPackages[] = $package;
$workQueue->enqueue(array( $requires = $package->getRequires();
'name' => $link->getTarget(), if ($loadDev) {
'constraint' => $link->getConstraint() $requires = array_merge($requires, $package->getDevRequires());
));
} }
foreach ($requires as $link) {
$workQueue->enqueue($link->getTarget());
} }
} }
} }
protected function loadName($pool, $name) return $loadedPackages;
}
protected function loadName($name, $acceptableCallback)
{ {
// skip platform packages // skip platform packages
if (preg_match(PlatformRepository::PLATFORM_PACKAGE_REGEX, $name) || '__root__' === $name) { if (preg_match(PlatformRepository::PLATFORM_PACKAGE_REGEX, $name) || '__root__' === $name) {
@ -145,7 +153,6 @@ class ComposerRepository extends ArrayRepository
} elseif ($this->providersUrl) { } elseif ($this->providersUrl) {
// package does not exist in this repo // package does not exist in this repo
if (!isset($this->providerListing[$name])) { if (!isset($this->providerListing[$name])) {
$this->providers[$name] = array();
return array(); return array();
} }
@ -158,7 +165,6 @@ class ComposerRepository extends ArrayRepository
// package does not exist in this repo // package does not exist in this repo
if (!isset($this->providerListing[$url])) { if (!isset($this->providerListing[$url])) {
$this->providers[$name] = array();
return array(); return array();
} }
$hash = $this->providerListing[$url]['sha256']; $hash = $this->providerListing[$url]['sha256'];
@ -171,7 +177,6 @@ class ComposerRepository extends ArrayRepository
$packages = $this->fetchFile($url, $cacheKey, $hash); $packages = $this->fetchFile($url, $cacheKey, $hash);
} }
$this->providers[$name] = array();
$loadedPackages = array(); $loadedPackages = array();
foreach ($packages['packages'] as $versions) { foreach ($packages['packages'] as $versions) {
foreach ($versions as $version) { foreach ($versions as $version) {
@ -179,14 +184,7 @@ class ComposerRepository extends ArrayRepository
continue; continue;
} }
// avoid loading the same objects twice if (!$acceptableCallback(strtolower($version['name']), VersionParser::parseStability($version['version']))) {
if (isset($this->providersByUid[$version['uid']])) {
/**
* @todo verify and remove
*/
throw new \RuntimeException("Should not happen anymore");
} else {
if (!$pool->isPackageAcceptable(strtolower($version['name']), VersionParser::parseStability($version['version']))) {
continue; continue;
} }
@ -201,39 +199,6 @@ class ComposerRepository extends ArrayRepository
$aliased->setRepository($this); $aliased->setRepository($this);
$loadedPackages[] = $aliased; $loadedPackages[] = $aliased;
foreach ($aliased->getNames() as $providedName) {
$this->providers[$providedName][$version['uid']] = $aliased;
$this->providers[$providedName][$version['uid'].'-alias'] = $package;
}
// override provider with its alias so it can be expanded in the if block above
$this->providersByUid[$version['uid']] = $package;
} else {
foreach ($package->getNames() as $providedName) {
$this->providers[$providedName][$version['uid']] = $package;
}
$this->providersByUid[$version['uid']] = $package;
}
// handle root package aliases
unset($rootAliasData);
if (isset($this->rootAliases[$package->getName()][$package->getVersion()])) {
$rootAliasData = $this->rootAliases[$package->getName()][$package->getVersion()];
} elseif ($package instanceof AliasPackage && isset($this->rootAliases[$package->getName()][$package->getAliasOf()->getVersion()])) {
$rootAliasData = $this->rootAliases[$package->getName()][$package->getAliasOf()->getVersion()];
}
if (isset($rootAliasData)) {
$alias = $this->createAliasPackage($package, $rootAliasData['alias_normalized'], $rootAliasData['alias']);
$alias->setRepository($this);
$loadedPackages[] = $alias;
$this->providers[$name][$version['uid'].'-root'] = $alias;
$this->providersByUid[$version['uid'].'-root'] = $alias;
}
} }
} }
} }
@ -385,31 +350,9 @@ class ComposerRepository extends ArrayRepository
return $this->hasProviders; return $this->hasProviders;
} }
public function resetPackageIds()
{
foreach ($this->providersByUid as $package) {
if ($package instanceof AliasPackage) {
$package->getAliasOf()->setId(-1);
}
$package->setId(-1);
}
}
public function whatProvides(Pool $pool, $name) public function whatProvides(Pool $pool, $name)
{ {
if (isset($this->providers[$name])) { throw new \RuntimeException("Runtime repository provider calculation no longer occurs");
return $this->providers[$name];
}
// skip platform packages
if (preg_match(PlatformRepository::PLATFORM_PACKAGE_REGEX, $name) || '__root__' === $name || 'composer-plugin-api' === $name) {
return array();
}
/**
* @todo verify this is no longer possible and change code to remove this
*/
throw new \RuntimeException("Could not find package that should have been loaded.");
} }
/** /**