1
0
Fork 0

Fix type errors and tests

pull/10320/head
Jordi Boggiano 2022-05-13 09:52:02 +02:00
parent 55dc80862e
commit b52053893c
No known key found for this signature in database
GPG Key ID: 7BBD42C429EC80BC
9 changed files with 45 additions and 50 deletions

View File

@ -66,7 +66,7 @@ trait CompletionTrait
if ($locker->isLocked()) {
$platformRepo = new PlatformRepository(array(), $locker->getPlatformOverrides());
} else {
$platformRepo = new PlatformRepository(array(), $composer->getConfig()->get('platform') ?: array());
$platformRepo = new PlatformRepository(array(), $composer->getConfig()->get('platform'));
}
if ($input->getCompletionValue() === '') {
// to reduce noise, when no text is yet entered we list only two entries for ext- and lib- prefixes
@ -115,36 +115,43 @@ trait CompletionTrait
$repos = new CompositeRepository($composer->getRepositoryManager()->getRepositories());
$results = [];
$showVendors = false;
if (!str_contains($input->getCompletionValue(), '/')) {
$results = $repos->search('^' . preg_quote($input->getCompletionValue()), RepositoryInterface::SEARCH_VENDOR);
$vendors = true;
$showVendors = true;
}
// if we get a single vendor, we expand it into its contents already
if (\count($results) <= 1) {
$results = $repos->search('^'.preg_quote($input->getCompletionValue()), RepositoryInterface::SEARCH_NAME);
$vendors = false;
$showVendors = false;
}
$results = array_column($results, 'name');
if ($vendors) {
if ($showVendors) {
$results = array_map(function (string $name): string {
return $name.'/';
}, $results);
// sort shorter results first to avoid auto-expanding the completion to a longer string than needed
usort($results, function (string $a, string $b) {
return \strlen($a) - \strlen($b);
$lenA = \strlen($a);
$lenB = \strlen($b);
if ($lenA === $lenB) {
return $a <=> $b;
}
return $lenA - $lenB;
});
$pinned = [];
// ensure if the input is an exact match that it is always in the result set
$completionInput = $input->getCompletionValue().'/';
if (in_array($completionInput, $results, true)) {
if (false !== ($exactIndex = array_search($completionInput, $results, true))) {
$pinned[] = $completionInput;
array_splice($results, array_search($completionInput, $results, true), 1);
array_splice($results, $exactIndex, 1);
}
return array_merge($pinned, array_slice($results, 0, $max - \count($pinned)));
@ -177,7 +184,7 @@ trait CompletionTrait
private function suggestPlatformPackage(): \Closure
{
return function (CompletionInput $input): array {
$repos = new PlatformRepository([], $this->requireComposer()->getConfig()->get('platform') ?? []);
$repos = new PlatformRepository([], $this->requireComposer()->getConfig()->get('platform'));
$pattern = BasePackage::packageNameToRegexp($input->getCompletionValue().'*');
return array_filter(array_map(function (PackageInterface $package) {

View File

@ -159,7 +159,7 @@ EOT
$preferSource,
$preferDist,
!$input->getOption('no-dev'),
$input->getOption('repository') ?: $input->getOption('repository-url'),
\count($input->getOption('repository')) > 0 ? $input->getOption('repository') : $input->getOption('repository-url'),
$input->getOption('no-plugins'),
$input->getOption('no-scripts'),
$input->getOption('no-progress'),
@ -197,7 +197,7 @@ EOT
$repositories = (array) $repositories;
}
$platformRequirementFilter = $platformRequirementFilter ?: PlatformRequirementFilterFactory::ignoreNothing();
$platformRequirementFilter = $platformRequirementFilter ?? PlatformRequirementFilterFactory::ignoreNothing();
// we need to manually load the configuration to pass the auth credentials to the io interface!
$io->loadConfiguration($config);
@ -424,7 +424,7 @@ EOT
}
}
$platformOverrides = $config->get('platform') ?: array();
$platformOverrides = $config->get('platform');
$platformRepo = new PlatformRepository(array(), $platformOverrides);
// find the latest version if there are multiple

View File

@ -119,6 +119,10 @@ EOT
private function prepareSubcommandInput(InputInterface $input, bool $quiet = false): StringInput
{
if (!method_exists($input, '__toString')) {
throw new \LogicException('Expected an Input instance that is stringable, got '.get_class($input));
}
// The COMPOSER env var should not apply to the global execution scope
if (Platform::getEnv('COMPOSER')) {
Platform::clearEnv('COMPOSER');

View File

@ -99,7 +99,7 @@ trait PackageDiscoveryTrait
foreach ($requires as $requirement) {
if (!isset($requirement['version'])) {
// determine the best version automatically
list($name, $version) = $this->findBestVersionAndNameForPackage($input, $requirement['name'], $platformRepo, $preferredStability, null, null, $fixed);
list($name, $version) = $this->findBestVersionAndNameForPackage($input, $requirement['name'], $platformRepo, $preferredStability, $fixed);
$requirement['version'] = $version;
// replace package name from packagist.org
@ -268,7 +268,7 @@ trait PackageDiscoveryTrait
* @throws \InvalidArgumentException
* @return array{string, string} name version
*/
private function findBestVersionAndNameForPackage(InputInterface $input, string $name, ?PlatformRepository $platformRepo = null, string $preferredStability = 'stable', ?string $requiredVersion = null, ?string $minimumStability = null, bool $fixed = false): array
private function findBestVersionAndNameForPackage(InputInterface $input, string $name, ?PlatformRepository $platformRepo = null, string $preferredStability = 'stable', bool $fixed = false): array
{
// handle ignore-platform-reqs flag if present
if ($input->hasOption('ignore-platform-reqs') && $input->hasOption('ignore-platform-req')) {
@ -278,17 +278,17 @@ trait PackageDiscoveryTrait
}
// find the latest version allowed in this repo set
$repoSet = $this->getRepositorySet($input, $minimumStability);
$repoSet = $this->getRepositorySet($input);
$versionSelector = new VersionSelector($repoSet, $platformRepo);
$effectiveMinimumStability = $minimumStability ?? $this->getMinimumStability($input);
$effectiveMinimumStability = $this->getMinimumStability($input);
$package = $versionSelector->findBestCandidate($name, $requiredVersion, $preferredStability, $platformRequirementFilter);
$package = $versionSelector->findBestCandidate($name, null, $preferredStability, $platformRequirementFilter);
if (false === $package) {
// platform packages can not be found in the pool in versions other than the local platform's has
// so if platform reqs are ignored we just take the user's word for it
if ($platformRequirementFilter->isIgnored($name)) {
return array($name, $requiredVersion ?: '*');
return array($name, '*');
}
// Check if it is a virtual package provided by others
@ -308,17 +308,16 @@ trait PackageDiscoveryTrait
}
// Check whether the package requirements were the problem
if (!($platformRequirementFilter instanceof IgnoreAllPlatformRequirementFilter) && false !== ($candidate = $versionSelector->findBestCandidate($name, $requiredVersion, $preferredStability, PlatformRequirementFilterFactory::ignoreAll()))) {
if (!($platformRequirementFilter instanceof IgnoreAllPlatformRequirementFilter) && false !== ($candidate = $versionSelector->findBestCandidate($name, null, $preferredStability, PlatformRequirementFilterFactory::ignoreAll()))) {
throw new \InvalidArgumentException(sprintf(
'Package %s%s has requirements incompatible with your PHP version, PHP extensions and Composer version' . $this->getPlatformExceptionDetails($candidate, $platformRepo),
$name,
is_string($requiredVersion) ? ' at version '.$requiredVersion : ''
'Package %s has requirements incompatible with your PHP version, PHP extensions and Composer version' . $this->getPlatformExceptionDetails($candidate, $platformRepo),
$name
));
}
// Check whether the minimum stability was the problem but the package exists
if (false !== ($package = $versionSelector->findBestCandidate($name, $requiredVersion, $preferredStability, $platformRequirementFilter, RepositorySet::ALLOW_UNACCEPTABLE_STABILITIES))) {
if (false !== ($package = $versionSelector->findBestCandidate($name, null, $preferredStability, $platformRequirementFilter, RepositorySet::ALLOW_UNACCEPTABLE_STABILITIES))) {
// we must first verify if a valid package would be found in a lower priority repository
if (false !== ($allReposPackage = $versionSelector->findBestCandidate($name, $requiredVersion, $preferredStability, $platformRequirementFilter, RepositorySet::ALLOW_SHADOWED_REPOSITORIES))) {
if (false !== ($allReposPackage = $versionSelector->findBestCandidate($name, null, $preferredStability, $platformRequirementFilter, RepositorySet::ALLOW_SHADOWED_REPOSITORIES))) {
throw new \InvalidArgumentException(
'Package '.$name.' exists in '.$allReposPackage->getRepository()->getRepoName().' and '.$package->getRepository()->getRepoName().' which has a higher repository priority. The packages from the higher priority repository do not match your minimum-stability and are therefore not installable. That repository is canonical so the lower priority repo\'s packages are not installable. See https://getcomposer.org/repoprio for details and assistance.'
);
@ -330,21 +329,6 @@ trait PackageDiscoveryTrait
$effectiveMinimumStability
));
}
// Check whether the required version was the problem
if (is_string($requiredVersion) && false !== ($package = $versionSelector->findBestCandidate($name, null, $preferredStability, $platformRequirementFilter))) {
// we must first verify if a valid package would be found in a lower priority repository
if (false !== ($allReposPackage = $versionSelector->findBestCandidate($name, $requiredVersion, $preferredStability, PlatformRequirementFilterFactory::ignoreNothing(), RepositorySet::ALLOW_SHADOWED_REPOSITORIES))) {
throw new \InvalidArgumentException(
'Package '.$name.' exists in '.$allReposPackage->getRepository()->getRepoName().' and '.$package->getRepository()->getRepoName().' which has a higher repository priority. The packages from the higher priority repository do not match your constraint and are therefore not installable. That repository is canonical so the lower priority repo\'s packages are not installable. See https://getcomposer.org/repoprio for details and assistance.'
);
}
throw new \InvalidArgumentException(sprintf(
'Could not find package %s in a version matching "%s" and a stability matching "'.$effectiveMinimumStability.'".',
$name,
$requiredVersion
));
}
// Check whether the PHP version was the problem for all versions
if (!$platformRequirementFilter instanceof IgnoreAllPlatformRequirementFilter && false !== ($candidate = $versionSelector->findBestCandidate($name, null, $preferredStability, PlatformRequirementFilterFactory::ignoreAll(), RepositorySet::ALLOW_UNACCEPTABLE_STABILITIES))) {
$additional = '';

View File

@ -187,7 +187,7 @@ EOT
// init repos
$platformOverrides = array();
if ($composer) {
$platformOverrides = $composer->getConfig()->get('platform') ?: array();
$platformOverrides = $composer->getConfig()->get('platform');
}
$platformRepo = new PlatformRepository(array(), $platformOverrides);
$lockedRepo = null;

View File

@ -65,7 +65,7 @@ EOT
$installedRepos[] = new PlatformRepository(array(), $locker->getPlatformOverrides());
$installedRepos[] = $locker->getLockedRepository(!$input->getOption('no-dev'));
} else {
$installedRepos[] = new PlatformRepository(array(), $composer->getConfig()->get('platform') ?: array());
$installedRepos[] = new PlatformRepository(array(), $composer->getConfig()->get('platform'));
$installedRepos[] = $composer->getRepositoryManager()->getLocalRepository();
}

View File

@ -59,7 +59,7 @@ class InputArgument extends BaseInputArgument
public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void
{
$values = $this->suggestedValues;
if ($values instanceof \Closure && !\is_array($values = $values($input, $suggestions))) {
if ($values instanceof \Closure && !\is_array($values = $values($input, $suggestions))) { // @phpstan-ignore-line
throw new LogicException(sprintf('Closure for option "%s" must return an array. Got "%s".', $this->getName(), get_debug_type($values)));
}
if ([] !== $values) {

View File

@ -62,7 +62,7 @@ class InputOption extends BaseInputOption
public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void
{
$values = $this->suggestedValues;
if ($values instanceof \Closure && !\is_array($values = $values($input, $suggestions))) {
if ($values instanceof \Closure && !\is_array($values = $values($input, $suggestions))) { // @phpstan-ignore-line
throw new LogicException(sprintf('Closure for argument "%s" must return an array. Got "%s".', $this->getName(), get_debug_type($values)));
}
if ([] !== $values) {

View File

@ -27,34 +27,34 @@ class CompletionFunctionalTest extends TestCase
*/
public function getCommandSuggestions(): iterable
{
$randomProject = '104corp/cache';
$randomVendor = 'a/';
$installedPackages = ['composer/semver', 'psr/log'];
$preferInstall = ['dist', 'source', 'auto'];
yield ['archive ', [$randomProject]];
yield ['archive ', [$randomVendor]];
yield ['archive symfony/http-', ['symfony/http-kernel', 'symfony/http-foundation']];
yield ['archive --format ', ['tar', 'zip']];
yield ['create-project ', [$randomProject]];
yield ['create-project ', [$randomVendor]];
yield ['create-project symfony/skeleton --prefer-install ', $preferInstall];
yield ['depends ', $installedPackages];
yield ['why ', $installedPackages];
yield ['exec ', ['composer', 'compile']];
yield ['exec ', ['composer', 'jsonlint', 'phpstan', 'phpstan.phar', 'simple-phpunit', 'validate-json']];
yield ['browse ', $installedPackages];
yield ['home -H ', $installedPackages];
yield ['init --require ', [$randomProject]];
yield ['init --require-dev foo/bar --require-dev ', [$randomProject]];
yield ['init --require ', [$randomVendor]];
yield ['init --require-dev foo/bar --require-dev ', [$randomVendor]];
yield ['install --prefer-install ', $preferInstall];
yield ['install ', $installedPackages];
yield ['outdated ', $installedPackages];
yield ['prohibits ', [$randomProject]];
yield ['prohibits ', [$randomVendor]];
yield ['why-not symfony/http-ker', ['symfony/http-kernel']];
yield ['reinstall --prefer-install ', $preferInstall];
@ -63,7 +63,7 @@ class CompletionFunctionalTest extends TestCase
yield ['remove ', $installedPackages];
yield ['require --prefer-install ', $preferInstall];
yield ['require ', [$randomProject]];
yield ['require ', [$randomVendor]];
yield ['require --dev symfony/http-', ['symfony/http-kernel', 'symfony/http-foundation']];
yield ['run-script ', ['compile', 'test', 'phpstan']];