8000 Adding baseline feature (#9) · symfony-tools/code-block-checker@628f5bc · GitHub
[go: up one dir, main page]

Skip to content

Commit 628f5bc

Browse files
authored
Adding baseline feature (#9)
* Adding baseline feature * Updated readme with example of baselien * cs
1 parent 8bb85fe commit 628f5bc

File tree

5 files changed

+125
-7
lines changed

5 files changed

+125
-7
lines changed

README.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,17 @@
33
Make sure that code blocks have valid syntax and can actually run.
44

55
```terminal
6-
./code-block-checker.php verify:docs /path/to/docs cache.rst controller.rst --env=dev
6+
$ ./code-block-checker.php verify:docs /path/to/docs cache.rst controller.rst --env=dev
7+
8+
::error file=cache,line=377::[Invalid syntax] PHP Parse error: syntax error, unexpected token "}"
9+
10+
[ERROR] Build completed with 1 errors
11+
12+
13+
$ ./code-block-checker.php verify:docs /path/to/docs cache.rst controller.rst --env=dev --generate-baseline=baseline.json
14+
$ ./code-block-checker.php verify:docs /path/to/docs cache.rst controller.rst --env=dev --baseline=baseline.json
15+
16+
[OK] Build completed successfully!
17+
718
```
19+

psalm.baseline.xml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
</UndefinedClass>
77
</file>
88
<file src="src/Service/CodeValidator.php">
9-
<InvalidArgument occurrences="1"/>
9+
<InvalidArgument occurrences="3">
10+
<code>'bis'</code>
11+
<code>'foobar'</code>
12+
</InvalidArgument>
1013
</file>
1114
</files>

src/Command/CheckDocsCommand.php

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
use Doctrine\RST\ErrorManager;
1111
use Doctrine\RST\Event\PostNodeCreateEvent;
1212
use Doctrine\RST\Meta\Metas;
13-
use Symfony\CodeBlockChecker\Issue\IssueCollection;
1413
use Symfony\CodeBlockChecker\Listener\CodeNodeCollector;
14+
use Symfony\CodeBlockChecker\Service\Baseline;
1515
use Symfony\CodeBlockChecker\Service\CodeValidator;
1616
use Symfony\Component\Console\Command\Command;
1717
use Symfony\Component\Console\Input\InputArgument;
@@ -27,25 +27,27 @@ class CheckDocsCommand extends Command
2727
protected static $defaultName = 'verify:docs';
2828

2929
private SymfonyStyle $io;
30-
private IssueCollection $errorManager;
3130
private ParseQueueProcessor $queueProcessor;
3231
private CodeNodeCollector $collector;
3332
private CodeValidator $validator;
33+
private Baseline $baseline;
3434

35-
public function __construct(CodeValidator $validator)
35+
public function __construct(CodeValidator $validator, Baseline $baseline)
3636
{
3737
parent::__construct(self::$defaultName);
3838
$this->validator = $validator;
39+
$this->baseline = $baseline;
3940
}
4041

4142
protected function configure()
4243
{
4344
$this
4445
->addArgument('source-dir', InputArgument::REQUIRED, 'RST files Source directory')
4546
->addArgument('files', InputArgument::IS_ARRAY + InputArgument::REQUIRED, 'RST files that should be verified.')
46-
->addOption('output-format', null, InputOption::VALUE_OPTIONAL, 'Valid options are github and console', 'github')
47+
->addOption('output-format', null, InputOption::VALUE_REQUIRED, 'Valid options are github and console', 'github')
48+
->addOption('generate-baseline', null, InputOption::VALUE_REQUIRED, 'Generate a new baseline', false)
49+
->addOption('baseline', null, InputOption::VALUE_REQUIRED, 'Use a baseline', false)
4750
->setDescription('Make sure the docs blocks are valid')
48-
4951
;
5052
}
5153

@@ -88,6 +90,16 @@ protected function execute(InputInterface $input, OutputInterface $output): int
8890
$this->queueProcessor->process($parseQueue);
8991
$issues = $this->validator->validateNodes($this->collector->getNodes());
9092

93+
if ($baselineFile = $input->getOption('generate-baseline')) {
94+
$this->baseline->generate($issues, $baselineFile);
95+
96+
return Command::SUCCESS;
97+
}
98+
99+
if ($baselineFile = $input->getOption('baseline')) {
100+
$issues = $this->baseline->filter($issues, $baselineFile);
101+
}
102+
91103
$issueCount = count($issues);
92104
if ($issueCount > 0) {
93105
$format = $input->getOption('output-format');

src/Issue/Issue.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ class Issue implements \Stringable
1616
private string $text;
1717
private string $type;
1818
private string $file;
19+
private ?string $erroredLine;
1920

2021
/**
2122
* The line in the file.
@@ -35,6 +36,7 @@ public function __construct(CodeNode $node, string $text, string $type, string $
3536
$this->file = $file;
3637
$this->localLine = $localLine;
3738
$this->line = null;
39+
$this->erroredLine = null;
3840
}
3941

4042
public function getHash(): string
@@ -67,6 +69,21 @@ public function getLine(): int
6769
return $this->line;
6870
}
6971

72+
public function getLocalLine(): int
73+
{
74+
return $this->localLine;
75+
}
76+
77+
public function getErroredLine()
78+
{
79+
if (null === $this->erroredLine) {
80+
$lines = explode(PHP_EOL, $this->node->getValue());
81+
$this->erroredLine = $lines[$this->localLine - 1];
82+
}
83+
84+
return $this->erroredLine;
85+
}
86+
7087
public function __toString()
7188
{
7289
return sprintf('[%s] %s in file %s at %d', $this->getType(), $this->getText(), $this->getFile(), $this->getLine());

src/Service/Baseline.php

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
<?php
2+
3+
namespace Symfony\CodeBlockChecker\Service;
4+
5+
use Symfony\CodeBlockChecker\Issue\Issue;
6+
use Symfony\CodeBlockChecker\Issue\IssueCollection;
7+
8+
/**
9+
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
10+
*/
11+
class Baseline
12+
{
13+
public function generate(IssueCollection $issues, string $file)
14+
{
15+
$data = ['issues' => []];
16+
foreach ($issues as $issue) {
17+
$data['issues'][$issue->getFile()][$issue->getHash()] = [
18+
'text' => $issue->getText(),
19+
'type' => $issue->getType(),
20+
'code' => $issue->getErroredLine(),
21+
];
22+
}
23+
24+
file_put_contents($file, json_encode($data, JSON_PRETTY_PRINT));
25+
}
26+
27+
/**
28+
* Remove items from $issues that are in the baseline.
29+
*/
30+
public function filter(IssueCollection $issues, string $file): IssueCollection
31+
{
32+
$json = file_get_contents($file);
33+
try {
34+
$baseline = json_decode($json, true, 512, JSON_THROW_ON_ERROR);
35+
$baseline = $baseline['issues'];
36+
} catch (\JsonException $e) {
37+
throw new \RuntimeException('Could not parse baseline', 0, $e);
38+
}
39+
40+
$output = new IssueCollection();
41+
$perFile = [];
42+
foreach ($issues as $issue) {
43+
if (!isset($baseline[$issue->getFile()])) {
44+
$output->addIssue($issue);
45+
continue;
46+
} elseif (isset($baseline[$issue->getFile()][$issue->getHash()])) {
47+
// This has not been modified.
48+
continue;
49+
}
50+
51+
$perFile[$issue->getFile()][] = $issue;
52+
}
53+
54+
foreach ($perFile as $file => $fileIssues) {
55+
$fileBaseline = $baseline[$file];
56+
/** @var Issue $issue */
57+
foreach ($fileIssues as $issue) {
58+
foreach ($fileBaseline as $i => $item) {
59+
if (
60+
$issue->getType() === $item['type'] &&
61+
$issue->getText() === $item['text'] &&
62+
$issue->getErroredLine()() === $item['code']
63+
) {
64+
unset($fileBaseline[$i]);
65+
} else {
66+
$out 5F3B put->addIssue($issue);
67+
}
68+
}
69+
}
70+
}
71+
72+
return $output;
73+
}
74+
}

0 commit comments

Comments
 (0)
0