diff --git a/composer.json b/composer.json index 59d9df80..681c2237 100644 --- a/composer.json +++ b/composer.json @@ -27,7 +27,7 @@ "phpcs": "./vendor/bin/phpcs --standard=phpcs.xml", "phpcs:fix": "./vendor/bin/phpcbf --standard=phpcs.xml", "phpcs:output": "./vendor/bin/phpcs --standard=phpcs.xml --report=json lib/ 2>/dev/null | tail -1 > phpcs-output.json", - "phpmd": "./vendor/bin/phpmd lib text phpmd.xml --baseline-file phpmd.baseline.xml", + "phpmd": "E=0; ./vendor/bin/phpmd lib text phpmd.xml --baseline-file phpmd.baseline.xml || E=$?; ./vendor/bin/phpmd lib text phpmd-unusedparams.xml --baseline-file phpmd.baseline.xml || E=$?; exit $E", "phpmetrics": "./vendor/bin/phpmetrics --report-html=phpmetrics lib/", "phpmetrics:violations": "./vendor/bin/phpmetrics --violations-xml=phpmetrics/violations.xml lib/", "psalm": "if [ -f vendor/bin/psalm ]; then ./vendor/bin/psalm --threads=1 --no-cache; else echo 'Psalm not installed, skipping...'; fi", diff --git a/phpmd-unusedparams.xml b/phpmd-unusedparams.xml new file mode 100644 index 00000000..a109ae4e --- /dev/null +++ b/phpmd-unusedparams.xml @@ -0,0 +1,40 @@ + + + + + Second PHPMD leg: UnusedFormalParameter only. + + This rule lives in its own ruleset because PHPMD honours <exclude-pattern> + ONLY as a direct child of <ruleset>; nested inside a <rule> it is parsed and + discarded (ConductionNL/.github#155). A direct child, however, is applied by + PDepend at file-collection time and drops the file from EVERY rule in the + ruleset. Isolating UnusedFormalParameter here means the lib/Migration + exclusion applies to this rule and this rule ALONE - every other rule still + analyses lib/Migration in the main leg. + + Why lib/Migration is excluded from THIS rule: OCP\Migration\IMigrationStep + mandates changeSchema(IOutput $output, Closure $schemaClosure, array $options) + and preSchemaChange/postSchemaChange with the same three parameters. A step + that needs none of them still cannot drop them. The signature cannot change. + + The pattern is */lib/Migration/* and deliberately NOT */Migration/* or + *Migration*. Those broader forms silently swallow ORDINARY CLASSES that merely + have "Migration" in their path - measured on openconnector, */Migration/* hides + a genuine finding in lib/Service/Migration/, and *Migration* additionally hides + every lib/Service/MigrationService.php, lib/Controller/MigrationController.php + and lib/Db/*Migration*.php. Those have no mandated signature and must stay + analysed. Only the app's own lib/Migration/ directory holds IMigrationStep + implementations, so only that directory is exempted. + + Both legs must always run - see the "phpmd" script in composer.json, which + keeps the worst exit code rather than letting the first leg short-circuit + the second. + + + */lib/Migration/* + + + diff --git a/phpmd.xml b/phpmd.xml index ee029854..5cea97ec 100644 --- a/phpmd.xml +++ b/phpmd.xml @@ -97,7 +97,27 @@ - - *Migration* - +