Skip to content

Commit f437efe

Browse files
committed
Add dev:lint-config to replace sort-config command
1 parent f4a29c4 commit f437efe

File tree

1 file changed

+121
-0
lines changed

1 file changed

+121
-0
lines changed
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace StaticPHP\Command\Dev;
6+
7+
use StaticPHP\Command\BaseCommand;
8+
use StaticPHP\Registry\Registry;
9+
use Symfony\Component\Console\Attribute\AsCommand;
10+
use Symfony\Component\Yaml\Yaml;
11+
12+
#[AsCommand('dev:lint-config', 'Lint configuration file format', ['dev:sort-config'])]
13+
class LintConfigCommand extends BaseCommand
14+
{
15+
public function handle(): int
16+
{
17+
// get loaded configs
18+
$loded_configs = Registry::getLoadedArtifactConfigs();
19+
foreach ($loded_configs as $file) {
20+
$this->sortConfigFile($file, 'artifact');
21+
}
22+
$loaded_pkg_configs = Registry::getLoadedPackageConfigs();
23+
foreach ($loaded_pkg_configs as $file) {
24+
$this->sortConfigFile($file, 'package');
25+
}
26+
return static::SUCCESS;
27+
}
28+
29+
public function artifactSortKey(string $a, string $b): int
30+
{
31+
// sort by predefined order, other not matching keys go to the end alphabetically
32+
$order = ['source', 'source-mirror', 'binary', 'binary-mirror', 'metadata'];
33+
34+
$pos_a = array_search($a, $order, true);
35+
$pos_b = array_search($b, $order, true);
36+
37+
// Both in order list
38+
if ($pos_a !== false && $pos_b !== false) {
39+
return $pos_a <=> $pos_b;
40+
}
41+
42+
// Only $a in order list
43+
if ($pos_a !== false) {
44+
return -1;
45+
}
46+
47+
// Only $b in order list
48+
if ($pos_b !== false) {
49+
return 1;
50+
}
51+
52+
// Neither in order list, sort alphabetically
53+
return $a <=> $b;
54+
}
55+
56+
public function packageSortKey(string $a, string $b): int
57+
{
58+
// sort by predefined order, other not matching keys go to the end alphabetically
59+
$order = ['type', 'artifact'];
60+
61+
// Handle suffix patterns (e.g., 'depends@unix', 'static-libs@windows')
62+
$base_a = preg_replace('/@(unix|windows|macos|linux|freebsd|bsd)$/', '', $a);
63+
$base_b = preg_replace('/@(unix|windows|macos|linux|freebsd|bsd)$/', '', $b);
64+
65+
$pos_a = array_search($base_a, $order, true);
66+
$pos_b = array_search($base_b, $order, true);
67+
68+
// Both in order list
69+
if ($pos_a !== false && $pos_b !== false) {
70+
if ($pos_a === $pos_b) {
71+
// Same base field, sort by suffix
72+
return $a <=> $b;
73+
}
74+
return $pos_a <=> $pos_b;
75+
}
76+
77+
// Only $a in order list
78+
if ($pos_a !== false) {
79+
return -1;
80+
}
81+
82+
// Only $b in order list
83+
if ($pos_b !== false) {
84+
return 1;
85+
}
86+
87+
// Neither in order list, sort alphabetically
88+
return $a <=> $b;
89+
}
90+
91+
private function sortConfigFile(mixed $file, string $config_type): void
92+
{
93+
// read file content with different extensions
94+
$content = file_get_contents($file);
95+
if ($content === false) {
96+
$this->output->writeln("Failed to read artifact config file: {$file}");
97+
return;
98+
}
99+
$data = match (pathinfo($file, PATHINFO_EXTENSION)) {
100+
'json' => json_decode($content, true),
101+
'yml', 'yaml' => Yaml::parse($content), // skip yaml files for now
102+
default => null,
103+
};
104+
if (!is_array($data)) {
105+
$this->output->writeln("Invalid JSON format in artifact config file: {$file}");
106+
return;
107+
}
108+
ksort($data);
109+
foreach ($data as $artifact_name => &$config) {
110+
uksort($config, $config_type === 'artifact' ? [$this, 'artifactSortKey'] : [$this, 'packageSortKey']);
111+
}
112+
unset($config);
113+
$new_content = match (pathinfo($file, PATHINFO_EXTENSION)) {
114+
'json' => json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . "\n",
115+
'yml', 'yaml' => Yaml::dump($data, 4, 2),
116+
default => null,
117+
};
118+
file_put_contents($file, $new_content);
119+
$this->output->writeln("Sorted artifact config file: {$file}");
120+
}
121+
}

0 commit comments

Comments
 (0)