From e410da786e267e7bb22070b42ffdbe3104dc3f9d Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Thu, 18 Oct 2012 16:39:47 +0200 Subject: [PATCH] Add ConfigSourceInterface and matching class --- src/Composer/Config.php | 21 +++++ src/Composer/Config/ConfigSourceInterface.php | 29 +++++++ src/Composer/Config/JsonConfigSource.php | 80 +++++++++++++++++++ src/Composer/Factory.php | 2 + 4 files changed, 132 insertions(+) create mode 100644 src/Composer/Config/ConfigSourceInterface.php create mode 100644 src/Composer/Config/JsonConfigSource.php diff --git a/src/Composer/Config.php b/src/Composer/Config.php index ced0007c6..df8563e81 100644 --- a/src/Composer/Config.php +++ b/src/Composer/Config.php @@ -12,6 +12,8 @@ namespace Composer; +use Composer\Config\ConfigSourceInterface; + /** * @author Jordi Boggiano */ @@ -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); diff --git a/src/Composer/Config/ConfigSourceInterface.php b/src/Composer/Config/ConfigSourceInterface.php new file mode 100644 index 000000000..08ac973a2 --- /dev/null +++ b/src/Composer/Config/ConfigSourceInterface.php @@ -0,0 +1,29 @@ + + * Jordi Boggiano + * + * 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 + */ +interface ConfigSourceInterface +{ + public function addRepository($name, $config); + + public function removeRepository($name); + + public function addConfigSetting($name, $value); + + public function removeConfigSetting($name); +} diff --git a/src/Composer/Config/JsonConfigSource.php b/src/Composer/Config/JsonConfigSource.php new file mode 100644 index 000000000..8de10a51e --- /dev/null +++ b/src/Composer/Config/JsonConfigSource.php @@ -0,0 +1,80 @@ + + * Jordi Boggiano + * + * 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 + */ +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); + } + } +} diff --git a/src/Composer/Factory.php b/src/Composer/Factory.php index 64689833f..f9bc0d971 100644 --- a/src/Composer/Factory.php +++ b/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; }