1
0
Fork 0

Fix config command issue handling objects in some conditions, fixes #11945

pull/11963/head
Jordi Boggiano 2024-04-29 10:59:21 +02:00
parent ea28853305
commit 232f4e7a5c
No known key found for this signature in database
GPG Key ID: 7BBD42C429EC80BC
4 changed files with 74 additions and 8 deletions

View File

@ -771,8 +771,12 @@ EOT
foreach ($bits as $bit) {
$currentValue = $currentValue[$bit] ?? null;
}
if (is_array($currentValue)) {
$value = array_merge($currentValue, $value);
if (is_array($currentValue) && is_array($value)) {
if (array_is_list($currentValue) && array_is_list($value)) {
$value = array_merge($currentValue, $value);
} else {
$value = $value + $currentValue;
}
}
}
}

View File

@ -416,6 +416,9 @@ class JsonManipulator
if ($subName !== null) {
$curVal = json_decode($children, true);
unset($curVal[$name][$subName]);
if ($curVal[$name] === []) {
$curVal[$name] = new \ArrayObject();
}
$this->addSubNode($mainNode, $name, $curVal[$name]);
}
@ -427,7 +430,7 @@ class JsonManipulator
if ($subName !== null) {
$curVal = json_decode($matches['content'], true);
unset($curVal[$name][$subName]);
$childrenClean = $this->format($curVal);
$childrenClean = $this->format($curVal, 0, true);
}
return $matches['start'] . $childrenClean . $matches['end'];
@ -534,12 +537,19 @@ class JsonManipulator
/**
* @param mixed $data
*/
public function format($data, int $depth = 0): string
public function format($data, int $depth = 0, bool $wasObject = false): string
{
if (is_array($data)) {
reset($data);
if ($data instanceof \stdClass || $data instanceof \ArrayObject) {
$data = (array) $data;
$wasObject = true;
}
if (is_numeric(key($data))) {
if (is_array($data)) {
if (\count($data) === 0) {
return $wasObject ? '{' . $this->newline . str_repeat($this->indent, $depth + 1) . '}' : '[]';
}
if (array_is_list($data)) {
foreach ($data as $key => $val) {
$data[$key] = $this->format($val, $depth + 1);
}
@ -550,7 +560,7 @@ class JsonManipulator
$out = '{' . $this->newline;
$elems = [];
foreach ($data as $key => $val) {
$elems[] = str_repeat($this->indent, $depth + 2) . JsonFile::encode($key). ': '.$this->format($val, $depth + 1);
$elems[] = str_repeat($this->indent, $depth + 2) . JsonFile::encode((string) $key). ': '.$this->format($val, $depth + 1);
}
return $out . implode(','.$this->newline, $elems) . $this->newline . str_repeat($this->indent, $depth + 1) . '}';

View File

@ -82,6 +82,26 @@ class ConfigCommandTest extends TestCase
['setting-key' => 'preferred-install.foo/*', '--unset' => true],
['config' => ['preferred-install' => []]],
];
yield 'set extra with merge' => [
[],
['setting-key' => 'extra.patches.foo/bar', 'setting-value' => ['{"123":"value"}'], '--json' => true, '--merge' => true],
['extra' => ['patches' => ['foo/bar' => [123 => 'value']]]],
];
yield 'combine extra with merge' => [
['extra' => ['patches' => ['foo/bar' => [5 => 'oldvalue']]]],
['setting-key' => 'extra.patches.foo/bar', 'setting-value' => ['{"123":"value"}'], '--json' => true, '--merge' => true],
['extra' => ['patches' => ['foo/bar' => [123 => 'value', 5 => 'oldvalue']]]],
];
yield 'combine extra with list' => [
['extra' => ['patches' => ['foo/bar' => ['oldvalue']]]],
['setting-key' => 'extra.patches.foo/bar', 'setting-value' => ['{"123":"value"}'], '--json' => true, '--merge' => true],
['extra' => ['patches' => ['foo/bar' => [123 => 'value', 0 => 'oldvalue']]]],
];
yield 'overwrite extra with merge' => [
['extra' => ['patches' => ['foo/bar' => [123 => 'oldvalue']]]],
['setting-key' => 'extra.patches.foo/bar', 'setting-value' => ['{"123":"value"}'], '--json' => true, '--merge' => true],
['extra' => ['patches' => ['foo/bar' => [123 => 'value']]]],
];
}
/**

View File

@ -1721,6 +1721,38 @@ class JsonManipulatorTest extends TestCase
', $manipulator->getContents());
}
public function testRemoveSubNodePreservesObjectTypeWhenEmpty(): void
{
$manipulator = new JsonManipulator('{
"test": {"0": "foo"}
}');
$this->assertTrue($manipulator->removeSubNode('test', '0'));
$this->assertEquals('{
"test": {
}
}
', $manipulator->getContents());
}
public function testRemoveSubNodePreservesObjectTypeWhenEmpty2(): void
{
$manipulator = new JsonManipulator('{
"config": {
"preferred-install": {"foo/*": "source"}
}
}');
$this->assertTrue($manipulator->removeConfigSetting('preferred-install.foo/*'));
$this->assertEquals('{
"config": {
"preferred-install": {
}
}
}
', $manipulator->getContents());
}
public function testAddSubNodeInRequire(): void
{
$manipulator = new JsonManipulator('{