Skip to main content
Drupal API
User account menu
  • Log in

Breadcrumb

  1. Drupal Core 11.1.x
  2. PackageDiscoveryTrait.php

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\Command

Code

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;
}

API Navigation

  • Drupal Core 11.1.x
  • Topics
  • Classes
  • Functions
  • Constants
  • Globals
  • Files
  • Namespaces
  • Deprecated
  • Services
RSS feed
Powered by Drupal