|
@@ -22,6 +22,8 @@ use Composer\Config;
|
|
|
use Composer\Config\JsonConfigSource;
|
|
|
use Composer\Factory;
|
|
|
use Composer\Json\JsonFile;
|
|
|
+use Composer\Semver\VersionParser;
|
|
|
+use Composer\Package\BasePackage;
|
|
|
|
|
|
/**
|
|
|
* @author Joshua Estes <Joshua.Estes@iostudio.com>
|
|
@@ -74,8 +76,10 @@ class ConfigCommand extends BaseCommand
|
|
|
new InputArgument('setting-value', InputArgument::IS_ARRAY, 'Setting value'),
|
|
|
))
|
|
|
->setHelp(<<<EOT
|
|
|
-This command allows you to edit some basic composer settings in either the
|
|
|
-local composer.json file or the global config.json file.
|
|
|
+This command allows you to edit composer config settings and repositories
|
|
|
+in either the local composer.json file or the global config.json file.
|
|
|
+
|
|
|
+Additionally it lets you edit most properties in the local composer.json.
|
|
|
|
|
|
To set a config setting:
|
|
|
|
|
@@ -227,6 +231,8 @@ EOT
|
|
|
|
|
|
// show the value if no value is provided
|
|
|
if (array() === $input->getArgument('setting-value') && !$input->getOption('unset')) {
|
|
|
+ $properties = array('name', 'type', 'description', 'homepage', 'version', 'minimum-stability', 'prefer-stable', 'keywords', 'license', 'extra');
|
|
|
+ $rawData = $this->configFile->read();
|
|
|
$data = $this->config->all();
|
|
|
if (preg_match('/^repos?(?:itories)?(?:\.(.+))?/', $settingKey, $matches)) {
|
|
|
if (empty($matches[1])) {
|
|
@@ -240,7 +246,11 @@ EOT
|
|
|
}
|
|
|
} elseif (strpos($settingKey, '.')) {
|
|
|
$bits = explode('.', $settingKey);
|
|
|
- $data = $data['config'];
|
|
|
+ if ($bits[0] === 'extra') {
|
|
|
+ $data = $rawData;
|
|
|
+ } else {
|
|
|
+ $data = $data['config'];
|
|
|
+ }
|
|
|
$match = false;
|
|
|
foreach ($bits as $bit) {
|
|
|
$key = isset($key) ? $key.'.'.$bit : $bit;
|
|
@@ -259,6 +269,8 @@ EOT
|
|
|
$value = $data;
|
|
|
} elseif (isset($data['config'][$settingKey])) {
|
|
|
$value = $this->config->get($settingKey, $input->getOption('absolute') ? 0 : Config::RELATIVE_PATHS);
|
|
|
+ } elseif (in_array($settingKey, $properties, true) && isset($rawData[$settingKey])) {
|
|
|
+ $value = $rawData[$settingKey];
|
|
|
} else {
|
|
|
throw new \RuntimeException($settingKey.' is not defined');
|
|
|
}
|
|
@@ -387,44 +399,67 @@ EOT
|
|
|
),
|
|
|
);
|
|
|
|
|
|
- foreach ($uniqueConfigValues as $name => $callbacks) {
|
|
|
- if ($settingKey === $name) {
|
|
|
- if ($input->getOption('unset')) {
|
|
|
- return $this->configSource->removeConfigSetting($settingKey);
|
|
|
- }
|
|
|
-
|
|
|
- list($validator, $normalizer) = $callbacks;
|
|
|
- if (1 !== count($values)) {
|
|
|
- throw new \RuntimeException('You can only pass one value. Example: php composer.phar config process-timeout 300');
|
|
|
- }
|
|
|
-
|
|
|
- if (true !== $validation = $validator($values[0])) {
|
|
|
- throw new \RuntimeException(sprintf(
|
|
|
- '"%s" is an invalid value'.($validation ? ' ('.$validation.')' : ''),
|
|
|
- $values[0]
|
|
|
- ));
|
|
|
- }
|
|
|
-
|
|
|
- return $this->configSource->addConfigSetting($settingKey, $normalizer($values[0]));
|
|
|
- }
|
|
|
+ if ($input->getOption('unset') && (isset($uniqueConfigValues[$settingKey]) || isset($multiConfigValues[$settingKey]))) {
|
|
|
+ return $this->configSource->removeConfigSetting($settingKey);
|
|
|
+ }
|
|
|
+ if (isset($uniqueConfigValues[$settingKey])) {
|
|
|
+ return $this->handleSingleValue($settingKey, $uniqueConfigValues[$settingKey], $values, 'addConfigSetting');
|
|
|
+ }
|
|
|
+ if (isset($multiConfigValues[$settingKey])) {
|
|
|
+ return $this->handleMultiValue($settingKey, $multiConfigValues[$settingKey], $values, 'addConfigSetting');
|
|
|
}
|
|
|
|
|
|
- foreach ($multiConfigValues as $name => $callbacks) {
|
|
|
- if ($settingKey === $name) {
|
|
|
- if ($input->getOption('unset')) {
|
|
|
- return $this->configSource->removeConfigSetting($settingKey);
|
|
|
- }
|
|
|
+ // handle properties
|
|
|
+ $uniqueProps = array(
|
|
|
+ 'name' => array('is_string', function ($val) { return $val; }),
|
|
|
+ 'type' => array('is_string', function ($val) { return $val; }),
|
|
|
+ 'description' => array('is_string', function ($val) { return $val; }),
|
|
|
+ 'homepage' => array('is_string', function ($val) { return $val; }),
|
|
|
+ 'version' => array('is_string', function ($val) { return $val; }),
|
|
|
+ 'minimum-stability' => array(
|
|
|
+ function ($val) { return isset(BasePackage::$stabilities[VersionParser::normalizeStability($val)]); },
|
|
|
+ function ($val) { return VersionParser::normalizeStability($val); }
|
|
|
+ ),
|
|
|
+ 'prefer-stable' => array($booleanValidator, $booleanNormalizer),
|
|
|
+ );
|
|
|
+ $multiProps = array(
|
|
|
+ 'keywords' => array(
|
|
|
+ function ($vals) {
|
|
|
+ if (!is_array($vals)) {
|
|
|
+ return 'array expected';
|
|
|
+ }
|
|
|
|
|
|
- list($validator, $normalizer) = $callbacks;
|
|
|
- if (true !== $validation = $validator($values)) {
|
|
|
- throw new \RuntimeException(sprintf(
|
|
|
- '%s is an invalid value'.($validation ? ' ('.$validation.')' : ''),
|
|
|
- json_encode($values)
|
|
|
- ));
|
|
|
- }
|
|
|
+ return true;
|
|
|
+ },
|
|
|
+ function ($vals) {
|
|
|
+ return $vals;
|
|
|
+ },
|
|
|
+ ),
|
|
|
+ 'license' => array(
|
|
|
+ function ($vals) {
|
|
|
+ if (!is_array($vals)) {
|
|
|
+ return 'array expected';
|
|
|
+ }
|
|
|
|
|
|
- return $this->configSource->addConfigSetting($settingKey, $normalizer($values));
|
|
|
- }
|
|
|
+ return true;
|
|
|
+ },
|
|
|
+ function ($vals) {
|
|
|
+ return $vals;
|
|
|
+ },
|
|
|
+ ),
|
|
|
+ );
|
|
|
+
|
|
|
+ if ($input->getOption('global') && (isset($uniqueProps[$settingKey]) || isset($multiProps[$settingKey]) || substr($settingKey, 0, 6) === 'extra.')) {
|
|
|
+ throw new \InvalidArgumentException('The '.$settingKey.' property can not be set in the global config.json file. Use `composer global config` to apply changes to the global composer.json');
|
|
|
+ }
|
|
|
+ if ($input->getOption('unset') && (isset($uniqueProps[$settingKey]) || isset($multiProps[$settingKey]))) {
|
|
|
+ return $this->configSource->removeProperty($settingKey);
|
|
|
+ }
|
|
|
+ if (isset($uniqueProps[$settingKey])) {
|
|
|
+ return $this->handleSingleValue($settingKey, $uniqueProps[$settingKey], $values, 'addProperty');
|
|
|
+ }
|
|
|
+ if (isset($multiProps[$settingKey])) {
|
|
|
+ return $this->handleMultiValue($settingKey, $multiProps[$settingKey], $values, 'addProperty');
|
|
|
}
|
|
|
|
|
|
// handle repositories
|
|
@@ -456,6 +491,15 @@ EOT
|
|
|
throw new \RuntimeException('You must pass the type and a url. Example: php composer.phar config repositories.foo vcs https://bar.com');
|
|
|
}
|
|
|
|
|
|
+ // handle extra
|
|
|
+ if (preg_match('/^extra\.(.+)/', $settingKey, $matches)) {
|
|
|
+ if ($input->getOption('unset')) {
|
|
|
+ return $this->configSource->removeProperty($settingKey);
|
|
|
+ }
|
|
|
+
|
|
|
+ return $this->configSource->addProperty($settingKey, $values[0]);
|
|
|
+ }
|
|
|
+
|
|
|
// handle platform
|
|
|
if (preg_match('/^platform\.(.+)/', $settingKey, $matches)) {
|
|
|
if ($input->getOption('unset')) {
|
|
@@ -500,6 +544,36 @@ EOT
|
|
|
throw new \InvalidArgumentException('Setting '.$settingKey.' does not exist or is not supported by this command');
|
|
|
}
|
|
|
|
|
|
+ protected function handleSingleValue($key, array $callbacks, array $values, $method)
|
|
|
+ {
|
|
|
+ list($validator, $normalizer) = $callbacks;
|
|
|
+ if (1 !== count($values)) {
|
|
|
+ throw new \RuntimeException('You can only pass one value. Example: php composer.phar config process-timeout 300');
|
|
|
+ }
|
|
|
+
|
|
|
+ if (true !== $validation = $validator($values[0])) {
|
|
|
+ throw new \RuntimeException(sprintf(
|
|
|
+ '"%s" is an invalid value'.($validation ? ' ('.$validation.')' : ''),
|
|
|
+ $values[0]
|
|
|
+ ));
|
|
|
+ }
|
|
|
+
|
|
|
+ return call_user_func(array($this->configSource, $method), $key, $normalizer($values[0]));
|
|
|
+ }
|
|
|
+
|
|
|
+ protected function handleMultiValue($key, array $callbacks, array $values, $method)
|
|
|
+ {
|
|
|
+ list($validator, $normalizer) = $callbacks;
|
|
|
+ if (true !== $validation = $validator($values)) {
|
|
|
+ throw new \RuntimeException(sprintf(
|
|
|
+ '%s is an invalid value'.($validation ? ' ('.$validation.')' : ''),
|
|
|
+ json_encode($values)
|
|
|
+ ));
|
|
|
+ }
|
|
|
+
|
|
|
+ return call_user_func(array($this->configSource, $method), $key, $normalizer($values));
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* Display the contents of the file in a pretty formatted way
|
|
|
*
|