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) { foreach ($bits as $bit) {
$currentValue = $currentValue[$bit] ?? null; $currentValue = $currentValue[$bit] ?? null;
} }
if (is_array($currentValue)) { if (is_array($currentValue) && is_array($value)) {
$value = array_merge($currentValue, $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) { if ($subName !== null) {
$curVal = json_decode($children, true); $curVal = json_decode($children, true);
unset($curVal[$name][$subName]); unset($curVal[$name][$subName]);
if ($curVal[$name] === []) {
$curVal[$name] = new \ArrayObject();
}
$this->addSubNode($mainNode, $name, $curVal[$name]); $this->addSubNode($mainNode, $name, $curVal[$name]);
} }
@ -427,7 +430,7 @@ class JsonManipulator
if ($subName !== null) { if ($subName !== null) {
$curVal = json_decode($matches['content'], true); $curVal = json_decode($matches['content'], true);
unset($curVal[$name][$subName]); unset($curVal[$name][$subName]);
$childrenClean = $this->format($curVal); $childrenClean = $this->format($curVal, 0, true);
} }
return $matches['start'] . $childrenClean . $matches['end']; return $matches['start'] . $childrenClean . $matches['end'];
@ -534,12 +537,19 @@ class JsonManipulator
/** /**
* @param mixed $data * @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)) { if ($data instanceof \stdClass || $data instanceof \ArrayObject) {
reset($data); $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) { foreach ($data as $key => $val) {
$data[$key] = $this->format($val, $depth + 1); $data[$key] = $this->format($val, $depth + 1);
} }
@ -550,7 +560,7 @@ class JsonManipulator
$out = '{' . $this->newline; $out = '{' . $this->newline;
$elems = []; $elems = [];
foreach ($data as $key => $val) { 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) . '}'; 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], ['setting-key' => 'preferred-install.foo/*', '--unset' => true],
['config' => ['preferred-install' => []]], ['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()); ', $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 public function testAddSubNodeInRequire(): void
{ {
$manipulator = new JsonManipulator('{ $manipulator = new JsonManipulator('{