Skip to content

Commit 63384f5

Browse files
Made it possible to pass multiple files and folders (#48)
This will allow it to check only certain files and folders. This is useful when you want to check only changed files and limits the time it takes to run this.
1 parent 11597c3 commit 63384f5

File tree

6 files changed

+143
-11
lines changed

6 files changed

+143
-11
lines changed

src/Business/Cognitive/CognitiveMetricsCollector.php

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,17 +44,29 @@ public function __construct(
4444
*/
4545
public function collect(string $path, CognitiveConfig $config): CognitiveMetricsCollection
4646
{
47-
$files = $this->findSourceFiles($path, $config->excludeFilePatterns);
47+
return $this->collectFromPaths([$path], $config);
48+
}
4849

49-
/** @var SplFileInfo[] $clonedFiles */
50-
$clonedFiles = [];
51-
foreach ($files as $file) {
52-
$clonedFiles[] = $file;
50+
/**
51+
* Collect cognitive metrics from multiple paths and merge them into a single collection
52+
*
53+
* @param array<string> $paths Array of paths to process
54+
* @param CognitiveConfig $config
55+
* @return CognitiveMetricsCollection Merged collection of metrics from all paths
56+
* @throws CognitiveAnalysisException|ExceptionInterface
57+
*/
58+
public function collectFromPaths(array $paths, CognitiveConfig $config): CognitiveMetricsCollection
59+
{
60+
$allFiles = [];
61+
62+
foreach ($paths as $path) {
63+
$files = $this->findSourceFiles($path, $config->excludeFilePatterns);
64+
$allFiles = array_merge($allFiles, iterator_to_array($files));
5365
}
5466

55-
$this->messageBus->dispatch(new SourceFilesFound($clonedFiles));
67+
$this->messageBus->dispatch(new SourceFilesFound($allFiles));
5668

57-
return $this->findMetrics($clonedFiles);
69+
return $this->findMetrics($allFiles);
5870
}
5971

6072
/**

src/Business/MetricsFacade.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,23 @@ public function getCognitiveMetrics(string $path): CognitiveMetricsCollection
5252
return $metricsCollection;
5353
}
5454

55+
/**
56+
* Collects and returns cognitive metrics for multiple paths.
57+
*
58+
* @param array<string> $paths Array of file or directory paths to collect metrics from.
59+
* @return CognitiveMetricsCollection The collected cognitive metrics from all paths.
60+
*/
61+
public function getCognitiveMetricsFromPaths(array $paths): CognitiveMetricsCollection
62+
{
63+
$metricsCollection = $this->cognitiveMetricsCollector->collectFromPaths($paths, $this->configService->getConfig());
64+
65+
foreach ($metricsCollection as $metric) {
66+
$this->scoreCalculator->calculate($metric, $this->configService->getConfig());
67+
}
68+
69+
return $metricsCollection;
70+
}
71+
5572
/**
5673
* @return array<string, array<string, mixed>>
5774
*/

src/Command/CognitiveMetricsCommand.php

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ protected function configure(): void
5454
->addArgument(
5555
name: self::ARGUMENT_PATH,
5656
mode: InputArgument::REQUIRED,
57-
description: 'Path to PHP files or directories to parse.'
57+
description: 'Path to PHP files or directories to parse. Can be a single path or comma-separated list of paths.'
5858
)
5959
->addOption(
6060
name: self::OPTION_CONFIG_FILE,
@@ -110,14 +110,15 @@ protected function configure(): void
110110
*/
111111
protected function execute(InputInterface $input, OutputInterface $output): int
112112
{
113-
$path = $input->getArgument(self::ARGUMENT_PATH);
113+
$pathInput = $input->getArgument(self::ARGUMENT_PATH);
114+
$paths = $this->parsePaths($pathInput);
114115

115116
$configFile = $input->getOption(self::OPTION_CONFIG_FILE);
116117
if ($configFile && !$this->loadConfiguration($configFile, $output)) {
117118
return Command::FAILURE;
118119
}
119120

120-
$metricsCollection = $this->metricsFacade->getCognitiveMetrics($path);
121+
$metricsCollection = $this->metricsFacade->getCognitiveMetricsFromPaths($paths);
121122

122123
$this->handleBaseLine($input, $metricsCollection);
123124

@@ -147,6 +148,20 @@ protected function execute(InputInterface $input, OutputInterface $output): int
147148
return Command::SUCCESS;
148149
}
149150

151+
/**
152+
* Parses the path input to handle both single paths and comma-separated multiple paths.
153+
*
154+
* @param string $pathInput The input path(s) from the command argument
155+
* @return array<string> Array of paths to process
156+
*/
157+
private function parsePaths(string $pathInput): array
158+
{
159+
$paths = array_map('trim', explode(',', $pathInput));
160+
return array_filter($paths, function ($path) {
161+
return !empty($path);
162+
});
163+
}
164+
150165
/**
151166
* Handles the baseline option and loads the baseline file if provided.
152167
*

tests/Unit/Business/Cognitive/CognitiveMetricsCollectorTest.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,4 +327,32 @@ public function simpleMethod() {
327327
}
328328
}
329329
}
330+
331+
#[Test]
332+
public function testCollectFromPaths(): void
333+
{
334+
$paths = [
335+
'./tests/TestCode/Paginator.php',
336+
'./tests/TestCode/FileWithTwoClasses.php'
337+
];
338+
339+
$metricsCollection = $this->metricsCollector->collectFromPaths($paths, $this->configService->getConfig());
340+
341+
$this->assertInstanceOf(CognitiveMetricsCollection::class, $metricsCollection);
342+
$this->assertGreaterThan(2, $metricsCollection->count(), 'Should have metrics from both files');
343+
}
344+
345+
#[Test]
346+
public function testCollectFromPathsWithMixedTypes(): void
347+
{
348+
$paths = [
349+
'./tests/TestCode', // Directory
350+
'./tests/TestCode/Paginator.php' // File
351+
];
352+
353+
$metricsCollection = $this->metricsCollector->collectFromPaths($paths, $this->configService->getConfig());
354+
355+
$this->assertInstanceOf(CognitiveMetricsCollection::class, $metricsCollection);
356+
$this->assertGreaterThan(0, $metricsCollection->count(), 'Should have metrics from directory and file');
357+
}
330358
}

tests/Unit/Business/MetricsFacadeTest.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,20 @@ public function testGetCognitiveMetrics(): void
3434
$this->assertCount(23, $cognitiveMetrics);
3535
}
3636

37+
#[Test]
38+
public function testGetCognitiveMetricsFromPaths(): void
39+
{
40+
$paths = [
41+
$this->testCodePath . '/Paginator.php',
42+
$this->testCodePath . '/FileWithTwoClasses.php'
43+
];
44+
45+
$cognitiveMetrics = $this->metricsFacade->getCognitiveMetricsFromPaths($paths);
46+
47+
$this->assertNotEmpty($cognitiveMetrics);
48+
$this->assertGreaterThan(0, $cognitiveMetrics->count());
49+
}
50+
3751
#[Test]
3852
public function testLoadConfig(): void
3953
{

tests/Unit/Command/CognitiveMetricsCommandTest.php

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,21 @@ public function testAnalyse(): void
4848
$this->assertEquals(Command::SUCCESS, $tester->getStatusCode(), 'Command should succeed');
4949
}
5050

51+
#[Test]
52+
#[DataProvider('multiplePathsDataProvider')]
53+
public function testAnalyseWithMultiplePaths(string $path, string $description): void
54+
{
55+
$application = new Application();
56+
$command = $application->getContainer()->get(CognitiveMetricsCommand::class);
57+
$tester = new CommandTester($command);
58+
59+
$tester->execute([
60+
'path' => $path,
61+
]);
62+
63+
$this->assertEquals(Command::SUCCESS, $tester->getStatusCode(), $description);
64+
}
65+
5166
#[Test]
5267
#[DataProvider('reportDataProvider')]
5368
public function testAnalyseWithJsonReport(array $input, int $returnCode): void
@@ -176,7 +191,7 @@ public function testOutputWithoutOptions(): void
176191
$this->assertStringEqualsFile(__DIR__ . '/OutputWithoutOptions.txt', $tester->getDisplay(true));
177192
}
178193

179-
#[\PHPUnit\Framework\Attributes\DataProvider('configurationOutputProvider')]
194+
#[DataProvider('configurationOutputProvider')]
180195
public function testConfigurationOutput(string $configFile, string $expectedOutputFile, string $description): void
181196
{
182197
$application = new Application();
@@ -238,4 +253,35 @@ public static function configurationOutputProvider(): array
238253
],
239254
];
240255
}
256+
257+
/**
258+
* Data provider for multiple paths tests
259+
*
260+
* @return array<int, array{string, string}>
261+
*/
262+
public static function multiplePathsDataProvider(): array
263+
{
264+
return [
265+
'multiple files' => [
266+
__DIR__ . '/../../../src/Command/CognitiveMetricsCommand.php,' . __DIR__ . '/../../../src/Business/MetricsFacade.php',
267+
'Command should succeed with multiple files'
268+
],
269+
'multiple files with spaces' => [
270+
__DIR__ . '/../../../src/Command/CognitiveMetricsCommand.php, ' . __DIR__ . '/../../../src/Business/MetricsFacade.php, ' . __DIR__ . '/../../../src/Business/DirectoryScanner.php',
271+
'Command should succeed with multiple files and spaces'
272+
],
273+
'multiple directories' => [
274+
__DIR__ . '/../../../src/Command,' . __DIR__ . '/../../../src/Business',
275+
'Command should succeed with multiple directories'
276+
],
277+
'mixed paths' => [
278+
__DIR__ . '/../../../src/Command,' . __DIR__ . '/../../../src/Business/MetricsFacade.php',
279+
'Command should succeed with mixed directories and files'
280+
],
281+
'mixed paths with spaces' => [
282+
__DIR__ . '/../../../src/Command, ' . __DIR__ . '/../../../src/Business/MetricsFacade.php, ' . __DIR__ . '/../../../src/Business/DirectoryScanner.php',
283+
'Command should succeed with mixed paths and spaces'
284+
],
285+
];
286+
}
241287
}

0 commit comments

Comments
 (0)