Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to override a rule/sniff in a PHP CodeSniffer ruleset correctly and to avoid doublechecking of code?

I've extended a class of the PSR-2 sniff set. Now the checks are executed two times -- even if my chid class is empty.

Why? And how to do it correctly?


EDIT:

I have an idea now why: Probably the Sniffer processes the rulesets bottom-up -- from the ruleset of the actually called standard to the highest (directly or inderectly included) parent standard. It executes them apparently completely. (Is ist so?) OK, but what to do? How to override parent rulesets -- replace their classes but custom ones and deactivate single rules?


Code:

[CodeSniffer]/Standards/ZF/ruleset.xml

<?xml version="1.0"?>
<ruleset name="ZF">
    <description>...</description>
    <!-- Include the whole PSR-2 standard -->
    <rule ref="PSR2"/>
    <!-- Argument lists MAY be split across multiple lines, where each subsequent line is indented once. When doing so, the first item in the list MUST be on the next line, and there MUST be only one argument per line. When the argument list is split across multiple lines, the closing parenthesis and opening brace MUST be placed together on their own line with one space between them. -->
    <rule ref="ZF.Functions.MultiLineFunctionDeclaration"/>
    ... just comments yet
    <!-- 5.7.2. Closure Definitions -->
    <!-- TODO: Revome unwished check: Space after the function keyword is required. -->
    <!-- 5.7.3. Function and Method Usage -->
    <!-- TODO: Revome unwished check: one argument per line in a multi-line function call is required. -->
    ... just comments yet
</ruleset>

[CodeSniffer]/Standards/ZF/Sniffs/Functions/MultiLineFunctionDeclarationSniff.php

<?php
if (class_exists('PEAR_Sniffs_Functions_FunctionDeclarationSniff', true) === false) {
    $error = 'Class PEAR_Sniffs_Functions_FunctionDeclarationSniff not found';
    throw new PHP_CodeSniffer_Exception($error);
}

class ZF_Sniffs_Functions_MultiLineFunctionDeclarationSniff extends PEAR_Sniffs_Functions_FunctionDeclarationSniff
{
    public function processMultiLineDeclaration(PHP_CodeSniffer_File $phpcsFile, $stackPtr, $tokens)
    {
    }

    public function processBracket(PHP_CodeSniffer_File $phpcsFile, $openBracket, $tokens, $type='function')
    {
    }
}
?>

Call:

$ phpcs --standard=ZF -sw /path/to/Test.php

FILE: /path/to/Test.php
--------------------------------------------------------------------------------
FOUND 2 ERROR(S) AFFECTING 1 LINE(S)
--------------------------------------------------------------------------------
 106 | ERROR | Expected 1 space after FUNCTION keyword; 0 found
     |       | (ZF.Functions.MultiLineFunctionDeclaration.SpaceAfterFunction)
 106 | ERROR | Expected 1 space after FUNCTION keyword; 0 found
     |       | (Squiz.Functions.MultiLineFunctionDeclaration.SpaceAfterFunction)
--------------------------------------------------------------------------------

Background information:

I want to write a PHP CodeSniffer ruleset for a Zend Framework 2 project. Around half of the Zend Framework 2 Coding Standards is already implemented in the PSR-2 sniffs folder.

The goal now is not to implement the whole Zend standard. I want to start with PSR-2 and maybe add/implement other Zend rules step by step.

The Problem is, that the PSR-2 sniffs also contain a couple of checks, that break the Zend standards. So I have to override these sniffs. Example: /path/to/php/PHP/CodeSniffer/Standards/Squiz/Sniffs/Functions/MultiLineFunctionDeclarationSniff.php (requires a space after the function keyword in closures). PSR-2 is based on PSR-1 and it uses this sniff. So I have to overwrite them.

like image 201
automatix Avatar asked Nov 05 '13 18:11

automatix


1 Answers

Excluding of a single sniff is easy done with the exclude direction, e.g.:

<?xml version="1.0"?>
<ruleset name="ZF">
    <description>...</description>
    <!-- Include the whole PSR-2 standard -->
    <rule ref="PSR2">
        <!-- to disable a single error -->
        <exclude name="Squiz.Functions.MultiLineFunctionDeclaration.SpaceAfterFunction"/>
        <!-- or to disable the whole sniff -->
        <exclude name="Squiz.Functions.MultiLineFunctionDeclaration"/>
    </rule>
    ...
</ruleset>

instead of

<?xml version="1.0"?>
<ruleset name="ZF">
    <description>...</description>
    <!-- Include the whole PSR-2 standard -->
    <rule ref="PSR2"/>
    ...
</ruleset>

Overriding = Excluding of a sniff + Creating of an alternative one.

See also the annotated sample ruleset.xml in the PHP CodeSniffer manual.

like image 147
automatix Avatar answered Oct 12 '22 12:10

automatix