Add support for list URL in composer repos, fixes #9009
parent
45f228a375
commit
70f211923b
|
@ -74,3 +74,9 @@ If your repository only has a small number of packages, and you want to avoid th
|
||||||
`"providers-api": "https://packagist.org/providers/%package%.json",`
|
`"providers-api": "https://packagist.org/providers/%package%.json",`
|
||||||
|
|
||||||
The providers-api is optional, but if you implement it it should return packages which provide a given package name, but not the package which has that name. For example https://packagist.org/providers/monolog/monolog.json lists some package which have a "provide" rule for monolog/monolog, but it does not list monolog/monolog itself.
|
The providers-api is optional, but if you implement it it should return packages which provide a given package name, but not the package which has that name. For example https://packagist.org/providers/monolog/monolog.json lists some package which have a "provide" rule for monolog/monolog, but it does not list monolog/monolog itself.
|
||||||
|
|
||||||
|
### list
|
||||||
|
|
||||||
|
This is also optional, it should accept an optional `?filter=xx` query param, which can contain `*` as wildcards matching any substring.
|
||||||
|
|
||||||
|
It must return an array of package names as `{"packageNames": ["a/b", "c/d"]}`. See https://packagist.org/packages/list.json?filter=composer/* for example.
|
||||||
|
|
|
@ -299,8 +299,9 @@ EOT
|
||||||
|
|
||||||
// list packages
|
// list packages
|
||||||
$packages = array();
|
$packages = array();
|
||||||
|
$packageFilterRegex = null;
|
||||||
if (null !== $packageFilter) {
|
if (null !== $packageFilter) {
|
||||||
$packageFilter = '{^'.str_replace('\\*', '.*?', preg_quote($packageFilter)).'$}i';
|
$packageFilterRegex = '{^'.str_replace('\\*', '.*?', preg_quote($packageFilter)).'$}i';
|
||||||
}
|
}
|
||||||
|
|
||||||
$packageListFilter = array();
|
$packageListFilter = array();
|
||||||
|
@ -342,18 +343,16 @@ EOT
|
||||||
$type = 'available';
|
$type = 'available';
|
||||||
}
|
}
|
||||||
if ($repo instanceof ComposerRepository) {
|
if ($repo instanceof ComposerRepository) {
|
||||||
foreach ($repo->getPackageNames() as $name) {
|
foreach ($repo->getPackageNames($packageFilter) as $name) {
|
||||||
if (!$packageFilter || preg_match($packageFilter, $name)) {
|
|
||||||
$packages[$type][$name] = $name;
|
$packages[$type][$name] = $name;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
foreach ($repo->getPackages() as $package) {
|
foreach ($repo->getPackages() as $package) {
|
||||||
if (!isset($packages[$type][$package->getName()])
|
if (!isset($packages[$type][$package->getName()])
|
||||||
|| !is_object($packages[$type][$package->getName()])
|
|| !is_object($packages[$type][$package->getName()])
|
||||||
|| version_compare($packages[$type][$package->getName()]->getVersion(), $package->getVersion(), '<')
|
|| version_compare($packages[$type][$package->getName()]->getVersion(), $package->getVersion(), '<')
|
||||||
) {
|
) {
|
||||||
if (!$packageFilter || preg_match($packageFilter, $package->getName())) {
|
if (!$packageFilterRegex || preg_match($packageFilterRegex, $package->getName())) {
|
||||||
if (!$packageListFilter || in_array($package->getName(), $packageListFilter, true)) {
|
if (!$packageListFilter || in_array($package->getName(), $packageListFilter, true)) {
|
||||||
$packages[$type][$package->getName()] = $package;
|
$packages[$type][$package->getName()] = $package;
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,6 +58,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
|
||||||
protected $providersApiUrl;
|
protected $providersApiUrl;
|
||||||
protected $hasProviders = false;
|
protected $hasProviders = false;
|
||||||
protected $providersUrl;
|
protected $providersUrl;
|
||||||
|
protected $listUrl;
|
||||||
protected $availablePackages;
|
protected $availablePackages;
|
||||||
protected $lazyProvidersUrl;
|
protected $lazyProvidersUrl;
|
||||||
protected $providerListing;
|
protected $providerListing;
|
||||||
|
@ -288,33 +289,53 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
|
||||||
return parent::getPackages();
|
return parent::getPackages();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getPackageNames()
|
public function getPackageNames($packageFilter = null)
|
||||||
{
|
{
|
||||||
// TODO add getPackageNames to the RepositoryInterface perhaps? With filtering capability embedded?
|
|
||||||
$hasProviders = $this->hasProviders();
|
$hasProviders = $this->hasProviders();
|
||||||
|
|
||||||
|
$packageFilterCb = function ($name) {
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
if (null !== $packageFilter) {
|
||||||
|
$packageFilterRegex = '{^'.str_replace('\\*', '.*?', preg_quote($packageFilter)).'$}i';
|
||||||
|
$packageFilterCb = function ($name) use ($packageFilterRegex) {
|
||||||
|
return (bool) preg_match($packageFilterRegex, $name);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
if ($this->lazyProvidersUrl) {
|
if ($this->lazyProvidersUrl) {
|
||||||
if (is_array($this->availablePackages)) {
|
if (is_array($this->availablePackages)) {
|
||||||
return array_keys($this->availablePackages);
|
return array_filter(array_keys($this->availablePackages), $packageFilterCb);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO implement new list API endpoint for those repos somehow?
|
if ($this->listUrl) {
|
||||||
|
$url = $this->listUrl;
|
||||||
|
if ($packageFilter) {
|
||||||
|
$url .= '?filter='.urlencode($packageFilter);
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = $this->httpDownloader->get($url, $this->options)->decodeJson();
|
||||||
|
|
||||||
|
return $result['packageNames'];
|
||||||
|
}
|
||||||
|
|
||||||
if ($this->hasPartialPackages()) {
|
if ($this->hasPartialPackages()) {
|
||||||
return array_keys($this->partialPackagesByName);
|
return array_filter(array_keys($this->partialPackagesByName), $packageFilterCb);
|
||||||
}
|
}
|
||||||
|
|
||||||
return array();
|
return array();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($hasProviders) {
|
if ($hasProviders) {
|
||||||
return $this->getProviderNames();
|
return array_filter($this->getProviderNames(), $packageFilterCb);
|
||||||
}
|
}
|
||||||
|
|
||||||
$names = array();
|
$names = array();
|
||||||
foreach ($this->getPackages() as $package) {
|
foreach ($this->getPackages() as $package) {
|
||||||
|
if ($packageFilterCb($package->getName())) {
|
||||||
$names[] = $package->getPrettyName();
|
$names[] = $package->getPrettyName();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return $names;
|
return $names;
|
||||||
}
|
}
|
||||||
|
@ -866,6 +887,10 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
|
||||||
$this->hasProviders = true;
|
$this->hasProviders = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!empty($data['list'])) {
|
||||||
|
$this->listUrl = $this->canonicalizeUrl($data['list']);
|
||||||
|
}
|
||||||
|
|
||||||
if (!empty($data['providers']) || !empty($data['providers-includes'])) {
|
if (!empty($data['providers']) || !empty($data['providers-includes'])) {
|
||||||
$this->hasProviders = true;
|
$this->hasProviders = true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue