specify covered names with regexes in 2.x repos
This supplements the available-packages list so that repositories may rule themselves out of a given name (and thus not be probed with lazy load requests) by regex, as well as by exact name match. The use case is sizeable and varying supplemental Composer repositories such as packages.drupal.org, which otherwise must either maintain a list of over 10k package names in their root packages.json or accept lots of lazy-load requests for unrelated packages that will 404.pull/9197/head
parent
0408207e35
commit
66a767c065
|
@ -12,6 +12,7 @@
|
||||||
|
|
||||||
namespace Composer\Repository;
|
namespace Composer\Repository;
|
||||||
|
|
||||||
|
use Composer\Package\BasePackage;
|
||||||
use Composer\Package\Loader\ArrayLoader;
|
use Composer\Package\Loader\ArrayLoader;
|
||||||
use Composer\Package\PackageInterface;
|
use Composer\Package\PackageInterface;
|
||||||
use Composer\Package\AliasPackage;
|
use Composer\Package\AliasPackage;
|
||||||
|
@ -55,7 +56,10 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
|
||||||
protected $hasProviders = false;
|
protected $hasProviders = false;
|
||||||
protected $providersUrl;
|
protected $providersUrl;
|
||||||
protected $listUrl;
|
protected $listUrl;
|
||||||
|
/** @var bool Indicates whether a comprehensive list of packages this repository might provide is expressed in the repository root. **/
|
||||||
|
protected $hasPredefinedPackageCoverage = false;
|
||||||
protected $availablePackages;
|
protected $availablePackages;
|
||||||
|
protected $availablePackageRegexes;
|
||||||
protected $lazyProvidersUrl;
|
protected $lazyProvidersUrl;
|
||||||
protected $providerListing;
|
protected $providerListing;
|
||||||
protected $loader;
|
protected $loader;
|
||||||
|
@ -162,7 +166,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
|
||||||
return $this->filterPackages($this->whatProvides($name), $constraint, true);
|
return $this->filterPackages($this->whatProvides($name), $constraint, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_array($this->availablePackages) && !isset($this->availablePackages[$name])) {
|
if ($this->lazyProvidersRepoDoesNotContain($name)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,7 +206,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
|
||||||
return $this->filterPackages($this->whatProvides($name), $constraint);
|
return $this->filterPackages($this->whatProvides($name), $constraint);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_array($this->availablePackages) && !isset($this->availablePackages[$name])) {
|
if ($this->lazyProvidersRepoDoesNotContain($name)) {
|
||||||
return array();
|
return array();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -260,7 +264,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
|
||||||
$hasProviders = $this->hasProviders();
|
$hasProviders = $this->hasProviders();
|
||||||
|
|
||||||
if ($this->lazyProvidersUrl) {
|
if ($this->lazyProvidersUrl) {
|
||||||
if (is_array($this->availablePackages)) {
|
if (is_array($this->availablePackages) && count($this->availablePackageRegexes) == 0) {
|
||||||
$packageMap = array();
|
$packageMap = array();
|
||||||
foreach ($this->availablePackages as $name) {
|
foreach ($this->availablePackages as $name) {
|
||||||
$packageMap[$name] = new MatchAllConstraint();
|
$packageMap[$name] = new MatchAllConstraint();
|
||||||
|
@ -388,10 +392,9 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->lazyProvidersUrl && count($packageNameMap)) {
|
if ($this->lazyProvidersUrl && count($packageNameMap)) {
|
||||||
if (is_array($this->availablePackages)) {
|
if ($this->hasPredefinedPackageCoverage) {
|
||||||
$availPackages = $this->availablePackages;
|
|
||||||
foreach ($packageNameMap as $name => $constraint) {
|
foreach ($packageNameMap as $name => $constraint) {
|
||||||
if (!isset($availPackages[strtolower($name)])) {
|
if ($this->lazyProvidersRepoDoesNotContain(strtolower($name))) {
|
||||||
unset($packageNameMap[$name]);
|
unset($packageNameMap[$name]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -876,6 +879,15 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
|
||||||
if (!empty($data['available-packages'])) {
|
if (!empty($data['available-packages'])) {
|
||||||
$availPackages = array_map('strtolower', $data['available-packages']);
|
$availPackages = array_map('strtolower', $data['available-packages']);
|
||||||
$this->availablePackages = array_combine($availPackages, $availPackages);
|
$this->availablePackages = array_combine($availPackages, $availPackages);
|
||||||
|
$this->hasPredefinedPackageCoverage = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Provides a list of package name regexes that are available in this repo
|
||||||
|
// Disables lazy-provider behavior as with available-packages, but may allow much more compact expression of packages covered by this repository.
|
||||||
|
// Over-specifying covered packages is safe, but may result in increased traffic to your repository.
|
||||||
|
if (!empty($data['available-package-regexes'])) {
|
||||||
|
$this->availablePackageRegexes = $data['available-package-regexes'];
|
||||||
|
$this->hasPredefinedPackageCoverage = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove legacy keys as most repos need to be compatible with Composer v1
|
// Remove legacy keys as most repos need to be compatible with Composer v1
|
||||||
|
@ -1306,4 +1318,36 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
|
||||||
// wipe rootData as it is fully consumed at this point and this saves some memory
|
// wipe rootData as it is fully consumed at this point and this saves some memory
|
||||||
$this->rootData = true;
|
$this->rootData = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true only if:
|
||||||
|
* - this repository uses lazy providers
|
||||||
|
* - this repository has predefined package coverage
|
||||||
|
* - the name passed is not among the known provider names
|
||||||
|
*
|
||||||
|
* @param $name
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
protected function lazyProvidersRepoDoesNotContain($name) {
|
||||||
|
if (! $this->hasPredefinedPackageCoverage) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$ruledOutByExactMatch = $ruledOutByRegex = true;
|
||||||
|
|
||||||
|
if (is_array($this->availablePackages)) {
|
||||||
|
$ruledOutByExactMatch = !isset($this->availablePackages[$name]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_array($this->availablePackageRegexes)) {
|
||||||
|
foreach ($this->availablePackageRegexes as $providerRegex) {
|
||||||
|
if (preg_match(BasePackage::packageNameToRegexp($providerRegex), $name) == 1) {
|
||||||
|
$ruledOutByRegex = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $ruledOutByExactMatch && $ruledOutByRegex;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue