PHP_CodeSniffer icon indicating copy to clipboard operation
PHP_CodeSniffer copied to clipboard

Exclude files relative to the root of the project

Open glen-84 opened this issue 9 years ago • 11 comments

I want to be able to exclude everything under the /data folder. There appear to be two options here, neither of which solve the problem:

  1. <exclude-pattern>*/data/*</exclude-pattern> – this will exclude files under any data folder, not just the one in the root of the project.
  2. <exclude-pattern type="relative">^/data/*</exclude-pattern> – this will exclude files under the data folder, but it won't work if you run phpcs for a specific file (which is how I assume most editor extensions work).

Is it somehow possible to have an exclusion of /data/* that works relative to the root of the project?

glen-84 avatar Apr 27 '16 19:04 glen-84

I can't think of a way you'll be able to do this, or even an easy PHPCS change that would make it possible. PHPCS doesn't know where your project root is, and it has even less information when an IDE is giving it a very specific file location, or a chunk of content on STDIN.

Something that might be possible is to add a new type of exclude-pattern that works relative to the coding standard ruleset.xml file it is defined in. If you then used a phpcs.xml file in your project's root directory, and you let PHPCS auto-detect this (or specify the location in an IDE) then any paths that are checked under that root location could be made relative to the root.

Maybe something like:

<exclude-pattern type="relative-root">^/Tests/*</exclude-pattern>

gsherwood avatar May 05 '16 22:05 gsherwood

If standard is included through composer and folder structure is like this, then this won't be much helpful:

/path/to/project
/path/to/project/vendor/aik099/coding-standard/CodingStandard/ruleset.xml

aik099 avatar May 06 '16 06:05 aik099

@gsherwood,

root-relative might sound better than relative-root (similar to root-relative URLs). Although, it might be considered standard-relative.

The only other option would be for linting extensions to read the phpcs.xml file, and ignore everything that is not defined in a <file> element.

@aik099,

You could just create a phpcs.xml file in the root of your project that references the standard in the vendor directory. This is usually a good idea anyway, to define other project-specific settings like encoding, extensions, files, etc.

glen-84 avatar May 08 '16 14:05 glen-84

I'll try that sometime, thanks. As a good developer I try to follow the rule: if it works, then don't change it. Currently I specify command line arguments in the ruleset.xml of custom standard I'm using and not using exclusion rules based on relative paths.

aik099 avatar May 08 '16 16:05 aik099

root-relative might sound better than relative-root (similar to root-relative URLs).

I think you're right.

Although, it might be considered standard-relative.

Good point. It is certainly relative to the location of the ruleset and not the location of any project "root" directory.

I've turned this into a feature request. I have no idea when I can get around to it yet, but it feels like something that will be helpful, or at least needs more thought.

gsherwood avatar May 08 '16 22:05 gsherwood

I am also encountering this problem and it's pretty irritating not being able to filter a file/directory out in relative move. This recently bit me as the OP suggests that */data/* is overly greedy. Can we use the basepath config parameter to determine the root? It seems that https://github.com/squizlabs/PHP_CodeSniffer/blob/master/src/Filters/Filter.php#L219 needs to be aware of the basepath rather than the folder root that the file was loaded from. Could this work instead?

$basepath = $this->config->basepath ?: $this->basedir;
if (strpos($path, $basepath) === 0) {
    // The +1 cuts off the directory separator as well.
    $relativePath = substr($path, (strlen($basepath) + 1));
}

This would allow for a basepath override by CLI or by phpcs.xml

oligriffiths avatar Dec 06 '17 23:12 oligriffiths

Could this work instead?

I don't think so. It would be a significant change of behaviour and would promote the basepath setting from a cosmetic setting (simplifies report output) to a core setting that allows you to change the cwd for (at least) filtering.

gsherwood avatar Jan 03 '18 04:01 gsherwood

hey guys, I think I kinda solved that.

I needed to exclude some directories from updaging the FQCNs and came up with this: https://github.com/oliwierptak/coding-standard/blob/master/coding-standard/Everon/Sniffs/Files/TypeNameMatchesFileNameSniff.php

Configuration example in project: https://github.com/oliwierptak/popo/blob/master/coding-standard/EveronCodingStandard/ruleset.xml

It works for me, so maybe it will be helpful to somebody else as well.

oliwierptak avatar Jul 14 '18 12:07 oliwierptak

So, there is, currently, no way of ignoring a folder located at the root of our project using a <exclude-pattern> without using absolute path (which changes between users/computers/servers)? The following documentation example is then invalid:

<!--
    Patterns can be specified as relative if you would
    like the relative path of the file checked instead of the
    full path. This can sometimes help with portability.
    
    The relative path is determined based on the paths you
    pass into PHP_CodeSniffer on the command line.
 -->
 <exclude-pattern type="relative">^/tests/*</exclude-pattern>
 <exclude-pattern type="relative">^/data/*</exclude-pattern>

Is it related to https://github.com/squizlabs/PHP_CodeSniffer/blob/278b643f2a5ec1b92fd60b2d7dac034f3a52ea4e/src/Files/File.php#L445-L461 which states While there is support for a type of each pattern (absolute or relative) we don't actually support it here.?

C-Duv avatar Dec 26 '19 16:12 C-Duv

FYI there is a way in the documentation now. It didn't work for me but might for you.

 <exclude-pattern type="relative">^/tests/*</exclude-pattern>
 <exclude-pattern type="relative">^/data/*</exclude-pattern>

weitzman avatar Apr 23 '20 19:04 weitzman

<exclude-pattern type="relative"> didn't work for me either. Is there any way to create a truly portable ruleset right now? It seems like you either have to hardcode a full absolute path, which is obviously not portable, or you have to use bare exclude patterns and just hope that some poor unsuspecting user doesn't have them in their base path.

danepowell avatar Jul 19 '21 17:07 danepowell