Jelajahi Sumber

Merge remote-tracking branch 'ntoniazzi/master'

Jordi Boggiano 9 tahun lalu
induk
melakukan
3e9efcfb85

+ 5 - 3
doc/03-cli.md

@@ -675,9 +675,11 @@ The `COMPOSER_HOME` var allows you to change the Composer home directory. This
 is a hidden, global (per-user on the machine) directory that is shared between
 all projects.
 
-By default it points to `/home/<user>/.composer` on \*nix,
-`/Users/<user>/.composer` on OSX and
-`C:\Users\<user>\AppData\Roaming\Composer` on Windows.
+By default it points to `C:\Users\<user>\AppData\Roaming\Composer` on Windows
+and `/Users/<user>/.composer` on OSX. On *nix systems that follow the [XDG Base
+Directory Specifications](http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html),
+it points to `$XDG_CONFIG_HOME/composer`. On other *nix systems, it points to
+`/home/<user>/.composer`.
 
 #### COMPOSER_HOME/config.json
 

+ 4 - 3
doc/06-config.md

@@ -89,9 +89,10 @@ into this directory.
 
 ## cache-dir
 
-Defaults to `$COMPOSER_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).
+Defaults `C:\Users\<user>\AppData\Local\Composer` on Windows,
+`$XDG_CACHE_HOME/composer` on unix systems that follow the XDG Base Directory
+Specifications, and `$home/cache` on other unix systems. Stores all the caches
+used by Composer. See also [COMPOSER_HOME](03-cli.md#composer-home).
 
 ## cache-files-dir
 

+ 1 - 1
src/Composer/Command/SelfUpdateCommand.php

@@ -70,7 +70,7 @@ EOT
         $remoteFilesystem = Factory::createRemoteFilesystem($io, $config);
 
         $cacheDir = $config->get('cache-dir');
-        $rollbackDir = $config->get('home');
+        $rollbackDir = $config->get('data-dir');
         $localFilename = realpath($_SERVER['argv'][0]) ?: $_SERVER['argv'][0];
 
         // check if current dir is writable and if not try the cache dir from settings

+ 2 - 0
src/Composer/Config.php

@@ -30,6 +30,7 @@ class Config
         'vendor-dir' => 'vendor',
         'bin-dir' => '{$vendor-dir}/bin',
         'cache-dir' => '{$home}/cache',
+        'data-dir' => '{$home}',
         'cache-files-dir' => '{$cache-dir}/files',
         'cache-repo-dir' => '{$cache-dir}/repo',
         'cache-vcs-dir' => '{$cache-dir}/vcs',
@@ -172,6 +173,7 @@ class Config
             case 'vendor-dir':
             case 'bin-dir':
             case 'process-timeout':
+            case 'data-dir':
             case 'cache-dir':
             case 'cache-files-dir':
             case 'cache-repo-dir':

+ 132 - 23
src/Composer/Factory.php

@@ -40,26 +40,75 @@ use Seld\JsonLint\JsonParser;
 class Factory
 {
     /**
+     *
+     * @return boolean
+     */
+    private static function useXdg()
+    {
+        foreach (array_keys($_SERVER) as $key) {
+            if (substr($key, 0, 4) === 'XDG_') {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * @return string
      * @throws \RuntimeException
+     */
+    private static function getUserDir()
+    {
+        if (!getenv('HOME')) {
+            throw new \RuntimeException('The HOME or COMPOSER_HOME environment variable must be set for composer to run correctly');
+        }
+        $userDir = rtrim(getenv('HOME'), '/');
+
+        return $userDir;
+    }
+
+    /**
      * @return string
+     * @throws \RuntimeException
      */
     protected static function getHomeDir()
     {
         $home = getenv('COMPOSER_HOME');
-        if (!$home) {
-            if (defined('PHP_WINDOWS_VERSION_MAJOR')) {
-                if (!getenv('APPDATA')) {
-                    throw new \RuntimeException('The APPDATA or COMPOSER_HOME environment variable must be set for composer to run correctly');
-                }
-                $home = strtr(getenv('APPDATA'), '\\', '/') . '/Composer';
-            } else {
-                if (!getenv('HOME')) {
-                    throw new \RuntimeException('The HOME or COMPOSER_HOME environment variable must be set for composer to run correctly');
-                }
-                $home = rtrim(getenv('HOME'), '/') . '/.composer';
+        if ($home) {
+            return $home;
+        }
+
+        if (defined('PHP_WINDOWS_VERSION_MAJOR')) {
+            if (!getenv('APPDATA')) {
+                throw new \RuntimeException('The APPDATA or COMPOSER_HOME environment variable must be set for composer to run correctly');
+            }
+            $home = strtr(getenv('APPDATA'), '\\', '/') . '/Composer';
+
+            return $home;
+        }
+
+        $userDir = self::getUserDir();
+
+        if (is_dir($userDir . '/.composer')) {
+            $home = $userDir . '/.composer';
+
+            return $home;
+        }
+
+        if (self::useXdg()) {
+            // XDG Base Directory Specifications
+            $xdgConfig = getenv('XDG_CONFIG_HOME');
+            if (!$xdgConfig) {
+                $xdgConfig = $userDir . '/.config';
             }
+            $home = $xdgConfig . '/composer';
+
+            return $home;
         }
 
+        $home = $userDir . '/.composer';
+
         return $home;
     }
 
@@ -70,24 +119,83 @@ class Factory
     protected static function getCacheDir($home)
     {
         $cacheDir = getenv('COMPOSER_CACHE_DIR');
-        if (!$cacheDir) {
-            if (defined('PHP_WINDOWS_VERSION_MAJOR')) {
-                if ($cacheDir = getenv('LOCALAPPDATA')) {
-                    $cacheDir .= '/Composer';
-                } else {
-                    $cacheDir = $home . '/cache';
-                }
-                $cacheDir = strtr($cacheDir, '\\', '/');
+        if ($cacheDir) {
+            return $cacheDir;
+        }
+
+        if (defined('PHP_WINDOWS_VERSION_MAJOR')) {
+            if ($cacheDir = getenv('LOCALAPPDATA')) {
+                $cacheDir .= '/Composer';
             } else {
-                $cacheDir = $home.'/cache';
+                $cacheDir = $home . '/cache';
             }
+            $cacheDir = strtr($cacheDir, '\\', '/');
+
+            return $cacheDir;
+        }
+
+        $userDir = self::getUserDir();
+
+        if ($home === $userDir . '/.composer' && is_dir($home . '/cache')) {
+            $cacheDir = $home . '/cache';
+
+            return $cacheDir;
         }
 
+        if (self::useXdg()) {
+            $xdgCache = getenv('XDG_CACHE_HOME');
+            if (!$xdgCache) {
+                $xdgCache = $userDir . '/.cache';
+            }
+            $cacheDir = $xdgCache . '/composer';
+
+            return $cacheDir;
+        }
+
+        $cacheDir = $home . '/cache';
+
         return $cacheDir;
     }
 
     /**
-     * @param  IOInterface|null $io
+     * @param string $home
+     *
+     * @return string
+     */
+    protected static function getDataDir($home)
+    {
+        if (defined('PHP_WINDOWS_VERSION_MAJOR')) {
+            $dataDir = strtr($home, '\\', '/');
+
+            return $dataDir;
+        }
+
+        $userDir = self::getUserDir();
+
+        if ($home === $userDir . '/.composer') {
+            $cacheDir = $home;
+
+            return $cacheDir;
+        }
+
+        if (self::useXdg()) {
+            $xdgData = getenv('XDG_DATA_HOME');
+            if (!$xdgData) {
+                $userDir = self::getUserDir();
+                $xdgData = $userDir . '/.local/share';
+            }
+            $dataDir = $xdgData . '/composer';
+
+            return $dataDir;
+        }
+
+        $dataDir = $home;
+
+        return $dataDir;
+    }
+
+    /**
+     * @param IOInterface|null $io
      * @return Config
      */
     public static function createConfig(IOInterface $io = null, $cwd = null)
@@ -97,11 +205,12 @@ class Factory
         // determine home and cache dirs
         $home     = self::getHomeDir();
         $cacheDir = self::getCacheDir($home);
+        $dataDir  = self::getDataDir($home);
 
         // 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) {
+        foreach (array($home, $cacheDir, $dataDir) as $dir) {
             if (!file_exists($dir . '/.htaccess')) {
                 if (!is_dir($dir)) {
                     @mkdir($dir, 0777, true);
@@ -113,7 +222,7 @@ class Factory
         $config = new Config(true, $cwd);
 
         // add dirs to the config
-        $config->merge(array('config' => array('home' => $home, 'cache-dir' => $cacheDir)));
+        $config->merge(array('config' => array('home' => $home, 'cache-dir' => $cacheDir, 'data-dir' => $dataDir)));
 
         // load global config
         $file = new JsonFile($config->get('home').'/config.json');