Skip to content

Commit fb7b3fc

Browse files
committed
phpmd - enable counting parsing errors
1 parent 5ca05e9 commit fb7b3fc

File tree

9 files changed

+47
-10
lines changed

9 files changed

+47
-10
lines changed

.phpqa.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ php-cs-fixer:
4545
phpmd:
4646
# alternatively you can use an array to define multiple rule sets (https://phpmd.org/documentation/index.html#using-multiple-rule-sets)
4747
standard: app/phpmd.xml
48+
ignoreParsingErrors: true
4849

4950
pdepend:
5051
# coverageReport: build/coverage-clover.xml

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,7 @@ Tool | Settings | Default Value | Your value
269269
[phpmetrics.composer](https://github.com/EdgedesignCZ/phpqa/pull/123) | phpmetrics v2 analyzes composer dependencies | `null` | Path to composer.json when the file is not included in `analyzedDirs`
270270
[pdepend.coverageReport](https://github.com/EdgedesignCZ/phpqa/pull/124) | Load Clover style CodeCoverage report | `null` | Path to report produced by PHPUnit's `--coverage-clover` option
271271
[phpmd.standard](http://phpmd.org/documentation/creating-a-ruleset.html) | Ruleset | [Edgedesign's standard](/app/phpmd.xml) | Path to ruleset. To specify [multiple rule sets](https://phpmd.org/documentation/index.html#using-multiple-rule-sets), you can use an array
272+
[phpcs.ignoreParsingErrors](https://github.com/EdgedesignCZ/phpqa/issues/230) | If parsing errors affect exit code, or just violations | `true` | Boolean value
272273
[phpcpd](https://github.com/sebastianbergmann/phpcpd/blob/de9056615da6c1230f3294384055fa7d722c38fa/src/CLI/Command.php#L136) | Minimum number of lines/tokens for copy-paste detection | 5 lines, 70 tokens |
273274
[phpstan](https://github.com/phpstan/phpstan#configuration) | Level, config file, memory limit | Level 0, `%currentWorkingDirectory%/phpstan.neon`, memoryLimit: null | Take a look at [phpqa config in tests/.ci](/tests/.ci/) |
274275
[phpunit.binary](https://github.com/EdgedesignCZ/phpqa/blob/4947416/.phpqa.yml#L40) | Phpunit binary | phpqa's phpunit | Path to phpunit executable in your project, typically [`vendor/bin/phpunit`](https://gitlab.com/costlocker/integrations/blob/master/basecamp/backend/.phpqa.yml#L2) |

src/RunningTool.php

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -83,24 +83,23 @@ public function getAllowedErrorsCount()
8383

8484
public function analyzeResult($hasNoOutput = false)
8585
{
86-
$xpath = $this->errorsXPath[$this->errorsType];
86+
$xpaths = $this->errorsXPath[$this->errorsType];
8787

8888
if ($hasNoOutput ||
8989
$this->hasOutput(OutputMode::RAW_CONSOLE_OUTPUT) ||
9090
$this->hasOutput(OutputMode::CUSTOM_OUTPUT_AND_EXIT_CODE)
9191
) {
9292
return $this->evaluteErrorsCount($this->process->getExitCode() ? 1 : 0);
93-
} elseif (!$xpath) {
93+
} elseif (!$xpaths) {
9494
return [true, ''];
9595
} elseif (!file_exists($this->getMainXml())) {
9696
return [$this->areErrorsIgnored(), "XML [{$this->getMainXml()}] not found"];
9797
}
9898

99-
list($isInvalidXml, $xpathOrError) = xmlXpath($this->getMainXml(), $xpath);
100-
if ($isInvalidXml) {
101-
return [$this->areErrorsIgnored(), $xpathOrError];
99+
list($errorsCount, $xmlError) = xmlXpaths($this->getMainXml(), (array) $xpaths);
100+
if ($xmlError) {
101+
return [$this->areErrorsIgnored(), $xmlError];
102102
}
103-
$errorsCount = count($xpathOrError);
104103
return $this->evaluteErrorsCount($errorsCount);
105104
}
106105

src/Tools/Analyzer/Phpmd.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,17 @@ class Phpmd extends \Edge\QA\Tools\Tool
77
public static $SETTINGS = array(
88
'optionSeparator' => ' ',
99
'xml' => ['phpmd.xml'],
10-
'errorsXPath' => '//pmd/file/violation',
10+
'errorsXPath' => [
11+
# ignoreParsingErrors => xpath
12+
true => '//pmd/file/violation',
13+
false => ['//pmd/file/violation', '//pmd/error'],
14+
],
1115
'composer' => 'phpmd/phpmd',
1216
);
1317

1418
public function __invoke()
1519
{
20+
$this->tool->errorsType = $this->config->value('phpmd.ignoreParsingErrors') === true;
1621
$rulesets = $this->config->pathsOrValues('phpmd.standard');
1722

1823
$args = array(

src/report.php

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,18 @@ function xmlToHtml(array $xmlDocuments, $style, $outputFile, array $params = [])
5151
}
5252
}
5353

54-
function xmlXpath($xmlFile, $xpathQuery)
54+
function xmlXpaths($xmlFile, array $xpathQueries)
5555
{
5656
convertPhpErrorsToExceptions();
57+
$matchedElements = 0;
5758
try {
5859
$xml = simplexml_load_file($xmlFile);
59-
return [false, $xml->xpath($xpathQuery)];
60+
foreach ($xpathQueries as $xpathQuery) {
61+
$matchedElements += count($xml->xpath($xpathQuery));
62+
}
63+
return [$matchedElements, ''];
6064
} catch (Exception $e) {
61-
return [true, $e->getMessage()];
65+
return [0, $e->getMessage()];
6266
}
6367
}
6468

tests/.ci/.phpqa.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ phpqa:
2626
- parallel-lint:0
2727
- deptrac
2828

29+
phpmd:
30+
ignoreParsingErrors: false
31+
2932
phpcs:
3033
standard:
3134
- PSR2

tests/Config/ConfigTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ public function testLoadDefaultConfig()
2222
assertThat($config->path('php-cs-fixer.config'), is(nullValue()));
2323
assertThat($config->path('phpmetrics.config'), is(nullValue()));
2424
assertThat($config->path('phpmd.standard'), is(nonEmptyString()));
25+
assertThat($config->value('phpmd.ignoreParsingErrors'), is(true));
2526
assertThat($config->value('phpstan.level'), identicalTo(0));
2627
assertThat($config->value('phpstan.memoryLimit'), is(nullValue()));
2728
assertThat($config->value('phpunit.config'), is(nullValue()));

tests/Error/errors.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@
22
<errors version="2.6.0">
33
<error severity="error">first</error>
44
<error severity="warning">second</error>
5+
<warning>third</warning>
56
</errors>
67

tests/RunningToolTest.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Edge\QA;
44

5+
/** @SuppressWarnings(PHPMD.TooManyPublicMethods) */
56
class RunningToolTest extends \PHPUnit_Framework_TestCase
67
{
78
private $errorsCountInXmlFile = 2;
@@ -75,6 +76,27 @@ public function testRuntimeSelectionOfErrorXpath()
7576
assertThat($tool->analyzeResult(), is([false, 1]));
7677
}
7778

79+
/** @dataProvider provideMultipleXpaths */
80+
public function testMultipleXpaths(array $xpaths, array $expectedResult)
81+
{
82+
$tool = new RunningTool('tool', [
83+
'xml' => ['tests/Error/errors.xml'],
84+
'errorsXPath' => [
85+
null => $xpaths,
86+
],
87+
'allowedErrorsCount' => 3,
88+
]);
89+
assertThat($tool->analyzeResult(), is($expectedResult));
90+
}
91+
92+
public function provideMultipleXpaths()
93+
{
94+
return [
95+
'multiple elements' => [['//errors/error', '//errors/warning'], [true, 2 + 1]],
96+
'invalid xpath' => [[null], [false, 'SimpleXMLElement::xpath(): Invalid expression']],
97+
];
98+
}
99+
78100
/** @dataProvider provideProcess */
79101
public function testAnalyzeExitCodeInCliMode($allowedErrors, $exitCode, array $expectedResult)
80102
{

0 commit comments

Comments
 (0)