Add available-packages key for new repo format, and many consistency tweaks/fixes across various repo formats

main
Jordi Boggiano 6 years ago
parent c97b7a9be5
commit 0f2f950cb6

@ -47,6 +47,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
protected $searchUrl;
protected $hasProviders = false;
protected $providersUrl;
protected $availablePackages;
protected $lazyProvidersUrl;
protected $providerListing;
protected $loader;
@ -131,20 +132,28 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
return $this->filterPackages($this->whatProvides($name), $constraint, true);
}
return $this->loadAsyncPackages(array($name => $constraint), function ($name, $stability) {
if (is_array($this->availablePackages) && !isset($this->availablePackages[$name])) {
return;
}
$packages = $this->loadAsyncPackages(array($name => $constraint), function ($name, $stability) {
return true;
});
}
if (!$hasProviders) {
return parent::findPackage($name, $constraint);
return reset($packages);
}
foreach ($this->getProviderNames() as $providerName) {
if ($name === $providerName) {
return $this->filterPackages($this->whatProvides($providerName), $constraint, true);
if ($hasProviders) {
foreach ($this->getProviderNames() as $providerName) {
if ($name === $providerName) {
return $this->filterPackages($this->whatProvides($providerName), $constraint, true);
}
}
return;
}
return parent::findPackage($name, $constraint);
}
/**
@ -165,22 +174,26 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
return $this->filterPackages($this->whatProvides($name), $constraint);
}
if (is_array($this->availablePackages) && !isset($this->availablePackages[$name])) {
return array();
}
return $this->loadAsyncPackages(array($name => $constraint ?: new EmptyConstraint()), function ($name, $stability) {
return true;
});
}
if (!$hasProviders) {
return parent::findPackages($name, $constraint);
}
foreach ($this->getProviderNames() as $providerName) {
if ($name === $providerName) {
return $this->filterPackages($this->whatProvides($providerName), $constraint);
if ($hasProviders) {
foreach ($this->getProviderNames() as $providerName) {
if ($name === $providerName) {
return $this->filterPackages($this->whatProvides($providerName), $constraint);
}
}
return array();
}
return array();
return parent::findPackages($name, $constraint);
}
private function filterPackages(array $packages, $constraint = null, $returnFirstMatch = false)
@ -216,7 +229,22 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
public function getPackages()
{
if ($this->hasProviders()) {
$hasProviders = $this->hasProviders();
if ($this->lazyProvidersUrl) {
if (is_array($this->availablePackages)) {
$packageMap = array();
foreach ($this->availablePackages as $name) {
$packageMap[$name] = new EmptyConstraint();
}
return array_values($this->loadAsyncPackages($packageMap, function ($name, $stability) { return true; }));
}
throw new \LogicException('Composer repositories that have lazy providers and no available-packages list can not load the complete list of packages, use getProviderNames instead.');
}
if ($hasProviders) {
throw new \LogicException('Composer repositories that have providers can not load the complete list of packages, use getProviderNames instead.');
}
@ -225,14 +253,28 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
public function getPackageNames()
{
if ($this->hasProviders()) {
// TODO add getPackageNames to the RepositoryInterface perhaps? With filtering capability embedded?
$hasProviders = $this->hasProviders();
if ($this->lazyProvidersUrl) {
if (is_array($this->availablePackages)) {
return array_keys($this->availablePackages);
}
// TODO implement new list API endpoint for those repos somehow?
return array();
}
if ($hasProviders) {
return $this->getProviderNames();
}
// TODO implement new list API endpoint for repos somehow?
// TODO add getPackageNames to the RepositoryInterface perhaps? With filtering capability embedded?
$names = array();
foreach ($this->getPackages() as $package) {
$names[] = $package->getPrettyName();
}
return $this->getPackages();
return $names;
}
public function loadPackages(array $packageNameMap, $isPackageAcceptableCallable)
@ -279,11 +321,16 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
unset($packageNameMap[$name]);
}
return $packages;
}
if ($this->lazyProvidersUrl && count($packageNameMap)) {
if (is_array($this->availablePackages)) {
$availPackages = $this->availablePackages;
$packageNameMap = array_filter($packageNameMap, function ($name) use ($availPackages) {
return isset($availPackages[strtolower($name)]);
}, ARRAY_FILTER_USE_KEY);
}
$packages = array_merge($packages, $this->loadAsyncPackages($packageNameMap, $isPackageAcceptableCallable));
}
@ -317,11 +364,11 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
return $results;
}
if ($this->hasProviders()) {
if ($this->hasProviders() || $this->lazyProvidersUrl) {
$results = array();
$regex = '{(?:'.implode('|', preg_split('{\s+}', $query)).')}i';
foreach ($this->getProviderNames() as $name) {
foreach ($this->getPackageNames() as $name) {
if (preg_match($regex, $name)) {
$results[] = array('name' => $name);
}
@ -683,6 +730,17 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
$this->hasProviders = false;
$this->hasPartialPackages = !empty($data['packages']) && is_array($data['packages']);
$this->allowSslDowngrade = false;
// provides a list of package names that are available in this repo
// this disables lazy-provider behavior in the sense that if a list is available we assume it is finite and won't search for other packages in that repo
// while if no list is there lazyProvidersUrl is used when looking for any package name to see if the repo knows it
if (!empty($data['available-packages'])) {
$availPackages = array_map('strtolower', $data['available-packages']);
$this->availablePackages = array_combine($availPackages, $availPackages);
}
// Remove legacy keys as most repos need to be compatible with Composer v1
// as well but we are not interested in the old format anymore at this point
unset($data['providers-url'], $data['providers'], $data['providers-includes']);
}

Loading…
Cancel
Save