Explorar o código

[#2492] Automatically using the latest version when requiring a package

This applies to the init and require commands.

Previously:

If you ommitted the version of a library, it prompted you to enter a version.

New Behavior:

If you omit the version, it automatically selects the latest version that is consistent
with your minimum-stability flag.

Is Jordi mentions, this is consistent with how npm works.
Ryan Weaver %!s(int64=11) %!d(string=hai) anos
pai
achega
58535a62fa

+ 7 - 11
src/Composer/Command/CreateProjectCommand.php

@@ -266,23 +266,14 @@ EOT
         $pool->addRepository($sourceRepo);
 
         $constraint = $packageVersion ? $parser->parseConstraints($packageVersion) : null;
-        $candidates = $pool->whatProvides($name, $constraint);
-        foreach ($candidates as $key => $candidate) {
-            if ($candidate->getName() !== $name) {
-                unset($candidates[$key]);
-            }
-        }
+        $candidates = $pool->whatProvides($name, $constraint, true);
 
         if (!$candidates) {
             throw new \InvalidArgumentException("Could not find package $name" . ($packageVersion ? " with version $packageVersion." : " with stability $stability."));
         }
 
-        if (null === $directory) {
-            $parts = explode("/", $name, 2);
-            $directory = getcwd() . DIRECTORY_SEPARATOR . array_pop($parts);
-        }
-
         // select highest version if we have many
+        // logic is repeated in InitCommand
         $package = reset($candidates);
         foreach ($candidates as $candidate) {
             if (version_compare($package->getVersion(), $candidate->getVersion(), '<')) {
@@ -291,6 +282,11 @@ EOT
         }
         unset($candidates);
 
+        if (null === $directory) {
+            $parts = explode("/", $name, 2);
+            $directory = getcwd() . DIRECTORY_SEPARATOR . array_pop($parts);
+        }
+
         $io->write('<info>Installing ' . $package->getName() . ' (' . VersionParser::formatVersion($package, false) . ')</info>');
 
         if ($disablePlugins) {

+ 52 - 11
src/Composer/Command/InitCommand.php

@@ -12,6 +12,7 @@
 
 namespace Composer\Command;
 
+use Composer\DependencyResolver\Pool;
 use Composer\Json\JsonFile;
 use Composer\Factory;
 use Composer\Package\BasePackage;
@@ -32,6 +33,7 @@ class InitCommand extends Command
 {
     private $gitConfig;
     private $repos;
+    private $pool;
 
     public function parseAuthorString($author)
     {
@@ -284,9 +286,11 @@ EOT
 
     protected function findPackages($name)
     {
-        $packages = array();
+        return $this->getRepos()->search($name);
+    }
 
-        // init repos
+    protected function getRepos()
+    {
         if (!$this->repos) {
             $this->repos = new CompositeRepository(array_merge(
                 array(new PlatformRepository),
@@ -294,7 +298,17 @@ EOT
             ));
         }
 
-        return $this->repos->search($name);
+        return $this->repos;
+    }
+
+    protected function getPool()
+    {
+        if (!$this->pool) {
+            $this->pool = new Pool($this->getComposer()->getPackage()->getMinimumStability());
+            $this->pool->addRepository($this->getRepos());
+        }
+
+        return $this->pool;
     }
 
     protected function determineRequirements(InputInterface $input, OutputInterface $output, $requires = array())
@@ -306,15 +320,42 @@ EOT
             $requires = $this->normalizeRequirements($requires);
             $result = array();
 
-            foreach ($requires as $key => $requirement) {
-                if (!isset($requirement['version']) && $input->isInteractive()) {
-                    $question = $dialog->getQuestion('Please provide a version constraint for the '.$requirement['name'].' requirement');
-                    if ($constraint = $dialog->ask($output, $question)) {
-                        $requirement['version'] = $constraint;
-                    }
-                }
+            foreach ($requires as $requirement) {
                 if (!isset($requirement['version'])) {
-                    throw new \InvalidArgumentException('The requirement '.$requirement['name'].' must contain a version constraint');
+
+                    $candidates = $this->getPool()->whatProvides($requirement['name'], null, true);
+
+                    if (!$candidates) {
+                        throw new \InvalidArgumentException(sprintf(
+                            'Could not find any versions for package "%s". Perhaps the name is wrong?',
+                            $requirement['name']
+                        ));
+                    }
+
+                    // select highest version if we have many
+                    // logic is repeated in CreateProjectCommand
+                    $package = reset($candidates);
+                    foreach ($candidates as $candidate) {
+                        if (version_compare($package->getVersion(), $candidate->getVersion(), '<')) {
+                            $package = $candidate;
+                        }
+                    }
+
+                    if (!$package) {
+                        throw new \Exception(sprintf(
+                            'No version of the package "%s" could be found that meets your minimum stability requirements of "%s"',
+                            $requirement['name'],
+                            $this->getComposer()->getPackage()->getMinimumStability()
+                        ));
+                    }
+
+                    $requirement['version'] = $package->getPrettyVersion();
+
+                    $output->writeln(sprintf(
+                        'Using version <info>%s</info> for <info>%s</info>',
+                        $requirement['version'],
+                        $requirement['name']
+                    ));
                 }
 
                 $result[] = $requirement['name'] . ' ' . $requirement['version'];