Browse Source

Merge branch 'newcachedir'

Jordi Boggiano 12 years ago
parent
commit
49238388e4

+ 12 - 3
doc/04-schema.md

@@ -593,13 +593,22 @@ The following options are supported:
 * **github-protocols:** Defaults to `["git", "https", "http"]`. A list of
   protocols to use for github.com clones, in priority order. Use this if you are
   behind a proxy or have somehow bad performances with the git protocol.
-* **notify-on-install:** Defaults to `true`. Composer allows repositories to
-  define a notification URL, so that they get notified whenever a package from
-  that repository is installed. This option allows you to disable that behaviour.
+* **cache-dir:** Defaults to `$home/cache` on unix systems and
+  `C:\Users\<user>\AppData\Local\Composer` on Windows. Stores all the caches
+  used by composer. See also [COMPOSER_HOME](03-cli.md#composer-home).
+* **cache-files-dir:** Defaults to `$cache-dir/files`. Stores the zip archives
+  of packages.
+* **cache-repo-dir:** Defaults to `$cache-dir/repo`. Stores repository metadata
+  for the `composer` type and the VCS repos of type `svn`, `github` and `*bitbucket`.
+* **cache-vcs-dir:** Defaults to `$cache-dir/vcs`. Stores VCS clones for
+  loading VCS repository metadata for the `git`/`hg` types and to speed up installs.
 * **cache-files-ttl:** Defaults to `15552000` (6 months). Composer caches all
   dist (zip, tar, ..) packages that it downloads. Those are purged after six
   months of being unused by default. This option allows you to tweak this
   duration (in seconds) or disable it completely by setting it to 0.
+* **notify-on-install:** Defaults to `true`. Composer allows repositories to
+  define a notification URL, so that they get notified whenever a package from
+  that repository is installed. This option allows you to disable that behaviour.
 
 Example:
 

+ 5 - 0
src/Composer/Cache.php

@@ -49,6 +49,11 @@ class Cache
         }
     }
 
+    public function isEnabled()
+    {
+        return $this->enabled;
+    }
+
     public function getRoot()
     {
         return $this->root;

+ 8 - 0
src/Composer/Config.php

@@ -26,6 +26,10 @@ class Config
         'bin-dir' => '{$vendor-dir}/bin',
         'notify-on-install' => true,
         'github-protocols' => array('git', 'https', 'http'),
+        'cache-dir' => '{$home}/cache',
+        'cache-files-dir' => '{$cache-dir}/files',
+        'cache-repo-dir' => '{$cache-dir}/repo',
+        'cache-vcs-dir' => '{$cache-dir}/vcs',
     );
 
     public static $defaultRepositories = array(
@@ -115,6 +119,10 @@ class Config
             case 'vendor-dir':
             case 'bin-dir':
             case 'process-timeout':
+            case 'cache-dir':
+            case 'cache-files-dir':
+            case 'cache-repo-dir':
+            case 'cache-vcs-dir':
                 // convert foo-bar to COMPOSER_FOO_BAR and check if it exists since it overrides the local config
                 $env = 'COMPOSER_' . strtoupper(strtr($key, '-', '_'));
 

+ 55 - 10
src/Composer/Factory.php

@@ -35,27 +35,44 @@ class Factory
      */
     public static function createConfig()
     {
-        // load main Composer configuration
-        if (!$home = getenv('COMPOSER_HOME')) {
+        // determine home and cache dirs
+        $home = getenv('COMPOSER_HOME');
+        $cacheDir = getenv('COMPOSER_CACHE_DIR');
+        if (!$home) {
             if (defined('PHP_WINDOWS_VERSION_MAJOR')) {
                 $home = getenv('APPDATA') . '/Composer';
             } else {
                 $home = rtrim(getenv('HOME'), '/') . '/.composer';
             }
         }
+        if (!$cacheDir) {
+            if (defined('PHP_WINDOWS_VERSION_MAJOR')) {
+                if ($cacheDir = getenv('LOCALAPPDATA')) {
+                    $cacheDir .= '/Composer';
+                } else {
+                    $cacheDir = getenv('APPDATA') . '/Composer/cache';
+                }
+            } else {
+                $cacheDir = $home.'/cache';
+            }
+        }
 
-        // Protect directory against web access
-        if (!file_exists($home . '/.htaccess')) {
-            if (!is_dir($home)) {
-                @mkdir($home, 0777, true);
+        // Protect directory against web access. Since HOME could be
+        // the www-data's user home and be web-accessible it is a
+        // potential security risk
+        foreach (array($home, $cacheDir) as $dir) {
+            if (!file_exists($dir . '/.htaccess')) {
+                if (!is_dir($dir)) {
+                    @mkdir($dir, 0777, true);
+                }
+                @file_put_contents($dir . '/.htaccess', 'Deny from all');
             }
-            @file_put_contents($home . '/.htaccess', 'Deny from all');
         }
 
         $config = new Config();
 
-        // add home dir to the config
-        $config->merge(array('config' => array('home' => $home)));
+        // add dirs to the config
+        $config->merge(array('config' => array('home' => $home, 'cache-dir' => $cacheDir)));
 
         $file = new JsonFile($home.'/config.json');
         if ($file->exists()) {
@@ -63,6 +80,34 @@ class Factory
         }
         $config->setConfigSource(new JsonConfigSource($file));
 
+        // move old cache dirs to the new locations
+        $legacyPaths = array(
+            'cache-repo-dir' => array('/cache' => '/http*', '/cache.svn' => '/*', '/cache.github' => '/*'),
+            'cache-vcs-dir' => array('/cache.git' => '/*', '/cache.hg' => '/*'),
+            'cache-files-dir' => array('/cache.files' => '/*'),
+        );
+        foreach ($legacyPaths as $key => $oldPaths) {
+            foreach ($oldPaths as $oldPath => $match) {
+                $dir = $config->get($key);
+                if ('/cache.github' === $oldPath) {
+                    $dir .= '/github.com';
+                }
+                $oldPath = $config->get('home').$oldPath;
+                $oldPathMatch = $oldPath . $match;
+                if (is_dir($oldPath) && $dir !== $oldPath) {
+                    if (!is_dir($dir)) {
+                        if (!@mkdir($dir, 0777, true)) {
+                            continue;
+                        }
+                    }
+                    foreach (glob($oldPathMatch) as $child) {
+                        @rename($child, $dir.'/'.basename($child));
+                    }
+                    @unlink($oldPath);
+                }
+            }
+        }
+
         return $config;
     }
 
@@ -242,7 +287,7 @@ class Factory
     {
         $cache = null;
         if ($config->get('cache-files-ttl') > 0) {
-            $cache = new Cache($io, $config->get('home').'/cache.files/', 'a-z0-9_./');
+            $cache = new Cache($io, $config->get('cache-files-dir'), 'a-z0-9_./');
         }
 
         $dm = new Downloader\DownloadManager();

+ 1 - 1
src/Composer/Repository/ComposerRepository.php

@@ -72,7 +72,7 @@ class ComposerRepository extends ArrayRepository implements NotifiableRepository
         $this->url = $repoConfig['url'];
         $this->baseUrl = rtrim(preg_replace('{^(.*)(?:/packages.json)?(?:[?#].*)?$}', '$1', $this->url), '/');
         $this->io = $io;
-        $this->cache = new Cache($io, $config->get('home').'/cache/'.preg_replace('{[^a-z0-9.]}i', '-', $this->url));
+        $this->cache = new Cache($io, $config->get('cache-repo-dir').'/'.preg_replace('{[^a-z0-9.]}i', '-', $this->url));
         $this->loader = new ArrayLoader();
     }
 

+ 1 - 1
src/Composer/Repository/Vcs/GitDriver.php

@@ -36,7 +36,7 @@ class GitDriver extends VcsDriver
         if (static::isLocalUrl($this->url)) {
             $this->repoDir = str_replace('file://', '', $this->url);
         } else {
-            $this->repoDir = $this->config->get('home') . '/cache.git/' . preg_replace('{[^a-z0-9.]}i', '-', $this->url) . '/';
+            $this->repoDir = $this->config->get('cache-vcs-dir') . '/' . preg_replace('{[^a-z0-9.]}i', '-', $this->url) . '/';
 
             $fs = new Filesystem();
             $fs->ensureDirectoryExists(dirname($this->repoDir));

+ 1 - 1
src/Composer/Repository/Vcs/GitHubDriver.php

@@ -50,7 +50,7 @@ class GitHubDriver extends VcsDriver
         $this->owner = $match[1];
         $this->repository = $match[2];
         $this->originUrl = 'github.com';
-        $this->cache = new Cache($this->io, $this->config->get('home').'/cache.github/'.$this->owner.'/'.$this->repository);
+        $this->cache = new Cache($this->io, $this->config->get('cache-repo-dir').'/'.$this->originUrl.'/'.$this->owner.'/'.$this->repository);
 
         $this->fetchRootIdentifier();
     }

+ 1 - 1
src/Composer/Repository/Vcs/HgDriver.php

@@ -36,7 +36,7 @@ class HgDriver extends VcsDriver
         if (static::isLocalUrl($this->url)) {
             $this->repoDir = str_replace('file://', '', $this->url);
         } else {
-            $cacheDir = $this->config->get('home') . '/cache.hg';
+            $cacheDir = $this->config->get('cache-vcs-dir');
             $this->repoDir = $cacheDir . '/' . preg_replace('{[^a-z0-9]}i', '-', $this->url) . '/';
 
             $fs = new Filesystem();

+ 1 - 1
src/Composer/Repository/Vcs/SvnDriver.php

@@ -63,7 +63,7 @@ class SvnDriver extends VcsDriver
             $this->baseUrl = substr($this->url, 0, $pos);
         }
 
-        $this->cache = new Cache($this->io, $this->config->get('home').'/cache.svn/'.preg_replace('{[^a-z0-9.]}i', '-', $this->baseUrl));
+        $this->cache = new Cache($this->io, $this->config->get('cache-repo-dir').'/'.preg_replace('{[^a-z0-9.]}i', '-', $this->baseUrl));
 
         $this->getBranches();
         $this->getTags();