Skip to content

Commit ef2ffda

Browse files
committed
Refactor so that only one markdown file is written per rule
1 parent eb899e3 commit ef2ffda

File tree

11 files changed

+210
-79
lines changed

11 files changed

+210
-79
lines changed

config/di.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
use App\CodeRepository\CodeRepository;
5+
use App\CodeRepository\GithubCodeRepository;
6+
use App\Generator\Generator as DocGenerator;
7+
use App\Generator\MarkdownGenerator;
8+
use App\SniffFinder\FilesystemSniffFinder;
9+
use App\SniffFinder\SniffFinder;
10+
11+
return [
12+
CodeRepository::class => DI\autowire(GithubCodeRepository::class),
13+
DocGenerator::class => DI\autowire(MarkdownGenerator::class),
14+
SniffFinder::class => DI\autowire(FilesystemSniffFinder::class),
15+
];

src/CodeRepository/CodeRepository.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33

44
namespace App\CodeRepository;
55

6+
use App\Value\Folder;
7+
68
interface CodeRepository
79
{
810
public const CODE_DOWNLOAD_PATH = 'var/repos/';
911

10-
public function downloadCode(string $repoName): string;
12+
public function downloadCode(string $repoName): Folder;
1113
}

src/CodeRepository/GithubCodeRepository.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@
33

44
namespace App\CodeRepository;
55

6+
use App\Value\Folder;
67
use Symfony\Component\Process\Exception\ProcessFailedException;
78
use Symfony\Component\Process\Process;
89

910
class GithubCodeRepository implements CodeRepository
1011
{
11-
public function downloadCode(string $repoName): string
12+
public function downloadCode(string $repoName): Folder
1213
{
13-
$repoPath = self::CODE_DOWNLOAD_PATH . '/' . $repoName;
14+
$repoPath = new Folder(self::CODE_DOWNLOAD_PATH . '/' . $repoName . '/');
1415

1516
$process = $this->cloneOrPull($repoPath, $repoName);
1617
$process->run();
@@ -22,9 +23,9 @@ public function downloadCode(string $repoName): string
2223
return $repoPath;
2324
}
2425

25-
private function cloneOrPull(string $repoPath, string $repoName): Process
26+
private function cloneOrPull(Folder $repoPath, string $repoName): Process
2627
{
27-
if (!is_dir($repoPath)) {
28+
if (!is_dir((string)$repoPath)) {
2829
return new Process([
2930
'git',
3031
'clone',

src/Handler/GenerateHandler.php

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace App\Handler;
5+
6+
use App\CodeRepository\CodeRepository;
7+
use App\Generator\Generator;
8+
use App\SniffFinder\SniffFinder;
9+
use App\Value\Folder;
10+
use Symfony\Component\Filesystem\Filesystem;
11+
12+
class GenerateHandler
13+
{
14+
private CodeRepository $codeRepository;
15+
private Generator $generator;
16+
private SniffFinder $sniffFinder;
17+
18+
public function __construct(CodeRepository $codeRepository, Generator $generator, SniffFinder $sniffFinder)
19+
{
20+
$this->codeRepository = $codeRepository;
21+
$this->generator = $generator;
22+
$this->sniffFinder = $sniffFinder;
23+
}
24+
25+
public function handle()
26+
{
27+
$repoName = 'PHPCompatibility/PHPCompatibility';
28+
$repoPath = $this->codeRepository->downloadCode($repoName);
29+
$filesystem = new Filesystem();
30+
31+
$standardPath = new Folder($repoPath . 'PHPCompatibility/');
32+
33+
foreach ($this->sniffFinder->getSniffs($standardPath) as $sniff) {
34+
$filesystem->dumpFile(
35+
// TODO: perhaps we can move this logic to the the sniff class
36+
$this->sniffCodeToMarkdownPath($sniff->getCode()),
37+
$this->generator->createSniffDoc($sniff)
38+
);
39+
}
40+
}
41+
42+
private function sniffCodeToMarkdownPath(string $code): string
43+
{
44+
[$standard, $category, $sniff] = explode('.', $code);
45+
46+
return "var/markdown/$standard/$category/$sniff.md";
47+
}
48+
}

src/Parser/SniffParser.php

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use App\Value\Sniff;
1010
use App\Value\Url;
1111
use App\Value\Urls;
12+
use GlobIterator;
1213
use phpDocumentor\Reflection\DocBlock\Tags\Var_;
1314
use phpDocumentor\Reflection\DocBlockFactory;
1415
use ReflectionProperty;
@@ -31,22 +32,29 @@ public function parse(string $phpFilePath): Sniff
3132
$xmlUrls = [];
3233
$description = '';
3334
$diffs = [];
34-
$xmlFilePath = str_replace(['/Sniffs/', 'Sniff.php'], ['/Docs/', 'Standard.xml'], $phpFilePath);
35-
if (file_exists($xmlFilePath)) {
36-
$xml = new SimpleXMLElement(file_get_contents($xmlFilePath));
35+
$xmlStandardPath = str_replace(['/Sniffs/', 'Sniff.php'], ['/Docs/', 'Standard.xml'], $phpFilePath);
36+
if (file_exists($xmlStandardPath)) {
37+
$xml = new SimpleXMLElement(file_get_contents($xmlStandardPath));
3738
$xmlUrls = $this->getXmlUrls($xml);
3839
$description = $this->getDescription($xml);
3940
$diffs = $this->getDiffs($xml);
4041
}
4142

43+
$xmlErrorGlob = new GlobIterator(
44+
str_replace(['/Sniffs/', 'Sniff.php'], ['/Docs/', 'Standard/*.xml'], $phpFilePath)
45+
);
46+
$violations = [];
47+
foreach ($xmlErrorGlob as $fileInfo) {
48+
$violations[] = (new ViolationParser)->parse($fileInfo->getPathname());
49+
}
4250
return new Sniff(
4351
$this->getCode($phpFilePath),
4452
$this->getDocBlock($classInfo->getDocComment()),
4553
$this->getProperties($classInfo),
4654
$this->getLinks($classInfo, $xmlUrls),
4755
$description,
4856
$diffs,
49-
[]
57+
$violations
5058
);
5159
}
5260

src/SniffFinder/FilesystemSniffFinder.php

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,17 @@
44
namespace App\SniffFinder;
55

66
use App\Parser\SniffParser;
7-
use App\Parser\ViolationParser;
8-
use App\Value\Standard;
7+
use App\Value\Folder;
98
use GlobIterator;
109
use Traversable;
1110

1211
class FilesystemSniffFinder implements SniffFinder
1312
{
14-
public function getSniffs(Standard $standard): Traversable
13+
public function getSniffs(Folder $folder): Traversable
1514
{
1615
$parser = new SniffParser();
17-
$glob = new GlobIterator($standard->getCodeLocation() . 'Sniffs/*/*Sniff.php');
18-
foreach ($glob as $fileInfo) {
19-
yield $parser->parse($fileInfo->getPathname());
20-
}
21-
}
22-
23-
public function getViolations(Standard $standard): Traversable
24-
{
25-
$parser = new ViolationParser();
26-
$glob = new GlobIterator($standard->getCodeLocation() . 'Docs/*/*Standard/*.xml');
27-
foreach ($glob as $fileInfo) {
16+
$globSniffs = new GlobIterator($folder->getPath() . 'Sniffs/*/*Sniff.php');
17+
foreach ($globSniffs as $fileInfo) {
2818
yield $parser->parse($fileInfo->getPathname());
2919
}
3020
}

src/SniffFinder/SniffFinder.php

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,14 @@
33

44
namespace App\SniffFinder;
55

6+
use App\Value\Folder;
67
use App\Value\Sniff;
7-
use App\Value\Standard;
8-
use App\Value\Violation;
98
use Traversable;
109

1110
interface SniffFinder
1211
{
1312
/**
1413
* @return Traversable<Sniff>
1514
*/
16-
public function getSniffs(Standard $standard): Traversable;
17-
18-
/**
19-
* @return Traversable<Violation>
20-
*/
21-
public function getViolations(Standard $standard): Traversable;
15+
public function getSniffs(Folder $folder): Traversable;
2216
}

src/Value/Folder.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace App\Value;
5+
6+
use Assert\Assert;
7+
8+
class Folder
9+
{
10+
private string $path;
11+
12+
public function __construct(string $path)
13+
{
14+
Assert::that($path)
15+
->endsWith('/');
16+
17+
$this->path = $path;
18+
}
19+
20+
public function getPath(): string
21+
{
22+
return $this->path;
23+
}
24+
25+
public function __toString()
26+
{
27+
return $this->getPath();
28+
}
29+
}

src/Value/Standard.php

Lines changed: 0 additions & 25 deletions
This file was deleted.
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace App\Tests\Handler;
5+
6+
use App\CodeRepository\CodeRepository;
7+
use App\Generator\Generator;
8+
use App\Handler\GenerateHandler;
9+
use App\SniffFinder\SniffFinder;
10+
use App\Value\Folder;
11+
use App\Value\Sniff;
12+
use App\Value\Urls;
13+
use App\Value\Violation;
14+
use PHPUnit\Framework\MockObject\MockObject;
15+
use PHPUnit\Framework\TestCase;
16+
17+
/** @covers \App\Handler\GenerateHandler */
18+
class GenerateHandlerTest extends TestCase
19+
{
20+
/**
21+
* @var GenerateHandler
22+
*/
23+
private GenerateHandler $handler;
24+
/**
25+
* @var CodeRepository|MockObject
26+
*/
27+
private $codeRepository;
28+
/**
29+
* @var Generator|MockObject
30+
*/
31+
private $generator;
32+
/**
33+
* @var SniffFinder|MockObject
34+
*/
35+
private $sniffFinder;
36+
37+
protected function setUp(): void
38+
{
39+
$this->codeRepository = $this->createMock(CodeRepository::class);
40+
$this->generator = $this->createMock(Generator::class);
41+
$this->sniffFinder = $this->createMock(SniffFinder::class);
42+
43+
$this->handler = new GenerateHandler(
44+
$this->codeRepository,
45+
$this->generator,
46+
$this->sniffFinder
47+
);
48+
}
49+
50+
/** @test */
51+
public function handle()
52+
{
53+
$this->codeRepository->method('downloadCode')->willReturn(new Folder('var/tests/src/'));
54+
$this->sniffFinder->method('getSniffs')->willReturn($this->createSniffs());
55+
56+
$this->handler->handle();
57+
58+
self::assertFileExists('var/markdown/Standard/Category/My.md');
59+
self::assertFileExists('var/markdown/Standard/Category/My/ErrorCode.md');
60+
}
61+
62+
private function createSniffs()
63+
{
64+
yield new Sniff(
65+
'Standard.Category.My',
66+
'',
67+
[],
68+
new Urls([]),
69+
'Description',
70+
[],
71+
[
72+
new Violation(
73+
'Standard.Category.My.ErrorCode',
74+
'Description',
75+
[],
76+
new Urls([])
77+
)
78+
]
79+
);
80+
}
81+
}

0 commit comments

Comments
 (0)