Skip to content

fix(phpmd): narrow the UnusedFormalParameter exclusion to */lib/Migration/* - #266

Merged
rubenvdlinde merged 1 commit into
developmentfrom
fix/narrow-migration-exclude-pattern
Aug 5, 2026
Merged

fix(phpmd): narrow the UnusedFormalParameter exclusion to */lib/Migration/*#266
rubenvdlinde merged 1 commit into
developmentfrom
fix/narrow-migration-exclude-pattern

Conversation

@rubenvdlinde

Copy link
Copy Markdown
Contributor

The trap

*/Migration/* in phpmd-unusedparams.xml is a path-segment pattern, not a directory anchor. PDepend compiles an exclude-pattern into an unanchored regexInput\ExcludePathFilter::__construct preg_quote()s the pattern and then turns \* into .*:

$this->relative = '(' . str_replace('\*', '.*', join('|', $quoted)) . ')i';

So */Migration/* matches any path containing a /Migration/ segment — lib/Service/Migration/, lib/Command/Migration/, any future lib/*/Migration/ — not just the app's IMigrationStep implementations. Those are ordinary classes with no interface-mandated signature, so a genuine unused parameter in one would never be reported and the run would still look clean.

Probe matrix — measured, not reasoned

PHPMD 2.15.0 / PHP 8.4.22 inside nextcloud:latest, three probe classes dropped onto a throwaway copy:

probe */Migration/* */lib/Migration/*
lib/Migration/… — UnusedFormalParameter not reported not reported (intended)
lib/Migration/… — ElseExpression (leg 1) reported reported (leg 1 unaffected)
lib/Service/… — UnusedFormalParameter reported reported
lib/Service/Migration/… — UnusedFormalParameter NOT REPORTED reported ← the leak

The IMigrationStep exclusion still does exactly its job: a step that cannot drop changeSchema / preSchemaChange / postSchemaChange's three mandated parameters is still spared, and leg 1 still analyses lib/Migration for every other rule.

Numbers: unchanged

A grep for /Migration/ directories outside lib/Migration/ found none in this repo, so nothing was actually being swallowed — as expected. Shipped findings and TRUE findings (measured with every @SuppressWarnings stripped on a throwaway copy) are identical before and after. The trap goes regardless, because the next lib/Service/Migration/ refactor would have walked straight into it.

One process note

The first draft of the explanatory comment contained a literal <- inside the <description>, which made the ruleset unparseable. PHPMD then exited 1 and reported nothing — and "no findings printed" is exactly what a clean run looks like to a grep. It was caught only by reading the exit code directly. The XML is validated as part of the check now.

No threshold changed, no rule removed, no baseline added (there is none, and there must not be — PHPMD auto-discovers phpmd.baseline.xml).

🤖 Generated with Claude Code

…on/* to */lib/Migration/*

`*/Migration/*` is a path-SEGMENT pattern, not a directory anchor. PDepend
compiles an exclude-pattern into an UNANCHORED regex — Input\ExcludePathFilter
preg_quote()s the pattern and then turns `\*` into `.*` — so it matches ANY path
containing a `/Migration/` segment: `lib/Service/Migration/`,
`lib/Command/Migration/`, any future `lib/*/Migration/`. Those are ordinary
classes with no interface-mandated signature, and a genuine unused parameter in
one of them would never be reported while the run still looked clean.

PROBE MATRIX, PHPMD 2.15.0 / PHP 8.4.22, three probe classes on a throwaway copy:

  probe                                   */Migration/*   */lib/Migration/*
  lib/Migration/…            UFP          not reported    not reported  (intended)
  lib/Migration/…            Else (leg 1) reported        reported      (leg 1 unaffected)
  lib/Service/…              UFP          reported        reported
  lib/Service/Migration/…    UFP          NOT REPORTED    reported      (the leak)

The IMigrationStep exclusion still does exactly its job — a step that cannot drop
changeSchema/preSchemaChange/postSchemaChange's three mandated parameters is
still spared — and leg 1 still analyses lib/Migration for every other rule.

Real numbers: UNCHANGED. A grep for `/Migration/` directories outside
lib/Migration/ found none in this repo, so nothing was actually being swallowed.
The trap goes regardless.

One process note worth recording: the first draft of this comment contained a
literal `<-` inside the <description>, which made the ruleset UNPARSEABLE. PHPMD
then exited 1 and reported NOTHING — and "no findings printed" is exactly what a
clean run looks like to a grep. It was caught only by reading the exit code
directly. The XML is validated as part of the check now.
@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/larpingapp @ e86917f

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
check-specs
test-l10n
composer ✅ 101/101
npm ✅ 537/537
PHPUnit
Newman
Playwright
Hydra gates

Quality workflow — 2026-08-05 15:47 UTC

Download the full PDF report from the workflow artifacts.

@rubenvdlinde
rubenvdlinde merged commit 6313aef into development Aug 5, 2026
30 of 36 checks passed
@rubenvdlinde
rubenvdlinde deleted the fix/narrow-migration-exclude-pattern branch August 5, 2026 15:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant