diff --git a/src/Composer/Command/InitCommand.php b/src/Composer/Command/InitCommand.php index 30ef1fd0c1e2..75bc92dd2df1 100644 --- a/src/Composer/Command/InitCommand.php +++ b/src/Composer/Command/InitCommand.php @@ -543,12 +543,6 @@ final protected function determineRequirements(InputInterface $input, OutputInte $requirement['version'], $requirement['name'] )); - } else { - // check that the specified version/constraint exists before we proceed - list($name) = $this->findBestVersionAndNameForPackage($input, $requirement['name'], $platformRepo, $preferredStability, $checkProvidedVersions ? $requirement['version'] : null, 'dev', $fixed); - - // replace package name from packagist.org - $requirement['name'] = $name; } $result[] = $requirement['name'] . ' ' . $requirement['version']; @@ -583,21 +577,9 @@ final protected function determineRequirements(InputInterface $input, OutputInte } $matches = array_values($matches); - $exactMatch = null; - $choices = array(); - 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('Abandoned. %s.', $replacement); - } - - $choices[] = sprintf(' %5s %s %s', "[$position]", $foundPackage['name'], $abandoned); - if ($foundPackage['name'] === $package) { + $exactMatch = false; + foreach ($matches as $match) { + if ($match['name'] === $package) { $exactMatch = true; break; } @@ -605,6 +587,26 @@ final protected function determineRequirements(InputInterface $input, OutputInte // no match, prompt which to pick if (!$exactMatch) { + $providers = $this->getRepos()->getProviders($package); + if (count($providers) > 0) { + array_unshift($matches, array('name' => $package, 'description' => '')); + } + + $choices = array(); + 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('Abandoned. %s.', $replacement); + } + + $choices[] = sprintf(' %5s %s %s', "[$position]", $foundPackage['name'], $abandoned); + } + $io->writeError(array( '', sprintf('Found %s packages matching %s', count($matches), $package), @@ -899,7 +901,8 @@ private function findBestVersionAndNameForPackage(InputInterface $input, $name, $platformRequirementFilter = PlatformRequirementFilterFactory::fromBoolOrList($ignorePlatformReqs); // find the latest version allowed in this repo set - $versionSelector = new VersionSelector($this->getRepositorySet($input, $minimumStability), $platformRepo); + $repoSet = $this->getRepositorySet($input, $minimumStability); + $versionSelector = new VersionSelector($repoSet, $platformRepo); $effectiveMinimumStability = $minimumStability ?: $this->getMinimumStability($input); $package = $versionSelector->findBestCandidate($name, $requiredVersion, $preferredStability, $platformRequirementFilter); @@ -911,6 +914,22 @@ private function findBestVersionAndNameForPackage(InputInterface $input, $name, return array($name, $requiredVersion ?: '*'); } + // Check if it is a virtual package provided by others + $providers = $repoSet->getProviders($name); + if (count($providers) > 0) { + $constraint = '*'; + if ($input->isInteractive()) { + $constraint = $this->getIO()->askAndValidate('Package "'.$name.'" does not exist but is provided by '.count($providers).' packages. Which version constraint would you like to use? [*] ', function ($value) { + $parser = new VersionParser(); + $parser->parseConstraints($value); + + return $value; + }, 3, '*'); + } + + return array($name, $constraint); + } + // Check whether the package requirements were the problem if (!($platformRequirementFilter instanceof IgnoreAllPlatformRequirementFilter) && ($candidate = $versionSelector->findBestCandidate($name, $requiredVersion, $preferredStability, PlatformRequirementFilterFactory::ignoreAll()))) { throw new \InvalidArgumentException(sprintf(