forked from ergebnis/json-normalizer
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPackageHashNormalizer.php
117 lines (99 loc) · 3.33 KB
/
PackageHashNormalizer.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
<?php
declare(strict_types=1);
/**
* Copyright (c) 2018-2023 Andreas Möller
*
* For the full copyright and license information, please view
* the LICENSE.md file that was distributed with this source code.
*
* @see https://github.com/ergebnis/json-normalizer
*/
namespace Ergebnis\Json\Normalizer\Vendor\Composer;
use Ergebnis\Json\Json;
use Ergebnis\Json\Normalizer\Format;
use Ergebnis\Json\Normalizer\Normalizer;
final class PackageHashNormalizer implements Normalizer
{
/**
* @see https://github.com/composer/composer/blob/2.0.11/src/Composer/Repository/PlatformRepository.php#L33
*/
private const PLATFORM_PACKAGE_REGEX = '{^(?:php(?:-64bit|-ipv6|-zts|-debug)?|hhvm|(?:ext|lib)-[a-z0-9](?:[_.-]?[a-z0-9]+)*|composer-(?:plugin|runtime)-api)$}iD';
private const PROPERTIES_THAT_SHOULD_BE_NORMALIZED = [
'conflict',
'provide',
'replace',
'require',
'require-dev',
'suggest',
];
public function normalize(Json $json): Json
{
$decoded = $json->decoded();
if (!\is_object($decoded)) {
return $json;
}
$objectPropertiesThatShouldBeNormalized = \array_intersect_key(
\get_object_vars($decoded),
\array_flip(self::PROPERTIES_THAT_SHOULD_BE_NORMALIZED),
);
if ([] === $objectPropertiesThatShouldBeNormalized) {
return $json;
}
foreach ($objectPropertiesThatShouldBeNormalized as $name => $value) {
/** @var array<string, string> $packages */
$packages = (array) $decoded->{$name};
if ([] === $packages) {
continue;
}
$decoded->{$name} = self::sortPackages($packages);
}
/** @var string $encoded */
$encoded = \json_encode(
$decoded,
Format\JsonEncodeOptions::default()->toInt(),
);
return Json::fromString($encoded);
}
/**
* This code is adopted from composer/composer (originally licensed under MIT by Nils Adermann <[email protected]>
* and Jordi Boggiano <[email protected]>).
*
* @see https://github.com/composer/composer/blob/1.6.2/src/Composer/Json/JsonManipulator.php#L110-L146
*
* @param array<string, string> $packages
*
* @return array<string, string>
*/
private static function sortPackages(array $packages): array
{
$prefix = static function (string $requirement): string {
if (1 === \preg_match(self::PLATFORM_PACKAGE_REGEX, $requirement)) {
return \preg_replace(
[
'/^php/',
'/^hhvm/',
'/^ext/',
'/^lib/',
'/^\D/',
],
[
'0-$0',
'1-$0',
'2-$0',
'3-$0',
'4-$0',
],
$requirement,
);
}
return '5-' . $requirement;
};
\uksort($packages, static function (string $a, string $b) use ($prefix): int {
return \strnatcmp(
$prefix($a),
$prefix($b),
);
});
return $packages;
}
}