Browse Source

add support for package based install type preferences

Steve Buzonas 10 years ago
parent
commit
bf08b6eb90

+ 2 - 2
res/composer-schema.json

@@ -117,8 +117,8 @@
                     "description": "If true, the Composer autoloader will also look for classes in the PHP include path."
                 },
                 "preferred-install": {
-                    "type": "string",
-                    "description": "The install method Composer will prefer to use, defaults to auto and can be any of source, dist or auto."
+                    "type": ["string", "object"],
+                    "description": "The install method Composer will prefer to use, defaults to auto and can be any of source, dist, auto, or a hash of {\"pattern\": \"preference\"}."
                 },
                 "notify-on-install": {
                     "type": "boolean",

+ 14 - 0
src/Composer/Config.php

@@ -108,6 +108,20 @@ class Config
             foreach ($config['config'] as $key => $val) {
                 if (in_array($key, array('github-oauth', 'http-basic')) && isset($this->config[$key])) {
                     $this->config[$key] = array_merge($this->config[$key], $val);
+                } elseif ('preferred-install' === $key && isset($this->config[$key])) {
+                    if (is_string($val)) {
+                        $val = array('*' => $val);
+                    }
+                    if (is_string($this->config[$key])) {
+                        $this->config[$key] = array('*' => $this->config[$key]);
+                    }
+                    $this->config[$key] = array_merge($this->config[$key], $val);
+                    // the full match pattern needs to be last
+                    if (isset($this->config[$key]['*'])) {
+                        $wildcard = $this->config[$key]['*'];
+                        unset($this->config[$key]['*']);
+                        $this->config[$key]['*'] = $wildcard;
+                    }
                 } else {
                     $this->config[$key] = $val;
                 }

+ 25 - 1
src/Composer/Downloader/DownloadManager.php

@@ -26,6 +26,7 @@ class DownloadManager
     private $io;
     private $preferDist = false;
     private $preferSource = false;
+    private $packagePreferences = array();
     private $filesystem;
     private $downloaders  = array();
 
@@ -69,6 +70,19 @@ class DownloadManager
         return $this;
     }
 
+    /**
+     * Sets fine tuned preference settings for package level source/dist selection.
+     *
+     * @param  array           $preferences array of preferences by package patterns
+     * @return DownloadManager
+     */
+    public function setPreferences(array $preferences)
+    {
+        $this->packagePreferences = $preferences;
+
+        return $this;
+    }
+
     /**
      * Sets whether to output download progress information for all registered
      * downloaders
@@ -184,7 +198,17 @@ class DownloadManager
             throw new \InvalidArgumentException('Package '.$package.' must have a source or dist specified');
         }
 
-        if ((!$package->isDev() || $this->preferDist) && !$preferSource) {
+        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) {
             $sources = array_reverse($sources);
         }
 

+ 5 - 1
src/Composer/Factory.php

@@ -383,7 +383,7 @@ class Factory
         }
 
         $dm = new Downloader\DownloadManager($io);
-        switch ($config->get('preferred-install')) {
+        switch ($preferred = $config->get('preferred-install')) {
             case 'dist':
                 $dm->setPreferDist(true);
                 break;
@@ -396,6 +396,10 @@ class Factory
                 break;
         }
 
+        if (is_array($preferred)) {
+            $dm->setPreferences($preferred);
+        }
+
         $dm->setDownloader('git', new Downloader\GitDownloader($io, $config));
         $dm->setDownloader('svn', new Downloader\SvnDownloader($io, $config));
         $dm->setDownloader('hg', new Downloader\HgDownloader($io, $config));