Skip to content

Feature: baseline violations #137

Open
@frankdekker

Description

@frankdekker

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 the ext-simplexml dependency.
  • json: can be read with if the ext-json dependency is added.
  • neon: requires additional dependency, for example nette/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 example PSR12.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 example PSR12.Files.FileHeader.SpacingAfterBlock.
  • count the number of violations: Keep track of that PSR12.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 example PSR12.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, or neon

  • Choose track strategy: code signature, violation count or message + violation count

  • I intend to create a pull request to implement this feature. See Add phpcs baseline support #115

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions