Add support for editing top level properties and extra values, replaces #2415, fixes #1411, fixes #2384
parent
3186b5eeca
commit
135783299a
|
@ -499,8 +499,10 @@ sudo -H composer self-update
|
||||||
|
|
||||||
## config
|
## config
|
||||||
|
|
||||||
The `config` command allows you to edit some basic Composer settings in either
|
The `config` command allows you to edit composer config settings and repositories
|
||||||
the local `composer.json` file or the global `config.json` file.
|
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`.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
php composer.phar config --list
|
php composer.phar config --list
|
||||||
|
@ -514,6 +516,11 @@ php composer.phar config --list
|
||||||
configuration value. For settings that can take an array of values (like
|
configuration value. For settings that can take an array of values (like
|
||||||
`github-protocols`), more than one setting-value arguments are allowed.
|
`github-protocols`), more than one setting-value arguments are allowed.
|
||||||
|
|
||||||
|
You can also edit the values of the following properties:
|
||||||
|
|
||||||
|
`description`, `homepage`, `keywords`, `license`, `minimum-stability`,
|
||||||
|
`name`, `prefer-stable`, `type` and `version`.
|
||||||
|
|
||||||
See the [Config](06-config.md) chapter for valid configuration options.
|
See the [Config](06-config.md) chapter for valid configuration options.
|
||||||
|
|
||||||
### Options
|
### Options
|
||||||
|
@ -547,6 +554,18 @@ If your repository requires more configuration options, you can instead pass its
|
||||||
php composer.phar config repositories.foo '{"type": "vcs", "url": "http://svn.example.org/my-project/", "trunk-path": "master"}'
|
php composer.phar config repositories.foo '{"type": "vcs", "url": "http://svn.example.org/my-project/", "trunk-path": "master"}'
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Modifying Extra Values
|
||||||
|
|
||||||
|
In addition to modifying the config section, the `config` command also supports making
|
||||||
|
changes to the extra section by using it the following way:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
php composer.phar config extra.foo.bar value
|
||||||
|
```
|
||||||
|
|
||||||
|
The dots indicate array nesting, a max depth of 3 levels is allowed though. The above
|
||||||
|
would set `"extra": { "foo": { "bar": "value" } }`.
|
||||||
|
|
||||||
## create-project
|
## create-project
|
||||||
|
|
||||||
You can use Composer to create new projects from an existing package. This is
|
You can use Composer to create new projects from an existing package. This is
|
||||||
|
|
|
@ -22,6 +22,8 @@ use Composer\Config;
|
||||||
use Composer\Config\JsonConfigSource;
|
use Composer\Config\JsonConfigSource;
|
||||||
use Composer\Factory;
|
use Composer\Factory;
|
||||||
use Composer\Json\JsonFile;
|
use Composer\Json\JsonFile;
|
||||||
|
use Composer\Semver\VersionParser;
|
||||||
|
use Composer\Package\BasePackage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Joshua Estes <Joshua.Estes@iostudio.com>
|
* @author Joshua Estes <Joshua.Estes@iostudio.com>
|
||||||
|
@ -74,8 +76,10 @@ class ConfigCommand extends BaseCommand
|
||||||
new InputArgument('setting-value', InputArgument::IS_ARRAY, 'Setting value'),
|
new InputArgument('setting-value', InputArgument::IS_ARRAY, 'Setting value'),
|
||||||
))
|
))
|
||||||
->setHelp(<<<EOT
|
->setHelp(<<<EOT
|
||||||
This command allows you to edit some basic composer settings in either the
|
This command allows you to edit composer config settings and repositories
|
||||||
local composer.json file or the global config.json file.
|
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:
|
To set a config setting:
|
||||||
|
|
||||||
|
@ -227,6 +231,8 @@ EOT
|
||||||
|
|
||||||
// show the value if no value is provided
|
// show the value if no value is provided
|
||||||
if (array() === $input->getArgument('setting-value') && !$input->getOption('unset')) {
|
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();
|
$data = $this->config->all();
|
||||||
if (preg_match('/^repos?(?:itories)?(?:\.(.+))?/', $settingKey, $matches)) {
|
if (preg_match('/^repos?(?:itories)?(?:\.(.+))?/', $settingKey, $matches)) {
|
||||||
if (empty($matches[1])) {
|
if (empty($matches[1])) {
|
||||||
|
@ -240,7 +246,11 @@ EOT
|
||||||
}
|
}
|
||||||
} elseif (strpos($settingKey, '.')) {
|
} elseif (strpos($settingKey, '.')) {
|
||||||
$bits = explode('.', $settingKey);
|
$bits = explode('.', $settingKey);
|
||||||
$data = $data['config'];
|
if ($bits[0] === 'extra') {
|
||||||
|
$data = $rawData;
|
||||||
|
} else {
|
||||||
|
$data = $data['config'];
|
||||||
|
}
|
||||||
$match = false;
|
$match = false;
|
||||||
foreach ($bits as $bit) {
|
foreach ($bits as $bit) {
|
||||||
$key = isset($key) ? $key.'.'.$bit : $bit;
|
$key = isset($key) ? $key.'.'.$bit : $bit;
|
||||||
|
@ -259,6 +269,8 @@ EOT
|
||||||
$value = $data;
|
$value = $data;
|
||||||
} elseif (isset($data['config'][$settingKey])) {
|
} elseif (isset($data['config'][$settingKey])) {
|
||||||
$value = $this->config->get($settingKey, $input->getOption('absolute') ? 0 : Config::RELATIVE_PATHS);
|
$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 {
|
} else {
|
||||||
throw new \RuntimeException($settingKey.' is not defined');
|
throw new \RuntimeException($settingKey.' is not defined');
|
||||||
}
|
}
|
||||||
|
@ -387,44 +399,67 @@ EOT
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
foreach ($uniqueConfigValues as $name => $callbacks) {
|
if ($input->getOption('unset') && (isset($uniqueConfigValues[$settingKey]) || isset($multiConfigValues[$settingKey]))) {
|
||||||
if ($settingKey === $name) {
|
return $this->configSource->removeConfigSetting($settingKey);
|
||||||
if ($input->getOption('unset')) {
|
}
|
||||||
return $this->configSource->removeConfigSetting($settingKey);
|
if (isset($uniqueConfigValues[$settingKey])) {
|
||||||
}
|
return $this->handleSingleValue($settingKey, $uniqueConfigValues[$settingKey], $values, 'addConfigSetting');
|
||||||
|
}
|
||||||
list($validator, $normalizer) = $callbacks;
|
if (isset($multiConfigValues[$settingKey])) {
|
||||||
if (1 !== count($values)) {
|
return $this->handleMultiValue($settingKey, $multiConfigValues[$settingKey], $values, 'addConfigSetting');
|
||||||
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]));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($multiConfigValues as $name => $callbacks) {
|
// handle properties
|
||||||
if ($settingKey === $name) {
|
$uniqueProps = array(
|
||||||
if ($input->getOption('unset')) {
|
'name' => array('is_string', function ($val) { return $val; }),
|
||||||
return $this->configSource->removeConfigSetting($settingKey);
|
'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;
|
return true;
|
||||||
if (true !== $validation = $validator($values)) {
|
},
|
||||||
throw new \RuntimeException(sprintf(
|
function ($vals) {
|
||||||
'%s is an invalid value'.($validation ? ' ('.$validation.')' : ''),
|
return $vals;
|
||||||
json_encode($values)
|
},
|
||||||
));
|
),
|
||||||
}
|
'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
|
// 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');
|
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
|
// handle platform
|
||||||
if (preg_match('/^platform\.(.+)/', $settingKey, $matches)) {
|
if (preg_match('/^platform\.(.+)/', $settingKey, $matches)) {
|
||||||
if ($input->getOption('unset')) {
|
if ($input->getOption('unset')) {
|
||||||
|
@ -500,6 +544,36 @@ EOT
|
||||||
throw new \InvalidArgumentException('Setting '.$settingKey.' does not exist or is not supported by this command');
|
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
|
* Display the contents of the file in a pretty formatted way
|
||||||
*
|
*
|
||||||
|
|
|
@ -50,6 +50,21 @@ interface ConfigSourceInterface
|
||||||
*/
|
*/
|
||||||
public function removeConfigSetting($name);
|
public function removeConfigSetting($name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a property
|
||||||
|
*
|
||||||
|
* @param string $name Name
|
||||||
|
* @param string $value Value
|
||||||
|
*/
|
||||||
|
public function addProperty($name, $value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a property
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
*/
|
||||||
|
public function removeProperty($name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a package link
|
* Add a package link
|
||||||
*
|
*
|
||||||
|
|
|
@ -114,6 +114,53 @@ class JsonConfigSource implements ConfigSourceInterface
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function addProperty($name, $value)
|
||||||
|
{
|
||||||
|
$this->manipulateJson('addProperty', $name, $value, function (&$config, $key, $val) {
|
||||||
|
if (substr($key, 0, 6) === 'extra.') {
|
||||||
|
$bits = explode('.', $key);
|
||||||
|
$last = array_pop($bits);
|
||||||
|
$arr =& $config['extra'];
|
||||||
|
foreach ($bits as $bit) {
|
||||||
|
if (!isset($arr[$bit])) {
|
||||||
|
$arr[$bit] = array();
|
||||||
|
}
|
||||||
|
$arr =& $arr[$bit];
|
||||||
|
}
|
||||||
|
$arr[$last] = $val;
|
||||||
|
} else {
|
||||||
|
$config[$key] = $val;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function removeProperty($name)
|
||||||
|
{
|
||||||
|
$authConfig = $this->authConfig;
|
||||||
|
$this->manipulateJson('removeProperty', $name, function (&$config, $key) {
|
||||||
|
if (substr($key, 0, 6) === 'extra.') {
|
||||||
|
$bits = explode('.', $key);
|
||||||
|
$last = array_pop($bits);
|
||||||
|
$arr =& $config['extra'];
|
||||||
|
foreach ($bits as $bit) {
|
||||||
|
if (!isset($arr[$bit])) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$arr =& $arr[$bit];
|
||||||
|
}
|
||||||
|
unset($arr[$last]);
|
||||||
|
} else {
|
||||||
|
unset($config[$key]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -163,12 +163,30 @@ class JsonManipulator
|
||||||
return $this->removeSubNode('config', $name);
|
return $this->removeSubNode('config', $name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function addProperty($name, $value)
|
||||||
|
{
|
||||||
|
if (substr($name, 0, 6) === 'extra.') {
|
||||||
|
return $this->addSubNode('extra', substr($name, 6), $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->addMainKey($name, $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function removeProperty($name)
|
||||||
|
{
|
||||||
|
if (substr($name, 0, 6) === 'extra.') {
|
||||||
|
return $this->removeSubNode('extra', substr($name, 6));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->removeMainKey($name);
|
||||||
|
}
|
||||||
|
|
||||||
public function addSubNode($mainNode, $name, $value)
|
public function addSubNode($mainNode, $name, $value)
|
||||||
{
|
{
|
||||||
$decoded = JsonFile::parseJson($this->contents);
|
$decoded = JsonFile::parseJson($this->contents);
|
||||||
|
|
||||||
$subName = null;
|
$subName = null;
|
||||||
if (in_array($mainNode, array('config', 'repositories')) && false !== strpos($name, '.')) {
|
if (in_array($mainNode, array('config', 'repositories', 'extra')) && false !== strpos($name, '.')) {
|
||||||
list($name, $subName) = explode('.', $name, 2);
|
list($name, $subName) = explode('.', $name, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,6 +229,9 @@ class JsonManipulator
|
||||||
$children = preg_replace_callback('{("'.preg_quote($name).'"\s*:\s*)('.self::$JSON_VALUE.')(,?)}', function ($matches) use ($name, $subName, $value, $that) {
|
$children = preg_replace_callback('{("'.preg_quote($name).'"\s*:\s*)('.self::$JSON_VALUE.')(,?)}', function ($matches) use ($name, $subName, $value, $that) {
|
||||||
if ($subName !== null) {
|
if ($subName !== null) {
|
||||||
$curVal = json_decode($matches[2], true);
|
$curVal = json_decode($matches[2], true);
|
||||||
|
if (!is_array($curVal)) {
|
||||||
|
$curVal = array();
|
||||||
|
}
|
||||||
$curVal[$subName] = $value;
|
$curVal[$subName] = $value;
|
||||||
$value = $curVal;
|
$value = $curVal;
|
||||||
}
|
}
|
||||||
|
@ -275,7 +296,7 @@ class JsonManipulator
|
||||||
}
|
}
|
||||||
|
|
||||||
$subName = null;
|
$subName = null;
|
||||||
if (in_array($mainNode, array('config', 'repositories')) && false !== strpos($name, '.')) {
|
if (in_array($mainNode, array('config', 'repositories', 'extra')) && false !== strpos($name, '.')) {
|
||||||
list($name, $subName) = explode('.', $name, 2);
|
list($name, $subName) = explode('.', $name, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -374,6 +395,34 @@ class JsonManipulator
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function removeMainKey($key)
|
||||||
|
{
|
||||||
|
$decoded = JsonFile::parseJson($this->contents);
|
||||||
|
|
||||||
|
if (!isset($decoded[$key])) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// key exists already
|
||||||
|
$regex = '{^(\s*\{\s*(?:'.self::$JSON_STRING.'\s*:\s*'.self::$JSON_VALUE.'\s*,\s*)*?)'.
|
||||||
|
'('.preg_quote(JsonFile::encode($key)).'\s*:\s*'.self::$JSON_VALUE.')\s*,?\s*(.*)}s';
|
||||||
|
if ($this->pregMatch($regex, $this->contents, $matches)) {
|
||||||
|
// invalid match due to un-regexable content, abort
|
||||||
|
if (!@json_decode('{'.$matches[2].'}')) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->contents = $matches[1] . $matches[3];
|
||||||
|
if (preg_match('#^\{\s*\}\s*$#', $this->contents)) {
|
||||||
|
$this->contents = "{\n}";
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public function format($data, $depth = 0)
|
public function format($data, $depth = 0)
|
||||||
{
|
{
|
||||||
if (is_array($data)) {
|
if (is_array($data)) {
|
||||||
|
|
|
@ -2143,6 +2143,67 @@ class JsonManipulatorTest extends \PHPUnit_Framework_TestCase
|
||||||
', $manipulator->getContents());
|
', $manipulator->getContents());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testRemoveMainKey()
|
||||||
|
{
|
||||||
|
$manipulator = new JsonManipulator('{
|
||||||
|
"repositories": [
|
||||||
|
{
|
||||||
|
"package": {
|
||||||
|
"require": {
|
||||||
|
"this/should-not-end-up-in-root-require": "~2.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"this/should-not-end-up-in-root-require-dev": "~2.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"require": {
|
||||||
|
"package/a": "*",
|
||||||
|
"package/b": "*",
|
||||||
|
"package/c": "*"
|
||||||
|
},
|
||||||
|
"foo": "bar",
|
||||||
|
"require-dev": {
|
||||||
|
"package/d": "*"
|
||||||
|
}
|
||||||
|
}');
|
||||||
|
|
||||||
|
$this->assertTrue($manipulator->removeMainKey('repositories'));
|
||||||
|
$this->assertEquals('{
|
||||||
|
"require": {
|
||||||
|
"package/a": "*",
|
||||||
|
"package/b": "*",
|
||||||
|
"package/c": "*"
|
||||||
|
},
|
||||||
|
"foo": "bar",
|
||||||
|
"require-dev": {
|
||||||
|
"package/d": "*"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
', $manipulator->getContents());
|
||||||
|
|
||||||
|
$this->assertTrue($manipulator->removeMainKey('foo'));
|
||||||
|
$this->assertEquals('{
|
||||||
|
"require": {
|
||||||
|
"package/a": "*",
|
||||||
|
"package/b": "*",
|
||||||
|
"package/c": "*"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"package/d": "*"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
', $manipulator->getContents());
|
||||||
|
|
||||||
|
$this->assertTrue($manipulator->removeMainKey('require'));
|
||||||
|
$this->assertTrue($manipulator->removeMainKey('require-dev'));
|
||||||
|
$this->assertEquals('{
|
||||||
|
}
|
||||||
|
', $manipulator->getContents());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public function testIndentDetection()
|
public function testIndentDetection()
|
||||||
{
|
{
|
||||||
$manipulator = new JsonManipulator('{
|
$manipulator = new JsonManipulator('{
|
||||||
|
|
Loading…
Reference in New Issue