mirror of
https://github.com/Vateron-Media/XC_VM.git
synced 2026-10-26 11:03:14 +01:00
Enable SlevomatCodingStandard.Namespaces.UnusedUses so a dangling `use` (e.g. left behind by a rename or refactor, like ModuleLoader's stale RouteProviderInterface import) gets caught by `make cs` instead of only an IDE hint. searchAnnotations=true is required, not optional: several core interfaces (StreamMiddlewareProviderInterface, MigratableInterface) reference their imported type only inside a @return/@param docblock, and without that property the sniff's fixer removes the import and silently breaks PHPStan's docblock type resolution. Also removes 10 genuinely dead imports across 7 files surfaced once the rule was correctly configured.
392 lines
20 KiB
XML
392 lines
20 KiB
XML
<?xml version="1.0" encoding="UTF-8"?>
|
|
<ruleset name="XC_VM PSR-12"
|
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
xsi:noNamespaceSchemaLocation="../../vendor/squizlabs/php_codesniffer/phpcs.xsd">
|
|
<description>
|
|
PSR-12 strict coding standard
|
|
Run via `make cs` (report) / `make cs-fix` (auto-fix, = phpcbf).
|
|
</description>
|
|
|
|
<!-- Analyzed set mirrors the old cs-fixer Finder (paths passed on the CLI by
|
|
the Makefile; these are the exclusions). -->
|
|
<exclude-pattern>*/vendor/*</exclude-pattern>
|
|
<exclude-pattern>*/Infrastructure/Tmdb/lib/*</exclude-pattern>
|
|
<exclude-pattern>*/tmp/*</exclude-pattern>
|
|
<exclude-pattern>*/backups/*</exclude-pattern>
|
|
<exclude-pattern>*/Public/Views/*</exclude-pattern>
|
|
<exclude-pattern>*/Modules/*/views/*</exclude-pattern>
|
|
|
|
<!-- Analyse PHP only. phpcbf's default extension list also covers js/css
|
|
(legacy tokenizers), which would otherwise reformat those files. -->
|
|
<arg name="extensions" value="php"/>
|
|
|
|
<!-- Indentation is a real tab (rendered 4 wide), not PSR-12's 4 spaces. -->
|
|
<arg name="tab-width" value="4"/>
|
|
|
|
<!-- Code MUST follow PSR-12, EXCEPT brace placement: this project uses
|
|
K&R / one-true-brace (opening brace on the SAME line), not PSR-12's
|
|
Allman placement. The Allman-enforcing sniffs are excluded here and the
|
|
K&R sniffs are added at the end of this ruleset. -->
|
|
<rule ref="PSR12">
|
|
<exclude name="Generic.Functions.OpeningFunctionBraceBsdAllman"/>
|
|
<exclude name="PSR2.Classes.ClassDeclaration.OpenBraceNewLine"/>
|
|
<exclude name="Generic.WhiteSpace.DisallowTabIndent"/>
|
|
<!-- Multi-line function declarations also keep the brace on the same
|
|
line (K&R), so drop PSR-12's "brace on new line" for them. -->
|
|
<exclude name="Squiz.Functions.MultiLineFunctionDeclaration.BraceOnSameLine"/>
|
|
|
|
<!-- ── Temporarily disabled PSR-family sniffs (technical-debt ratchet) ──
|
|
These come from the PSR12 parent, so they can only be switched off
|
|
here with <exclude>. To ENABLE one: DELETE its exclude line, run
|
|
`make cs`, fix the fallout, commit. (…N) = current violation count. -->
|
|
<exclude name="PSR1.Methods.CamelCapsMethodName"/> <!-- 40: legacy snake_case methods -->
|
|
<exclude name="PSR1.Classes.ClassDeclaration"/> <!-- 2: legacy non-namespaced (XC_Bootstrap) -->
|
|
<exclude name="PSR2.Classes.PropertyDeclaration.Underscore"/> <!-- 2: legacy _property names -->
|
|
<exclude name="PSR2.Methods.MethodDeclaration.Underscore"/> <!-- 12: legacy _method names -->
|
|
<exclude name="PSR2.ControlStructures.SwitchDeclaration.TerminatingComment"/> <!-- 6: add `// no break` -->
|
|
<exclude name="PSR12.Files.FileHeader.IncorrectOrder"/> <!-- 29: header declare/namespace/use order -->
|
|
<exclude name="Squiz.Classes.ValidClassName"/> <!-- 1: legacy class name -->
|
|
<exclude name="PSR1.Files.SideEffects"/> <!-- 22: declares symbols AND runs code -->
|
|
|
|
<!-- Line length (3480 warnings across 284 of 557 analysed files). Muted
|
|
for REPORT NOISE only: it is a warning, and ignore_warnings_on_exit
|
|
below already keeps it from failing the run. NOT part of the ratchet
|
|
above: Generic.Files.LineLength has no fixer (it only calls
|
|
addWarning), so neither phpcbf nor PHP-CS-Fixer nor Rector can wrap
|
|
these lines — re-enabling it would mean splitting them by hand. The
|
|
one sniff that could help, PEAR.Functions.FunctionCallSignature, is
|
|
permanently disabled below because it cannot converge under tabs. -->
|
|
<exclude name="Generic.Files.LineLength"/>
|
|
|
|
<!-- ── PERMANENTLY disabled — DO NOT ENABLE ──
|
|
Space-alignment sniff that cannot converge under tab indentation:
|
|
LineIndent counts SPACES ("expected 12, found 8" on 3 tabs) and
|
|
FirstExpressionLine/CloseParenthesisLine force the expanded PSR-12
|
|
layout, so phpcbf oscillates → FAILED TO FIX. The tab-safe
|
|
equivalent PEAR.ControlStructures.MultiLineCondition is enabled
|
|
below and enforces the same multi-line `if` layout. See 689663d4. -->
|
|
<exclude name="PSR12.ControlStructures.ControlStructureSpacing"/>
|
|
</rule>
|
|
|
|
<!-- Indentation MUST use tabs (one tab per level), not PSR-12's 4 spaces. -->
|
|
<rule ref="Generic.WhiteSpace.DisallowSpaceIndent"/>
|
|
<rule ref="Generic.WhiteSpace.ScopeIndent">
|
|
<properties>
|
|
<property name="indent" value="4"/>
|
|
<property name="tabIndent" value="true"/>
|
|
</properties>
|
|
</rule>
|
|
|
|
<!-- Generic rules -->
|
|
|
|
<!-- All values in multiline arrays must be indented with 4 spaces. -->
|
|
<rule ref="Generic.Arrays.ArrayIndent"/>
|
|
|
|
<!-- The short array syntax MUST be used to define arrays. -->
|
|
<rule ref="Generic.Arrays.DisallowLongArraySyntax"/>
|
|
|
|
<!-- There MUST NOT be duplicate class names. -->
|
|
<rule ref="Generic.Classes.DuplicateClassName"/>
|
|
|
|
<!-- The final keyword on methods MUST be omitted in final classes. -->
|
|
<rule ref="Generic.CodeAnalysis.UnnecessaryFinalModifier"/>
|
|
|
|
<!-- Detects unnecessary overridden methods that simply call their parent. -->
|
|
<rule ref="Generic.CodeAnalysis.UselessOverridingMethod"/>
|
|
|
|
<!-- There MUST be one whitespace after a type casting operator. -->
|
|
<rule ref="Generic.Formatting.SpaceAfterCast"/>
|
|
|
|
<!-- Checks the cyclomatic complexity (McCabe) for functions.
|
|
DISABLED — MaxExceeded(201 errors) + TooHigh(190 warnings). Complexity is
|
|
already ratcheted by the CRAP gate (.claude/quartermaster/crap.json,
|
|
ceiling 6 against main), which blocks NEW complexity per function; this
|
|
sniff only restated the existing backlog. Uncomment to surface it again,
|
|
then refactor the fallout. -->
|
|
<!--
|
|
<rule ref="Generic.Metrics.CyclomaticComplexity">
|
|
<exclude name="Generic.Metrics.CyclomaticComplexity.MaxExceeded"/>
|
|
</rule>
|
|
-->
|
|
|
|
<!-- Checks the nesting level for methods.
|
|
DISABLED — MaxExceeded(2 errors) + TooHigh(84 warnings). Same reasoning as
|
|
the complexity sniff above; uncomment to enforce. -->
|
|
<!--
|
|
<rule ref="Generic.Metrics.NestingLevel">
|
|
<exclude name="Generic.Metrics.NestingLevel.MaxExceeded"/>
|
|
</rule>
|
|
-->
|
|
|
|
<!-- Checks that abstract classes are prefixed by Abstract.
|
|
DISABLED (2) — uncomment to enable. -->
|
|
<!-- <rule ref="Generic.NamingConventions.AbstractClassNamePrefix"/> -->
|
|
|
|
<!-- Ensures method and functions are named correctly.
|
|
DISABLED (187) — legacy snake_case function names; renames break
|
|
callers. Uncomment to enable. -->
|
|
<!-- <rule ref="Generic.NamingConventions.CamelCapsFunctionName"/> -->
|
|
|
|
<!-- Checks that interfaces are suffixed by Interface.
|
|
DISABLED (1) — uncomment to enable. -->
|
|
<!-- <rule ref="Generic.NamingConventions.InterfaceNameSuffix"/> -->
|
|
|
|
<!-- Checks that traits are suffixed by Trait.
|
|
DISABLED (1) — uncomment to enable. -->
|
|
<!-- <rule ref="Generic.NamingConventions.TraitNameSuffix"/> -->
|
|
|
|
<!-- The backtick operator MUST NOT be used. -->
|
|
<rule ref="Generic.PHP.BacktickOperator"/>
|
|
|
|
<!-- Deprecated PHP functions MUST be avoided.
|
|
DISABLED (1) — uncomment to enable. -->
|
|
<!-- <rule ref="Generic.PHP.DeprecatedFunctions"/> -->
|
|
|
|
<!-- The PHP `goto` language construct SHOULD NOT be used. -->
|
|
<rule ref="Generic.PHP.DiscourageGoto"/>
|
|
|
|
<!-- Alias functions SHOULD NOT be used. -->
|
|
<rule ref="Generic.PHP.ForbiddenFunctions">
|
|
<properties>
|
|
<property name="forbiddenFunctions" type="array">
|
|
<element key="chop" value="rtrim"/>
|
|
<element key="close" value="closedir"/>
|
|
<element key="compact" value="null"/>
|
|
<element key="delete" value="unset"/>
|
|
<element key="doubleval" value="floatval"/>
|
|
<element key="extract" value="null"/>
|
|
<element key="fputs" value="fwrite"/>
|
|
<element key="ini_alter" value="ini_set"/>
|
|
<element key="is_double" value="is_float"/>
|
|
<element key="is_integer" value="is_int"/>
|
|
<element key="is_long" value="is_int"/>
|
|
<element key="is_real" value="is_float"/>
|
|
<element key="join" value="implode"/>
|
|
<element key="key_exists" value="array_key_exists"/>
|
|
<element key="pos" value="current"/>
|
|
<element key="settype" value="null"/>
|
|
<element key="show_source" value="highlight_file"/>
|
|
<element key="sizeof" value="count"/>
|
|
<element key="strchr" value="strstr"/>
|
|
</property>
|
|
</properties>
|
|
</rule>
|
|
|
|
<!-- Throws an error or warning when any code prefixed with an asperand is encountered.
|
|
DISABLED (473) — uncomment to enable. Not a style fix: each `@` is either
|
|
deliberate (@unlink on a maybe-missing file) or masking a real error, so
|
|
they have to be judged one at a time, with a test per behaviour change. -->
|
|
<!-- <rule ref="Generic.PHP.NoSilencedErrors"/> -->
|
|
|
|
<!-- Checks that the `strict_types` has been declared. -->
|
|
<!-- <rule ref="Generic.PHP.RequireStrictTypes"/> -->
|
|
|
|
<!-- The constant `PHP_SAPI` SHOULD be used instead of the `php_sapi_name()` function.
|
|
DISABLED (7) — uncomment to enable (mechanical: php_sapi_name() → PHP_SAPI). -->
|
|
<!-- <rule ref="Generic.PHP.SAPIUsage"/> -->
|
|
|
|
<!-- Checks that two strings are not concatenated together; suggests using one string instead.
|
|
DISABLED (41) — uncomment to enable. -->
|
|
<!-- <rule ref="Generic.Strings.UnnecessaryStringConcat"/> -->
|
|
|
|
<!-- Check & fix whitespace on the inside of arbitrary parentheses. -->
|
|
<rule ref="Generic.WhiteSpace.ArbitraryParenthesesSpacing"/>
|
|
|
|
<!-- Verifies spacing between the spread operator and the variable/function call it applies to. -->
|
|
<rule ref="Generic.WhiteSpace.SpreadOperatorSpacingAfter"/>
|
|
|
|
<!-- PEAR rules -->
|
|
|
|
<!-- Verifies that control statements conform to their coding standards. -->
|
|
<rule ref="PEAR.ControlStructures.ControlSignature"/>
|
|
|
|
<!-- Ensure multi-line `if` conditions are defined correctly. Tab-safe
|
|
replacement for the disabled PSR12 ControlStructureSpacing (see the
|
|
PSR12 exclude block above). -->
|
|
<rule ref="PEAR.ControlStructures.MultiLineCondition"/>
|
|
|
|
<!-- If an assignment goes over two lines, ensure the equal sign is indented.
|
|
DISABLED (49) — uncomment to enable. -->
|
|
<!-- <rule ref="PEAR.Formatting.MultiLineAssignment"/> -->
|
|
|
|
<!-- Ensure single and multi-line function declarations are defined correctly. -->
|
|
<rule ref="PEAR.Functions.FunctionDeclaration">
|
|
<!-- K&R: opening brace stays on the same line, incl. multi-line signatures. -->
|
|
<exclude name="PEAR.Functions.FunctionDeclaration.BraceOnSameLine"/>
|
|
</rule>
|
|
|
|
<!-- Checks that object operators are indented correctly. -->
|
|
<rule ref="PEAR.WhiteSpace.ObjectOperatorIndent"/>
|
|
|
|
<!-- Checks that the closing braces of scopes are aligned correctly. -->
|
|
<rule ref="PEAR.WhiteSpace.ScopeClosingBrace"/>
|
|
|
|
<!-- Squiz rules -->
|
|
|
|
<!-- Checks the declaration of the class and its inheritance is correct. -->
|
|
<rule ref="Squiz.Classes.ClassDeclaration">
|
|
<!-- K&R: class opening brace on the SAME line (see Generic.Classes.OpeningBraceSameLine). -->
|
|
<exclude name="Squiz.Classes.ClassDeclaration.OpenBraceNewLine"/>
|
|
</rule>
|
|
|
|
<!-- The file name MUST match the case of the terminating class name.
|
|
DISABLED (1) — uncomment to enable. -->
|
|
<!-- <rule ref="Squiz.Classes.ClassFileName"/> -->
|
|
|
|
<!-- For self-reference a class lower-case `self::` MUST be used
|
|
without spaces around the scope resolution operator. -->
|
|
<rule ref="Squiz.Classes.SelfMemberReference"/>
|
|
|
|
<!-- The `&&` and `||` operators SHOULD be used instead of `and` and `or`. -->
|
|
<rule ref="Squiz.Operators.ValidLogicalOperators"/>
|
|
|
|
<!-- The `global` keyword MUST NOT be used.
|
|
DISABLED (478) — architectural `global $db` → DatabaseAware migration;
|
|
not a quick style fix. Uncomment to enable. -->
|
|
<!-- <rule ref="Squiz.PHP.GlobalKeyword"/> -->
|
|
|
|
<!-- PHP function calls MUST be in lowercase. -->
|
|
<rule ref="Squiz.PHP.LowercasePHPFunctions"/>
|
|
|
|
<!-- Non executable code MUST be removed. -->
|
|
<rule ref="Squiz.PHP.NonExecutableCode"/>
|
|
|
|
<!-- The pseudo-variable `$this` MUST NOT be called inside a static method or function. -->
|
|
<rule ref="Squiz.Scope.StaticThisUsage"/>
|
|
|
|
<!-- Makes sure there are no spaces around the concatenation operator. -->
|
|
<rule ref="Squiz.Strings.ConcatenationSpacing">
|
|
<properties>
|
|
<property name="spacing" value="1" />
|
|
<!-- Don't collapse indentation into a single space on multi-line
|
|
concatenations (the `.` at the start of an indented continuation
|
|
line) — that fights the indent sniff and prevents phpcbf from
|
|
converging. -->
|
|
<property name="ignoreNewlines" value="true" />
|
|
</properties>
|
|
</rule>
|
|
|
|
<!-- Checks the separation between functions and methods. -->
|
|
<rule ref="Squiz.WhiteSpace.FunctionSpacing">
|
|
<properties>
|
|
<property name="spacing" value="1" />
|
|
<property name="spacingBeforeFirst" value="0" />
|
|
<property name="spacingAfterLast" value="0" />
|
|
</properties>
|
|
</rule>
|
|
|
|
<!-- There MUST NOT be any white space around the object operator UNLESS multilines are used. -->
|
|
<rule ref="Squiz.WhiteSpace.LogicalOperatorSpacing"/>
|
|
|
|
<!-- Verifies that class members are spaced correctly. -->
|
|
<rule ref="Squiz.WhiteSpace.MemberVarSpacing">
|
|
<properties>
|
|
<property name="spacing" value="1" />
|
|
<property name="spacingBeforeFirst" value="0" />
|
|
</properties>
|
|
</rule>
|
|
|
|
<!-- Ensure there is no whitespace before/after an object operator. -->
|
|
<rule ref="Squiz.WhiteSpace.ObjectOperatorSpacing">
|
|
<properties>
|
|
<property name="ignoreNewlines" value="true"/>
|
|
</properties>
|
|
</rule>
|
|
|
|
<!-- Verifies that operators have valid spacing surrounding them. -->
|
|
<rule ref="Squiz.WhiteSpace.OperatorSpacing">
|
|
<properties>
|
|
<property name="ignoreNewlines" value="true"/>
|
|
</properties>
|
|
</rule>
|
|
|
|
<!-- There MUST NOT be a space before a semicolon. Redundant semicolons SHOULD be avoided. -->
|
|
<rule ref="Squiz.WhiteSpace.SemicolonSpacing"/>
|
|
|
|
<!-- ══════════════════════════════════════════════════════════════════
|
|
PERMANENTLY disabled — DO NOT ENABLE (not part of the ratchet).
|
|
|
|
Space-alignment sniffs that align multi-line continuations with SPACES
|
|
relative to a tab-indented base. phpcbf inserts the spaces,
|
|
Generic.WhiteSpace.DisallowSpaceIndent strips them back, and the fixer
|
|
never converges → FAILED TO FIX. Multi-line call-argument alignment has
|
|
no tab-safe fixer, so this stays off (multi-line `if` layout IS enforced,
|
|
via PEAR.ControlStructures.MultiLineCondition above). -->
|
|
<!-- <rule ref="PEAR.Functions.FunctionCallSignature"/> -->
|
|
|
|
<!-- `use` imports that nothing in the file references MUST be removed
|
|
(dead code from a rename/refactor, e.g. an IDE flagging "declared but
|
|
not used"). searchAnnotations=true is REQUIRED: several core
|
|
interfaces (StreamMiddlewareProviderInterface, MigratableInterface)
|
|
reference their imported type only inside a @return/@param docblock,
|
|
never in the actual signature — without this the sniff/fixer treats
|
|
them as unused and removing the import breaks PHPStan's docblock type
|
|
resolution (class.notFound), even though `make cs` stays green. -->
|
|
<rule ref="SlevomatCodingStandard.Namespaces.UnusedUses">
|
|
<properties>
|
|
<property name="searchAnnotations" value="true"/>
|
|
</properties>
|
|
</rule>
|
|
|
|
<!-- SlevomatCodingStandard.TypeHints.ParameterTypeHint — DO NOT ENABLE yet.
|
|
As a FIXER it auto-added native param types from @param docblocks that
|
|
crash on null at runtime (the "null given" footgun — see TYPE_AUDIT.md).
|
|
Keep off until that audit is worked through; then uncomment. -->
|
|
<!--
|
|
<rule ref="SlevomatCodingStandard.TypeHints.ParameterTypeHint">
|
|
<properties>
|
|
<property name="enableObjectTypeHint" value="true"/>
|
|
</properties>
|
|
</rule>
|
|
-->
|
|
|
|
<!-- ── K&R / one-true-brace style (overrides PSR-12 Allman) ──────────
|
|
Opening brace on the SAME line as the declaration, for classes and
|
|
for functions/methods/closures. Both sniffs are phpcbf-fixable. -->
|
|
<rule ref="Generic.Classes.OpeningBraceSameLine"/>
|
|
<rule ref="Generic.Functions.OpeningFunctionBraceKernighanRitchie">
|
|
<properties>
|
|
<property name="checkClosures" value="true"/>
|
|
</properties>
|
|
</rule>
|
|
|
|
<!-- ══════════════════════════════════════════════════════════════════
|
|
Technical-debt ratchet — how to gradually tighten this ruleset.
|
|
|
|
Sniffs that legacy code still violates are DISABLED so `make cs` stays
|
|
green and can act as a baseline. Enable ONE at a time: flip its toggle,
|
|
run `make cs`, fix the fallout, run `make cs-fix` (confirm it converges,
|
|
no FAILED TO FIX), commit. Do NOT add new violations under a disabled
|
|
rule. Each disabled rule is a single-line toggle:
|
|
|
|
• Own `<rule ref>` commented out above → UNCOMMENT it:
|
|
NoSilencedErrors(473), CamelCapsFunctionName(187),
|
|
CyclomaticComplexity(201 err + 190 warn), NestingLevel(2 + 84),
|
|
MultiLineAssignment(49), UnnecessaryStringConcat(41), SAPIUsage(7),
|
|
AbstractClassNamePrefix(2), InterfaceNameSuffix(1), TraitNameSuffix(1),
|
|
DeprecatedFunctions(1), Squiz.Classes.ClassFileName(1),
|
|
Squiz.PHP.GlobalKeyword(478).
|
|
• <exclude> in the PSR12 block above → DELETE the exclude line.
|
|
(Sniffs inherited from the PSR12 parent CANNOT be commented out —
|
|
<exclude> is the only switch for them.)
|
|
CamelCapsMethodName(40), FileHeader.IncorrectOrder(29),
|
|
PSR1.Files.SideEffects(22),
|
|
MethodDeclaration.Underscore(12), SwitchDeclaration.TerminatingComment(6),
|
|
PSR1.Classes.ClassDeclaration(2), PropertyDeclaration.Underscore(2),
|
|
Squiz.Classes.ValidClassName(1), Generic.Files.LineLength(3480 — has
|
|
no fixer, see its own note; not really part of this ratchet).
|
|
|
|
Suggested order (cheapest / lowest-risk first): SAPIUsage,
|
|
DeprecatedFunctions, SwitchDeclaration.TerminatingComment,
|
|
MultiLineAssignment, UnnecessaryStringConcat, FileHeader.IncorrectOrder,
|
|
the small naming/rename sniffs, then the underscore renames. Leave the
|
|
architectural ones (GlobalKeyword, Cyclomatic/Nesting, CamelCaps names)
|
|
for dedicated refactors. See the "PERMANENTLY disabled" blocks for the
|
|
two that must stay off.
|
|
|
|
Warnings (line length, cyclomatic "too high", silenced errors, …) are
|
|
reported but do NOT fail the run:
|
|
══════════════════════════════════════════════════════════════════════ -->
|
|
<config name="ignore_warnings_on_exit" value="1"/>
|
|
</ruleset>
|