Skip to content

Commit d81f7b4

Browse files
committed
feat: Config builder for cascading rules
1 parent 4b31cd7 commit d81f7b4

5 files changed

Lines changed: 140 additions & 92 deletions

File tree

README.md

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -71,25 +71,19 @@ add `.php-cs-fixer.dist.php` in your project
7171
```php
7272
<?php
7373

74+
use whatwedo\PhpCodingStandard\PhpCsFixerConfig\BaseCsFixerConfig;
7475
use whatwedo\PhpCodingStandard\PhpCsFixerConfig\SymfonyCsFixerConfig;
76+
use whatwedo\PhpCodingStandard\PhpCsFixerConfigBuilder;
77+
78+
$configs = [
79+
SymfonyCsFixerConfig::class,
80+
BaseCsFixerConfig::class,
81+
];
82+
//PhpCsFixerConfigBuilder::dumpRules($configs);
83+
//PhpCsFixerConfigBuilder::dumpExcludes($configs);
7584

76-
// create preconfigured Config
77-
$config = SymfonyCsFixerConfig::createConfig(__DIR__);
78-
79-
// exclude some custom directories
80-
$config->getFinder()->exclude(
81-
[
82-
'data',
83-
'doc',
84-
'docker',
85-
'drivers',
86-
'vendor-bin',
87-
]);
8885

89-
// add some project rules
90-
// be careful, can be tricky, rules are dependent of the order
91-
$existingRules = $config->getRules();
92-
$existingRules['some_new_rule'] => true;
86+
$config = PhpCsFixerConfigBuilder::build(__DIR__, $configs);
9387

9488
return $config;
9589
```

src/PhpCsFixerConfig/BaseCsFixerConfig.php

Lines changed: 11 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,40 +2,23 @@
22

33
namespace whatwedo\PhpCodingStandard\PhpCsFixerConfig;
44

5-
use PhpCsFixer;
6-
75
class BaseCsFixerConfig implements WwdPhpCsFixerConfigInterface
86
{
9-
public static function createConfig(string $projectDir): PhpCsFixer\ConfigInterface
7+
public static function getRules(): array
108
{
11-
$finder = new PhpCsFixer\Finder();
12-
self::configureFinder($finder, $projectDir);
13-
14-
$config = new PhpCsFixer\Config();
15-
$config->setFinder($finder);
16-
self::configure($config);
17-
return $config;
18-
}
9+
return [
10+
100 => ['@PER-CS' => true],
11+
200 => ['@PSR12' => true],
1912

20-
21-
public static function configureFinder(PhpCsFixer\Finder $finder, string $projectDir)
22-
{
23-
$finder->in($projectDir);
13+
10000 => ['strict_param' => true],
14+
// make ecs compatible
15+
15000 => ['phpdoc_to_comment' => false],
16+
16000 => ['single_line_throw' => false],
17+
];
2418
}
2519

26-
public static function configure(PhpCsFixer\ConfigInterface $config)
20+
public static function getExcludes(): array
2721
{
28-
$config
29-
->setRiskyAllowed(true)
30-
->setRules(
31-
[
32-
'@PER-CS' => true,
33-
'@PSR12' => true,
34-
'strict_param' => true,
35-
// make ecs compatible
36-
'phpdoc_to_comment' => false,
37-
'single_line_throw' => false,
38-
]
39-
);
22+
return [];
4023
}
4124
}

src/PhpCsFixerConfig/SymfonyCsFixerConfig.php

Lines changed: 15 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -2,54 +2,27 @@
22

33
namespace whatwedo\PhpCodingStandard\PhpCsFixerConfig;
44

5-
use PhpCsFixer;
6-
75
class SymfonyCsFixerConfig implements WwdPhpCsFixerConfigInterface
86
{
9-
public static function createConfig(string $projectDir): PhpCsFixer\ConfigInterface
10-
{
11-
$finder = new PhpCsFixer\Finder();
12-
self::configureFinder($finder, $projectDir);
13-
14-
$config = new PhpCsFixer\Config();
15-
$config->setFinder($finder);
16-
self::configure($config);
17-
return $config;
18-
}
197

20-
21-
public static function configureFinder(PhpCsFixer\Finder $finder, string $projectDir)
8+
public static function getRules(): array
229
{
23-
$finder->in($projectDir)
24-
->exclude([
25-
'assets',
26-
'bin',
27-
'config',
28-
'node_modules',
29-
'public',
30-
'vendor',
31-
'var',
32-
]
33-
);
10+
return [
11+
300 => ['@PHP83Migration' => true],
12+
400 => ['@Symfony' => true],
13+
];
3414
}
3515

36-
public static function configure(PhpCsFixer\ConfigInterface $config)
16+
public static function getExcludes(): array
3717
{
38-
39-
$config
40-
->setRiskyAllowed(true)
41-
->setRules(
42-
[
43-
'@PER-CS' => true,
44-
'@PSR12' => true,
45-
'@PHP83Migration' => true,
46-
'@Symfony' => true,
47-
'strict_param' => true,
48-
// make ecs compatible
49-
'phpdoc_to_comment' => false,
50-
'single_line_throw' => false,
51-
]
52-
53-
);
18+
return [
19+
'assets',
20+
'bin',
21+
'config',
22+
'node_modules',
23+
'public',
24+
'vendor',
25+
'var',
26+
];
5427
}
5528
}

src/PhpCsFixerConfig/WwdPhpCsFixerConfigInterface.php

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,12 @@
22

33
namespace whatwedo\PhpCodingStandard\PhpCsFixerConfig;
44

5-
use PhpCsFixer\ConfigInterface;
6-
use PhpCsFixer\Finder;
7-
85
interface WwdPhpCsFixerConfigInterface
96
{
10-
public static function createConfig(string $basePath);
11-
public static function configure(ConfigInterface $config);
12-
public static function configureFinder(Finder $finder, string $projectDir);
7+
/**
8+
* @var array <int, <array<string, mixed>>
9+
*/
10+
public static function getRules(): array;
1311

12+
public static function getExcludes(): array;
1413
}

src/PhpCsFixerConfigBuilder.php

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
<?php
2+
3+
namespace whatwedo\PhpCodingStandard;
4+
5+
use PhpCsFixer;
6+
use PhpCsFixer\ConfigInterface;
7+
use whatwedo\PhpCodingStandard\PhpCsFixerConfig\WwdPhpCsFixerConfigInterface;
8+
9+
class PhpCsFixerConfigBuilder
10+
{
11+
/**
12+
* @param class-string<WwdPhpCsFixerConfigInterface>[] $configs
13+
*/
14+
public static function build(
15+
string $projectDir,
16+
array $configs
17+
): ConfigInterface
18+
{
19+
$excludes = self::buildExcludes($configs);
20+
21+
$finder = new PhpCsFixer\Finder();
22+
$finder->in($projectDir)
23+
->exclude($excludes);
24+
25+
$config = new PhpCsFixer\Config();
26+
$config->setFinder($finder)
27+
->setRiskyAllowed(true)
28+
->setRules(self::buildRules($configs));
29+
30+
return $config;
31+
}
32+
33+
private static function getNextOrder(array $rules, int $order)
34+
{
35+
while (array_key_exists($order, $rules)) {
36+
$order++;
37+
}
38+
return $order;
39+
}
40+
41+
/**
42+
* @param class-string<WwdPhpCsFixerConfigInterface>[] $configs
43+
*/
44+
private static function buildRules(array $configs): array
45+
{
46+
/**
47+
* @var array <int, <array<string, mixed>>
48+
*/
49+
$rulesGroups = [];
50+
51+
foreach ($configs as $config) {
52+
foreach ($config::getRules() as $order => $configRule) {
53+
$rulesGroups[self::getNextOrder($rulesGroups, $order)] = $configRule;
54+
}
55+
}
56+
57+
// order rules from Configs
58+
ksort($rulesGroups);
59+
60+
$rules = [];
61+
foreach ($rulesGroups as $rulesGroup) {
62+
foreach ($rulesGroup as $rule => $ruleSetting) {
63+
$rules[$rule] = $ruleSetting;
64+
}
65+
}
66+
67+
return $rules;
68+
}
69+
70+
/**
71+
* @param class-string<WwdPhpCsFixerConfigInterface>[] $configs
72+
*/
73+
public static function dumpRules(array $configs)
74+
{
75+
var_dump(self::buildRules($configs));
76+
}
77+
78+
/**
79+
* @param class-string<WwdPhpCsFixerConfigInterface>[] $configs
80+
*/
81+
public static function dumpExcludes(array $configs)
82+
{
83+
var_dump(self::buildExcludes($configs));
84+
}
85+
86+
/**
87+
* @param class-string<WwdPhpCsFixerConfigInterface>[] $configs
88+
*/
89+
private static function buildExcludes(array $configs): array
90+
{
91+
$excludes = [];
92+
foreach ($configs as $config) {
93+
foreach ($config::getExcludes() as $configExclude) {
94+
$excludes[] = $configExclude;
95+
}
96+
}
97+
return $excludes;
98+
}
99+
}

0 commit comments

Comments
 (0)