PHPCSStandards / PHP_CodeSniffer

PHP_CodeSniffer tokenizes PHP files and detects violations of a defined set of coding standards.
BSD 3-Clause "New" or "Revised" License
961 stars 57 forks source link

`exclude-pattern` not respected #683

Open tomasnorre opened 1 day ago

tomasnorre commented 1 day ago

Created based on discussion: https://github.com/PHPCSStandards/PHP_CodeSniffer/discussions/680

Describe the bug

After adjusting (1) the Sniff according to https://github.com/PHPCSStandards/PHP_CodeSniffer/wiki/Coding-Standard-Tutorial#creating-the-sniff my exclude-pattern isn't respected anymore.

Code sample

<?php

declare(strict_types=1);

class KindergartenGarden
{
    public function getName(): string
    {
        return "Random Kindergarden";
    }
}

ExplainStrictTypesSniff.php

<?php

declare(strict_types=1);

namespace Exercism\Sniffs\StrictTypes;

use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Fixer;
use PHP_CodeSniffer\Sniffs\Sniff;

class ExplainStrictTypesSniff implements Sniff
{
    private static string $explanation = <<<EOT
/*
 * By adding type hints and enabling strict type checking, code can become
 * easier to read, self-documenting and reduce the number of potential bugs.
 * By default, type declarations are non-strict, which means they will attempt
 * to change the original type to match the type specified by the
 * type-declaration.
 *
 * In other words, if you pass a string to a function requiring a float,
 * it will attempt to convert the string value to a float.
 *
 * To enable strict mode, a single declare directive must be placed at the top
 * of the file.
 * This means that the strictness of typing is configured on a per-file basis.
 * This directive not only affects the type declarations of parameters, but also
 * a function's return type.
 *
 * For more info review the Concept on strict type checking in the PHP track
 * <link>.
 *
 * To disable strict typing, comment out the directive below.
 */
EOT;

    private ?Fixer $fixer = null;
    private int $position = 0;

    private array $tokens = [
        T_COMMENT,
    ];

    public function register(): array
    {
        return [
            T_DECLARE,
        ];
    }

    public function process(File $phpcsFile, $stackPtr): void
    {
        $this->fixer = $phpcsFile->fixer;
        $this->position = $stackPtr;

        if (!$phpcsFile->findPrevious($this->tokens, $stackPtr)) {
            $phpcsFile->addFixableError(
                'Missing explanation of declaration of strict types.',
                $stackPtr - 1,
                self::class
            );
            $this->fix();
        }
    }

    private function fix(): void
    {
        $this->fixer->addContent($this->position - 1, self::$explanation);
    }
}
<?xml version="1.0"?>
<ruleset
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:noNamespaceSchemaLocation="vendor/squizlabs/php_codesniffer/phpcs.xsd"
  name="Exercism PHP Coding Standard"
>
  <description>Coding standard for Exercism PHP exercises</description>

  <!-- Expect all files are UTF-8 -->
  <arg name="encoding" value="utf-8" />

  <!-- No warnings (ignore them) -->
  <arg value="n" />

  <!-- Show sniffs (it's easy to find solutions knowing the code) -->
  <arg value="s" />

  <!-- A TAB is 4 chars wide (does not replace them, for calculation only!) -->
  <arg name="tab-width" value="4" />

  <!-- Run on 60 files in parallel -->
  <arg name="parallel" value="60" />

  <file>exercises</file>
  <file>src</file>

  <!-- Include all sniffs in the PSR12 standard except... -->
  <rule ref="PSR12">
    <exclude name="PSR1.Classes.ClassDeclaration.MissingNamespace" />
    <exclude name="PSR1.Classes.ClassDeclaration.MultipleClasses" />
    <exclude name="PSR1.Files.SideEffects.FoundWithSymbols" />
  </rule>
  <rule ref="Squiz.Scope.MethodScope.Missing">
    <exclude-pattern>*/concept/city-office/*</exclude-pattern>
    <exclude-pattern>*/concept/windowing-system/*</exclude-pattern>
  </rule>
 <rule ref="src/Sniffs/StrictTypes/ExplainStrictTypesSniff.php">
    <exclude-pattern>*/*Test\.php</exclude-pattern>
    <exclude-pattern>*/.meta/*\.php</exclude-pattern>
    <exclude-pattern>src/*</exclude-pattern>
    <exclude-pattern>contribution/*.php</exclude-pattern>
  </rule>
</ruleset>

Custom ruleset

<rule ref="src/Sniffs/StrictTypes/ExplainStrictTypesSniff.php">
  <exclude-pattern>*/*Test\.php</exclude-pattern>
  <exclude-pattern>*/.meta/*\.php</exclude-pattern>
  <exclude-pattern>src/*</exclude-pattern>
  <exclude-pattern>contribution/*.php</exclude-pattern>
</rule>

When I run vendor/bin/phpcs -s I don't get an error code, and the two errors are from the exclude-pattern files from above.


$ php  vendor/bin/phpcs -s exercises/practice/kindergarten-garden

FILE: /home/tomas/Projects/exercism/php/exercises/practice/kindergarten-garden/.meta/example.php
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
FOUND 1 ERROR AFFECTING 1 LINE
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
 2 | ERROR | [x] Missing explanation of declaration of strict types. (Exercism.StrictTypes.ExplainStrictTypes.Exercism\Sniffs\StrictTypes\ExplainStrictTypesSniff)
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
PHPCBF CAN FIX THE 1 MARKED SNIFF VIOLATIONS AUTOMATICALLY
-------------------------------------------------------------------------------------------------------------------------------------------------------------------

FILE: /home/tomas/Projects/exercism/php/exercises/practice/kindergarten-garden/KindergartenGardenTest.php
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
FOUND 1 ERROR AFFECTING 1 LINE
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
 2 | ERROR | [x] Missing explanation of declaration of strict types. (Exercism.StrictTypes.ExplainStrictTypes.Exercism\Sniffs\StrictTypes\ExplainStrictTypesSniff)
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
PHPCBF CAN FIX THE 1 MARKED SNIFF VIOLATIONS AUTOMATICALLY
-------------------------------------------------------------------------------------------------------------------------------------------------------------------

1) https://github.com/exercism/php/pull/857

To reproduce

Steps to reproduce the behavior:

  1. Create a file called KindergartenGarden.php in a folder called .meta with the code sample above
  2. Create ExplainStrictTypesSniff.php in folder src/Sniffs/StrictTypes/ from the code above
  3. Create phpcs.xml in base-folder with content from above
  4. Run vendor/bin/phpcs -s .meta/KindergartenGarden.php
  5. Now you will see that the file isn't ignored.
vendor/bin/phpcs -s .meta/KindergartenGarden.php

FILE: /tmp/.meta/KindergartenGarden.php
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
FOUND 1 ERROR AFFECTING 1 LINE
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
 2 | ERROR | [x] Missing explanation of declaration of strict types. (Exercism.StrictTypes.ExplainStrictTypes.Exercism\Sniffs\StrictTypes\ExplainStrictTypesSniff)
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
PHPCBF CAN FIX THE 1 MARKED SNIFF VIOLATIONS AUTOMATICALLY
-------------------------------------------------------------------------------------------------------------------------------------------------------------------

Expected behavior

I would expect the error not to be reported as the .meta directory is in the exclude-pattern.

Versions (please complete the following information)

Operating System Ubuntu 24.10
PHP version PHP 8.3.12
PHP_CodeSniffer version 3.11.0
Standard PSR12
Install type composer

Please confirm

jrfnl commented 1 day ago

@tomasnorre Thanks for opening the issue.

I've already been looking into this and can confirm the issue.

To reproduce and investigate this, I've used a minimal setup with control:

Directory layout:

- project root
  - src
    - Sniffs
      - SniffsDirSniff.php
      - SniffsDirWithExcludeSniff.php
      - StrictTypes (directory)
        - CategorySniff.php
        - CategoryWithExcludeSniff.php

The content of the sniff files is the same with only minimal variation:

namespace Exercism\Sniffs;

use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Sniffs\Sniff;

class SniffsDirSniff implements Sniff
{

    public function register()
    {
        return [T_OPEN_TAG];
    }

    public function process(File $phpcsFile, $stackPtr)
    {
        $phpcsFile->addError('Running', $stackPtr, 'Control');
    }
}

The only differences between the four sniffs are:

  1. The namespace for the Category sniffs is updated to Exercism\Sniffs\StrictTypes.
  2. The error code for the *WithExclude sniffs is updated from Control to ThisErrorShouldHaveBeenExcluded.

Ruleset:

<?xml version="1.0"?>
<ruleset
  name="Exercism PHP Coding Standard"
>
  <file>src</file>

  <rule ref="src/Sniffs/SniffsDirSniff.php"/>
  <!-- This works. -->
  <rule ref="src/Sniffs/SniffsDirWithExcludeSniff.php">
    <exclude-pattern>src/*</exclude-pattern>
  </rule>
  <rule ref="src/Sniffs/StrictTypes/CategorySniff.php"/>
  <!-- This doesn't work, but should. -->
  <rule ref="src/Sniffs/StrictTypes/CategoryWithExcludeSniff.php">
    <exclude-pattern>src/*</exclude-pattern>
  </rule>
</ruleset>

Command run from the project root:

phpcs -ps --basepath=.

Result

FILE: src\Sniffs\SniffsDirSniff.php
------------------------------------------------------------------------------------------------
FOUND 3 ERRORS AFFECTING 1 LINE
------------------------------------------------------------------------------------------------
 1 | ERROR | Running (.Sniffs.SniffsDir.Control)
 1 | ERROR | Running (Exercism.StrictTypes.Category.Control)
 1 | ERROR | Running (Exercism.StrictTypes.CategoryWithExclude.ThisErrorShouldHaveBeenExcluded)
------------------------------------------------------------------------------------------------

FILE: src\Sniffs\SniffsDirWithExcludeSniff.php
------------------------------------------------------------------------------------------------
FOUND 3 ERRORS AFFECTING 1 LINE
------------------------------------------------------------------------------------------------
 1 | ERROR | Running (.Sniffs.SniffsDir.Control)
 1 | ERROR | Running (Exercism.StrictTypes.Category.Control)
 1 | ERROR | Running (Exercism.StrictTypes.CategoryWithExclude.ThisErrorShouldHaveBeenExcluded)
------------------------------------------------------------------------------------------------

FILE: src\Sniffs\StrictTypes\CategorySniff.php
------------------------------------------------------------------------------------------------
FOUND 3 ERRORS AFFECTING 1 LINE
------------------------------------------------------------------------------------------------
 1 | ERROR | Running (.Sniffs.SniffsDir.Control)
 1 | ERROR | Running (Exercism.StrictTypes.Category.Control)
 1 | ERROR | Running (Exercism.StrictTypes.CategoryWithExclude.ThisErrorShouldHaveBeenExcluded)
------------------------------------------------------------------------------------------------

FILE: src\Sniffs\StrictTypes\CategoryWithExcludeSniff.php
------------------------------------------------------------------------------------------------
FOUND 3 ERRORS AFFECTING 1 LINE
------------------------------------------------------------------------------------------------
 1 | ERROR | Running (.Sniffs.SniffsDir.Control)
 1 | ERROR | Running (Exercism.StrictTypes.Category.Control)
 1 | ERROR | Running (Exercism.StrictTypes.CategoryWithExclude.ThisErrorShouldHaveBeenExcluded)
------------------------------------------------------------------------------------------------

As the original discussion mentioned that it "used to work", I've done some git bisecting to validate this and see where things changed, starting at PHPCS 3.1.0.

My findings based on that are, however, different: This never worked (between PHPCS 3.1.0 and now) and it used to be worse.

This will need further investigation and a fix, which probably needs to build on the prior fix from squizlabs/PHP_CodeSniffer#2501.


Detailed bisect analysis results and findings ### PHPCS 3.1.0 ``` Processing ruleset phpcs.xml Processing rule "Generic.WhiteSpace.DisallowTabIndent" => D:\000_GitHub\PHPCS\PHP_CodeSniffer\src\Standards\Generic\Sniffs\WhiteSpace\DisallowTabIndentSniff.php Processing rule "Squiz.Scope.MethodScope.Missing" => D:\000_GitHub\PHPCS\PHP_CodeSniffer\src\Standards\Squiz\Sniffs\Scope\MethodScopeSniff.php Excluding sniff "Squiz.Scope.MethodScope" except for "Missing" Processing rule "src/Sniffs/SniffsDirSniff.php" Processing rule "src/Sniffs/SniffsDirWithExcludeSniff.php" => added rule-specific absolute ignore pattern: src/* => added rule-specific absolute ignore pattern for ..src/Sniffs/SniffsDirWithExclude: src/* Processing rule "src/Sniffs/StrictTypes/CategorySniff.php" Processing rule "src/Sniffs/StrictTypes/CategoryWithExcludeSniff.php" => added rule-specific absolute ignore pattern: src/* => added rule-specific absolute ignore pattern for ..src/Sniffs/StrictTypes/CategoryWithExclude: src/* ``` ``` Creating file list... DONE (2 files in queue) Changing into directory src\Sniffs Processing SniffsDirSniff.php [PHP => 122 tokens in 24 lines]... DONE in 5ms (4 errors, 0 warnings) Changing into directory src\Sniffs\StrictTypes Processing CategorySniff.php [PHP => 123 tokens in 23 lines]... DONE in 1ms (4 errors, 0 warnings) FILE: src\Sniffs\SniffsDirSniff.php ------------------------------------------------------------------------------------------------ FOUND 4 ERRORS AFFECTING 1 LINE ------------------------------------------------------------------------------------------------ 1 | ERROR | Running (.Sniffs.SniffsDir.Control) 1 | ERROR | Running (.Sniffs.SniffsDirWithExclude.ThisErrorShouldHaveBeenExcluded) 1 | ERROR | Running (Exercism.StrictTypes.Category.Control) 1 | ERROR | Running (Exercism.StrictTypes.CategoryWithExclude.ThisErrorShouldHaveBeenExcluded) ------------------------------------------------------------------------------------------------ FILE: src\Sniffs\StrictTypes\CategorySniff.php ------------------------------------------------------------------------------------------------ FOUND 4 ERRORS AFFECTING 1 LINE ------------------------------------------------------------------------------------------------ 1 | ERROR | Running (.Sniffs.SniffsDir.Control) 1 | ERROR | Running (.Sniffs.SniffsDirWithExclude.ThisErrorShouldHaveBeenExcluded) 1 | ERROR | Running (Exercism.StrictTypes.Category.Control) 1 | ERROR | Running (Exercism.StrictTypes.CategoryWithExclude.ThisErrorShouldHaveBeenExcluded) ------------------------------------------------------------------------------------------------ ``` #### Findings * PROBLEM: only 2 out of 4 files are scanned * PROBLEM: excludes are not respected AT ALL --- ### PHPCS 3.5.0 ``` Processing ruleset phpcs.xml Processing rule "Generic.WhiteSpace.DisallowTabIndent" => D:\000_GitHub\PHPCS\PHP_CodeSniffer\src\Standards\Generic\Sniffs\WhiteSpace\DisallowTabIndentSniff.php Processing rule "Squiz.Scope.MethodScope.Missing" => D:\000_GitHub\PHPCS\PHP_CodeSniffer\src\Standards\Squiz\Sniffs\Scope\MethodScopeSniff.php Excluding sniff "Squiz.Scope.MethodScope" except for "Missing" Processing rule "src/Sniffs/SniffsDirSniff.php" Processing rule "src/Sniffs/SniffsDirWithExcludeSniff.php" => added rule-specific absolute ignore pattern: src/* => added rule-specific absolute ignore pattern for ..src/Sniffs/SniffsDirWithExclude: src/* Processing rule "src/Sniffs/StrictTypes/CategorySniff.php" Processing rule "src/Sniffs/StrictTypes/CategoryWithExcludeSniff.php" => added rule-specific absolute ignore pattern: src/* => added rule-specific absolute ignore pattern for ..src/Sniffs/StrictTypes/CategoryWithExclude: src/* ``` ``` Creating file list... DONE (4 files in queue) Changing into directory src\Sniffs Processing SniffsDirSniff.php [PHP => 122 tokens in 24 lines]... DONE in 5ms (4 errors, 0 warnings) Processing SniffsDirWithExcludeSniff.php [PHP => 122 tokens in 24 lines]... DONE in 1ms (4 errors, 0 warnings) Changing into directory src\Sniffs\StrictTypes Processing CategorySniff.php [PHP => 123 tokens in 23 lines]... DONE in 1ms (4 errors, 0 warnings) Processing CategoryWithExcludeSniff.php [PHP => 123 tokens in 23 lines]... DONE in 1ms (4 errors, 0 warnings) FILE: src\Sniffs\SniffsDirSniff.php ------------------------------------------------------------------------------------------------ FOUND 4 ERRORS AFFECTING 1 LINE ------------------------------------------------------------------------------------------------ 1 | ERROR | Running (.Sniffs.SniffsDir.Control) 1 | ERROR | Running (.Sniffs.SniffsDirWithExclude.ThisErrorShouldHaveBeenExcluded) 1 | ERROR | Running (Exercism.StrictTypes.Category.Control) 1 | ERROR | Running | | (Exercism.StrictTypes.CategoryWithExclude.ThisErrorShouldHaveBeenExcluded) ------------------------------------------------------------------------------------------------ FILE: src\Sniffs\SniffsDirWithExcludeSniff.php ------------------------------------------------------------------------------------------------ FOUND 4 ERRORS AFFECTING 1 LINE ------------------------------------------------------------------------------------------------ 1 | ERROR | Running (.Sniffs.SniffsDir.Control) 1 | ERROR | Running (.Sniffs.SniffsDirWithExclude.ThisErrorShouldHaveBeenExcluded) 1 | ERROR | Running (Exercism.StrictTypes.Category.Control) 1 | ERROR | Running | | (Exercism.StrictTypes.CategoryWithExclude.ThisErrorShouldHaveBeenExcluded) ------------------------------------------------------------------------------------------------ FILE: src\Sniffs\StrictTypes\CategorySniff.php ------------------------------------------------------------------------------------------------ FOUND 4 ERRORS AFFECTING 1 LINE ------------------------------------------------------------------------------------------------ 1 | ERROR | Running (.Sniffs.SniffsDir.Control) 1 | ERROR | Running (.Sniffs.SniffsDirWithExclude.ThisErrorShouldHaveBeenExcluded) 1 | ERROR | Running (Exercism.StrictTypes.Category.Control) 1 | ERROR | Running | | (Exercism.StrictTypes.CategoryWithExclude.ThisErrorShouldHaveBeenExcluded) ------------------------------------------------------------------------------------------------ FILE: src\Sniffs\StrictTypes\CategoryWithExcludeSniff.php ------------------------------------------------------------------------------------------------ FOUND 4 ERRORS AFFECTING 1 LINE ------------------------------------------------------------------------------------------------ 1 | ERROR | Running (.Sniffs.SniffsDir.Control) 1 | ERROR | Running (.Sniffs.SniffsDirWithExclude.ThisErrorShouldHaveBeenExcluded) 1 | ERROR | Running (Exercism.StrictTypes.Category.Control) 1 | ERROR | Running | | (Exercism.StrictTypes.CategoryWithExclude.ThisErrorShouldHaveBeenExcluded) ------------------------------------------------------------------------------------------------ ``` #### Findings * SOLVED Problem: only 2 out of 4 files are scanned Related to: https://github.com/squizlabs/PHP_CodeSniffer/issues/2391 Fixed via: https://github.com/squizlabs/PHP_CodeSniffer/pull/2392 Released in PHPCS 3.5.0 * PROBLEM: excludes are not respected AT ALL --- ### PHPCS 3.5.4 ``` Processing ruleset phpcs.xml Processing rule "Generic.WhiteSpace.DisallowTabIndent" => D:\000_GitHub\PHPCS\PHP_CodeSniffer\src\Standards\Generic\Sniffs\WhiteSpace\DisallowTabIndentSniff.php Processing rule "Squiz.Scope.MethodScope.Missing" => D:\000_GitHub\PHPCS\PHP_CodeSniffer\src\Standards\Squiz\Sniffs\Scope\MethodScopeSniff.php Excluding sniff "Squiz.Scope.MethodScope" except for "Missing" Processing rule "src/Sniffs/SniffsDirSniff.php" Processing rule "src/Sniffs/SniffsDirWithExcludeSniff.php" => added rule-specific absolute ignore pattern: src/* => added rule-specific absolute ignore pattern for .Sniffs.SniffsDirWithExclude: src/* Processing rule "src/Sniffs/StrictTypes/CategorySniff.php" Processing rule "src/Sniffs/StrictTypes/CategoryWithExcludeSniff.php" => added rule-specific absolute ignore pattern: src/* => added rule-specific absolute ignore pattern for src.StrictTypes.CategoryWithExclude: src/* ``` ``` Creating file list... DONE (4 files in queue) Changing into directory src\Sniffs Processing SniffsDirSniff.php [PHP => 122 tokens in 24 lines]... DONE in 6ms (3 errors, 0 warnings) Processing SniffsDirWithExcludeSniff.php [PHP => 122 tokens in 24 lines]... DONE in 2ms (3 errors, 0 warnings) Changing into directory src\Sniffs\StrictTypes Processing CategorySniff.php [PHP => 123 tokens in 23 lines]... DONE in 1ms (3 errors, 0 warnings) Processing CategoryWithExcludeSniff.php [PHP => 123 tokens in 23 lines]... DONE in 1ms (3 errors, 0 warnings) FILE: src\Sniffs\SniffsDirSniff.php ------------------------------------------------------------------------------------------------ FOUND 3 ERRORS AFFECTING 1 LINE ------------------------------------------------------------------------------------------------ 1 | ERROR | Running (.Sniffs.SniffsDir.Control) 1 | ERROR | Running (Exercism.StrictTypes.Category.Control) 1 | ERROR | Running | | (Exercism.StrictTypes.CategoryWithExclude.ThisErrorShouldHaveBeenExcluded) ------------------------------------------------------------------------------------------------ FILE: src\Sniffs\SniffsDirWithExcludeSniff.php ------------------------------------------------------------------------------------------------ FOUND 3 ERRORS AFFECTING 1 LINE ------------------------------------------------------------------------------------------------ 1 | ERROR | Running (.Sniffs.SniffsDir.Control) 1 | ERROR | Running (Exercism.StrictTypes.Category.Control) 1 | ERROR | Running | | (Exercism.StrictTypes.CategoryWithExclude.ThisErrorShouldHaveBeenExcluded) ------------------------------------------------------------------------------------------------ FILE: src\Sniffs\StrictTypes\CategorySniff.php ------------------------------------------------------------------------------------------------ FOUND 3 ERRORS AFFECTING 1 LINE ------------------------------------------------------------------------------------------------ 1 | ERROR | Running (.Sniffs.SniffsDir.Control) 1 | ERROR | Running (Exercism.StrictTypes.Category.Control) 1 | ERROR | Running | | (Exercism.StrictTypes.CategoryWithExclude.ThisErrorShouldHaveBeenExcluded) ------------------------------------------------------------------------------------------------ FILE: src\Sniffs\StrictTypes\CategoryWithExcludeSniff.php ------------------------------------------------------------------------------------------------ FOUND 3 ERRORS AFFECTING 1 LINE ------------------------------------------------------------------------------------------------ 1 | ERROR | Running (.Sniffs.SniffsDir.Control) 1 | ERROR | Running (Exercism.StrictTypes.Category.Control) 1 | ERROR | Running | | (Exercism.StrictTypes.CategoryWithExclude.ThisErrorShouldHaveBeenExcluded) ------------------------------------------------------------------------------------------------ ``` #### Findings * SOLVED Problem: only 2 out of 4 files are scanned Related to: https://github.com/squizlabs/PHP_CodeSniffer/issues/2391 Fixed via: https://github.com/squizlabs/PHP_CodeSniffer/pull/2392 Released in PHPCS 3.5.0 * SOLVED: Problem: excludes are not respected when the file included sniff does not have a category Related to: https://github.com/squizlabs/PHP_CodeSniffer/issues/2497 Fixed via: https://github.com/squizlabs/PHP_CodeSniffer/pull/2501 Released in PHPCS 3.5.4 * Problem: excludes are not respected when the file included sniff has a category --- ### PHPCS 3.11.1 / `master` ``` Processing ruleset phpcs.xml Processing rule "Generic.WhiteSpace.DisallowTabIndent" => D:\000_GitHub\PHPCS\PHP_CodeSniffer\src\Standards\Generic\Sniffs\WhiteSpace\DisallowTabIndentSniff.php Processing rule "Squiz.Scope.MethodScope.Missing" => D:\000_GitHub\PHPCS\PHP_CodeSniffer\src\Standards\Squiz\Sniffs\Scope\MethodScopeSniff.php Excluding sniff "Squiz.Scope.MethodScope" except for "Missing" Processing rule "src/Sniffs/SniffsDirSniff.php" Processing rule "src/Sniffs/SniffsDirWithExcludeSniff.php" => added rule-specific absolute ignore pattern: src/* => added rule-specific absolute ignore pattern for .Sniffs.SniffsDirWithExclude: src/* Processing rule "src/Sniffs/StrictTypes/CategorySniff.php" Processing rule "src/Sniffs/StrictTypes/CategoryWithExcludeSniff.php" => added rule-specific absolute ignore pattern: src/* => added rule-specific absolute ignore pattern for src.StrictTypes.CategoryWithExclude: src/* ``` ``` Creating file list... DONE (4 files in queue) Changing into directory src\Sniffs Processing SniffsDirSniff.php [PHP => 122 tokens in 24 lines]... DONE in 8ms (3 errors, 0 warnings) Processing SniffsDirWithExcludeSniff.php [PHP => 122 tokens in 24 lines]... DONE in 1ms (3 errors, 0 warnings) Changing into directory src\Sniffs\StrictTypes Processing CategorySniff.php [PHP => 123 tokens in 23 lines]... DONE in 1ms (3 errors, 0 warnings) Processing CategoryWithExcludeSniff.php [PHP => 123 tokens in 23 lines]... DONE in 2ms (3 errors, 0 warnings) FILE: src\Sniffs\SniffsDirSniff.php ------------------------------------------------------------------------------------------------ FOUND 3 ERRORS AFFECTING 1 LINE ------------------------------------------------------------------------------------------------ 1 | ERROR | Running (.Sniffs.SniffsDir.Control) 1 | ERROR | Running (Exercism.StrictTypes.Category.Control) 1 | ERROR | Running (Exercism.StrictTypes.CategoryWithExclude.ThisErrorShouldHaveBeenExcluded) ------------------------------------------------------------------------------------------------ FILE: src\Sniffs\SniffsDirWithExcludeSniff.php ------------------------------------------------------------------------------------------------ FOUND 3 ERRORS AFFECTING 1 LINE ------------------------------------------------------------------------------------------------ 1 | ERROR | Running (.Sniffs.SniffsDir.Control) 1 | ERROR | Running (Exercism.StrictTypes.Category.Control) 1 | ERROR | Running (Exercism.StrictTypes.CategoryWithExclude.ThisErrorShouldHaveBeenExcluded) ------------------------------------------------------------------------------------------------ FILE: src\Sniffs\StrictTypes\CategorySniff.php ------------------------------------------------------------------------------------------------ FOUND 3 ERRORS AFFECTING 1 LINE ------------------------------------------------------------------------------------------------ 1 | ERROR | Running (.Sniffs.SniffsDir.Control) 1 | ERROR | Running (Exercism.StrictTypes.Category.Control) 1 | ERROR | Running (Exercism.StrictTypes.CategoryWithExclude.ThisErrorShouldHaveBeenExcluded) ------------------------------------------------------------------------------------------------ FILE: src\Sniffs\StrictTypes\CategoryWithExcludeSniff.php ------------------------------------------------------------------------------------------------ FOUND 3 ERRORS AFFECTING 1 LINE ------------------------------------------------------------------------------------------------ 1 | ERROR | Running (.Sniffs.SniffsDir.Control) 1 | ERROR | Running (Exercism.StrictTypes.Category.Control) 1 | ERROR | Running (Exercism.StrictTypes.CategoryWithExclude.ThisErrorShouldHaveBeenExcluded) ------------------------------------------------------------------------------------------------ ``` ### Findings * SOLVED Problem: only 2 out of 4 files are scanned Related to: https://github.com/squizlabs/PHP_CodeSniffer/issues/2391 Fixed via: https://github.com/squizlabs/PHP_CodeSniffer/pull/2392 Released in PHPCS 3.5.0 * SOLVED: Problem: excludes are not respected when the file included sniff does not have a category Related to: https://github.com/squizlabs/PHP_CodeSniffer/issues/2497 Fixed via: https://github.com/squizlabs/PHP_CodeSniffer/pull/2501 Released in PHPCS 3.5.4 * Problem: excludes are not respected when the file included sniff has a category
tomasnorre commented 21 hours ago

Thanks @jrfnl for your thorough investigation. I'm not super familiar with PHPCS it self, but if there is anything I can do to help out, let me know.

jrfnl commented 2 hours ago

Thanks @jrfnl for your thorough investigation. I'm not super familiar with PHPCS it self, but if there is anything I can do to help out, let me know.

Well, actually...

Sorry, I don't know where my head was, but I've taken another look at this and suddenly realized that the problem is that - even after the proposed update in https://github.com/exercism/php/pull/857 -, the naming conventions from PHPCS are still not followed for your sniff.

I've submitted a fix for this (https://github.com/tomasnorre/exercism-php/pull/2) and with that fix included, things are working as expected.

With that in mind, I'm going to mark this ticket as a close candidate.

While, yes, this is a bug (as something is not working), I don't think PHPCS should have to support sniff file includes when the sniffs do not comply with the PHPCS naming conventions.

The fact that this is "partially" supported now is more by accident than by design and I think it is a good idea to formally and completely drop support for sniffs not complying with the PHPCS naming conventions in PHPCS 4.0.

tomasnorre commented 48 minutes ago

Thanks for your PR and your further investigation. I totally overlooked that extra directory missing too.