Skip to content

fix(NO-TASK): Replace PSR2R namespace sniffs removed upstream - #42

Merged
aaronware merged 1 commit into
mainfrom
fix/psr2r-removed-sniffs
Aug 3, 2026
Merged

fix(NO-TASK): Replace PSR2R namespace sniffs removed upstream#42
aaronware merged 1 commit into
mainfrom
fix/psr2r-removed-sniffs

Conversation

@aaronware

Copy link
Copy Markdown
Contributor

The problem

composer.json requires fig-r/psr2r-sniffer: ^2.0.0, but the Linchpin ruleset still referenced two sniffs that psr2r 2.x deleted:

  • PSR2R.Namespaces.UnusedUseStatement
  • PSR2R.Namespaces.UseInAlphabeticalOrder

Namespaces.NoInlineFullyQualifiedClassName is the only sniff left in that category upstream.

phpcs treats an unresolvable rule ref as a hard error, not a warning, so the entire standard failed to load before running a single check:

ERROR: Referenced sniff "PSR2R.Namespaces.UnusedUseStatement" does not exist.
ERROR: Referenced sniff "PSR2R.Namespaces.UseInAlphabeticalOrder" does not exist.

Consumers cannot work around this on their side either — phpcs resolves refs before applying <exclude>, so excluding the dead sniffs in a project's phpcs.xml.dist still aborts (it just prints the error twice).

Linchpin-Minimum never referenced them, which is why linchpin-blocks was unaffected.

The fix

Swapped both to their Slevomat equivalents. slevomat/coding-standard is a hard dependency of fig-r/psr2r-sniffer 2.x, so it is guaranteed present wherever the ^2.0.0 constraint resolves — no new dependency.

UnusedUses is configured with searchAnnotations: true. Without it the sniff flags imports referenced only from @param/@return/@var docblocks — which PHPStan then reports as unresolvable types. This was not theoretical: it fired on a real @return array<int,REST_Interface> while testing.

Why this needs releasing promptly

mantle's composer.json says 1.1.8 while its composer.lock still pins v1.1.6 with psr2r 0.6.4, where the old sniffs exist. Its composer phpcs works today and breaks the moment that lock is refreshed. Same exposure for any repo on the full Linchpin ruleset.

Verification

Confirmed against a real consumer (linchpin/packagist-plugin-manager, which is adopting the standard in linchpin/packagist-plugin-manager#TBD): the ruleset now loads and runs, where before it aborted.

The repo's own PHPUnit suite errors on WordPressCS\WordPress\AbstractArrayAssignmentRestrictionsSniff not found in SlowMetaQuerySniff — I verified this is pre-existing by stashing this change and re-running: identical failure. Unrelated to this PR, but worth a separate look.

🤖 Generated with Claude Code

composer.json requires fig-r/psr2r-sniffer ^2.0.0, but the Linchpin ruleset
still referenced PSR2R.Namespaces.UnusedUseStatement and
PSR2R.Namespaces.UseInAlphabeticalOrder. psr2r 2.x deleted both in favour of
Slevomat's implementations, leaving NoInlineFullyQualifiedClassName as the only
sniff in that category.

phpcs treats an unresolvable rule ref as a hard error, so the whole standard
failed to load:

    ERROR: Referenced sniff "PSR2R.Namespaces.UnusedUseStatement" does not exist

Consumers could not work around it either — phpcs resolves refs before applying
<exclude>, so excluding the dead sniffs in a project's phpcs.xml.dist still
aborts. Linchpin-Minimum never referenced them, which is why linchpin-blocks
was unaffected.

Swapped both to their Slevomat equivalents. slevomat/coding-standard is a hard
dependency of psr2r-sniffer 2.x, so it is always installed alongside it.

UnusedUses is configured with searchAnnotations so an import referenced only
from a @param/@return/@var docblock still counts as used — without it the sniff
tells you to delete imports that PHPStan then reports as unresolvable types.

Note for consumers: mantle's composer.json says 1.1.8 while its composer.lock
still pins v1.1.6 with psr2r 0.6.4, where the old sniffs exist. Its phpcs run
works today and breaks the moment that lock is refreshed, so this wants
releasing before any repo on the full Linchpin ruleset updates.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@aaronware
aaronware merged commit 69c063f into main Aug 3, 2026
1 check passed
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