Skip to content

Commit 5b5edfb

Browse files
Use Config class to collect several configurations (#488)
1 parent 46c0bd2 commit 5b5edfb

12 files changed

+223
-129
lines changed

src/CLI/Baseline.php

+15-10
Original file line numberDiff line numberDiff line change
@@ -27,25 +27,30 @@ public function applyTo(Violations $violations, bool $ignoreBaselineLinenumbers)
2727
$violations->remove($this->violations, $ignoreBaselineLinenumbers);
2828
}
2929

30+
/**
31+
* @psalm-suppress RiskyTruthyFalsyComparison
32+
*/
33+
public static function resolveFilePath(?string $filePath, string $defaultFilePath): ?string
34+
{
35+
if (!$filePath && file_exists($defaultFilePath)) {
36+
$filePath = $defaultFilePath;
37+
}
38+
39+
return $filePath ?: null;
40+
}
41+
3042
public static function empty(): self
3143
{
3244
return new self(new Violations(), '');
3345
}
3446

35-
/**
36-
* @psalm-suppress RiskyTruthyFalsyComparison
37-
*/
38-
public static function create(bool $skipBaseline, ?string $baselineFilePath, string $defaultFilePath): self
47+
public static function create(bool $skipBaseline, ?string $baselineFilePath): self
3948
{
40-
if ($skipBaseline) {
49+
if ($skipBaseline || null === $baselineFilePath) {
4150
return self::empty();
4251
}
4352

44-
if (!$baselineFilePath && file_exists($defaultFilePath)) {
45-
$baselineFilePath = $defaultFilePath;
46-
}
47-
48-
return $baselineFilePath ? self::loadFromFile($baselineFilePath) : self::empty();
53+
return self::loadFromFile($baselineFilePath);
4954
}
5055

5156
public static function loadFromFile(string $filename): self

src/CLI/Command/Check.php

+23-50
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,17 @@
55
namespace Arkitect\CLI\Command;
66

77
use Arkitect\CLI\Baseline;
8-
use Arkitect\CLI\Config;
8+
use Arkitect\CLI\ConfigBuilder;
99
use Arkitect\CLI\Printer\PrinterFactory;
1010
use Arkitect\CLI\Progress\DebugProgress;
1111
use Arkitect\CLI\Progress\ProgressBarProgress;
1212
use Arkitect\CLI\Runner;
1313
use Arkitect\CLI\TargetPhpVersion;
14-
use Arkitect\Rules\Violations;
1514
use Symfony\Component\Console\Command\Command;
1615
use Symfony\Component\Console\Input\InputInterface;
1716
use Symfony\Component\Console\Input\InputOption;
1817
use Symfony\Component\Console\Output\ConsoleOutputInterface;
1918
use Symfony\Component\Console\Output\OutputInterface;
20-
use Webmozart\Assert\Assert;
2119

2220
class Check extends Command
2321
{
@@ -51,7 +49,8 @@ protected function configure(): void
5149
self::CONFIG_FILENAME_PARAM,
5250
'c',
5351
InputOption::VALUE_OPTIONAL,
54-
'File containing configs, such as rules to be matched'
52+
'File containing configs, such as rules to be matched',
53+
self::DEFAULT_RULES_FILENAME
5554
)
5655
->addOption(
5756
self::TARGET_PHP_PARAM,
@@ -107,6 +106,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
107106

108107
try {
109108
$verbose = (bool) $input->getOption('verbose');
109+
$rulesFilename = $input->getOption(self::CONFIG_FILENAME_PARAM);
110110
$stopOnFailure = (bool) $input->getOption(self::STOP_ON_FAILURE_PARAM);
111111
$useBaseline = (string) $input->getOption(self::USE_BASELINE_PARAM);
112112
$skipBaseline = (bool) $input->getOption(self::SKIP_BASELINE_PARAM);
@@ -120,46 +120,44 @@ protected function execute(InputInterface $input, OutputInterface $output): int
120120
$stdOut = $output;
121121
$output = $output instanceof ConsoleOutputInterface ? $output->getErrorOutput() : $output;
122122

123-
$targetPhpVersion = TargetPhpVersion::create($phpVersion);
123+
$this->printHeadingLine($output);
124124

125-
$progress = $verbose ? new DebugProgress($output) : new ProgressBarProgress($output);
125+
$config = ConfigBuilder::loadFromFile($rulesFilename)
126+
->stopOnFailure($stopOnFailure)
127+
->targetPhpVersion(TargetPhpVersion::create($phpVersion))
128+
->baselineFilePath(Baseline::resolveFilePath($useBaseline, self::DEFAULT_BASELINE_FILENAME))
129+
->ignoreBaselineLinenumbers($ignoreBaselineLinenumbers)
130+
->skipBaseline($skipBaseline)
131+
->format($format);
126132

127-
$baseline = Baseline::create($skipBaseline, $useBaseline, self::DEFAULT_BASELINE_FILENAME);
133+
$printer = PrinterFactory::create($config->getFormat());
128134

129-
$printer = (new PrinterFactory())->create($format);
135+
$progress = $verbose ? new DebugProgress($output) : new ProgressBarProgress($output);
130136

131-
$this->printHeadingLine($output);
137+
$baseline = Baseline::create($config->isSkipBaseline(), $config->getBaselineFilePath());
132138

133139
$baseline->getFilename() && $output->writeln("Baseline file '{$baseline->getFilename()}' found");
134-
135-
$rulesFilename = $this->getConfigFilename($input);
136-
137140
$output->writeln("Config file '$rulesFilename' found\n");
138141

139-
$config = new Config();
140-
141-
$this->readRules($config, $rulesFilename);
142-
143-
$runner = new Runner($stopOnFailure);
144-
$result = $runner->run($config, $progress, $targetPhpVersion);
145-
146-
$violations = $result->getViolations();
142+
$runner = new Runner();
147143

148144
if (false !== $generateBaseline) {
149-
$baselineFilePath = Baseline::save($generateBaseline, self::DEFAULT_BASELINE_FILENAME, $violations);
145+
$result = $runner->baseline($config, $progress);
146+
147+
$baselineFilePath = Baseline::save($generateBaseline, self::DEFAULT_BASELINE_FILENAME, $result->getViolations());
150148

151149
$output->writeln("ℹ️ Baseline file '$baselineFilePath' created!");
152150

153151
return self::SUCCESS_CODE;
154152
}
155153

156-
$baseline->applyTo($violations, $ignoreBaselineLinenumbers);
154+
$result = $runner->run($config, $baseline, $progress);
157155

158156
// we always print this so we do not have to do additional ifs later
159-
$stdOut->writeln($printer->print($violations->groupedByFqcn()));
157+
$stdOut->writeln($printer->print($result->getViolations()->groupedByFqcn()));
160158

161-
if ($violations->count() > 0) {
162-
$output->writeln("⚠️ {$violations->count()} violations detected!");
159+
if ($result->hasViolations()) {
160+
$output->writeln("⚠️ {$result->getViolations()->count()} violations detected!");
163161
}
164162

165163
if ($result->hasParsingErrors()) {
@@ -179,18 +177,6 @@ protected function execute(InputInterface $input, OutputInterface $output): int
179177
}
180178
}
181179

182-
protected function readRules(Config $ruleChecker, string $rulesFilename): void
183-
{
184-
\Closure::fromCallable(function () use ($ruleChecker, $rulesFilename): ?bool {
185-
/** @psalm-suppress UnresolvableInclude $config */
186-
$config = require $rulesFilename;
187-
188-
Assert::isCallable($config);
189-
190-
return $config($ruleChecker);
191-
})();
192-
}
193-
194180
protected function printHeadingLine(OutputInterface $output): void
195181
{
196182
$app = $this->getApplication();
@@ -207,17 +193,4 @@ protected function printExecutionTime(OutputInterface $output, float $startTime)
207193

208194
$output->writeln("⏱️ Execution time: $executionTime\n");
209195
}
210-
211-
private function getConfigFilename(InputInterface $input): string
212-
{
213-
$filename = $input->getOption(self::CONFIG_FILENAME_PARAM);
214-
215-
if (null === $filename) {
216-
$filename = self::DEFAULT_RULES_FILENAME;
217-
}
218-
219-
Assert::file($filename, "Config file '$filename' not found");
220-
221-
return $filename;
222-
}
223196
}

src/CLI/Config.php

+91
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
use Arkitect\ClassSet;
77
use Arkitect\ClassSetRules;
8+
use Arkitect\CLI\Printer\PrinterFactory;
89
use Arkitect\Rules\DSL\ArchRule;
910

1011
class Config
@@ -16,11 +17,29 @@ class Config
1617

1718
private bool $parseCustomAnnotations;
1819

20+
private bool $stopOnFailure;
21+
22+
private bool $skipBaseline;
23+
24+
private ?string $baselineFilePath;
25+
26+
private bool $ignoreBaselineLinenumbers;
27+
28+
private string $format;
29+
30+
private TargetPhpVersion $targetPhpVersion;
31+
1932
public function __construct()
2033
{
2134
$this->classSetRules = [];
2235
$this->runOnlyARule = false;
2336
$this->parseCustomAnnotations = true;
37+
$this->stopOnFailure = false;
38+
$this->skipBaseline = false;
39+
$this->baselineFilePath = null;
40+
$this->ignoreBaselineLinenumbers = false;
41+
$this->format = PrinterFactory::default();
42+
$this->targetPhpVersion = TargetPhpVersion::latest();
2443
}
2544

2645
public function add(ClassSet $classSet, ArchRule ...$rules): self
@@ -61,4 +80,76 @@ public function isParseCustomAnnotationsEnabled(): bool
6180
{
6281
return $this->parseCustomAnnotations;
6382
}
83+
84+
public function targetPhpVersion(TargetPhpVersion $targetPhpVersion): self
85+
{
86+
$this->targetPhpVersion = $targetPhpVersion;
87+
88+
return $this;
89+
}
90+
91+
public function getTargetPhpVersion(): TargetPhpVersion
92+
{
93+
return $this->targetPhpVersion;
94+
}
95+
96+
public function stopOnFailure(bool $stopOnFailure): self
97+
{
98+
$this->stopOnFailure = $stopOnFailure;
99+
100+
return $this;
101+
}
102+
103+
public function isStopOnFailure(): bool
104+
{
105+
return $this->stopOnFailure;
106+
}
107+
108+
public function baselineFilePath(?string $baselineFilePath): self
109+
{
110+
$this->baselineFilePath = $baselineFilePath;
111+
112+
return $this;
113+
}
114+
115+
public function getBaselineFilePath(): ?string
116+
{
117+
return $this->baselineFilePath;
118+
}
119+
120+
public function ignoreBaselineLinenumbers(bool $ignoreBaselineLinenumbers): self
121+
{
122+
$this->ignoreBaselineLinenumbers = $ignoreBaselineLinenumbers;
123+
124+
return $this;
125+
}
126+
127+
public function isIgnoreBaselineLinenumbers(): bool
128+
{
129+
return $this->ignoreBaselineLinenumbers;
130+
}
131+
132+
public function format(string $format): self
133+
{
134+
$this->format = $format;
135+
136+
return $this;
137+
}
138+
139+
public function getFormat(): string
140+
{
141+
return $this->format;
142+
}
143+
144+
public function skipBaseline(bool $skipBaseline): self
145+
{
146+
$this->skipBaseline = $skipBaseline;
147+
148+
return $this;
149+
}
150+
151+
public function isSkipBaseline(): bool
152+
{
153+
return $this->skipBaseline;
154+
}
64155
}

src/CLI/ConfigBuilder.php

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Arkitect\CLI;
6+
7+
use Webmozart\Assert\Assert;
8+
9+
class ConfigBuilder
10+
{
11+
public static function loadFromFile(string $filePath): Config
12+
{
13+
Assert::file($filePath, "Config file '$filePath' not found");
14+
15+
$config = new Config();
16+
17+
\Closure::fromCallable(function () use ($config, $filePath): ?bool {
18+
/** @psalm-suppress UnresolvableInclude $config */
19+
$configFunction = require $filePath;
20+
21+
Assert::isCallable($configFunction);
22+
23+
return $configFunction($config);
24+
})();
25+
26+
return $config;
27+
}
28+
}

src/CLI/Printer/PrinterFactory.php

+6-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,12 @@
55

66
final class PrinterFactory
77
{
8-
public function create(string $format): Printer
8+
public static function default(): string
9+
{
10+
return Printer::FORMAT_TEXT;
11+
}
12+
13+
public static function create(string $format): Printer
914
{
1015
switch ($format) {
1116
case Printer::FORMAT_GITLAB:

0 commit comments

Comments
 (0)