Skip to content

Commit 954a78e

Browse files
committed
ref: CodemapCommand
1 parent 62e302a commit 954a78e

File tree

1 file changed

+96
-68
lines changed

1 file changed

+96
-68
lines changed

src/Console/CodemapCommand.php

Lines changed: 96 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@
55
namespace Kauffinger\Codemap\Console;
66

77
use Exception;
8+
use InvalidArgumentException;
89
use Kauffinger\Codemap\Config\CodemapConfig;
910
use Kauffinger\Codemap\Enum\PhpVersion;
1011
use Kauffinger\Codemap\Formatter\TextCodemapFormatter;
1112
use Kauffinger\Codemap\Generator\CodemapGenerator;
1213
use Override;
14+
use RuntimeException;
1315
use Symfony\Component\Console\Command\Command;
1416
use Symfony\Component\Console\Input\InputArgument;
1517
use Symfony\Component\Console\Input\InputInterface;
@@ -44,120 +46,146 @@ protected function execute(InputInterface $input, OutputInterface $output): int
4446

4547
protected function handle(): int
4648
{
47-
$codemapConfigFilePath = getcwd().'/codemap.php';
48-
$configuredScanPaths = [];
49-
$configuredPhpVersion = null;
49+
try {
50+
$this->ensureConfigurationExists();
51+
$config = $this->loadConfiguration();
5052

51-
if (file_exists($codemapConfigFilePath)) {
52-
$codemapConfiguration = require $codemapConfigFilePath;
53-
if ($codemapConfiguration instanceof CodemapConfig) {
54-
$configuredScanPaths = $codemapConfiguration->getScanPaths();
55-
$configuredPhpVersion = $codemapConfiguration->getConfiguredPhpVersion();
56-
}
57-
} else {
58-
$composerJsonPath = getcwd().'/composer.json';
59-
$composerContents = file_get_contents($composerJsonPath) ?: '';
60-
$composerData = json_decode($composerContents, true);
61-
/* @phpstan-ignore-next-line */
62-
$composerPhpVersionString = $composerData['require']['php'] ?? '^8.4.0';
63-
64-
$parsedComposerVersion = '8.4';
65-
/* @phpstan-ignore-next-line */
66-
if (preg_match('/(\d+\.\d+)/', (string) $composerPhpVersionString, $matches)) {
67-
$parsedComposerVersion = $matches[1];
68-
}
53+
$scanPaths = $this->argument('paths') ? (array) $this->argument('paths') : $config->getScanPaths();
54+
if ($scanPaths === []) {
55+
$this->error('No scan paths provided or configured.');
6956

70-
$mappedPhpVersion = PhpVersion::PHP_8_4;
71-
foreach (PhpVersion::cases() as $phpVersionCase) {
72-
if ($phpVersionCase->value === $parsedComposerVersion) {
73-
$mappedPhpVersion = $phpVersionCase;
74-
break;
75-
}
57+
return Command::FAILURE;
7658
}
7759

78-
$generatedDefaultConfig = $this->generateDefaultConfig($mappedPhpVersion);
79-
try {
80-
file_put_contents($codemapConfigFilePath, $generatedDefaultConfig);
81-
$this->info('Created default codemap config at: '.$codemapConfigFilePath);
82-
} catch (Exception $e) {
83-
$this->error('Failed to create config file: '.$e->getMessage());
60+
$phpVersion = $this->getPhpVersion($config);
8461

85-
return Command::FAILURE;
62+
$codemapResults = $this->generateCodemap($scanPaths, $phpVersion);
63+
64+
$formatter = new TextCodemapFormatter;
65+
$formattedOutput = $formatter->format($codemapResults);
66+
67+
$outputFile = $this->option('output');
68+
$this->writeOutput($formattedOutput, $outputFile);
69+
70+
return Command::SUCCESS;
71+
} catch (Exception $e) {
72+
$this->error($e->getMessage());
73+
74+
return Command::FAILURE;
75+
}
76+
}
77+
78+
private function ensureConfigurationExists(): void
79+
{
80+
$codemapConfigFilePath = getcwd().'/codemap.php';
81+
if (file_exists($codemapConfigFilePath)) {
82+
return;
83+
}
84+
85+
$composerJsonPath = getcwd().'/composer.json';
86+
if (! file_exists($composerJsonPath)) {
87+
throw new RuntimeException('composer.json not found.');
88+
}
89+
90+
$composerContents = file_get_contents($composerJsonPath);
91+
if ($composerContents === false) {
92+
throw new RuntimeException('Failed to read composer.json.');
93+
}
94+
95+
$composerData = json_decode($composerContents, true);
96+
if (! is_array($composerData)) {
97+
throw new RuntimeException('Invalid composer.json.');
98+
}
99+
$composerPhpVersionString = $composerData['require']['php'] ?? '^8.4.0';
100+
101+
$parsedVersion = preg_match('/(\d+\.\d+)/', (string) $composerPhpVersionString, $matches) ? $matches[1] : '8.4';
102+
$mappedPhpVersion = PhpVersion::PHP_8_4;
103+
foreach (PhpVersion::cases() as $phpVersionCase) {
104+
if ($phpVersionCase->value === $parsedVersion) {
105+
$mappedPhpVersion = $phpVersionCase;
106+
break;
86107
}
87-
$configuredScanPaths = [getcwd().'/src'];
88-
$configuredPhpVersion = $mappedPhpVersion;
89108
}
90109

91-
/* @var array<string> $paths */
92-
$paths = (array) $this->argument('paths');
93-
if ($paths === []) {
94-
$paths = $configuredScanPaths;
110+
$generatedConfig = $this->generateDefaultConfig($mappedPhpVersion);
111+
if (! file_put_contents($codemapConfigFilePath, $generatedConfig)) {
112+
throw new RuntimeException('Failed to write codemap.php.');
95113
}
96114

97-
if ($paths === []) {
98-
$this->error('No scan paths provided or configured.');
115+
$this->info('Created default codemap config at: '.$codemapConfigFilePath);
116+
}
99117

100-
return Command::FAILURE;
118+
private function loadConfiguration(): CodemapConfig
119+
{
120+
$codemapConfigFilePath = getcwd().'/codemap.php';
121+
if (! file_exists($codemapConfigFilePath)) {
122+
throw new RuntimeException('codemap.php not found.');
123+
}
124+
$codemapConfiguration = require $codemapConfigFilePath;
125+
if (! $codemapConfiguration instanceof CodemapConfig) {
126+
throw new RuntimeException('Invalid codemap configuration.');
101127
}
102128

103-
/* @phpstan-ignore-next-line */
104-
$phpVersionString = (string) $this->option('php-version');
105-
if ($phpVersionString !== '') {
129+
return $codemapConfiguration;
130+
}
131+
132+
private function getPhpVersion(CodemapConfig $config): ?PhpVersion
133+
{
134+
$phpVersionString = $this->option('php-version');
135+
if ($phpVersionString) {
106136
$phpVersion = PhpVersion::tryFrom($phpVersionString);
107137
if (! $phpVersion instanceof PhpVersion) {
108-
$this->error('Invalid PHP version: '.$phpVersionString);
109-
110-
return Command::FAILURE;
138+
throw new InvalidArgumentException('Invalid PHP version: '.$phpVersionString);
111139
}
112-
} else {
113-
$phpVersion = $configuredPhpVersion;
140+
141+
return $phpVersion;
114142
}
115143

116-
$outputFile = $this->option('output');
144+
return $config->getConfiguredPhpVersion();
145+
}
117146

147+
private function generateCodemap(array $scanPaths, ?PhpVersion $phpVersion): array
148+
{
118149
$codemapGenerator = new CodemapGenerator;
119150
if ($phpVersion instanceof PhpVersion) {
120-
$codemapGenerator->setPhpParserVersion(\PhpParser\PhpVersion::fromString($phpVersion->value));
151+
$codemapGenerator->setPhpParserVersion($phpVersion->toParserPhpVersion());
121152
}
122153
$codemapGenerator->setErrorHandler(fn ($message) => $this->error($message));
123154

124155
$aggregatedCodemapResults = [];
125-
foreach ($paths as $scanPath) {
126-
/* @phpstan-ignore-next-line */
156+
foreach ($scanPaths as $scanPath) {
127157
if (! file_exists($scanPath)) {
128158
$this->error('Warning: Path "'.$scanPath.'" does not exist.');
129159

130160
continue;
131161
}
132162
try {
133-
/* @phpstan-ignore-next-line */
134163
$fileResults = $codemapGenerator->generate($scanPath);
135-
foreach ($fileResults as $fileName => $codemapDto) {
136-
$aggregatedCodemapResults[$fileName] = $codemapDto;
137-
}
164+
$aggregatedCodemapResults += $fileResults;
138165
} catch (Exception $e) {
139166
$this->error('Error processing "'.$scanPath.'": '.$e->getMessage());
140167
}
141168
}
142169

143-
$formatter = new TextCodemapFormatter;
144-
$formattedCodemapOutput = $formatter->format($aggregatedCodemapResults);
170+
return $aggregatedCodemapResults;
171+
}
145172

173+
/**
174+
* @throws Exception
175+
*/
176+
private function writeOutput(string $output, string $outputFile): void
177+
{
146178
if ($outputFile === '-') {
147-
$this->output->write($formattedCodemapOutput);
179+
$this->output->write($output);
148180
} else {
149181
try {
150-
/* @phpstan-ignore-next-line */
151-
file_put_contents($outputFile, $formattedCodemapOutput);
182+
file_put_contents($outputFile, $output);
152183
$this->info('Codemap generated at: '.$outputFile);
153184
} catch (Exception $e) {
154185
$this->error('Failed to write to "'.$outputFile.'": '.$e->getMessage());
155-
156-
return Command::FAILURE;
186+
throw $e;
157187
}
158188
}
159-
160-
return Command::SUCCESS;
161189
}
162190

163191
private function generateDefaultConfig(PhpVersion $mappedPhpVersion): string

0 commit comments

Comments
 (0)