From bc274fe9e8957f2c9361dfcbaadbba1f9fa14552 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20M=C3=B6ller?= Date: Tue, 29 Dec 2020 09:01:11 +0100 Subject: [PATCH] Enhancement: Let ConfigHashNormalizer recursively sort hashes by key --- CHANGELOG.md | 15 ++++- README.md | 2 +- psalm-baseline.xml | 7 ++- src/Vendor/Composer/ConfigHashNormalizer.php | 34 ++++++++--- .../Composer/ConfigHashNormalizerTest.php | 56 +++++++++++++++++++ 5 files changed, 99 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index db26e187..5b11e679 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,15 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ## Unreleased -For a full diff see [`0.14.1...main`][0.14.1...main]. +For a full diff see [`1.0.0...main`][1.0.0...main]. + +## [`1.0.0`][1.0.0] + +For a full diff see [`0.14.1...1.0.0`][0.14.1...1.0.0]. + +### Changed + +* Adjusted `Vendor\Composer\ConfigHashNormalizer` to recursively sort hashes by key ([#424]), by [@localheinz] ## [`0.14.1`][0.14.1] @@ -284,6 +292,7 @@ For a full diff see [`5d8b3e2...0.1.0`][5d8b3e2...0.1.0]. [0.13.1]: https://github.com/ergebnis/json-normalizer/releases/tag/0.13.1 [0.14.0]: https://github.com/ergebnis/json-normalizer/releases/tag/0.14.0 [0.14.1]: https://github.com/ergebnis/json-normalizer/releases/tag/0.14.1 +[1.0.0]: https://github.com/ergebnis/json-normalizer/releases/tag/1.0.0 [5d8b3e2...0.1.0]: https://github.com/ergebnis/json-normalizer/compare/5d8b3e2...0.1.0 [0.1.0...0.2.0]: https://github.com/ergebnis/json-normalizer/compare/0.1.0...0.2.0 @@ -304,7 +313,8 @@ For a full diff see [`5d8b3e2...0.1.0`][5d8b3e2...0.1.0]. [0.13.0...0.13.1]: https://github.com/ergebnis/json-normalizer/compare/0.13.0...0.13.1 [0.13.1...0.14.0]: https://github.com/ergebnis/json-normalizer/compare/0.13.1...0.14.0 [0.14.0...0.14.1]: https://github.com/ergebnis/json-normalizer/compare/0.14.0...0.14.1 -[0.14.1...main]: https://github.com/ergebnis/json-normalizer/compare/0.14.1...main +[0.14.1...1.0.0]: https://github.com/ergebnis/json-normalizer/compare/0.14.1...1.0.0 +[1.0.0...main]: https://github.com/ergebnis/json-normalizer/compare/1.0.0...main [#1]: https://github.com/ergebnis/json-normalizer/pull/1 [#2]: https://github.com/ergebnis/json-normalizer/pull/2 @@ -367,6 +377,7 @@ For a full diff see [`5d8b3e2...0.1.0`][5d8b3e2...0.1.0]. [#335]: https://github.com/ergebnis/json-normalizer/pull/335 [#384]: https://github.com/ergebnis/json-normalizer/pull/384 [#423]: https://github.com/ergebnis/json-normalizer/pull/423 +[#424]: https://github.com/ergebnis/json-normalizer/pull/424 [@BackEndTea]: https://github.com/BackEndTea [@ergebnis]: https://github.com/ergebnis diff --git a/README.md b/README.md index ec9e724c..bd5448bb 100644 --- a/README.md +++ b/README.md @@ -389,7 +389,7 @@ When `composer.json` contains any configuration in the * `extra` * `scripts-descriptions` -sections, the `Vendor\Composer\ConfigHashNormalizer` will sort the content of these sections by key in ascending order. +sections, the `Vendor\Composer\ConfigHashNormalizer` will sort the content of these sections by key in ascending order. If a value is an object, it will continue to sort its properties by name. :bulb: Find out more about the `config` section at [Composer: The composer.json schema](https://getcomposer.org/doc/06-config.md). diff --git a/psalm-baseline.xml b/psalm-baseline.xml index f5b1447d..aab96b98 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -60,12 +60,13 @@ + + $value + $value + $value - - $value - diff --git a/src/Vendor/Composer/ConfigHashNormalizer.php b/src/Vendor/Composer/ConfigHashNormalizer.php index b559aaf0..85c0bdc9 100644 --- a/src/Vendor/Composer/ConfigHashNormalizer.php +++ b/src/Vendor/Composer/ConfigHashNormalizer.php @@ -48,15 +48,7 @@ public function normalize(Json $json): Json } foreach ($objectProperties as $name => $value) { - $config = (array) $decoded->{$name}; - - if (0 === \count($config)) { - continue; - } - - \ksort($config); - - $decoded->{$name} = $config; + $decoded->{$name} = self::sortByKey($value); } /** @var string $encoded */ @@ -64,4 +56,28 @@ public function normalize(Json $json): Json return Json::fromEncoded($encoded); } + + /** + * @param null|array|bool|false|\stdClass|string $value + * + * @return null|array|bool|false|\stdClass|string + */ + private static function sortByKey($value) + { + if (!\is_object($value)) { + return $value; + } + + $sorted = (array) $value; + + if ([] === $sorted) { + return $value; + } + + \ksort($sorted); + + return \array_map(static function ($value) { + return self::sortByKey($value); + }, $sorted); + } } diff --git a/test/Unit/Vendor/Composer/ConfigHashNormalizerTest.php b/test/Unit/Vendor/Composer/ConfigHashNormalizerTest.php index ef2994e4..9cf9c0d2 100644 --- a/test/Unit/Vendor/Composer/ConfigHashNormalizerTest.php +++ b/test/Unit/Vendor/Composer/ConfigHashNormalizerTest.php @@ -140,6 +140,62 @@ public function testNormalizeSortsConfigHashIfPropertyExists(string $property): self::assertJsonStringEqualsJsonStringNormalized($expected->encoded(), $normalized->encoded()); } + /** + * @dataProvider provideProperty + */ + public function testNormalizeSortsConfigHashRecursivelyIfPropertyExists(string $property): void + { + $json = Json::fromEncoded( + <<normalize($json); + + self::assertJsonStringEqualsJsonStringNormalized($expected->encoded(), $normalized->encoded()); + } + /** * @return \Generator> */