예제 #1
0
 public function whatProvides(Pool $pool, $name)
 {
     if (isset($this->providers[$name])) {
         return $this->providers[$name];
     }
     // 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])) {
             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])) {
             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();
     foreach ($packages['packages'] as $versions) {
         foreach ($versions as $version) {
             // avoid loading the same objects twice
             if (isset($this->providersByUid[$version['uid']])) {
                 // 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 (isset($version['provide']) || isset($version['replace'])) {
                     // collect names
                     $names = array(strtolower($version['name']) => true);
                     if (isset($version['provide'])) {
                         foreach ($version['provide'] as $target => $constraint) {
                             $names[strtolower($target)] = true;
                         }
                     }
                     if (isset($version['replace'])) {
                         foreach ($version['replace'] as $target => $constraint) {
                             $names[strtolower($target)] = true;
                         }
                     }
                     $names = array_keys($names);
                 } else {
                     $names = array(strtolower($version['name']));
                 }
                 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);
                 if ($package instanceof AliasPackage) {
                     $aliased = $package->getAliasOf();
                     $aliased->setRepository($this);
                     $this->providers[$name][$version['uid']] = $aliased;
                     $this->providers[$name][$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 {
                     $this->providers[$name][$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);
                     $this->providers[$name][$version['uid'] . '-root'] = $alias;
                     $this->providersByUid[$version['uid'] . '-root'] = $alias;
                 }
             }
         }
     }
     return $this->providers[$name];
 }
예제 #2
0
 /**
  * @param  Pool        $pool
  * @param  string      $name          package name
  * @param  bool        $bypassFilters If set to true, this bypasses the stability filtering, and forces a recompute without cache
  * @return array|mixed
  */
 public function whatProvides(Pool $pool, $name, $bypassFilters = false)
 {
     if (isset($this->providers[$name]) && !$bypassFilters) {
         return $this->providers[$name];
     }
     // skip platform packages, root package and composer-plugin-api
     if (preg_match(PlatformRepository::PLATFORM_PACKAGE_REGEX, $name) || '__root__' === $name || 'composer-plugin-api' === $name) {
         return array();
     }
     if (null === $this->providerListing) {
         $this->loadProviderListings($this->loadRootServerFile());
     }
     $useLastModifiedCheck = false;
     if ($this->lazyProvidersUrl && !isset($this->providerListing[$name])) {
         $hash = null;
         $url = str_replace('%package%', $name, $this->lazyProvidersUrl);
         $cacheKey = 'provider-' . strtr($name, '/', '$') . '.json';
         $useLastModifiedCheck = true;
     } elseif ($this->providersUrl) {
         // package does not exist in this repo
         if (!isset($this->providerListing[$name])) {
             return array();
         }
         $hash = $this->providerListing[$name]['sha256'];
         $url = str_replace(array('%package%', '%hash%'), array($name, $hash), $this->providersUrl);
         $cacheKey = 'provider-' . strtr($name, '/', '$') . '.json';
     } else {
         return array();
     }
     $packages = null;
     if ($cacheKey) {
         if (!$useLastModifiedCheck && $hash && $this->cache->sha256($cacheKey) === $hash) {
             $packages = json_decode($this->cache->read($cacheKey), true);
         } elseif ($useLastModifiedCheck) {
             if ($contents = $this->cache->read($cacheKey)) {
                 $contents = json_decode($contents, true);
                 if (isset($contents['last-modified'])) {
                     $response = $this->fetchFileIfLastModified($url, $cacheKey, $contents['last-modified']);
                     if (true === $response) {
                         $packages = $contents;
                     } elseif ($response) {
                         $packages = $response;
                     }
                 }
             }
         }
     }
     if (!$packages) {
         try {
             $packages = $this->fetchFile($url, $cacheKey, $hash, $useLastModifiedCheck);
         } catch (TransportException $e) {
             // 404s are acceptable for lazy provider repos
             if ($e->getStatusCode() === 404 && $this->lazyProvidersUrl) {
                 $packages = array('packages' => array());
             } else {
                 throw $e;
             }
         }
     }
     $this->providers[$name] = array();
     foreach ($packages['packages'] as $versions) {
         foreach ($versions as $version) {
             // avoid loading the same objects twice
             if (isset($this->providersByUid[$version['uid']])) {
                 // 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 (!$bypassFilters && !$pool->isPackageAcceptable(strtolower($version['name']), VersionParser::parseStability($version['version']))) {
                     continue;
                 }
                 // load acceptable packages in the providers
                 $package = $this->createPackage($version, 'Composer\\Package\\CompletePackage');
                 $package->setRepository($this);
                 if ($package instanceof AliasPackage) {
                     $aliased = $package->getAliasOf();
                     $aliased->setRepository($this);
                     $this->providers[$name][$version['uid']] = $aliased;
                     $this->providers[$name][$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 {
                     $this->providers[$name][$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);
                     $this->providers[$name][$version['uid'] . '-root'] = $alias;
                     $this->providersByUid[$version['uid'] . '-root'] = $alias;
                 }
             }
         }
     }
     $result = $this->providers[$name];
     // clean up the cache because otherwise using this puts the repo in an inconsistent state with a polluted unfiltered cache
     // which is likely not an issue but might cause hard to track behaviors depending on how the repo is used
     if ($bypassFilters) {
         foreach ($this->providers[$name] as $uid => $provider) {
             unset($this->providersByUid[$uid]);
         }
         unset($this->providers[$name]);
     }
     return $result;
 }
예제 #3
0
 public function whatProvides(Pool $pool, $name)
 {
     // skip platform packages
     if ($name === 'php' || in_array(substr($name, 0, 4), array('ext-', 'lib-'), true) || $name === '__root__') {
         return array();
     }
     if (isset($this->providers[$name])) {
         return $this->providers[$name];
     }
     if (null === $this->providerListing) {
         $this->loadProviderListings($this->loadRootServerFile());
     }
     $url = 'p/' . $name . '.json';
     // package does not exist in this repo
     if (!isset($this->providerListing[$url])) {
         return array();
     }
     if ($this->cache->sha256($url) === $this->providerListing[$url]['sha256']) {
         $packages = json_decode($this->cache->read($url), true);
     } else {
         $packages = $this->fetchFile($url, null, $this->providerListing[$url]['sha256']);
     }
     $this->providers[$name] = array();
     foreach ($packages['packages'] as $versions) {
         foreach ($versions as $version) {
             // avoid loading the same objects twice
             if (isset($this->providersByUid[$version['uid']])) {
                 // 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);
                 $this->providers[$name][$version['uid']] = $package;
                 $this->providersByUid[$version['uid']] = $package;
                 if ($package->getAlias()) {
                     $alias = $this->createAliasPackage($package);
                     $alias->setRepository($this);
                     $this->providers[$name][$version['uid'] . '-alias'] = $alias;
                     // override provider with its alias so it can be expanded in the if block above
                     $this->providersByUid[$version['uid']] = $alias;
                 }
                 // handle root package aliases
                 unset($rootAliasData);
                 if (isset($this->rootAliases[$name][$package->getVersion()])) {
                     $rootAliasData = $this->rootAliases[$name][$package->getVersion()];
                 } elseif (($aliasNormalized = $package->getAlias()) && isset($this->rootAliases[$name][$aliasNormalized])) {
                     $rootAliasData = $this->rootAliases[$name][$aliasNormalized];
                 }
                 if (isset($rootAliasData)) {
                     $alias = $this->createAliasPackage($package, $rootAliasData['alias_normalized'], $rootAliasData['alias']);
                     $alias->setRepository($this);
                     $this->providers[$name][$version['uid'] . '-root'] = $alias;
                     $this->providersByUid[$version['uid'] . '-root'] = $alias;
                 }
             }
         }
     }
     return $this->providers[$name];
 }
예제 #4
0
 public function whatProvides(Pool $pool, $name)
 {
     if (isset($this->providers[$name])) {
         return $this->providers[$name];
     }
     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) {
         if (!isset($this->providerListing[$name])) {
             return array();
         }
         $hash = $this->providerListing[$name]['sha256'];
         $url = str_replace(array('%package%', '%hash%'), array($name, $hash), $this->providersUrl);
         $cacheKey = 'provider-' . strtr($name, '/', '$') . '.json';
     } else {
         $url = 'p/' . $name . '.json';
         if (!isset($this->providerListing[$url])) {
             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();
     foreach ($packages['packages'] as $versions) {
         foreach ($versions as $version) {
             if (isset($this->providersByUid[$version['uid']])) {
                 if (!isset($this->providers[$name][$version['uid']])) {
                     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']];
                     }
                     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;
                 }
                 $package = $this->createPackage($version, 'Composer\\Package\\Package');
                 $package->setRepository($this);
                 if ($package instanceof AliasPackage) {
                     $aliased = $package->getAliasOf();
                     $aliased->setRepository($this);
                     $this->providers[$name][$version['uid']] = $aliased;
                     $this->providers[$name][$version['uid'] . '-alias'] = $package;
                     $this->providersByUid[$version['uid']] = $package;
                 } else {
                     $this->providers[$name][$version['uid']] = $package;
                     $this->providersByUid[$version['uid']] = $package;
                 }
                 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);
                     $this->providers[$name][$version['uid'] . '-root'] = $alias;
                     $this->providersByUid[$version['uid'] . '-root'] = $alias;
                 }
             }
         }
     }
     return $this->providers[$name];
 }
예제 #5
0
 public function whatProvides(Pool $pool, $name, $bypassFilters = false)
 {
     // split on vendor and name
     if (count($parts = explode('/', $name)) !== 2) {
         return [];
     }
     list($vendor, $shortName) = $parts;
     // does the vendor match one of our virtual vendors?
     if (!isset($this->vendors[$vendor])) {
         return [];
     }
     // do we already have its packages?
     if (isset($this->providers[$name])) {
         return $this->providers[$name];
     }
     // make sure the providers have been loaded
     $this->loadProviders();
     // does the shortname even exist in this repo?
     if (!isset($this->providerHash[$shortName])) {
         return [];
     }
     // base url for the requested set of packages (i.e. the provider)
     // there should be no trailing slash
     $providerUrl = $this->providerHash[$shortName];
     $packages = [];
     // get a listing of available packages
     // these are paths under the provider url where we should find actual packages
     foreach ((array) $this->repoConfig->get('package-paths') as $path) {
         // the relative path without surrounding slashes
         $relPath = trim($path, '/');
         // if the path ends with a slash, we grab its subdirectories
         if (substr($path, -1) === '/') {
             // try to fetch the packages!
             try {
                 if ($this->io->isVerbose()) {
                     $this->io->writeError("Fetching available versions for {$name}");
                 }
                 $pkgRaw = $this->svnUtil->execute('ls', "{$providerUrl}/{$relPath}");
             } catch (\RuntimeException $e) {
                 // @todo maybe don't throw an exception and just pass this one up?
                 throw new \RuntimeException("SVN Error: Could not retrieve package listing for {$name}. " . $e->getMessage());
             }
             // check the versions and add any good ones to the set
             foreach (SvnUtil::parseSvnList($pkgRaw) as $version) {
                 // format the version identifier to be composer-compatible
                 $version = Util::fixVersion($version, 'dev-default');
                 $version = Util::callFilter($this->repoConfig->get('version-filter'), $version, $name, $path, $providerUrl);
                 // if the version string is empty, we don't take it
                 if (!empty($version)) {
                     $packages[$version] = trim("{$relPath}/{$version}", '/');
                 }
             }
         } else {
             // otherwise we add as-is (no checking is performed to see if this reference really exists)
             // @todo: perhaps add an optional check?
             $version = Util::fixVersion(basename($path), 'dev-default');
             $version = Util::callFilter($this->repoConfig->get('version-filter'), $version, $name, $path, $providerUrl);
             // if the version string is empty, we don't take it
             if (!empty($version)) {
                 $packages[$version] = $relPath;
             }
         }
     }
     // store the providers based on its full name (i.e. with vendor)
     // this allows the same package to be loaded as different types,
     // which allows the package type to be changed in composer.json,
     // i.e. the type that is being removed AND the type that is being installed
     // both have to exist during the solving
     $this->providers[$name] = [];
     // create a package for each tag
     foreach ($packages as $version => $reference) {
         if (!$pool->isPackageAcceptable($shortName, VersionParser::parseStability($version))) {
             continue;
         }
         // first, setup the repo-determined package properties
         $data = ['name' => $name, 'version' => $version, 'type' => $this->vendors[$vendor], 'source' => ['type' => 'svn', 'url' => "{$providerUrl}/", 'reference' => $reference ?: '/']];
         // next, fill in any defaults that were missing
         if (($defaults = $this->repoConfig->get('package-defaults')) && is_array($defaults)) {
             $data = array_merge($defaults, $data);
         }
         // finally, apply any overrides
         if (($overrides = $this->repoConfig->get('package-overrides')) && is_array($overrides)) {
             $data = array_replace($data, $overrides);
         }
         // create the package object
         $package = $this->createPackage($data, 'Composer\\Package\\CompletePackage');
         $package->setRepository($this);
         // add "replaces" array for any other vendors that this repository supports
         if (count($this->vendors) > 1) {
             $replaces = [];
             $constraint = new Constraint('=', $package->getVersion());
             foreach ($this->vendors as $vendorName => $type) {
                 // it doesn't replace itself
                 if ($vendorName === $vendor) {
                     continue;
                 }
                 $replaces[] = new Link($package->getName(), "{$vendorName}/{$shortName}", $constraint, "'{$type}' alias for", $package->getPrettyVersion());
             }
             $package->setReplaces($replaces);
         }
         // apply a filter to the package object
         Util::callFilter($this->repoConfig->get('package-filter'), $package);
         // add the package object to the set
         $this->providers[$name][$version] = $package;
         // handle root aliases
         // @todo: not sure if this is correct (this was copped from the parent class)
         if (isset($this->rootAliases[$package->getName()][$package->getVersion()])) {
             $rootAliasData = $this->rootAliases[$package->getName()][$package->getVersion()];
             $alias = $this->createAliasPackage($package, $rootAliasData['alias_normalized'], $rootAliasData['alias']);
             $alias->setRepository($this);
             $this->providers[$name][$version . '-root'] = $alias;
         }
     }
     return $this->providers[$name];
 }