Skip to content

Commit ff4137f

Browse files
authored
Make use of entropy/console for command and application skeleton (#115)
* make use of entropy command * remove deprectaed GenerateSymfonyConfigBuildersCommand * rerun rector
1 parent 5521c9d commit ff4137f

21 files changed

+353
-476
lines changed

.github/workflows/code_analysis.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,11 @@ jobs:
3434

3535
-
3636
name: 'Check Commented Code'
37-
run: bin/swiss-knife check-commented-code src tests --ansi
37+
run: bin/swiss-knife check-commented-code src tests
3838

3939
-
4040
name: 'Check Active Classes'
41-
run: vendor/bin/class-leak check bin src --ansi
41+
run: vendor/bin/class-leak check bin src --skip-type="\Entropy\Console\Contract\CommandInterface"
4242

4343
-
4444
name: 'Unusued check'

bin/swiss-knife.php

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@
22

33
declare(strict_types=1);
44

5-
use Symfony\Component\Console\Application;
6-
use Symfony\Component\Console\Input\ArgvInput;
7-
use Symfony\Component\Console\Output\ConsoleOutput;
5+
use Entropy\Console\ConsoleApplication;
86
use Rector\SwissKnife\DependencyInjection\ContainerFactory;
97

108
$scoperAutoloadFilepath = __DIR__ . '/../vendor/scoper-autoload.php';
@@ -32,7 +30,7 @@
3230
$containerFactory = new ContainerFactory();
3331
$container = $containerFactory->create();
3432

35-
$application = $container->make(Application::class);
33+
$consoleApplication = $container->make(ConsoleApplication::class);
3634

37-
$exitCode = $application->run(new ArgvInput(), new ConsoleOutput());
35+
$exitCode = $consoleApplication->run($argv);
3836
exit($exitCode);

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@
2121
"phpstan/extension-installer": "^1.4",
2222
"phpstan/phpstan": "^2.1",
2323
"phpunit/phpunit": "^12.5",
24+
"symfony/config": "^6.4",
2425
"rector/jack": "^0.5.1",
2526
"rector/rector": "^2.3",
2627
"shipmonk/composer-dependency-analyser": "^1.8",
27-
"symfony/config": "^6.4",
2828
"symfony/dependency-injection": "^6.4",
2929
"symplify/phpstan-extensions": "^12.0",
3030
"tomasvotruba/class-leak": "^2.1",

phpstan.neon

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,12 @@ parameters:
3333
identifier: argument.type
3434
path: src/Testing/MockWire.php
3535

36-
# optional command, depends on present of classes
36+
# magic contract
3737
-
38-
identifier: argument.unresolvableType
39-
path: src/Command/GenerateSymfonyConfigBuildersCommand.php
38+
identifier: public.method.unused
39+
message: '#Public method "Rector\\SwissKnife\\(.*?)Command\:\:run\(\)" is never used#'
40+
41+
# depends on symfony extenison class presence
42+
-
43+
message: '#Parameter \#1 \$objectOrClass of class ReflectionClass constructor contains unresolvable type#'
44+
path: src/Command/GenerateSymfonyConfigBuildersCommand.php

rector.php

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,20 @@
55
use Rector\Config\RectorConfig;
66

77
return RectorConfig::configure()
8-
->withPaths([__DIR__ . '/src', __DIR__ . '/tests'])
8+
->withPaths([__DIR__ . '/bin', __DIR__ . '/src', __DIR__ . '/tests'])
99
->withPhpSets()
10+
->withRootFiles()
1011
->withPreparedSets(
11-
codeQuality: true,
1212
deadCode: true,
13+
codeQuality: true,
14+
codingStyle: true,
1315
typeDeclarations: true,
1416
typeDeclarationDocblocks: true,
1517
privatization: true,
16-
earlyReturn: true,
17-
codingStyle: true,
18+
naming: true,
1819
instanceOf: true,
19-
naming: true
20+
earlyReturn: true,
21+
rectorPreset: true,
2022
)
2123
->withImportNames(removeUnusedImports: true)
2224
->withSkip(['*/scoper.php', '*/Source/*', '*/Fixture/*']);

src/Command/AliceYamlFixturesToPhpCommand.php

Lines changed: 20 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,45 +4,32 @@
44

55
namespace Rector\SwissKnife\Command;
66

7+
use Entropy\Console\Contract\CommandInterface;
8+
use Entropy\Console\Enum\ExitCode;
79
use Nette\Utils\FileSystem;
810
use PhpParser\BuilderHelpers;
911
use PhpParser\Node\Stmt\Return_;
1012
use PhpParser\PrettyPrinter\Standard;
1113
use Rector\SwissKnife\Finder\FilesFinder;
12-
use Symfony\Component\Console\Command\Command;
13-
use Symfony\Component\Console\Input\InputArgument;
14-
use Symfony\Component\Console\Input\InputInterface;
15-
use Symfony\Component\Console\Output\OutputInterface;
1614
use Symfony\Component\Console\Style\SymfonyStyle;
1715
use Symfony\Component\Yaml\Yaml;
1816

1917
/**
2018
* @see https://github.com/nelmio/alice/blob/v2.3.0/doc/complete-reference.md#php
2119
*/
22-
final class AliceYamlFixturesToPhpCommand extends Command
20+
final readonly class AliceYamlFixturesToPhpCommand implements CommandInterface
2321
{
2422
public function __construct(
25-
private readonly SymfonyStyle $symfonyStyle,
23+
private SymfonyStyle $symfonyStyle,
2624
) {
27-
parent::__construct();
2825
}
2926

30-
protected function configure(): void
31-
{
32-
$this->setName('alice-yaml-fixtures-to-php');
33-
34-
$this->addArgument(
35-
'sources',
36-
InputArgument::REQUIRED | InputArgument::IS_ARRAY,
37-
'One or more paths to check'
38-
);
39-
40-
$this->setDescription('Converts Alice YAML fixtures to PHP format, so Rector and PHPStan can understand it');
41-
}
42-
43-
protected function execute(InputInterface $input, OutputInterface $output): int
27+
/**
28+
* @param string[] $sources One or more paths to check
29+
* @return ExitCode::*
30+
*/
31+
public function run(array $sources): int
4432
{
45-
$sources = (array) $input->getArgument('sources');
4633
$yamlFileInfos = FilesFinder::findYamlFiles($sources);
4734

4835
$standard = new Standard();
@@ -75,7 +62,17 @@ protected function execute(InputInterface $input, OutputInterface $output): int
7562
sprintf('Successfully converted %d Alice YAML fixtures to PHP', count($yamlFileInfos))
7663
);
7764

78-
return self::SUCCESS;
65+
return ExitCode::SUCCESS;
66+
}
67+
68+
public function getName(): string
69+
{
70+
return 'alice-yaml-fixtures-to-php';
71+
}
72+
73+
public function getDescription(): string
74+
{
75+
return 'Converts Alice YAML fixtures to PHP format, so Rector and PHPStan can understand it';
7976
}
8077

8178
/**

src/Command/CheckCommentedCodeCommand.php

Lines changed: 26 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -4,64 +4,36 @@
44

55
namespace Rector\SwissKnife\Command;
66

7+
use Entropy\Console\Contract\CommandInterface;
8+
use Entropy\Console\Enum\ExitCode;
79
use Rector\SwissKnife\Comments\CommentedCodeAnalyzer;
810
use Rector\SwissKnife\Finder\PhpFilesFinder;
9-
use Symfony\Component\Console\Command\Command;
10-
use Symfony\Component\Console\Input\InputArgument;
11-
use Symfony\Component\Console\Input\InputInterface;
12-
use Symfony\Component\Console\Input\InputOption;
13-
use Symfony\Component\Console\Output\OutputInterface;
1411
use Symfony\Component\Console\Style\SymfonyStyle;
1512

16-
final class CheckCommentedCodeCommand extends Command
13+
final readonly class CheckCommentedCodeCommand implements CommandInterface
1714
{
1815
private const int DEFAULT_LINE_LIMIT = 5;
1916

2017
public function __construct(
21-
private readonly CommentedCodeAnalyzer $commentedCodeAnalyzer,
22-
private readonly SymfonyStyle $symfonyStyle,
18+
private CommentedCodeAnalyzer $commentedCodeAnalyzer,
19+
private SymfonyStyle $symfonyStyle,
2320
) {
24-
parent::__construct();
2521
}
2622

27-
protected function configure(): void
23+
/**
24+
* @param string[] $sources One or more paths to check
25+
* @param string[] $skipFiles File paths to skip
26+
* @param int $lineLimit Maximum number of comment lines in a row allowed
27+
*
28+
* @return ExitCode::*
29+
*/
30+
public function run(array $sources, array $skipFiles = [], int $lineLimit = self::DEFAULT_LINE_LIMIT): int
2831
{
29-
$this->setName('check-commented-code');
30-
31-
$this->addArgument(
32-
'sources',
33-
InputArgument::REQUIRED | InputArgument::IS_ARRAY,
34-
'One or more paths to check'
35-
);
36-
$this->addOption(
37-
'skip-file',
38-
null,
39-
InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
40-
'Skip file path'
41-
);
42-
$this->setDescription('Checks code for commented snippets');
43-
44-
$this->addOption(
45-
'line-limit',
46-
null,
47-
InputOption::VALUE_REQUIRED | InputOption::VALUE_OPTIONAL,
48-
'Amount of allowed comment lines in a row',
49-
self::DEFAULT_LINE_LIMIT
50-
);
51-
}
52-
53-
protected function execute(InputInterface $input, OutputInterface $output): int
54-
{
55-
$sources = (array) $input->getArgument('sources');
56-
$skipFiles = (array) $input->getOption('skip-file');
57-
5832
$phpFileInfos = PhpFilesFinder::find($sources, $skipFiles);
5933

6034
$message = sprintf('Analysing %d *.php files', count($phpFileInfos));
6135
$this->symfonyStyle->note($message);
6236

63-
$lineLimit = (int) $input->getOption('line-limit');
64-
6537
$commentedLinesByFilePaths = [];
6638
foreach ($phpFileInfos as $phpFileInfo) {
6739
$commentedLines = $this->commentedCodeAnalyzer->process($phpFileInfo->getRealPath(), $lineLimit);
@@ -75,7 +47,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
7547

7648
if ($commentedLinesByFilePaths === []) {
7749
$this->symfonyStyle->success('No commented code found');
78-
return self::SUCCESS;
50+
return ExitCode::SUCCESS;
7951
}
8052

8153
foreach ($commentedLinesByFilePaths as $filePath => $commentedLines) {
@@ -86,6 +58,17 @@ protected function execute(InputInterface $input, OutputInterface $output): int
8658
}
8759

8860
$this->symfonyStyle->error('Errors found');
89-
return self::FAILURE;
61+
62+
return ExitCode::ERROR;
63+
}
64+
65+
public function getName(): string
66+
{
67+
return 'check-commented-code';
68+
}
69+
70+
public function getDescription(): string
71+
{
72+
return 'Checks code for commented snippets';
9073
}
9174
}

src/Command/CheckConflictsCommand.php

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,37 +4,28 @@
44

55
namespace Rector\SwissKnife\Command;
66

7+
use Entropy\Console\Contract\CommandInterface;
8+
use Entropy\Console\Enum\ExitCode;
79
use Rector\SwissKnife\Finder\FilesFinder;
810
use Rector\SwissKnife\Git\ConflictResolver;
9-
use Symfony\Component\Console\Command\Command;
10-
use Symfony\Component\Console\Input\InputArgument;
11-
use Symfony\Component\Console\Input\InputInterface;
12-
use Symfony\Component\Console\Output\OutputInterface;
1311
use Symfony\Component\Console\Style\SymfonyStyle;
1412

15-
final class CheckConflictsCommand extends Command
13+
final readonly class CheckConflictsCommand implements CommandInterface
1614
{
1715
public function __construct(
18-
private readonly ConflictResolver $conflictResolver,
19-
private readonly SymfonyStyle $symfonyStyle,
16+
private ConflictResolver $conflictResolver,
17+
private SymfonyStyle $symfonyStyle,
2018
) {
21-
parent::__construct();
2219
}
2320

24-
protected function configure(): void
21+
/**
22+
* @param string[] $sources One or more path to project
23+
* @return ExitCode::*
24+
*/
25+
public function run(array $sources): int
2526
{
26-
$this->setName('check-conflicts');
27-
28-
$this->setDescription('Check files for missed git conflicts');
29-
$this->addArgument('sources', InputArgument::REQUIRED | InputArgument::IS_ARRAY, 'Path to project');
30-
}
31-
32-
protected function execute(InputInterface $input, OutputInterface $output): int
33-
{
34-
/** @var string[] $sources */
35-
$sources = (array) $input->getArgument('sources');
36-
3727
$fileInfos = FilesFinder::find($sources);
28+
3829
$filePaths = [];
3930
foreach ($fileInfos as $fileInfo) {
4031
$filePaths[] = $fileInfo->getRealPath();
@@ -45,14 +36,24 @@ protected function execute(InputInterface $input, OutputInterface $output): int
4536
$message = sprintf('No conflicts found in %d files', count($fileInfos));
4637
$this->symfonyStyle->success($message);
4738

48-
return self::SUCCESS;
39+
return ExitCode::SUCCESS;
4940
}
5041

5142
foreach ($conflictsCountByFilePath as $file => $conflictCount) {
5243
$message = sprintf('File "%s" contains %d unresolved conflicts', $file, $conflictCount);
5344
$this->symfonyStyle->error($message);
5445
}
5546

56-
return self::FAILURE;
47+
return ExitCode::ERROR;
48+
}
49+
50+
public function getName(): string
51+
{
52+
return 'check-conflicts';
53+
}
54+
55+
public function getDescription(): string
56+
{
57+
return 'Check files for missed git conflicts';
5758
}
5859
}

src/Command/DumpEditorconfigCommand.php

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,37 +4,41 @@
44

55
namespace Rector\SwissKnife\Command;
66

7+
use Entropy\Console\Contract\CommandInterface;
8+
use Entropy\Console\Enum\ExitCode;
79
use Nette\Utils\FileSystem;
8-
use Symfony\Component\Console\Command\Command;
9-
use Symfony\Component\Console\Input\InputInterface;
10-
use Symfony\Component\Console\Output\OutputInterface;
1110
use Symfony\Component\Console\Style\SymfonyStyle;
1211

13-
final class DumpEditorconfigCommand extends Command
12+
final readonly class DumpEditorconfigCommand implements CommandInterface
1413
{
1514
public function __construct(
16-
private readonly SymfonyStyle $symfonyStyle,
15+
private SymfonyStyle $symfonyStyle,
1716
) {
18-
parent::__construct();
1917
}
2018

21-
protected function configure(): void
19+
public function getName(): string
2220
{
23-
$this->setName('dump-editorconfig');
24-
$this->setDescription('Dump .editorconfig file to project root');
21+
return 'dump-editorconfig';
2522
}
2623

27-
protected function execute(InputInterface $input, OutputInterface $output): int
24+
public function getDescription(): string
25+
{
26+
return 'Dump .editorconfig file to project root';
27+
}
28+
29+
public function run(): int
2830
{
2931
$projectEditorconfigFilePath = getcwd() . '/.editorconfig';
3032
if (file_exists($projectEditorconfigFilePath)) {
3133
$this->symfonyStyle->error('.editorconfig file already exists');
32-
return self::FAILURE;
34+
35+
return ExitCode::ERROR;
3336
}
3437

3538
FileSystem::copy(__DIR__ . '/../../templates/.editorconfig', $projectEditorconfigFilePath);
39+
3640
$this->symfonyStyle->success('.editorconfig file was created');
3741

38-
return self::SUCCESS;
42+
return ExitCode::SUCCESS;
3943
}
4044
}

0 commit comments

Comments
 (0)