Add support for one-file-per-provider composer repositories
parent
fde3477563
commit
c0e5736ae7
|
@ -20,6 +20,7 @@ use Composer\Package\LinkConstraint\LinkConstraintInterface;
|
|||
use Composer\Package\LinkConstraint\VersionConstraint;
|
||||
use Composer\Repository\RepositoryInterface;
|
||||
use Composer\Repository\CompositeRepository;
|
||||
use Composer\Repository\ComposerRepository;
|
||||
use Composer\Repository\InstalledRepositoryInterface;
|
||||
use Composer\Repository\StreamableRepositoryInterface;
|
||||
use Composer\Repository\PlatformRepository;
|
||||
|
@ -39,11 +40,13 @@ class Pool
|
|||
const MATCH_REPLACE = 3;
|
||||
|
||||
protected $repositories = array();
|
||||
protected $composerRepos = array();
|
||||
protected $packages = array();
|
||||
protected $packageByName = array();
|
||||
protected $acceptableStabilities;
|
||||
protected $stabilityFlags;
|
||||
protected $versionParser;
|
||||
protected $id = 1;
|
||||
|
||||
public function __construct($minimumStability = 'stable', array $stabilityFlags = array())
|
||||
{
|
||||
|
@ -72,18 +75,20 @@ class Pool
|
|||
$repos = array($repo);
|
||||
}
|
||||
|
||||
$id = count($this->packages) + 1;
|
||||
foreach ($repos as $repo) {
|
||||
$this->repositories[] = $repo;
|
||||
|
||||
$exempt = $repo instanceof PlatformRepository || $repo instanceof InstalledRepositoryInterface;
|
||||
if ($repo instanceof StreamableRepositoryInterface) {
|
||||
|
||||
if ($repo instanceof ComposerRepository && $repo->hasProviders()) {
|
||||
$this->composerRepos[] = $repo;
|
||||
} elseif ($repo instanceof StreamableRepositoryInterface) {
|
||||
foreach ($repo->getMinimalPackages() as $package) {
|
||||
$name = $package['name'];
|
||||
$version = $package['version'];
|
||||
$stability = VersionParser::parseStability($version);
|
||||
if ($exempt || $this->isPackageAcceptable($name, $stability)) {
|
||||
$package['id'] = $id++;
|
||||
$package['id'] = $this->id++;
|
||||
$this->packages[] = $package;
|
||||
|
||||
// collect names
|
||||
|
@ -102,7 +107,7 @@ class Pool
|
|||
}
|
||||
|
||||
foreach (array_keys($names) as $provided) {
|
||||
$this->packageByName[$provided][] =& $this->packages[$id-2];
|
||||
$this->packageByName[$provided][] =& $this->packages[$this->id - 2];
|
||||
}
|
||||
|
||||
// handle root package aliases
|
||||
|
@ -119,12 +124,12 @@ class Pool
|
|||
$alias['version'] = $rootAliasData['alias_normalized'];
|
||||
$alias['alias'] = $rootAliasData['alias'];
|
||||
$alias['alias_of'] = $package['id'];
|
||||
$alias['id'] = $id++;
|
||||
$alias['id'] = $this->id++;
|
||||
$alias['root_alias'] = true;
|
||||
$this->packages[] = $alias;
|
||||
|
||||
foreach (array_keys($names) as $name) {
|
||||
$this->packageByName[$name][] =& $this->packages[$id-2];
|
||||
$this->packageByName[$name][] =& $this->packages[$this->id - 2];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -135,11 +140,11 @@ class Pool
|
|||
$alias['version'] = $package['alias_normalized'];
|
||||
$alias['alias'] = $package['alias'];
|
||||
$alias['alias_of'] = $package['id'];
|
||||
$alias['id'] = $id++;
|
||||
$alias['id'] = $this->id++;
|
||||
$this->packages[] = $alias;
|
||||
|
||||
foreach (array_keys($names) as $name) {
|
||||
$this->packageByName[$name][] =& $this->packages[$id-2];
|
||||
$this->packageByName[$name][] =& $this->packages[$this->id - 2];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -149,7 +154,7 @@ class Pool
|
|||
$name = $package->getName();
|
||||
$stability = $package->getStability();
|
||||
if ($exempt || $this->isPackageAcceptable($name, $stability)) {
|
||||
$package->setId($id++);
|
||||
$package->setId($this->id++);
|
||||
$this->packages[] = $package;
|
||||
|
||||
foreach ($package->getNames() as $name) {
|
||||
|
@ -163,7 +168,7 @@ class Pool
|
|||
$package->setPrettyAlias($alias['alias']);
|
||||
$package->getRepository()->addPackage($aliasPackage = new AliasPackage($package, $alias['alias_normalized'], $alias['alias']));
|
||||
$aliasPackage->setRootPackageAlias(true);
|
||||
$aliasPackage->setId($id++);
|
||||
$aliasPackage->setId($this->id++);
|
||||
|
||||
$this->packages[] = $aliasPackage;
|
||||
|
||||
|
@ -208,7 +213,7 @@ class Pool
|
|||
*/
|
||||
public function getMaxId()
|
||||
{
|
||||
return count($this->packages);
|
||||
return $this->id - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -221,11 +226,25 @@ class Pool
|
|||
*/
|
||||
public function whatProvides($name, LinkConstraintInterface $constraint = null)
|
||||
{
|
||||
if (!isset($this->packageByName[$name])) {
|
||||
$candidates = array();
|
||||
|
||||
foreach ($this->composerRepos as $repo) {
|
||||
foreach ($repo->whatProvides($name) as $candidate) {
|
||||
$candidates[] = $candidate;
|
||||
if ($candidate->getId() < 1) {
|
||||
$candidate->setId($this->id++);
|
||||
$this->packages[$candidate->getId()] = $candidate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($this->packageByName[$name]) && !$candidates) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$candidates = $this->packageByName[$name];
|
||||
if (isset($this->packageByName[$name])) {
|
||||
$candidates = array_merge($candidates, $this->packageByName[$name]);
|
||||
}
|
||||
|
||||
if (null === $constraint) {
|
||||
foreach ($candidates as $key => $candidate) {
|
||||
|
|
|
@ -85,7 +85,7 @@ class JsonFile
|
|||
$json = file_get_contents($this->path);
|
||||
}
|
||||
} catch (TransportException $e) {
|
||||
throw new \RuntimeException($e->getMessage());
|
||||
throw new \RuntimeException($e->getMessage(), 0, $e);
|
||||
} catch (\Exception $e) {
|
||||
throw new \RuntimeException('Could not read '.$this->path."\n\n".$e->getMessage());
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ use Composer\Cache;
|
|||
use Composer\Config;
|
||||
use Composer\IO\IOInterface;
|
||||
use Composer\Util\RemoteFilesystem;
|
||||
use Composer\Downloader\TransportException;
|
||||
|
||||
/**
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
|
@ -32,10 +33,14 @@ class ComposerRepository extends ArrayRepository implements NotifiableRepository
|
|||
protected $io;
|
||||
protected $cache;
|
||||
protected $notifyUrl;
|
||||
protected $providersUrl;
|
||||
protected $providers = array();
|
||||
protected $providersByUid = array();
|
||||
protected $loader;
|
||||
private $rawData;
|
||||
private $minimalPackages;
|
||||
private $degradedMode = false;
|
||||
private $rootData;
|
||||
|
||||
public function __construct(array $repoConfig, IOInterface $io, Config $config)
|
||||
{
|
||||
|
@ -182,6 +187,55 @@ class ComposerRepository extends ArrayRepository implements NotifiableRepository
|
|||
return $aliasPackage;
|
||||
}
|
||||
|
||||
public function hasProviders()
|
||||
{
|
||||
$this->loadRootServerFile();
|
||||
|
||||
return null !== $this->providersUrl;
|
||||
}
|
||||
|
||||
public function whatProvides($name)
|
||||
{
|
||||
if (isset($this->providers[$name])) {
|
||||
return $this->providers[$name];
|
||||
}
|
||||
|
||||
$url = str_replace('%package%', strtolower($name), $this->providersUrl);
|
||||
|
||||
try {
|
||||
$json = new JsonFile($url, new RemoteFilesystem($this->io));
|
||||
$packages = $json->read();
|
||||
} catch (\RuntimeException $e) {
|
||||
if (!$e->getPrevious() instanceof TransportException || $e->getPrevious()->getCode() !== 404) {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
$this->providers[$name] = array();
|
||||
foreach ($packages['packages'] as $name => $versions) {
|
||||
foreach ($versions as $version) {
|
||||
if (isset($this->providersByUid[$version['uid']])) {
|
||||
$this->providers[$name][] = $this->providersByUid[$version['uid']];
|
||||
} else {
|
||||
$package = $this->createPackage($version, 'Composer\Package\Package');
|
||||
$package->setRepository($this);
|
||||
|
||||
$this->providers[$name][] = $package;
|
||||
$this->providersByUid[$version['uid']] = $package;
|
||||
|
||||
if ($package->getAlias()) {
|
||||
$alias = $this->createAliasPackage($package);
|
||||
|
||||
$this->providers[$name][] = $alias;
|
||||
$this->providersByUid[$version['uid']] = $alias;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->providers[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
@ -196,8 +250,12 @@ class ComposerRepository extends ArrayRepository implements NotifiableRepository
|
|||
}
|
||||
}
|
||||
|
||||
protected function loadDataFromServer()
|
||||
protected function loadRootServerFile()
|
||||
{
|
||||
if (null !== $this->rootData) {
|
||||
return $this->rootData;
|
||||
}
|
||||
|
||||
if (!extension_loaded('openssl') && 'https' === substr($this->url, 0, 5)) {
|
||||
throw new \RuntimeException('You must enable the openssl extension in your php.ini to load information from '.$this->url);
|
||||
}
|
||||
|
@ -220,6 +278,21 @@ class ComposerRepository extends ArrayRepository implements NotifiableRepository
|
|||
}
|
||||
}
|
||||
|
||||
if (!empty($data['providers'])) {
|
||||
if ('/' === $data['providers'][0]) {
|
||||
$this->providersUrl = preg_replace('{(https?://[^/]+).*}i', '$1' . $data['providers'], $this->url);
|
||||
} else {
|
||||
$this->providersUrl = $data['providers'];
|
||||
}
|
||||
}
|
||||
|
||||
return $this->rootData = $data;
|
||||
}
|
||||
|
||||
protected function loadDataFromServer()
|
||||
{
|
||||
$data = $this->loadRootServerFile();
|
||||
|
||||
return $this->loadIncludes($data);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue