Просмотр исходного кода

Add ConfigSourceInterface and matching class

Jordi Boggiano 12 лет назад
Родитель
Сommit
e410da786e

+ 21 - 0
src/Composer/Config.php

@@ -12,6 +12,8 @@
 
 namespace Composer;
 
+use Composer\Config\ConfigSourceInterface;
+
 /**
  * @author Jordi Boggiano <j.boggiano@seld.be>
  */
@@ -34,6 +36,7 @@ class Config
 
     private $config;
     private $repositories;
+    private $configSource;
 
     public function __construct()
     {
@@ -42,6 +45,16 @@ class Config
         $this->repositories = static::$defaultRepositories;
     }
 
+    public function setConfigSource(ConfigSourceInterface $source)
+    {
+        $this->configSource = $source;
+    }
+
+    public function getConfigSource()
+    {
+        return $this->configSource;
+    }
+
     /**
      * Merges new config values with the existing ones (overriding)
      *
@@ -110,6 +123,10 @@ class Config
                 return rtrim($this->process($this->config[$key]), '/\\');
 
             default:
+                if (!isset($this->config[$key])) {
+                    return null;
+                }
+
                 return $this->process($this->config[$key]);
         }
     }
@@ -135,6 +152,10 @@ class Config
     {
         $config = $this;
 
+        if (!is_string($value)) {
+            return $value;
+        }
+
         return preg_replace_callback('#\{\$(.+)\}#', function ($match) use ($config) {
             return $config->get($match[1]);
         }, $value);

+ 29 - 0
src/Composer/Config/ConfigSourceInterface.php

@@ -0,0 +1,29 @@
+<?php
+
+/*
+ * This file is part of Composer.
+ *
+ * (c) Nils Adermann <naderman@naderman.de>
+ *     Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Composer\Config;
+
+use Composer\Json\JsonManipulator;
+
+/**
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ */
+interface ConfigSourceInterface
+{
+    public function addRepository($name, $config);
+
+    public function removeRepository($name);
+
+    public function addConfigSetting($name, $value);
+
+    public function removeConfigSetting($name);
+}

+ 80 - 0
src/Composer/Config/JsonConfigSource.php

@@ -0,0 +1,80 @@
+<?php
+
+/*
+ * This file is part of Composer.
+ *
+ * (c) Nils Adermann <naderman@naderman.de>
+ *     Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Composer\Config;
+
+use Composer\Json\JsonManipulator;
+use Composer\Json\JsonFile;
+
+/**
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ */
+class JsonConfigSource implements ConfigSourceInterface
+{
+    private $file;
+    private $manipulator;
+
+    public function __construct(JsonFile $file)
+    {
+        $this->file = $file;
+    }
+
+    public function addRepository($name, $config)
+    {
+        return $this->manipulateJson('addRepository', $name, $config, function (&$config, $repo, $repoConfig) {
+            $config['repositories'][$repo] = $repoConfig;
+        });
+    }
+
+    public function removeRepository($name)
+    {
+        return $this->manipulateJson('removeRepository', $name, function (&$config, $repo) {
+            unset($config['repositories'][$repo]);
+        });
+    }
+
+    public function addConfigSetting($name, $value)
+    {
+        $this->manipulateJson('addConfigSetting', $name, $value, function (&$config, $key, $val) {
+            $config['config'][$key] = $val;
+        });
+    }
+
+    public function removeConfigSetting($name)
+    {
+        return $this->manipulateJson('removeConfigSetting', $name, function (&$config, $key) {
+            unset($config['config'][$key]);
+        });
+    }
+
+    protected function manipulateJson($method, $args, $fallback)
+    {
+        $args = func_get_args();
+        // remove method & fallback
+        array_shift($args);
+        $fallback = array_pop($args);
+
+        $contents = file_get_contents($this->file->getPath());
+        $manipulator = new JsonManipulator($contents);
+
+        // try to update cleanly
+        if (call_user_func_array(array($manipulator, $method), $args)) {
+            file_put_contents($this->file->getPath(), $manipulator->getContents());
+        } else {
+            // on failed clean update, call the fallback and rewrite the whole file
+            $config = $this->file->read();
+            array_unshift($args, $config);
+            call_user_func_array($fallback, $args);
+            $this->file->write($config);
+        }
+    }
+}

+ 2 - 0
src/Composer/Factory.php

@@ -12,6 +12,7 @@
 
 namespace Composer;
 
+use Composer\Config\JsonConfigSource;
 use Composer\Json\JsonFile;
 use Composer\IO\IOInterface;
 use Composer\Repository\ComposerRepository;
@@ -59,6 +60,7 @@ class Factory
         if ($file->exists()) {
             $config->merge($file->read());
         }
+        $config->setConfigSource(new JsonConfigSource($file));
 
         return $config;
     }