Procházet zdrojové kódy

fix preference resolution to be backwards compatible

Steve Buzonas před 10 roky
rodič
revize
124739d055

+ 4 - 0
src/Composer/Config.php

@@ -21,6 +21,10 @@ class Config
 {
     const RELATIVE_PATHS = 1;
 
+    const INSTALL_PREFERENCE_AUTO = 'auto';
+    const INSTALL_PREFERENCE_DIST = 'dist';
+    const INSTALL_PREFERENCE_SOURCE = 'source';
+    
     public static $defaultConfig = array(
         'process-timeout' => 300,
         'use-include-path' => false,

+ 23 - 11
src/Composer/Downloader/DownloadManager.php

@@ -12,6 +12,7 @@
 
 namespace Composer\Downloader;
 
+use Composer\Config;
 use Composer\Package\PackageInterface;
 use Composer\IO\IOInterface;
 use Composer\Util\Filesystem;
@@ -198,17 +199,7 @@ class DownloadManager
             throw new \InvalidArgumentException('Package '.$package.' must have a source or dist specified');
         }
 
-        if (!$this->preferDist && !$preferSource) {
-            foreach ($this->packagePreferences as $pattern => $preference) {
-                $pattern = '{^'.str_replace('*', '.*', $pattern).'$}i';
-                if (preg_match($pattern, $package->getName())) {
-                    if ('dist' === $preference || (!$package->isDev() && 'auto' === $preference)) {
-                        $sources = array_reverse($sources);
-                    }
-                    break;
-                }
-            }
-        } elseif ((!$package->isDev() || $this->preferDist) && !$preferSource) {
+        if (Config::INSTALL_PREFERENCE_DIST === $this->resolvePackageInstallPreference($package, $preferSource)) {
             $sources = array_reverse($sources);
         }
 
@@ -296,4 +287,25 @@ class DownloadManager
             $downloader->remove($package, $targetDir);
         }
     }
+
+    protected function resolvePackageInstallPreference(PackageInterface $package, $preferSource = false)
+    {
+        if ($this->preferSource || $preferSource) {
+            return Config::INSTALL_PREFERENCE_SOURCE;
+        }
+        if ($this->preferDist) {
+            return Config::INSTALL_PREFERENCE_DIST;
+        }
+        foreach ($this->packagePreferences as $pattern => $preference) {
+            $pattern = '{^'.str_replace('*', '.*', $pattern).'$}i';
+            if (preg_match($pattern, $package->getName())) {
+                if (Config::INSTALL_PREFERENCE_DIST === $preference || (!$package->isDev() && Config::INSTALL_PREFERENCE_AUTO === $preference)) {
+                    return Config::INSTALL_PREFERENCE_DIST;
+                }
+                return Config::INSTALL_PREFERENCE_SOURCE;
+            }
+        }
+
+        return $package->isDev() ? Config::INSTALL_PREFERENCE_SOURCE : Config::INSTALL_PREFERENCE_DIST;
+    }
 }

+ 20 - 0
tests/Composer/Test/ConfigTest.php

@@ -112,6 +112,26 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
         return $data;
     }
 
+    public function testPreferredInstallAsString()
+    {
+        $config = new Config(false);
+        $config->merge(array('config' => array('preferred-install' => 'source')));
+
+        $this->assertEquals(array('*' => 'source'), $config->get('preferred-install'));
+    }
+
+    public function testMergePreferredInstall()
+    {
+        $config = new Config(false);
+        $config->merge(array('config' => array('preferred-install' => 'dist')));
+        $config->merge(array('config' => array('preferred-install' => array('foo/*' => 'source'))));
+
+        // This assertion needs to make sure full wildcard preferences are placed last
+        // Handled by composer because we convert string preferences for BC, all other
+        // care for ordering and collision prevention is up to the user
+        $this->assertEquals(array('foo/*' => 'source', '*' => 'dist'), $config->get('preferred-install'));
+    }
+
     public function testMergeGithubOauth()
     {
         $config = new Config(false);