Procházet zdrojové kódy

POC Implementation of loading only explicitly named package data

Nils Adermann před 10 roky
rodič
revize
4d0db5add6

+ 7 - 0
src/Composer/DependencyResolver/Pool.php

@@ -160,6 +160,13 @@ class Pool
         return $this->packages[$id - 1];
     }
 
+    public function ensureLoaded($constrainedNames)
+    {
+        foreach ($this->providerRepos as $repo) {
+            $repo->ensureLoaded($this, $constrainedNames);
+        }
+    }
+
     /**
      * Searches all packages providing the given package name and match the constraint
      *

+ 15 - 0
src/Composer/DependencyResolver/Solver.php

@@ -169,6 +169,21 @@ class Solver
         $this->jobs = $request->getJobs();
 
         $this->setupInstalledMap();
+
+        $constrainedNames = array();
+        foreach ($this->jobs as $job) {
+            switch ($job['cmd']) {
+                case 'install':
+                    $constrainedNames[] = array(
+                        'name' => $job['packageName'],
+                        'constraint' => $job['constraint'],
+                    );
+                    break;
+            }
+        }
+
+        $this->pool->ensureLoaded($constrainedNames);
+
         $this->rules = $this->ruleSetGenerator->getRulesFor($this->jobs, $this->installedMap, $ignorePlatformReqs);
         $this->checkForRootRequireProblems($ignorePlatformReqs);
         $this->decisions = new Decisions($this->pool);

+ 159 - 1
src/Composer/Repository/ComposerRepository.php

@@ -96,6 +96,161 @@ class ComposerRepository extends ArrayRepository
         $this->rootAliases = $rootAliases;
     }
 
+    public function ensureLoaded($pool, array $constrainedNames)
+    {
+        $workQueue = new \SplQueue;
+
+        foreach ($constrainedNames as $packageSpec) {
+            $workQueue->enqueue($packageSpec);
+        }
+
+        $loadedMap = array();
+
+        while (!$workQueue->isEmpty()) {
+            $packageSpec = $workQueue->dequeue();
+            if (isset($this->loadedMap[$packageSpec['name']])) {
+                continue;
+            }
+
+            $this->loadedMap[$packageSpec['name']] = true;
+
+            $packages = $this->loadName($pool, $packageSpec['name']);
+
+            foreach ($packages as $package) {
+                foreach ($package->getRequires() as $link) {
+                    $workQueue->enqueue(array(
+                        'name' => $link->getTarget(),
+                        'constraint' => $link->getConstraint()
+                    ));
+                }
+            }
+        }
+    }
+
+    protected function loadName($pool, $name)
+    {echo "Loading $name\n";
+        // skip platform packages
+        if (preg_match(PlatformRepository::PLATFORM_PACKAGE_REGEX, $name) || '__root__' === $name) {
+            return array();
+        }
+
+        if (null === $this->providerListing) {
+            $this->loadProviderListings($this->loadRootServerFile());
+        }
+
+        if ($this->lazyProvidersUrl && !isset($this->providerListing[$name])) {
+            $hash = null;
+            $url = str_replace('%package%', $name, $this->lazyProvidersUrl);
+            $cacheKey = false;
+        } elseif ($this->providersUrl) {
+            // package does not exist in this repo
+            if (!isset($this->providerListing[$name])) {
+                $this->providers[$name] = array();
+                return array();
+            }
+
+            $hash = $this->providerListing[$name]['sha256'];
+            $url = str_replace(array('%package%', '%hash%'), array($name, $hash), $this->providersUrl);
+            $cacheKey = 'provider-'.strtr($name, '/', '$').'.json';
+        } else {
+            // BC handling for old providers-includes
+            $url = 'p/'.$name.'.json';
+
+            // package does not exist in this repo
+            if (!isset($this->providerListing[$url])) {
+                $this->providers[$name] = array();
+                return array();
+            }
+            $hash = $this->providerListing[$url]['sha256'];
+            $cacheKey = null;
+        }
+
+        if ($cacheKey && $this->cache->sha256($cacheKey) === $hash) {
+            $packages = json_decode($this->cache->read($cacheKey), true);
+        } else {
+            $packages = $this->fetchFile($url, $cacheKey, $hash);
+        }
+
+        $this->providers[$name] = array();
+        $loadedPackages = array();
+        foreach ($packages['packages'] as $versions) {
+            foreach ($versions as $version) {
+                if ($version['name'] !== $name) {
+                    continue;
+                }
+
+                // avoid loading the same objects twice
+                if (isset($this->providersByUid[$version['uid']])) {die("wtf?");
+                    // skip if already assigned
+                    if (!isset($this->providers[$name][$version['uid']])) {
+                        // expand alias in two packages
+                        if ($this->providersByUid[$version['uid']] instanceof AliasPackage) {
+                            $this->providers[$name][$version['uid']] = $this->providersByUid[$version['uid']]->getAliasOf();
+                            $this->providers[$name][$version['uid'].'-alias'] = $this->providersByUid[$version['uid']];
+                        } else {
+                            $this->providers[$name][$version['uid']] = $this->providersByUid[$version['uid']];
+                        }
+                        // check for root aliases
+                        if (isset($this->providersByUid[$version['uid'].'-root'])) {
+                            $this->providers[$name][$version['uid'].'-root'] = $this->providersByUid[$version['uid'].'-root'];
+                        }
+                    }
+                } else {
+                    if (!$pool->isPackageAcceptable(strtolower($version['name']), VersionParser::parseStability($version['version']))) {
+                        continue;
+                    }
+
+                    // load acceptable packages in the providers
+                    $package = $this->createPackage($version, 'Composer\Package\Package');
+                    $package->setRepository($this);
+
+                    $loadedPackages[] = $package;
+
+                    if ($package instanceof AliasPackage) {
+                        $aliased = $package->getAliasOf();
+                        $aliased->setRepository($this);
+
+                        $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;
+                    }
+                }
+            }
+        }
+
+        return $loadedPackages;
+    }
+
     /**
      * {@inheritDoc}
      */
@@ -257,9 +412,12 @@ class ComposerRepository extends ArrayRepository
         }
 
         // skip platform packages
-        if (preg_match(PlatformRepository::PLATFORM_PACKAGE_REGEX, $name) || '__root__' === $name) {
+        if (preg_match(PlatformRepository::PLATFORM_PACKAGE_REGEX, $name) || '__root__' === $name || 'composer-plugin-api' === $name) {
             return array();
         }
+        var_dump($name);
+        debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
+        die("should not reach\n");
 
         if (null === $this->providerListing) {
             $this->loadProviderListings($this->loadRootServerFile());