irstea/phpmd-config
A ready-made PHPMD ruleset for PHP projects, so you can drop in consistent mess-detection rules without hand-writing XML. Simplifies setup of PHP Mess Detector in CI or local tooling and keeps code-quality checks uniform across projects.
Architecture fit. This is not a Laravel package in any operational sense: no service provider, no autoloaded classes, no framework coupling, no runtime footprint. It is a PHPMD ruleset distribution — an XML artifact defining complexity, design, unused-code, and naming thresholds — published from an internal IRSTEA GitLab group. It never enters the application dependency graph, never affects composer install --no-dev, and places no constraint on PHP or Laravel versions at runtime. The correct mental model for a TPM is a coding-standard asset that informs a quality-gate policy decision, not a library to evaluate for adoption.
Integration feasibility. Mechanically trivial, procedurally awkward. The package is not on Packagist and lives on an institute-controlled GitLab host, so any composer require path requires a VCS repositories entry plus deploy keys or an access token — meaning every developer workstation and CI runner inherits a live credential dependency on an external research organisation's infrastructure. Because the payload is a single XML file, the integration collapses naturally to a file copy: vendor the ruleset into tools/phpmd/phpmd.xml and point vendor/bin/phpmd at it. That is the recommended shape. Note that running it presupposes PHPMD itself, which is a mature but comparatively declining tool next to PHPStan/Larastan, Pint, and Rector — adopting a ruleset for a tool the team does not otherwise run is new toolchain surface, not a config swap.
Technical risk. Low at runtime, medium-high on supply chain and process:
| Risk | Assessment |
|---|---|
| Availability | Builds fail if the host is unreachable or credentials rotate. A research institute's internal tooling is not a supported distribution channel. |
| Versioning | Zero stars, zero dependents implies no tags, no semver discipline, no downstream pressure. Unpinned dev-main means non-reproducible builds. |
| Staleness | Rulesets authored against an older PHP/PHPMD generation can reference rules removed in modern PHPMD, which errors on unknown rule refs — a red pipeline from a config file nobody touched. |
| Calibration | Thresholds tuned to IRSTEA's codebase, not ours. Expect a high false-positive rate on first run. |
| Licensing | No license declared in the metadata. Treat as "all rights reserved" until verified; forking without clarity is a compliance question, not a hypothetical. |
Key questions.
<rule ref> into external rulesets (hidden transitive config)?composer.json constraint?Stack fit. Laravel/PHP 8.x stacks absorb this cleanly as a dev-only quality gate, wired as a Composer script:
"scripts": {
"analyse:pmd": "phpmd app,src text tools/phpmd/phpmd.xml --exclude vendor,tests/fixtures"
}
No service provider, no publish step, no autoload impact. It complements PHPStan/Larastan and Pint rather than replacing them — PHPMD's niche is complexity and design smells (cyclomatic complexity, NPath, coupling, unused code), which PHPStan covers poorly. For Laravel-specific correctness and anti-patterns, Larastan and Enlightn remain the backbone; PHPMD is the third, optional gate.
Migration path. Additive, never a replacement:
phpmd.xml, adopt rule-by-rule, retire the local file only at parity.tools/phpmd/ with a header crediting the upstream source and pinned commit. This is roughly a 30-minute task and eliminates auth, availability, and versioning risk simultaneously. Keep upstream as a reference for future rule updates only.Compatibility. Validate against PHP 8.1–8.3 with PHPMD ≥ 2.15 (required for enums, attributes, readonly, match, first-class callables, and intersection types). Confirm the naming rules do not duplicate PHP_CodeSniffer/Pint output; disable PHPMD's style-adjacent rules if they do, keeping complexity and design only.
Sequencing.
--minimumpriority and no CI gate; measure violation volume and review the top 50 findings for signal vs. noise.--exclude legacy paths); document ownership and the update procedure.Maintenance. Runtime maintenance is effectively nil — a static file cannot page anyone. The real cost is stewardship: a named owner must track PHPMD releases and PHP upgrades, because un-owned config rots quietly. Within 18 months an unattended ruleset either stops parsing on a PHP bump or becomes so noisy that developers suppress everything. Assign an owner in CODEOWNERS and schedule a quarterly review.
Support. Assume zero upstream support. Zero stars, zero dependents, and a private GitLab host imply no issue triage, no SLA, and possibly no active maintainer. The escalation path is entirely internal: fork, patch, document. Do not represent this to stakeholders as a supported third-party dependency.
Scaling. Computationally trivial — seconds to low minutes for a few thousand files, scaling linearly with lines of code, not with traffic or tenants. For monorepos, shard PHPMD across packages in a CI matrix and cache the binary. The genuine constraint is social: onboarding N teams onto a sudden blocking gate produces a wave of @SuppressWarnings annotations that permanently erodes signal. Stage enforcement by directory and by rule class.
Failure modes.
| Failure | Impact | Mitigation |
|---|---|---|
| GitLab outage or credential rotation | Installs and CI fail across the org | Vendor/mirror the XML internally; never fetch at build time |
| Upstream force-push or re-tag | Non-reproducible builds | Pin to commit SHA; record it in the mirror README |
| PHPMD upgrade removes a rule | Config error, red pipeline | Pin PHPMD version; test config in a scheduled job before upgrading |
| Thresholds too strict | Mass suppression, lost signal | Baseline legacy code; gate changed files only; tune before enforcing |
| License prohibits redistribution | Legal exposure | Resolve licensing before mirroring; fall back to internal reimplementation of the thresholds |
| Overlap with Pint/PHPStan | Duplicate, conflicting findings | Keep complexity/design rules; drop naming and style rules from PHPMD |
Ramp-up. Low for engineers — under a day to run locally and interpret output; PHPMD messages are self-describing. The effort sits entirely in calibration and change management: choosing thresholds the team will accept, writing the baseline, and explaining why complexity gates exist. Budget 2–3 days of a senior engineer's time for trial, tuning, and CI wiring, plus ongoing quarterly review.
TPM bottom line. Leverage this as prior art, not a dependency. The decision it informs — do we gate merges on complexity metrics, and at what threshold — is a policy decision we should own internally. Adopt the artifact by copying it in, credit the source, verify the license, and keep the gate advisory until thresholds are proven. Cost of doing so: near zero. Cost of depending on it as-is: a silently broken quality gate nobody notices for months.
How can I help you explore Laravel packages today?