Skip to content

Commit df515c4

Browse files
committed
Allow running with single sniff
1 parent 9562191 commit df515c4

File tree

6 files changed

+144
-28
lines changed

6 files changed

+144
-28
lines changed

bin/phpcsdocs

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#!/usr/bin/env php
2+
<?php
3+
declare(strict_types=1);
4+
5+
require __DIR__.'/../vendor/autoload.php';
6+
7+
use App\Command\GenerateCommand;
8+
use DI\ContainerBuilder;
9+
use Symfony\Component\Console\Application;
10+
11+
$application = new Application();
12+
13+
$containerBuilder = new ContainerBuilder;
14+
$containerBuilder->addDefinitions(__DIR__ . '/../config/di.php');
15+
$container = $containerBuilder->build();
16+
17+
$application->add($container->get(GenerateCommand::class));
18+
$application->run();

src/Command/GenerateCommand.php

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace App\Command;
5+
6+
use App\Handler\GenerateHandler;
7+
use Symfony\Component\Console\Command\Command;
8+
use Symfony\Component\Console\Input\InputArgument;
9+
use Symfony\Component\Console\Input\InputInterface;
10+
use Symfony\Component\Console\Output\OutputInterface;
11+
12+
class GenerateCommand extends Command
13+
{
14+
protected static $defaultName = 'generate';
15+
private GenerateHandler $handler;
16+
17+
public function __construct(GenerateHandler $handler)
18+
{
19+
parent::__construct(self::$defaultName);
20+
$this->handler = $handler;
21+
}
22+
23+
protected function configure()
24+
{
25+
$this->addArgument('sniff', InputArgument::OPTIONAL);
26+
}
27+
28+
protected function execute(InputInterface $input, OutputInterface $output)
29+
{
30+
$sniffPath = null;
31+
if ($input->hasArgument('sniff')) {
32+
$sniffPath = $input->getArgument('sniff');
33+
}
34+
35+
foreach ($this->handler->handle($sniffPath) as $message) {
36+
$output->writeln($message);
37+
};
38+
39+
return Command::SUCCESS;
40+
}
41+
}

src/Handler/GenerateHandler.php

+12-4
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
use App\Generator\Generator;
88
use App\SniffFinder\SniffFinder;
99
use App\Value\Folder;
10-
use Iterator;
1110
use Symfony\Component\Filesystem\Filesystem;
1211

1312
class GenerateHandler
@@ -24,17 +23,26 @@ public function __construct(CodeRepository $codeRepository, Generator $generator
2423
}
2524

2625
/**
27-
* @return Iterator<string>
26+
* @return iterable<string>
2827
*/
29-
public function handle(): Iterator
28+
public function handle(string $sniffPath = null): iterable
3029
{
3130
$repoName = 'PHPCompatibility/PHPCompatibility';
3231
$repoPath = $this->codeRepository->downloadCode($repoName);
3332
$filesystem = new Filesystem();
3433

3534
$standardPath = new Folder($repoPath . 'PHPCompatibility/');
3635

37-
foreach ($this->sniffFinder->getSniffs($standardPath) as $sniff) {
36+
if ($sniffPath !== null) {
37+
$sniffs = [$this->sniffFinder->getSniff($standardPath, $sniffPath)];
38+
} else {
39+
$sniffs = $this->sniffFinder->getSniffs($standardPath);
40+
}
41+
42+
$count = count($sniffs);
43+
yield "Found {$count} sniff(s)";
44+
45+
foreach ($sniffs as $sniff) {
3846
$markdownPath = $this->sniffCodeToMarkdownPath($sniff->getCode());
3947
$filesystem->dumpFile(
4048
// TODO: perhaps we can move this logic to the the sniff class

src/SniffFinder/FilesystemSniffFinder.php

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

66
use App\Parser\SniffParser;
77
use App\Value\Folder;
8+
use App\Value\Sniff;
89
use CallbackFilterIterator;
910
use GlobIterator;
1011
use Iterator;
@@ -14,11 +15,17 @@
1415
use Roave\BetterReflection\SourceLocator\Type\FileIteratorSourceLocator;
1516
use Roave\BetterReflection\SourceLocator\Type\SourceLocator;
1617
use SplFileInfo;
17-
use Traversable;
1818

1919
class FilesystemSniffFinder implements SniffFinder
2020
{
21-
public function getSniffs(Folder $folder): Traversable
21+
public function getSniff(Folder $folder, string $sniffPath): Sniff
22+
{
23+
$parser = new SniffParser();
24+
$projectSourceLocator = $this->createProjectSourceLocator($folder);
25+
return $parser->parse($sniffPath, $projectSourceLocator);
26+
}
27+
28+
public function getSniffs(Folder $folder): iterable
2229
{
2330
$parser = new SniffParser();
2431
$globSniffs = new GlobIterator($folder->getPath() . 'Sniffs/*/*Sniff.php');

src/SniffFinder/SniffFinder.php

+4-3
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,13 @@
55

66
use App\Value\Folder;
77
use App\Value\Sniff;
8-
use Traversable;
98

109
interface SniffFinder
1110
{
11+
public function getSniff(Folder $folder, string $sniffPath): Sniff;
12+
1213
/**
13-
* @return Traversable<Sniff>
14+
* @return iterable<Sniff>
1415
*/
15-
public function getSniffs(Folder $folder): Traversable;
16+
public function getSniffs(Folder $folder): iterable;
1617
}

tests/Handler/GenerateHandlerTest.php

+60-19
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use App\Value\Violation;
1414
use PHPUnit\Framework\MockObject\MockObject;
1515
use PHPUnit\Framework\TestCase;
16+
use Symfony\Component\Filesystem\Filesystem;
1617

1718
/** @covers \App\Handler\GenerateHandler */
1819
class GenerateHandlerTest extends TestCase
@@ -35,38 +36,58 @@ class GenerateHandlerTest extends TestCase
3536
private $sniffFinder;
3637

3738
/** @test */
38-
public function handle()
39+
public function handle_WithoutArguments_CreatesFile()
3940
{
4041
$this->codeRepository->method('downloadCode')->willReturn(new Folder('var/tests/'));
41-
$this->sniffFinder->method('getSniffs')->willReturn($this->createSniffs());
42+
$sniffs = $this->createSniffs(['First', 'Second']);
43+
$this->sniffFinder->method('getSniffs')->willReturn($sniffs);
44+
$this->generator->method('createSniffDoc')->withConsecutive([$sniffs[0]], [$sniffs[1]]);
4245

43-
$this->handler->handle();
46+
/** @var \Generator $messages */
47+
$messages = $this->handler->handle();
4448

45-
self::assertFileExists('var/markdown/Standard/Category/My.md');
49+
self::assertEquals(
50+
[
51+
'Found 2 sniff(s)',
52+
'Created file: var/markdown/Standard/Category/First.md',
53+
'Created file: var/markdown/Standard/Category/Second.md'
54+
],
55+
iterator_to_array($messages)
56+
);
4657
}
4758

48-
private function createSniffs()
59+
/** @test */
60+
public function handle_WithSniffPath_CreatesSingleFile()
4961
{
50-
yield new Sniff(
51-
'Standard.Category.My',
52-
'',
53-
[],
54-
new Urls([]),
55-
'Description',
56-
[],
62+
$this->codeRepository->method('downloadCode')->willReturn(new Folder('var/tests/'));
63+
$this->sniffFinder->method('getSniff')->willReturn($this->createSniff('First'));
64+
65+
/** @var \Generator $messages */
66+
$messages = $this->handler->handle('var/tests/Standard/Category/Sniffs/FirstSniff.php');
67+
68+
self::assertEquals(
5769
[
58-
new Violation(
59-
'Standard.Category.My.ErrorCode',
60-
'Description',
61-
[],
62-
new Urls([])
63-
)
64-
]
70+
'Found 1 sniff(s)',
71+
'Created file: var/markdown/Standard/Category/First.md',
72+
],
73+
iterator_to_array($messages)
6574
);
6675
}
6776

77+
/**
78+
* @param string[] $names
79+
*/
80+
private function createSniffs(array $names): iterable
81+
{
82+
return array_map(function (string $name) {
83+
return $this->createSniff($name);
84+
}, $names);
85+
}
86+
6887
protected function setUp(): void
6988
{
89+
(new Filesystem())->remove('var/markdown/Standard');
90+
7091
$this->codeRepository = $this->createMock(CodeRepository::class);
7192
$this->generator = $this->createMock(Generator::class);
7293
$this->sniffFinder = $this->createMock(SniffFinder::class);
@@ -77,4 +98,24 @@ protected function setUp(): void
7798
$this->sniffFinder
7899
);
79100
}
101+
102+
private function createSniff(string $name): Sniff
103+
{
104+
return new Sniff(
105+
'Standard.Category.' . $name,
106+
'',
107+
[],
108+
new Urls([]),
109+
'Description',
110+
[],
111+
[
112+
new Violation(
113+
'Standard.Category.' . $name . '.ErrorCode',
114+
'Description',
115+
[],
116+
new Urls([])
117+
)
118+
]
119+
);
120+
}
80121
}

0 commit comments

Comments
 (0)