function PackageDiscoveryTrait::determineRequirements
Parameters
array<string> $requires:
Return value
array<string>
Throws
\Exception
2 calls to PackageDiscoveryTrait::determineRequirements()
- InitCommand::interact in vendor/
composer/ composer/ src/ Composer/ Command/ InitCommand.php - @inheritDoc
- RequireCommand::execute in vendor/
composer/ composer/ src/ Composer/ Command/ RequireCommand.php
File
-
vendor/
composer/ composer/ src/ Composer/ Command/ PackageDiscoveryTrait.php, line 97
Class
- PackageDiscoveryTrait
- @internal
Namespace
Composer\CommandCode
protected final function determineRequirements(InputInterface $input, OutputInterface $output, array $requires = [], ?PlatformRepository $platformRepo = null, string $preferredStability = 'stable', bool $useBestVersionConstraint = true, bool $fixed = false) : array {
if (count($requires) > 0) {
$requires = $this->normalizeRequirements($requires);
$result = [];
$io = $this->getIO();
foreach ($requires as $requirement) {
if (isset($requirement['version']) && Preg::isMatch('{^\\d+(\\.\\d+)?$}', $requirement['version'])) {
$io->writeError('<warning>The "' . $requirement['version'] . '" constraint for "' . $requirement['name'] . '" appears too strict and will likely not match what you want. See https://getcomposer.org/constraints</warning>');
}
if (!isset($requirement['version'])) {
// determine the best version automatically
[
$name,
$version,
] = $this->findBestVersionAndNameForPackage($this->getIO(), $input, $requirement['name'], $platformRepo, $preferredStability, $fixed);
// replace package name from packagist.org
$requirement['name'] = $name;
if ($useBestVersionConstraint) {
$requirement['version'] = $version;
$io->writeError(sprintf('Using version <info>%s</info> for <info>%s</info>', $requirement['version'], $requirement['name']));
}
else {
$requirement['version'] = 'guess';
}
}
$result[] = $requirement['name'] . ' ' . $requirement['version'];
}
return $result;
}
$versionParser = new VersionParser();
// Collect existing packages
$composer = $this->tryComposer();
$installedRepo = null;
if (null !== $composer) {
$installedRepo = $composer->getRepositoryManager()
->getLocalRepository();
}
$existingPackages = [];
if (null !== $installedRepo) {
foreach ($installedRepo->getPackages() as $package) {
$existingPackages[] = $package->getName();
}
}
unset($composer, $installedRepo);
$io = $this->getIO();
while (null !== ($package = $io->ask('Search for a package: '))) {
$matches = $this->getRepos()
->search($package);
if (count($matches) > 0) {
// Remove existing packages from search results.
foreach ($matches as $position => $foundPackage) {
if (in_array($foundPackage['name'], $existingPackages, true)) {
unset($matches[$position]);
}
}
$matches = array_values($matches);
$exactMatch = false;
foreach ($matches as $match) {
if ($match['name'] === $package) {
$exactMatch = true;
break;
}
}
// no match, prompt which to pick
if (!$exactMatch) {
$providers = $this->getRepos()
->getProviders($package);
if (count($providers) > 0) {
array_unshift($matches, [
'name' => $package,
'description' => '',
]);
}
$choices = [];
foreach ($matches as $position => $foundPackage) {
$abandoned = '';
if (isset($foundPackage['abandoned'])) {
if (is_string($foundPackage['abandoned'])) {
$replacement = sprintf('Use %s instead', $foundPackage['abandoned']);
}
else {
$replacement = 'No replacement was suggested';
}
$abandoned = sprintf('<warning>Abandoned. %s.</warning>', $replacement);
}
$choices[] = sprintf(' <info>%5s</info> %s %s', "[{$position}]", $foundPackage['name'], $abandoned);
}
$io->writeError([
'',
sprintf('Found <info>%s</info> packages matching <info>%s</info>', count($matches), $package),
'',
]);
$io->writeError($choices);
$io->writeError('');
$validator = static function (string $selection) use ($matches, $versionParser) {
if ('' === $selection) {
return false;
}
if (is_numeric($selection) && isset($matches[(int) $selection])) {
$package = $matches[(int) $selection];
return $package['name'];
}
if (Preg::isMatch('{^\\s*(?P<name>[\\S/]+)(?:\\s+(?P<version>\\S+))?\\s*$}', $selection, $packageMatches)) {
if (isset($packageMatches['version'])) {
// parsing `acme/example ~2.3`
// validate version constraint
$versionParser->parseConstraints($packageMatches['version']);
return $packageMatches['name'] . ' ' . $packageMatches['version'];
}
// parsing `acme/example`
return $packageMatches['name'];
}
throw new \Exception('Not a valid selection');
};
$package = $io->askAndValidate('Enter package # to add, or the complete package name if it is not listed: ', $validator, 3, '');
}
// no constraint yet, determine the best version automatically
if (false !== $package && false === strpos($package, ' ')) {
$validator = static function (string $input) {
$input = trim($input);
return strlen($input) > 0 ? $input : false;
};
$constraint = $io->askAndValidate('Enter the version constraint to require (or leave blank to use the latest version): ', $validator, 3, '');
if (false === $constraint) {
[
,
$constraint,
] = $this->findBestVersionAndNameForPackage($this->getIO(), $input, $package, $platformRepo, $preferredStability);
$io->writeError(sprintf('Using version <info>%s</info> for <info>%s</info>', $constraint, $package));
}
$package .= ' ' . $constraint;
}
if (false !== $package) {
$requires[] = $package;
$existingPackages[] = explode(' ', $package)[0];
}
}
}
return $requires;
}