|
@@ -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');
|