-
Notifications
You must be signed in to change notification settings - Fork 58
Description
phpmd 3.x introduced a new CLI structure based on Symfony Console with an analyze subcommand. The current command generation in src/Tools/Analyzer/Phpmd.php produces a phpmd 2.x-style command that is incompatible with phpmd 3.x.
Current behavior
phpqa generates:
vendor/bin/phpmd "web/modules/custom","web/themes/custom" xml "/path/to/phpmd.xml.dist" --exclude /vendor/,/node_modules/,/tests/src/ --suffixes php,module,install,theme --reportfile "reports/codereview/phpmd.xml"
This fails with phpmd 3.x:
Command "web/modules/custom,web/themes/custom" is not defined.
phpmd 3.x interprets the first positional argument as a subcommand name.
Expected behavior
phpqa should generate a phpmd 3.x-compatible command:
vendor/bin/phpmd analyze
--exclude 'vendor/' --exclude 'node_modules/' --exclude 'tests/src/'
--suffixes php --suffixes module --suffixes install --suffixes theme
--ruleset "/path/to/phpmd.xml.dist"
--format xml
--reportfile-xml "reports/codereview/phpmd.xml"
-- "web/modules/custom" "web/themes/custom"
Breaking changes in phpmd 3.x CLI
| Area | phpmd 2.x | phpmd 3.x |
|---|---|---|
| Subcommand | none (positional source dirs first) | analyze required as first arg |
| Source dirs | first positional arg (comma-separated) | trailing args after -- separator |
| Format | second positional arg (xml/text) |
--format xml |
| Ruleset | third positional arg | --ruleset /path/to/ruleset.xml |
| Exclude | --exclude /vendor/,/node_modules/ (comma-separated, slash-delimited) |
--exclude '*vendor/*' (one flag per pattern, glob-style with asterisks) |
| Suffixes | --suffixes php,module,install (comma-separated, single flag) |
--suffixes php --suffixes module (one flag per extension) |
| Report file | --reportfile file.xml |
--reportfile-xml file.xml |
Proposed fix
Two files need updating:
src/IgnoredPaths.php — add a phpmd3() method that generates glob-style --exclude patterns:
public function phpmd3()
{
$parts = [];
foreach ($this->ignoreDirs as $dir) {
$dir = trim($dir, '/');
$parts[] = '--exclude ' . escapeshellarg('*' . $dir . '/*');
}
foreach ($this->ignoreFiles as $file) {
$file = ltrim($file, '/');
$parts[] = '--exclude ' . escapeshellarg('*' . $file);
}
return $parts ? ' ' . implode(' ', $parts) : '';
}src/Tools/Analyzer/Phpmd.php — rewrite __invoke() to use the phpmd 3.x command structure. Version detection via $this->toolVersionIs('>=', '3.0.0') can be used to maintain backward compatibility with phpmd 2.x if needed:
public function __invoke()
{
$this->tool->errorsType = $this->config->value('phpmd.ignoreParsingErrors') === true;
$rulesets = $this->config->pathsOrValues('phpmd.standard');
$extensions = array_filter(array_map('trim', explode(',', $this->config->csv('phpqa.extensions'))));
$suffixArgs = ' ' . implode(' ', array_map(function ($ext) {
return '--suffixes ' . $ext;
}, $extensions));
$args = [];
$args[] = 'analyze';
$args[] = $this->options->ignore->phpmd3();
$args[] = $suffixArgs;
$args['ruleset'] = \Edge\QA\escapePath(implode(',', $rulesets));
$args['format'] = $this->options->isSavedToFiles ? 'xml' : 'text';
if ($this->options->isSavedToFiles) {
$args['reportfile-xml'] = $this->tool->getEscapedXmlFile();
}
$args[] = '-- ' . $this->options->getAnalyzedDirs(' ');
return $args;
}Environment
- phpmd/phpmd: 3.x
- edgedesign/phpqa: dev-master
- PHP: 8.4