Skip to content

Commit

Permalink
Sort allow-plugins and preferred-install, usually
Browse files Browse the repository at this point in the history
No sorting will be applied if there are wildcards in the middle of strings.
  • Loading branch information
fredden authored and localheinz committed Oct 10, 2023
1 parent 318079a commit 9d8f548
Show file tree
Hide file tree
Showing 15 changed files with 164 additions and 11 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),

For a full diff see [`4.2.0...main`][4.2.0...main].

### Changed

- Sort `allow-plugins` and `preferred-install` as sensibly as is feasible ([#980]), by [@fredden]

## [`4.2.0`][4.2.0]

For a full diff see [`4.1.0...4.2.0`][4.1.0...4.2.0].
Expand Down Expand Up @@ -630,6 +634,7 @@ For a full diff see [`5d8b3e2...0.1.0`][5d8b3e2...0.1.0].
[#873]: https://github.com/ergebnis/json-normalizer/pull/873
[#889]: https://github.com/ergebnis/json-normalizer/pull/889
[#917]: https://github.com/ergebnis/json-normalizer/pull/917
[#980]: https://github.com/ergebnis/json-normalizer/pull/980

[@alexis-saransig-lullabot]: https://github.com/alexis-saransig-lullabot
[@BackEndTea]: https://github.com/BackEndTea
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,8 @@ When `composer.json` contains an array of scripts in the `bin` section, the `Ven

When `composer.json` contains configuration in the `config` section, the `Vendor\Composer\ConfigHashNormalizer` will sort the content of these sections by key in ascending order.

The `allow-plugins` and `preferred-install` keys have special handling as they both support wildcards. When no wildcards are used, these are sorted in ascending order. When wildcards are in use, then the list will be sorted if possible (ie, when the wildcards are only at the end of package names). Due to internal implementation details of the wildcard feature within Composer, sorting keys when there are wildcards part-way through is not feasible.

:bulb: Find out more about the `config` section at [Composer: The composer.json schema](https://getcomposer.org/doc/06-config.md).

#### `Vendor\Composer\PackageHashNormalizer`
Expand Down
42 changes: 42 additions & 0 deletions src/Vendor/Composer/ConfigHashNormalizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@

final class ConfigHashNormalizer implements Normalizer
{
private const PROPERTIES_WITH_WILDCARDS = [
'allow-plugins',
'preferred-install',
];

public function normalize(Json $json): Json
{
$decoded = $json->decoded();
Expand All @@ -44,6 +49,12 @@ public function normalize(Json $json): Json

\ksort($config);

foreach (self::PROPERTIES_WITH_WILDCARDS as $property) {
if (isset($config[$property]) && \is_object($config[$property])) {
self::sortPropertyWithWildcard($config, $property);
}
}

$decoded->config = $config;

/** @var string $encoded */
Expand All @@ -54,4 +65,35 @@ public function normalize(Json $json): Json

return Json::fromString($encoded);
}

/**
* When sorting with wildcards, special care needs to be taken.
*
* See also https://github.com/ergebnis/json-normalizer/pull/775#issuecomment-1346095415
*/
private static function sortPropertyWithWildcard(array &$config, string $propertyToSort): void
{
$property = (array) $config[$propertyToSort];

if ([] === $property) {
return;
}

foreach (\array_keys($property) as $package) {
if (\str_contains(\rtrim((string) $package, '*'), '*')) {
// We cannot reliably sort allow-plugins when there's a wildcard other than at the end of the string.
return;
}
}

\uksort($property, static function ($a, $b): int {
// Any key with an asterisk needs to be the last entry in its group
$a = \str_replace('*', '~', (string) $a);
$b = \str_replace('*', '~', (string) $b);

return \strcmp($a, $b);
});

$config[$propertyToSort] = $property;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
"config": {
"allow-plugins": {
"composer/package-versions-deprecated": true,
"infection/extension-installer": true,
"composer/*": false
"ergebnis/composer-normalize": true,
"infection/extension-installer": true
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
"homepage": "https://getcomposer.org/doc/06-config.md#allow-plugins",
"config": {
"allow-plugins": {
"composer/*": false,
"infection/extension-installer": true,
"ergebnis/composer-normalize": true,
"composer/package-versions-deprecated": true
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"name": "ergebnis/json-normalizer",
"description": "Provides generic and vendor-specific normalizers for normalizing JSON documents.",
"license": "MIT",
"type": "library",
"keywords": [
"json",
"normalizer"
],
"authors": [
{
"name": "Andreas Möller",
"email": "[email protected]"
}
],
"homepage": "https://getcomposer.org/doc/06-config.md#allow-plugins",
"config": {
"allow-plugins": {
"ergebnis/composer-normalize": true,
"composer/unwanted-plugin-1-test": false,
"composer/*-test": true,
"composer/unwanted-plugin-2-test": false,
"infection/extension-installer": true
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"name": "ergebnis/json-normalizer",
"description": "Provides generic and vendor-specific normalizers for normalizing JSON documents.",
"license": "MIT",
"type": "library",
"keywords": [
"json",
"normalizer"
],
"authors": [
{
"name": "Andreas Möller",
"email": "[email protected]"
}
],
"homepage": "https://getcomposer.org/doc/06-config.md#allow-plugins",
"config": {
"allow-plugins": {
"ergebnis/composer-normalize": true,
"composer/unwanted-plugin-1-test": false,
"composer/*-test": true,
"composer/unwanted-plugin-2-test": false,
"infection/extension-installer": true
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@
"homepage": "https://getcomposer.org/doc/06-config.md#allow-plugins",
"config": {
"allow-plugins": {
"composer/package-versions-deprecated": true,
"composer/*": false,
"infection/extension-installer": true,
"composer/package-versions-deprecated": true
"ergebnis/composer-normalize": true,
"infection/extension-installer": true
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"homepage": "https://getcomposer.org/doc/06-config.md#allow-plugins",
"config": {
"allow-plugins": {
"ergebnis/composer-normalize": true,
"composer/package-versions-deprecated": true,
"infection/extension-installer": true,
"composer/*": false
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"name": "ergebnis/json-normalizer",
"description": "Provides generic and vendor-specific normalizers for normalizing JSON documents.",
"license": "MIT",
"type": "library",
"keywords": [
"json",
"normalizer"
],
"authors": [
{
"name": "Andreas Möller",
"email": "[email protected]"
}
],
"homepage": "https://getcomposer.org/doc/06-config.md#preferred-install",
"config": {
"preferred-install": {
"foo/four": "source",
"foo/one": "source",
"foo/three": "source",
"foo/two": "source"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"name": "ergebnis/json-normalizer",
"description": "Provides generic and vendor-specific normalizers for normalizing JSON documents.",
"license": "MIT",
"type": "library",
"keywords": [
"json",
"normalizer"
],
"authors": [
{
"name": "Andreas Möller",
"email": "[email protected]"
}
],
"homepage": "https://getcomposer.org/doc/06-config.md#preferred-install",
"config": {
"preferred-install": {
"foo/one": "source",
"foo/two": "source",
"foo/three": "source",
"foo/four": "source"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@
"homepage": "https://getcomposer.org/doc/06-config.md#preferred-install",
"config": {
"preferred-install": {
"*": "dist",
"foo/*": "dist",
"foo/something-longer-but-alphabetically-after-package-*": "source",
"foo/package-two": "dist",
"foo/*-test": "source",
"foo/package-*": "source",
"foo/package-one": "dist"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@
"config": {
"preferred-install": {
"foo/something-longer-but-alphabetically-after-package-*": "source",
"foo/package-one": "dist",
"foo/package-two": "dist",
"foo/*-test": "source",
"foo/package-*": "source",
"foo/*": "dist",
"*": "dist"
"foo/package-one": "dist"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@
"homepage": "https://getcomposer.org/doc/06-config.md#preferred-install",
"config": {
"preferred-install": {
"foo/something-longer-but-alphabetically-after-package-*": "source",
"foo/package-one": "dist",
"foo/package-*": "source",
"foo/something-longer-but-alphabetically-after-package-*": "source",
"foo/*": "dist",
"*": "dist"
}
Expand Down

0 comments on commit 9d8f548

Please sign in to comment.