Description
In a large existing codebase, it usually not possible to fix all violations at once. Or when new violations appear when new rules are added. Think for example the Slevomat Coding Standard. This feature will allow to create a baseline of the current violations, and only report new violations. This is a proposal to add a baseline feature:
Commandline
Create a baseline, and save it to the --baseline-file <path>
or default to phpcs-baseline.xml
vendor/bin/phpcs ... --generate-baseline [--baseline-file=<path>]
Update the baseline, but only remove, not add new violations
vendor/bin/phpcs ... --update-baseline [--baseline-file=<path>]
Using the baseline. If --baseline-file
argument is absent will look for phpcs-baseline.xml
in the root of the project.
vendor/bin/phpcs ... [--baseline-file=<path>]
To ignore the current baseline:
vendor/bin/phpcs ... --ignore-baseline
Options for baseline file format
Which baseline format would we prefer?
xml
: No additional dependency, due to theext-simplexml
dependency.json
: can be read with if theext-json
dependency is added.neon
: requires additional dependency, for examplenette/neon
.
Proposal for baseline file name
phpcs-baseline._format
. Similar to PHPStan's phpstan-baseline.neon.- default location is the root of the project. Root is where
/vendor/
directory lives.
Proposal for strict mode
- Add a strict option in which violations that are in the baseline but do not appear will
result in a violation. Commandline option:--baseline-strict
( ? )
Violation tracking strategies
To be able to track violations, we need to be able to identify them. We minimally need:
file path
: This is the file path the violation occurred in. The file path will be normalized to be relative to the project root and only contain forward slashes.- Ignore the line in the file a violation occurs. Modifications to the top of the file will have unwanted effects.
Further the following strategies can be chosen:
Code signature:
the name of the sniff
: For examplePSR12.Files.FileHeader.SpacingAfterBlock
.hash of surrounding code
: The code surrounding the violation is hashed. This is a very strict strategy, but
also very sensitive to changes in the code. Downside there's a performance penalty for hashing the code.
Example:
<?xml version="1.0" encoding="UTF-8"?>
<phpcs-baseline>
<violation file="relative/path/to/file"
sniff="PSR12.Files.FileHeader.SpacingAfterBlock"
signature="81a547481bf2e1839bf4cff69dffeb6674dbc203"
/>
</phpcs-baseline>
Violation count:
the name of the sniff
: For examplePSR12.Files.FileHeader.SpacingAfterBlock
.count the number of violations
: Keep track of thatPSR12.Files.FileHeader.SpacingAfterBlock
occurs at most 2 times
in the file. This is a very loose strategy, but also very insensitive to changes in the code. Downside is that
it's not very strict, and it's not possible to track the specific violation messages. It will however prevent
additional violations from being added.
Example:
<?xml version="1.0" encoding="UTF-8"?>
<phpcs-baseline>
<violation file="relative/path/to/file"
sniff="PSR12.Files.FileHeader.SpacingAfterBlock"
count="2"
/>
</phpcs-baseline>
Violation message:
the name of the sniff
: For examplePSR12.Files.FileHeader.SpacingAfterBlock
.the violation message
: Keep track of the specific violation message. Token index and
line number should be excluded here as adding code above the violation with change these values.
The difference with the strategy above is that different messages within the same Sniff can be
baselined. This will improve accuracy.count the number of violations
: In this strategy also keep count of the violations.
Example:
<?xml version="1.0" encoding="UTF-8"?>
<phpcs-baseline>
<violation file="relative/path/to/file"
sniff="PSR2.Classes.ClassDeclaration.CloseBraceAfterBody"
message="The closing brace for the class must go on the next line after the body"
count="1"
/>
</phpcs-baseline>
Final words
In short:
-
Choose file format:
xml
,json
, orneon
-
Choose track strategy:
code signature
,violation count
ormessage + violation count
-
I intend to create a pull request to implement this feature. See Add phpcs baseline support #115