diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b11e679..2eddfe85 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 [`1.0.0...main`][1.0.0...main]. +For a full diff see [`1.0.1...main`][1.0.1...main]. + +## [`1.0.1`][1.0.1] + +For a full diff see [`1.0.0...1.0.1`][1.0.0...1.0.1]. + +### Fixed + +* Adjusted `Vendor\Composer\ConfigHashNormalizer` to ignore the `preferred-install` hash ([#425]), by [@localheinz] ## [`1.0.0`][1.0.0] @@ -293,6 +301,7 @@ For a full diff see [`5d8b3e2...0.1.0`][5d8b3e2...0.1.0]. [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 +[1.0.1]: https://github.com/ergebnis/json-normalizer/releases/tag/1.0.1 [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 @@ -314,7 +323,8 @@ For a full diff see [`5d8b3e2...0.1.0`][5d8b3e2...0.1.0]. [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...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.0.0...1.0.1]: https://github.com/ergebnis/json-normalizer/compare/1.0.0...1.0.0 +[1.0.1...main]: https://github.com/ergebnis/json-normalizer/compare/1.0.1...main [#1]: https://github.com/ergebnis/json-normalizer/pull/1 [#2]: https://github.com/ergebnis/json-normalizer/pull/2 @@ -378,6 +388,7 @@ For a full diff see [`5d8b3e2...0.1.0`][5d8b3e2...0.1.0]. [#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 +[#425]: https://github.com/ergebnis/json-normalizer/pull/425 [@BackEndTea]: https://github.com/BackEndTea [@ergebnis]: https://github.com/ergebnis diff --git a/src/Vendor/Composer/ConfigHashNormalizer.php b/src/Vendor/Composer/ConfigHashNormalizer.php index 85c0bdc9..b71b03fc 100644 --- a/src/Vendor/Composer/ConfigHashNormalizer.php +++ b/src/Vendor/Composer/ConfigHashNormalizer.php @@ -30,6 +30,16 @@ final class ConfigHashNormalizer implements NormalizerInterface 'scripts-descriptions', ]; + /** + * @phpstan-var list + * @psalm-var list + * + * @var array + */ + private static $propertiesThatShouldNotBeSorted = [ + 'preferred-install', + ]; + public function normalize(Json $json): Json { $decoded = $json->decoded(); @@ -48,7 +58,10 @@ public function normalize(Json $json): Json } foreach ($objectProperties as $name => $value) { - $decoded->{$name} = self::sortByKey($value); + $decoded->{$name} = self::sortByKey( + $name, + $value + ); } /** @var string $encoded */ @@ -62,12 +75,17 @@ public function normalize(Json $json): Json * * @return null|array|bool|false|\stdClass|string */ - private static function sortByKey($value) + private static function sortByKey(string $name, $value) { + if (\in_array($name, self::$propertiesThatShouldNotBeSorted, true)) { + return $value; + } + if (!\is_object($value)) { return $value; } + /** @var array $sorted */ $sorted = (array) $value; if ([] === $sorted) { @@ -76,8 +94,16 @@ private static function sortByKey($value) \ksort($sorted); - return \array_map(static function ($value) { - return self::sortByKey($value); - }, $sorted); + $names = \array_keys($sorted); + + return \array_combine( + $names, + \array_map(static function ($value, string $name) { + return self::sortByKey( + $name, + $value + ); + }, $sorted, $names) + ); } } diff --git a/test/Unit/Vendor/Composer/ConfigHashNormalizerTest.php b/test/Unit/Vendor/Composer/ConfigHashNormalizerTest.php index 9cf9c0d2..e69e5062 100644 --- a/test/Unit/Vendor/Composer/ConfigHashNormalizerTest.php +++ b/test/Unit/Vendor/Composer/ConfigHashNormalizerTest.php @@ -196,6 +196,49 @@ public function testNormalizeSortsConfigHashRecursivelyIfPropertyExists(string $ self::assertJsonStringEqualsJsonStringNormalized($expected->encoded(), $normalized->encoded()); } + /** + * @see https://github.com/ergebnis/composer-normalize/issues/644 + * @see https://getcomposer.org/doc/06-config.md#preferred-install + */ + public function testNormalizeDoesNotSortPreferredInstall(): void + { + $json = Json::fromEncoded( + <<<'JSON' +{ + "config": { + "sort-packages": true, + "preferred-install": { + "foo/*": "source", + "bar/*": "source", + "*": "dist" + } + } +} +JSON + ); + + $expected = Json::fromEncoded( + <<<'JSON' +{ + "config": { + "preferred-install": { + "foo/*": "source", + "bar/*": "source", + "*": "dist" + }, + "sort-packages": true + } +} +JSON + ); + + $normalizer = new ConfigHashNormalizer(); + + $normalized = $normalizer->normalize($json); + + self::assertJsonStringEqualsJsonStringNormalized($expected->encoded(), $normalized->encoded()); + } + /** * @return \Generator> */