1
0
Fork 0

Refactor the BasePackage::$stabilities into a constant

pull/12046/head
Jordi Boggiano 2024-07-12 11:27:44 +02:00
parent 07aee7ea8e
commit 685add70ec
No known key found for this signature in database
23 changed files with 80 additions and 54 deletions

26
composer.lock generated
View File

@ -297,16 +297,16 @@
},
{
"name": "composer/semver",
"version": "3.4.0",
"version": "3.4.1",
"source": {
"type": "git",
"url": "https://github.com/composer/semver.git",
"reference": "35e8d0af4486141bc745f23a29cc2091eb624a32"
"reference": "8536c1b9103405bcbd310c69e7a5739a1c2b1f0b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/composer/semver/zipball/35e8d0af4486141bc745f23a29cc2091eb624a32",
"reference": "35e8d0af4486141bc745f23a29cc2091eb624a32",
"url": "https://api.github.com/repos/composer/semver/zipball/8536c1b9103405bcbd310c69e7a5739a1c2b1f0b",
"reference": "8536c1b9103405bcbd310c69e7a5739a1c2b1f0b",
"shasum": ""
},
"require": {
@ -358,7 +358,7 @@
"support": {
"irc": "ircs://irc.libera.chat:6697/composer",
"issues": "https://github.com/composer/semver/issues",
"source": "https://github.com/composer/semver/tree/3.4.0"
"source": "https://github.com/composer/semver/tree/3.4.1"
},
"funding": [
{
@ -374,7 +374,7 @@
"type": "tidelift"
}
],
"time": "2023-08-31T09:50:34+00:00"
"time": "2024-07-12T09:13:09+00:00"
},
{
"name": "composer/spdx-licenses",
@ -760,23 +760,23 @@
},
{
"name": "seld/jsonlint",
"version": "1.10.2",
"version": "1.11.0",
"source": {
"type": "git",
"url": "https://github.com/Seldaek/jsonlint.git",
"reference": "9bb7db07b5d66d90f6ebf542f09fc67d800e5259"
"reference": "1748aaf847fc731cfad7725aec413ee46f0cc3a2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/9bb7db07b5d66d90f6ebf542f09fc67d800e5259",
"reference": "9bb7db07b5d66d90f6ebf542f09fc67d800e5259",
"url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/1748aaf847fc731cfad7725aec413ee46f0cc3a2",
"reference": "1748aaf847fc731cfad7725aec413ee46f0cc3a2",
"shasum": ""
},
"require": {
"php": "^5.3 || ^7.0 || ^8.0"
},
"require-dev": {
"phpstan/phpstan": "^1.5",
"phpstan/phpstan": "^1.11",
"phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0 || ^8.5.13"
},
"bin": [
@ -808,7 +808,7 @@
],
"support": {
"issues": "https://github.com/Seldaek/jsonlint/issues",
"source": "https://github.com/Seldaek/jsonlint/tree/1.10.2"
"source": "https://github.com/Seldaek/jsonlint/tree/1.11.0"
},
"funding": [
{
@ -820,7 +820,7 @@
"type": "tidelift"
}
],
"time": "2024-02-07T12:57:50+00:00"
"time": "2024-07-11T14:55:45+00:00"
},
{
"name": "seld/phar-utils",

View File

@ -169,7 +169,7 @@ EOT
}
if ($version !== null && Preg::isMatchStrictGroups('{@(stable|RC|beta|alpha|dev)$}i', $version, $match)) {
$minStability = $match[1];
$minStability = VersionParser::normalizeStability($match[1]);
$version = (string) substr($version, 0, -strlen($match[0]));
}

View File

@ -664,7 +664,7 @@ EOT
}],
'minimum-stability' => [
static function ($val): bool {
return isset(BasePackage::$stabilities[VersionParser::normalizeStability($val)]);
return isset(BasePackage::STABILITIES[VersionParser::normalizeStability($val)]);
},
static function ($val): string {
return VersionParser::normalizeStability($val);

View File

@ -375,7 +375,7 @@ EOT
if (null === $stability) {
if (null === $packageVersion) {
$stability = 'stable';
} elseif (Preg::isMatchStrictGroups('{^[^,\s]*?@('.implode('|', array_keys(BasePackage::$stabilities)).')$}i', $packageVersion, $match)) {
} elseif (Preg::isMatchStrictGroups('{^[^,\s]*?@('.implode('|', array_keys(BasePackage::STABILITIES)).')$}i', $packageVersion, $match)) {
$stability = $match[1];
} else {
$stability = VersionParser::parseStability($packageVersion);
@ -384,8 +384,8 @@ EOT
$stability = VersionParser::normalizeStability($stability);
if (!isset(BasePackage::$stabilities[$stability])) {
throw new \InvalidArgumentException('Invalid stability provided ('.$stability.'), must be one of: '.implode(', ', array_keys(BasePackage::$stabilities)));
if (!isset(BasePackage::STABILITIES[$stability])) {
throw new \InvalidArgumentException('Invalid stability provided ('.$stability.'), must be one of: '.implode(', ', array_keys(BasePackage::STABILITIES)));
}
$composer = $this->createComposerInstance($input, $io, $config->all(), $disablePlugins, $disableScripts);

View File

@ -61,7 +61,7 @@ class InitCommand extends BaseCommand
new InputOption('homepage', null, InputOption::VALUE_REQUIRED, 'Homepage of package'),
new InputOption('require', null, InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'Package to require with a version constraint, e.g. foo/bar:1.0.0 or foo/bar=1.0.0 or "foo/bar 1.0.0"', null, $this->suggestAvailablePackageInclPlatform()),
new InputOption('require-dev', null, InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'Package to require for development with a version constraint, e.g. foo/bar:1.0.0 or foo/bar=1.0.0 or "foo/bar 1.0.0"', null, $this->suggestAvailablePackageInclPlatform()),
new InputOption('stability', 's', InputOption::VALUE_REQUIRED, 'Minimum stability (empty or one of: '.implode(', ', array_keys(BasePackage::$stabilities)).')'),
new InputOption('stability', 's', InputOption::VALUE_REQUIRED, 'Minimum stability (empty or one of: '.implode(', ', array_keys(BasePackage::STABILITIES)).')'),
new InputOption('license', 'l', InputOption::VALUE_REQUIRED, 'License of package'),
new InputOption('repository', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Add custom repositories, either by URL or using JSON arrays'),
new InputOption('autoload', 'a', InputOption::VALUE_REQUIRED, 'Add PSR-4 autoload mapping. Maps your package\'s namespace to the provided directory. (Expects a relative path, e.g. src/)'),
@ -364,10 +364,10 @@ EOT
return $minimumStability;
}
if (!isset(BasePackage::$stabilities[$value])) {
if (!isset(BasePackage::STABILITIES[$value])) {
throw new \InvalidArgumentException(
'Invalid minimum stability "'.$value.'". Must be empty or one of: '.
implode(', ', array_keys(BasePackage::$stabilities))
implode(', ', array_keys(BasePackage::STABILITIES))
);
}

View File

@ -16,6 +16,7 @@ use Composer\Factory;
use Composer\Filter\PlatformRequirementFilter\IgnoreAllPlatformRequirementFilter;
use Composer\Filter\PlatformRequirementFilter\PlatformRequirementFilterFactory;
use Composer\IO\IOInterface;
use Composer\Package\BasePackage;
use Composer\Package\CompletePackageInterface;
use Composer\Package\PackageInterface;
use Composer\Package\Version\VersionParser;
@ -52,6 +53,9 @@ trait PackageDiscoveryTrait
return $this->repos;
}
/**
* @param key-of<BasePackage::STABILITIES>|null $minimumStability
*/
private function getRepositorySet(InputInterface $input, ?string $minimumStability = null): RepositorySet
{
$key = $minimumStability ?? 'default';
@ -64,6 +68,9 @@ trait PackageDiscoveryTrait
return $this->repositorySets[$key];
}
/**
* @return key-of<BasePackage::STABILITIES>
*/
private function getMinimumStability(InputInterface $input): string
{
if ($input->hasOption('stability')) { // @phpstan-ignore-line as InitCommand does have this option but not all classes using this trait do

View File

@ -1454,7 +1454,7 @@ EOT
$stability = $composer->getPackage()->getMinimumStability();
$flags = $composer->getPackage()->getStabilityFlags();
if (isset($flags[$name])) {
$stability = array_search($flags[$name], BasePackage::$stabilities, true);
$stability = array_search($flags[$name], BasePackage::STABILITIES, true);
}
$bestStability = $stability;

View File

@ -53,7 +53,7 @@ class DefaultPolicy implements PolicyInterface
public function versionCompare(PackageInterface $a, PackageInterface $b, string $operator): bool
{
if ($this->preferStable && ($stabA = $a->getStability()) !== ($stabB = $b->getStability())) {
return BasePackage::$stabilities[$stabA] < BasePackage::$stabilities[$stabB];
return BasePackage::STABILITIES[$stabA] < BasePackage::STABILITIES[$stabB];
}
// dev versions need to be compared as branches via matchSpecific's special treatment, the rest can be optimized with compiling matcher

View File

@ -40,7 +40,7 @@ class PoolBuilder
{
/**
* @var int[]
* @phpstan-var array<string, BasePackage::STABILITY_*>
* @phpstan-var array<key-of<BasePackage::STABILITIES>, BasePackage::STABILITY_*>
*/
private $acceptableStabilities;
/**
@ -153,7 +153,7 @@ class PoolBuilder
/**
* @param int[] $acceptableStabilities array of stability => BasePackage::STABILITY_* value
* @phpstan-param array<string, BasePackage::STABILITY_*> $acceptableStabilities
* @phpstan-param array<key-of<BasePackage::STABILITIES>, BasePackage::STABILITY_*> $acceptableStabilities
* @param int[] $stabilityFlags an array of package name => BasePackage::STABILITY_* value
* @phpstan-param array<string, BasePackage::STABILITY_*> $stabilityFlags
* @param array[] $rootAliases

View File

@ -910,7 +910,7 @@ class Installer
$this->fixedRootPackage->setRequires([]);
$this->fixedRootPackage->setDevRequires([]);
$stabilityFlags[$this->package->getName()] = BasePackage::$stabilities[VersionParser::parseStability($this->package->getVersion())];
$stabilityFlags[$this->package->getName()] = BasePackage::STABILITIES[VersionParser::parseStability($this->package->getVersion())];
$repositorySet = new RepositorySet($minimumStability, $stabilityFlags, $rootAliases, $this->package->getReferences(), $rootRequires, $this->temporaryConstraints);
$repositorySet->addRepository(new RootPackageRepository($this->fixedRootPackage));

View File

@ -40,8 +40,7 @@ abstract class BasePackage implements PackageInterface
public const STABILITY_ALPHA = 15;
public const STABILITY_DEV = 20;
/** @var array<string, self::STABILITY_*> */
public static $stabilities = [
public const STABILITIES = [
'stable' => self::STABILITY_STABLE,
'RC' => self::STABILITY_RC,
'beta' => self::STABILITY_BETA,
@ -49,6 +48,14 @@ abstract class BasePackage implements PackageInterface
'dev' => self::STABILITY_DEV,
];
/**
* @deprecated
* @readonly
* @var array<key-of<BasePackage::STABILITIES>, self::STABILITY_*>
* @phpstan-ignore property.readOnlyByPhpDocDefaultValue
*/
public static $stabilities = self::STABILITIES;
/**
* READ-ONLY: The package id, public for fast access in dependency solver
* @var int
@ -234,7 +241,7 @@ abstract class BasePackage implements PackageInterface
*/
public function getStabilityPriority(): int
{
return self::$stabilities[$this->getStability()];
return self::STABILITIES[$this->getStability()];
}
public function __clone()

View File

@ -227,6 +227,7 @@ class RootPackageLoader extends ArrayLoader
*
* @param array<string, string> $requires
* @param array<string, int> $stabilityFlags
* @param key-of<BasePackage::STABILITIES> $minimumStability
*
* @return array<string, int>
*
@ -235,8 +236,7 @@ class RootPackageLoader extends ArrayLoader
*/
public static function extractStabilityFlags(array $requires, string $minimumStability, array $stabilityFlags): array
{
$stabilities = BasePackage::$stabilities;
/** @var int $minimumStability */
$stabilities = BasePackage::STABILITIES;
$minimumStability = $stabilities[$minimumStability];
foreach ($requires as $reqName => $reqVersion) {
$constraints = [];

View File

@ -323,8 +323,8 @@ class ValidatingArrayLoader implements LoaderInterface
}
if ($this->validateString('minimum-stability') && isset($this->config['minimum-stability'])) {
if (!isset(BasePackage::$stabilities[strtolower($this->config['minimum-stability'])]) && $this->config['minimum-stability'] !== 'RC') {
$this->errors[] = 'minimum-stability : invalid value ('.$this->config['minimum-stability'].'), must be one of '.implode(', ', array_keys(BasePackage::$stabilities));
if (!isset(BasePackage::STABILITIES[strtolower($this->config['minimum-stability'])]) && $this->config['minimum-stability'] !== 'RC') {
$this->errors[] = 'minimum-stability : invalid value ('.$this->config['minimum-stability'].'), must be one of '.implode(', ', array_keys(BasePackage::STABILITIES));
unset($this->config['minimum-stability']);
}
}

View File

@ -247,6 +247,9 @@ class Locker
return $requirements;
}
/**
* @return key-of<BasePackage::STABILITIES>
*/
public function getMinimumStability(): string
{
$lockData = $this->getLockData();
@ -431,7 +434,7 @@ class Locker
$spec = $this->dumper->dump($package);
unset($spec['version_normalized']);
// remove `transport-options.ssl` from lock file to prevent storing
// remove `transport-options.ssl` from lock file to prevent storing
// local-filesystem repo config paths in the lock file as that makes it less portable
if (isset($spec['transport-options']['ssl'])) {
unset($spec['transport-options']['ssl']);

View File

@ -21,7 +21,7 @@ class RootPackage extends CompletePackage implements RootPackageInterface
{
public const DEFAULT_PRETTY_VERSION = '1.0.0+no-version-set';
/** @var string */
/** @var key-of<BasePackage::STABILITIES> */
protected $minimumStability = 'stable';
/** @var bool */
protected $preferStable = false;

View File

@ -33,6 +33,8 @@ interface RootPackageInterface extends CompletePackageInterface
/**
* Returns the minimum stability of the package
*
* @return key-of<BasePackage::STABILITIES>
*/
public function getMinimumStability(): string;
@ -120,12 +122,14 @@ interface RootPackageInterface extends CompletePackageInterface
/**
* Set the stabilityFlags
*
* @param array<string, BasePackage::STABILITY_*> $stabilityFlags
* @phpstan-param array<string, BasePackage::STABILITY_*> $stabilityFlags
*/
public function setStabilityFlags(array $stabilityFlags): void;
/**
* Set the minimumStability
*
* @phpstan-param key-of<BasePackage::STABILITIES> $minimumStability
*/
public function setMinimumStability(string $minimumStability): void;

View File

@ -23,11 +23,11 @@ class StabilityFilter
* Checks if any of the provided package names in the given stability match the configured acceptable stability and flags
*
* @param int[] $acceptableStabilities array of stability => BasePackage::STABILITY_* value
* @phpstan-param array<string, BasePackage::STABILITY_*> $acceptableStabilities
* @phpstan-param array<key-of<BasePackage::STABILITIES>, BasePackage::STABILITY_*> $acceptableStabilities
* @param int[] $stabilityFlags an array of package name => BasePackage::STABILITY_* value
* @phpstan-param array<string, BasePackage::STABILITY_*> $stabilityFlags
* @param string[] $names The package name(s) to check for stability flags
* @param string $stability one of 'stable', 'RC', 'beta', 'alpha' or 'dev'
* @param key-of<BasePackage::STABILITIES> $stability one of 'stable', 'RC', 'beta', 'alpha' or 'dev'
* @return bool true if any package name is acceptable
*/
public static function isPackageAcceptable(array $acceptableStabilities, array $stabilityFlags, array $names, string $stability): bool
@ -35,7 +35,7 @@ class StabilityFilter
foreach ($names as $name) {
// allow if package matches the package-specific stability flag
if (isset($stabilityFlags[$name])) {
if (BasePackage::$stabilities[$stability] <= $stabilityFlags[$name]) {
if (BasePackage::STABILITIES[$stability] <= $stabilityFlags[$name]) {
return true;
}
} elseif (isset($acceptableStabilities[$stability])) {

View File

@ -71,7 +71,7 @@ class VersionSelector
*/
public function findBestCandidate(string $packageName, ?string $targetPackageVersion = null, string $preferredStability = 'stable', $platformRequirementFilter = null, int $repoSetFlags = 0, ?IOInterface $io = null, $showWarnings = true)
{
if (!isset(BasePackage::$stabilities[$preferredStability])) {
if (!isset(BasePackage::STABILITIES[$preferredStability])) {
// If you get this, maybe you are still relying on the Composer 1.x signature where the 3rd arg was the php version
throw new \UnexpectedValueException('Expected a valid stability name as 3rd argument, got '.$preferredStability);
}
@ -86,7 +86,7 @@ class VersionSelector
$constraint = $targetPackageVersion ? $this->getParser()->parseConstraints($targetPackageVersion) : null;
$candidates = $this->repositorySet->findPackages(strtolower($packageName), $constraint, $repoSetFlags);
$minPriority = BasePackage::$stabilities[$preferredStability];
$minPriority = BasePackage::STABILITIES[$preferredStability];
usort($candidates, static function (PackageInterface $a, PackageInterface $b) use ($minPriority) {
$aPriority = $a->getStabilityPriority();
$bPriority = $b->getStabilityPriority();

View File

@ -827,7 +827,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
/**
* @param string $name package name
* @param array<string, int>|null $acceptableStabilities
* @phpstan-param array<string, BasePackage::STABILITY_*>|null $acceptableStabilities
* @phpstan-param array<key-of<BasePackage::STABILITIES>, BasePackage::STABILITY_*>|null $acceptableStabilities
* @param array<string, int>|null $stabilityFlags an array of package name => BasePackage::STABILITY_* value
* @phpstan-param array<string, BasePackage::STABILITY_*>|null $stabilityFlags
* @param array<string, array<string, PackageInterface>> $alreadyLoaded
@ -997,7 +997,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
* @param array<string, ConstraintInterface|null> $packageNames array of package name => ConstraintInterface|null - if a constraint is provided, only
* packages matching it will be loaded
* @param array<string, int>|null $acceptableStabilities
* @phpstan-param array<string, BasePackage::STABILITY_*>|null $acceptableStabilities
* @phpstan-param array<key-of<BasePackage::STABILITIES>, BasePackage::STABILITY_*>|null $acceptableStabilities
* @param array<string, int>|null $stabilityFlags an array of package name => BasePackage::STABILITY_* value
* @phpstan-param array<string, BasePackage::STABILITY_*>|null $stabilityFlags
* @param array<string, array<string, PackageInterface>> $alreadyLoaded
@ -1129,7 +1129,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
* @param string $name package name (must be lowercased already)
* @param array<string, mixed> $versionData
* @param array<string, int>|null $acceptableStabilities
* @phpstan-param array<string, BasePackage::STABILITY_*>|null $acceptableStabilities
* @phpstan-param array<key-of<BasePackage::STABILITIES>, BasePackage::STABILITY_*>|null $acceptableStabilities
* @param array<string, int>|null $stabilityFlags an array of package name => BasePackage::STABILITY_* value
* @phpstan-param array<string, BasePackage::STABILITY_*>|null $stabilityFlags
*/

View File

@ -72,12 +72,13 @@ interface RepositoryInterface extends \Countable
* - The namesFound returned are names which should be considered as canonically found in this repository, that should not be looked up in any further lower priority repositories
*
* @param ConstraintInterface[] $packageNameMap package names pointing to constraints
* @param array<string, BasePackage::STABILITY_*> $acceptableStabilities array of stability => BasePackage::STABILITY_* value
* @param array<string, int> $acceptableStabilities array of stability => BasePackage::STABILITY_* value
* @param array<string, BasePackage::STABILITY_*> $stabilityFlags an array of package name => BasePackage::STABILITY_* value
* @param array<string, array<string, PackageInterface>> $alreadyLoaded an array of package name => package version => package
*
* @return array
*
* @phpstan-param array<key-of<BasePackage::STABILITIES>, BasePackage::STABILITY_*> $acceptableStabilities
* @phpstan-param array<string, ConstraintInterface|null> $packageNameMap
* @phpstan-return array{namesFound: array<string>, packages: array<BasePackage>}
*/

View File

@ -65,7 +65,7 @@ class RepositorySet
/**
* @var int[] array of stability => BasePackage::STABILITY_* value
* @phpstan-var array<string, BasePackage::STABILITY_*>
* @phpstan-var array<key-of<BasePackage::STABILITIES>, BasePackage::STABILITY_*>
*/
private $acceptableStabilities;
@ -96,6 +96,7 @@ class RepositorySet
* passing minimumStability is all you need to worry about. The rest is for advanced pool creation including
* aliases, pinned references and other special cases.
*
* @param key-of<BasePackage::STABILITIES> $minimumStability
* @param int[] $stabilityFlags an array of package name => BasePackage::STABILITY_* value
* @phpstan-param array<string, BasePackage::STABILITY_*> $stabilityFlags
* @param array[] $rootAliases
@ -112,8 +113,8 @@ class RepositorySet
$this->rootReferences = $rootReferences;
$this->acceptableStabilities = [];
foreach (BasePackage::$stabilities as $stability => $value) {
if ($value <= BasePackage::$stabilities[$minimumStability]) {
foreach (BasePackage::STABILITIES as $stability => $value) {
if ($value <= BasePackage::STABILITIES[$minimumStability]) {
$this->acceptableStabilities[$stability] = $value;
}
}
@ -195,7 +196,7 @@ class RepositorySet
}
} else {
foreach ($this->repositories as $repository) {
$result = $repository->loadPackages([$name => $constraint], $ignoreStability ? BasePackage::$stabilities : $this->acceptableStabilities, $ignoreStability ? [] : $this->stabilityFlags);
$result = $repository->loadPackages([$name => $constraint], $ignoreStability ? BasePackage::STABILITIES : $this->acceptableStabilities, $ignoreStability ? [] : $this->stabilityFlags);
$packages[] = $result['packages'];
foreach ($result['namesFound'] as $nameFound) {
@ -300,8 +301,8 @@ class RepositorySet
/**
* Check for each given package name whether it would be accepted by this RepositorySet in the given $stability
*
* @param string[] $names
* @param string $stability one of 'stable', 'RC', 'beta', 'alpha' or 'dev'
* @param string[] $names
* @param key-of<BasePackage::STABILITIES> $stability one of 'stable', 'RC', 'beta', 'alpha' or 'dev'
*/
public function isPackageAcceptable(array $names, string $stability): bool
{

View File

@ -50,7 +50,10 @@ class PoolBuilderTest extends TestCase
$stabilityFlags = !empty($root['stability-flags']) ? $root['stability-flags'] : [];
$rootReferences = !empty($root['references']) ? $root['references'] : [];
$stabilityFlags = array_map(static function ($stability): int {
return BasePackage::$stabilities[$stability];
if (!isset(BasePackage::STABILITIES[$stability])) {
throw new \LogicException('Invalid stability given: '.$stability);
}
return BasePackage::STABILITIES[$stability];
}, $stabilityFlags);
$parser = new VersionParser();

View File

@ -86,7 +86,7 @@ class FilterRepositoryTest extends TestCase
public function testCanonicalDefaultTrue(): void
{
$repo = new FilterRepository($this->arrayRepo, []);
$result = $repo->loadPackages(['foo/aaa' => new MatchAllConstraint], BasePackage::$stabilities, []);
$result = $repo->loadPackages(['foo/aaa' => new MatchAllConstraint], BasePackage::STABILITIES, []);
self::assertCount(1, $result['packages']);
self::assertCount(1, $result['namesFound']);
}
@ -94,7 +94,7 @@ class FilterRepositoryTest extends TestCase
public function testNonCanonical(): void
{
$repo = new FilterRepository($this->arrayRepo, ['canonical' => false]);
$result = $repo->loadPackages(['foo/aaa' => new MatchAllConstraint], BasePackage::$stabilities, []);
$result = $repo->loadPackages(['foo/aaa' => new MatchAllConstraint], BasePackage::STABILITIES, []);
self::assertCount(1, $result['packages']);
self::assertCount(0, $result['namesFound']);
}