diff --git a/src/Composer/Command/InitCommand.php b/src/Composer/Command/InitCommand.php index 55d966d31..75bc92dd2 100644 --- a/src/Composer/Command/InitCommand.php +++ b/src/Composer/Command/InitCommand.php @@ -577,21 +577,9 @@ EOT } $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; } @@ -599,6 +587,26 @@ EOT // 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), @@ -893,7 +901,8 @@ EOT $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); @@ -905,6 +914,22 @@ EOT 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(