Skip to content

Commit cbd78c5

Browse files
authored
Merge pull request #38 from anne-gaelle123inkt/master
Add support for multiple coverage files passed as argument
2 parents cfbf1ba + 0229df3 commit cbd78c5

File tree

10 files changed

+279
-119
lines changed

10 files changed

+279
-119
lines changed

README.md

+11-10
Original file line numberDiff line numberDiff line change
@@ -82,23 +82,24 @@ php vendor/bin/phpfci inspect coverage.xml --reportGitlab=reports/gitlab.errors.
8282
Text format to stdout:
8383
```shell script
8484
php vendor/bin/phpfci inspect coverage.xml
85+
php vendor/bin/phpfci inspect coverage1.xml coverage2.xml
8586
```
8687
```shell script
8788
php vendor/bin/phpfci inspect coverage.xml --reportText
8889
```
8990

9091
## Command line arguments
9192

92-
| Option | Values | Description |
93-
|-------------------------------|------------------------------------------|-------------------------------------------------------------------------|
94-
| `argument 1` | `inspect`, `baseline` | the command to execute. |
95-
| `argument 2` | `coverage.xml` | the phpunit clover coverage input file. |
96-
| `--reportGitlab=[<file>]` | filepath or if absent stdout | the file (or stdout) to write the gitlab format to. |
97-
| `--reportCheckstyle=[<file>]` | filepath or if absent stdout | the file (or stdout) to write the checkstyle format to. |
98-
| `--reportText=[<file>]` | filepath or if absent stdout | the file (or stdout) to write the checkstyle format to. |
99-
| `--config=<path-to-file>` | `phpfci.xml` | the path to the config file. |
100-
| `--baseDir=<path>` | defaults to directory of the output file | The root directory of the project, will be used to make paths relative. |
101-
| `--exit-code-on-failure` | - | Set exit code to `1` when there are failures. |
93+
| Option | Values | Description |
94+
|--------------------------------|------------------------------------------|-------------------------------------------------------------------------|
95+
| `argument 1` | `inspect`, `baseline` | the command to execute. |
96+
| `argument 2` [`argument 3`]... | `coverage.xml` [`coverage2.xml`] | the phpunit clover coverage input file(s). |
97+
| `--reportGitlab=[<file>]` | filepath or if absent stdout | the file (or stdout) to write the gitlab format to. |
98+
| `--reportCheckstyle=[<file>]` | filepath or if absent stdout | the file (or stdout) to write the checkstyle format to. |
99+
| `--reportText=[<file>]` | filepath or if absent stdout | the file (or stdout) to write the checkstyle format to. |
100+
| `--config=<path-to-file>` | `phpfci.xml` | the path to the config file. |
101+
| `--baseDir=<path>` | defaults to directory of the output file | The root directory of the project, will be used to make paths relative. |
102+
| `--exit-code-on-failure` | - | Set exit code to `1` when there are failures. |
102103

103104
Note: if no `--reportGitlab`, `--reportCheckstyle` or `--reportText` is set, it will default to `--reportText=php://stdout`
104105

src/Command/InspectCommand.php

+9-4
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use DigitalRevolution\CodeCoverageInspection\Renderer\TextRenderer;
1616
use JsonException;
1717
use Symfony\Component\Console\Command\Command;
18+
use Symfony\Component\Console\Input\InputArgument;
1819
use Symfony\Component\Console\Input\InputInterface;
1920
use Symfony\Component\Console\Input\InputOption;
2021
use Symfony\Component\Console\Output\OutputInterface;
@@ -25,7 +26,7 @@
2526
class InspectCommand extends Command
2627
{
2728
private ConfigFactory $configFactory;
28-
private string $schemaPath;
29+
private string $schemaPath;
2930

3031
public function __construct(string $name = null)
3132
{
@@ -38,7 +39,7 @@ protected function configure(): void
3839
{
3940
$this->setName("inspect")
4041
->setDescription("PHPUnit code coverage inspection")
41-
->addArgument('coverage', InputOption::VALUE_REQUIRED, 'Path to phpunit\'s coverage.xml')
42+
->addArgument('coverage', InputArgument::REQUIRED | InputArgument::IS_ARRAY, 'Path to phpunit\'s coverage.xml')
4243
->addOption('config', 'c', InputOption::VALUE_REQUIRED, 'Path to configuration file. Optional')
4344
->addOption('baseDir', '', InputOption::VALUE_REQUIRED, 'Base directory from where to determine the relative config paths')
4445
->addOption('reportGitlab', '', InputOption::VALUE_OPTIONAL, 'Gitlab output format. To file or if absent to stdout', false)
@@ -62,10 +63,14 @@ protected function execute(InputInterface $input, OutputInterface $output): int
6263
// gather data
6364
$domConfig = DOMDocumentFactory::getValidatedDOMDocument($inputConfig->getConfigPath(), $this->schemaPath);
6465
$config = InspectionConfigFactory::fromDOMDocument($inputConfig->getBaseDir(), $domConfig);
65-
$metrics = MetricsFactory::getFileMetrics(DOMDocumentFactory::getDOMDocument($inputConfig->getCoverageFilepath()));
6666

67+
$domDocuments = [];
68+
foreach ($inputConfig->getCoveragesFilepath() as $coverageFilepath) {
69+
$domDocuments[] = DOMDocumentFactory::getDOMDocument($coverageFilepath);
70+
}
71+
$metrics = MetricsFactory::getFilesMetrics($domDocuments);
6772
if (count($metrics) === 0) {
68-
$output->writeln("No metrics found in coverage file: " . $inputConfig->getCoverageFilepath());
73+
$output->writeln("No metrics found in coverage files: " . implode(', ', $inputConfig->getCoveragesFilepath()));
6974

7075
return Command::FAILURE;
7176
}

src/Lib/Config/ConfigFactory.php

+11-4
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,16 @@ class ConfigFactory
1515
*/
1616
public function createInspectConfig(InputInterface $input)
1717
{
18-
$configPath = FileUtil::getExistingFile($input->getOption('config') ?? FileUtil::findFilePath((string)getcwd(), self::CONFIG_FILES));
19-
$coverageFilepath = FileUtil::getExistingFile($input->getArgument('coverage'));
20-
$baseDir = $input->getOption('baseDir') ?? $configPath->getPath();
18+
$configPath = FileUtil::getExistingFile($input->getOption('config') ?? FileUtil::findFilePath((string)getcwd(), self::CONFIG_FILES));
19+
$coveragesFilepath = [];
20+
$coverageArgument = $input->getArgument('coverage');
21+
if (is_array($coverageArgument) === false) {
22+
return new ConfigViolation('Coverage argument should be an array');
23+
}
24+
foreach ($coverageArgument as $coverageFilepath) {
25+
$coveragesFilepath[] = FileUtil::getExistingFile($coverageFilepath);
26+
}
27+
$baseDir = $input->getOption('baseDir') ?? $configPath->getPath();
2128

2229
if (is_string($baseDir) === false) {
2330
return new ConfigViolation('--base-dir expecting a value string as argument');
@@ -46,7 +53,7 @@ public function createInspectConfig(InputInterface $input)
4653

4754
$exitCodeOnFailure = $input->getOption('exit-code-on-failure') !== false;
4855

49-
return new InspectConfig($coverageFilepath, $configPath, $baseDir, $reportGitlab, $reportCheckstyle, $reportText, $exitCodeOnFailure);
56+
return new InspectConfig($coveragesFilepath, $configPath, $baseDir, $reportGitlab, $reportCheckstyle, $reportText, $exitCodeOnFailure);
5057
}
5158

5259
/**

src/Lib/Config/InspectConfig.php

+17-10
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,28 @@
77

88
class InspectConfig
99
{
10-
private SplFileInfo $coverageFilepath;
10+
/** @var SplFileInfo[] */
11+
private array $coveragesFilepath;
1112
private SplFileInfo $configPath;
12-
private string $baseDir;
13-
private ?string $reportGitlab;
14-
private ?string $reportCheckstyle;
15-
private ?string $reportText;
16-
private bool $exitCodeOnFailure;
13+
private string $baseDir;
14+
private ?string $reportGitlab;
15+
private ?string $reportCheckstyle;
16+
private ?string $reportText;
17+
private bool $exitCodeOnFailure;
1718

19+
/**
20+
* @param SplFileInfo[] $coveragesFilepath
21+
*/
1822
public function __construct(
19-
SplFileInfo $coverageFilepath,
23+
array $coveragesFilepath,
2024
SplFileInfo $configPath,
2125
string $baseDir,
2226
?string $reportGitlab,
2327
?string $reportCheckstyle,
2428
?string $reportText,
2529
bool $exitCodeOnFailure
2630
) {
27-
$this->coverageFilepath = $coverageFilepath;
31+
$this->coveragesFilepath = $coveragesFilepath;
2832
$this->configPath = $configPath;
2933
$this->baseDir = $baseDir;
3034
$this->reportGitlab = $reportGitlab;
@@ -33,9 +37,12 @@ public function __construct(
3337
$this->exitCodeOnFailure = $exitCodeOnFailure;
3438
}
3539

36-
public function getCoverageFilepath(): SplFileInfo
40+
/**
41+
* @return SplFileInfo[]
42+
*/
43+
public function getCoveragesFilepath(): array
3744
{
38-
return $this->coverageFilepath;
45+
return $this->coveragesFilepath;
3946
}
4047

4148
public function getConfigPath(): SplFileInfo

src/Lib/IO/MetricsFactory.php

+27
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,33 @@ class MetricsFactory
1414
{
1515
private const COVERAGE_PERCENTAGE_PRECISION = 2;
1616

17+
/**
18+
* Get metrics information from coverage.xml files
19+
*
20+
* @param DOMDocument[] $documents
21+
*
22+
* @return FileMetric[]
23+
*/
24+
public static function getFilesMetrics(array $documents): array
25+
{
26+
$metrics = [];
27+
28+
foreach ($documents as $document) {
29+
$foundMetrics = self::getFileMetrics($document);
30+
foreach ($foundMetrics as $metric) {
31+
if (isset($metrics[$metric->getFilepath()])) {
32+
$previousMetric = $metrics[$metric->getFilepath()];
33+
if ($previousMetric->getCoverage() > $metric->getCoverage()) {
34+
continue;
35+
}
36+
}
37+
$metrics[$metric->getFilepath()] = $metric;
38+
}
39+
}
40+
41+
return $metrics;
42+
}
43+
1744
/**
1845
* Get metrics information from coverage.xml file
1946
*
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<coverage generated="1598702199">
3+
<project timestamp="1598702199">
4+
<!-- custom configured files -->
5+
<!-- coverage 60% -->
6+
<file name="/home/workspace/test/case/above-threshold.php">
7+
<metrics loc="11"
8+
ncloc="11"
9+
classes="0"
10+
methods="0"
11+
coveredmethods="0"
12+
conditionals="0"
13+
coveredconditionals="0"
14+
statements="100"
15+
coveredstatements="60"
16+
elements="0"
17+
coveredelements="0"/>
18+
</file>
19+
<!-- coverage 50% -->
20+
<file name="/home\workspace/test/case\below-threshold.php">
21+
<metrics loc="11"
22+
ncloc="11"
23+
classes="0"
24+
methods="0"
25+
coveredmethods="0"
26+
conditionals="0"
27+
coveredconditionals="0"
28+
statements="100"
29+
coveredstatements="50"
30+
elements="0"
31+
coveredelements="0"/>
32+
</file>
33+
34+
<!-- coverage 90% -->
35+
<file name="\home/workspace/test/case\unnecessary-custom-rule.php">
36+
<metrics loc="11"
37+
ncloc="11"
38+
classes="0"
39+
methods="0"
40+
coveredmethods="0"
41+
conditionals="0"
42+
coveredconditionals="0"
43+
statements="100"
44+
coveredstatements="90"
45+
elements="0"
46+
coveredelements="0"/>
47+
</file>
48+
49+
<!-- coverage 90% and uncovered methods -->
50+
<file name="/home/workspace/test/case/uncovered-method.php">
51+
<line num="16" type="method" name="__construct" visibility="public" complexity="1" crap="2" count="0"/>
52+
<line num="30" type="method" name="myMethod" visibility="public" complexity="3" crap="3" count="2"/>
53+
<metrics loc="11"
54+
ncloc="11"
55+
classes="0"
56+
methods="0"
57+
coveredmethods="0"
58+
conditionals="0"
59+
coveredconditionals="0"
60+
statements="100"
61+
coveredstatements="90"
62+
elements="0"
63+
coveredelements="0"/>
64+
</file>
65+
66+
<!-- coverage 90% and ignore uncovered methods -->
67+
<file name="/home/workspace/test/case/ignored-uncovered-method.php">
68+
<line num="16" type="method" name="__construct" visibility="public" complexity="1" crap="2" count="0"/>
69+
<metrics loc="11"
70+
ncloc="11"
71+
classes="0"
72+
methods="0"
73+
coveredmethods="0"
74+
conditionals="0"
75+
coveredconditionals="0"
76+
statements="100"
77+
coveredstatements="90"
78+
elements="0"
79+
coveredelements="0"/>
80+
</file>
81+
82+
<!-- coverage same test 70%, will be ignored, coverage at 90% in coverage.xml -->
83+
<file name="/home/workspace/test\case/result-same-test.php">
84+
<metrics loc="11"
85+
ncloc="11"
86+
classes="0"
87+
methods="0"
88+
coveredmethods="0"
89+
conditionals="0"
90+
coveredconditionals="0"
91+
statements="100"
92+
coveredstatements="70"
93+
elements="0"
94+
coveredelements="0"/>
95+
</file>
96+
</project>
97+
</coverage>

tests/Functional/Command/InspectCommand/Data/coverage.xml

+2-67
Original file line numberDiff line numberDiff line change
@@ -58,72 +58,8 @@
5858
elements="0"
5959
coveredelements="0"/>
6060
</file>
61-
62-
<!-- custom configured files -->
63-
<!-- coverage 60% -->
64-
<file name="/home/workspace/test/case/above-threshold.php">
65-
<metrics loc="11"
66-
ncloc="11"
67-
classes="0"
68-
methods="0"
69-
coveredmethods="0"
70-
conditionals="0"
71-
coveredconditionals="0"
72-
statements="100"
73-
coveredstatements="60"
74-
elements="0"
75-
coveredelements="0"/>
76-
</file>
77-
<!-- coverage 50% -->
78-
<file name="/home\workspace/test/case\below-threshold.php">
79-
<metrics loc="11"
80-
ncloc="11"
81-
classes="0"
82-
methods="0"
83-
coveredmethods="0"
84-
conditionals="0"
85-
coveredconditionals="0"
86-
statements="100"
87-
coveredstatements="50"
88-
elements="0"
89-
coveredelements="0"/>
90-
</file>
91-
92-
<!-- coverage 90% -->
93-
<file name="\home/workspace/test/case\unnecessary-custom-rule.php">
94-
<metrics loc="11"
95-
ncloc="11"
96-
classes="0"
97-
methods="0"
98-
coveredmethods="0"
99-
conditionals="0"
100-
coveredconditionals="0"
101-
statements="100"
102-
coveredstatements="90"
103-
elements="0"
104-
coveredelements="0"/>
105-
</file>
106-
107-
<!-- coverage 90% and uncovered methods -->
108-
<file name="/home/workspace/test/case/uncovered-method.php">
109-
<line num="16" type="method" name="__construct" visibility="public" complexity="1" crap="2" count="0"/>
110-
<line num="30" type="method" name="myMethod" visibility="public" complexity="3" crap="3" count="2"/>
111-
<metrics loc="11"
112-
ncloc="11"
113-
classes="0"
114-
methods="0"
115-
coveredmethods="0"
116-
conditionals="0"
117-
coveredconditionals="0"
118-
statements="100"
119-
coveredstatements="90"
120-
elements="0"
121-
coveredelements="0"/>
122-
</file>
123-
124-
<!-- coverage 90% and ignore uncovered methods -->
125-
<file name="/home/workspace/test/case/ignored-uncovered-method.php">
126-
<line num="16" type="method" name="__construct" visibility="public" complexity="1" crap="2" count="0"/>
61+
<!-- coverage same test 90% -->
62+
<file name="/home/workspace/test\case/result-same-test.php">
12763
<metrics loc="11"
12864
ncloc="11"
12965
classes="0"
@@ -136,6 +72,5 @@
13672
elements="0"
13773
coveredelements="0"/>
13874
</file>
139-
14075
</project>
14176
</coverage>

0 commit comments

Comments
 (0)