Skip to content

Commit 941e96b

Browse files
gsherwoodjrfnl
andcommitted
Filter: files without extension are no longer ignored if the path is passed in directly
Fixes squizlabs/PHP_CodeSniffer 2916 Co-authored-by: jrfnl <jrfnl@users.noreply.github.com>
1 parent b8c4907 commit 941e96b

File tree

3 files changed

+98
-2
lines changed

3 files changed

+98
-2
lines changed

phpcs.xml.dist

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44

55
<file>autoload.php</file>
66
<file>requirements.php</file>
7-
<file>bin</file>
7+
<file>bin/phpcs</file>
8+
<file>bin/phpcbf</file>
89
<file>scripts</file>
910
<file>src</file>
1011
<file>tests</file>

src/Filters/Filter.php

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,15 @@ class Filter extends RecursiveFilterIterator
2727
*/
2828
protected $basedir = null;
2929

30+
/**
31+
* Whether the basedir is a file or a directory.
32+
*
33+
* TRUE if the basedir is actually a directory.
34+
*
35+
* @var boolean
36+
*/
37+
protected $isBasedirDir = false;
38+
3039
/**
3140
* The config data for the run.
3241
*
@@ -82,6 +91,10 @@ public function __construct($iterator, $basedir, Config $config, Ruleset $rulese
8291
$this->config = $config;
8392
$this->ruleset = $ruleset;
8493

94+
if (is_dir($basedir) === true || Common::isPharFile($basedir) === true) {
95+
$this->isBasedirDir = true;
96+
}
97+
8598
}//end __construct()
8699

87100

@@ -172,7 +185,17 @@ protected function shouldProcessFile($path)
172185
$fileName = basename($path);
173186
$fileParts = explode('.', $fileName);
174187
if ($fileParts[0] === $fileName || $fileParts[0] === '') {
175-
return false;
188+
if ($this->isBasedirDir === true) {
189+
// We are recursing a directory, so ignore any
190+
// files with no extension.
191+
return false;
192+
}
193+
194+
// We are processing a single file, so always
195+
// accept files with no extension as they have been
196+
// explicitly requested and there is no config setting
197+
// to ignore them.
198+
return true;
176199
}
177200

178201
// Checking multi-part file extensions, so need to create a
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<?php
2+
/**
3+
* Tests for the \PHP_CodeSniffer\Filters\Filter class.
4+
*
5+
* @author Juliette Reinders Folmer <phpcs_nospam@adviesenzo.nl>
6+
* @copyright 2025 PHPCSStandards Contributors
7+
* @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
8+
*/
9+
10+
namespace PHP_CodeSniffer\Tests\Core\Filters\Filter;
11+
12+
use PHP_CodeSniffer\Filters\Filter;
13+
use PHP_CodeSniffer\Tests\Core\Filters\AbstractFilterTestCase;
14+
use RecursiveArrayIterator;
15+
16+
/**
17+
* Tests handling of files without extension.
18+
*
19+
* @covers \PHP_CodeSniffer\Filters\Filter
20+
*/
21+
final class ShouldProcessFileWithoutExtensionTest extends AbstractFilterTestCase
22+
{
23+
24+
25+
/**
26+
* Verify that if a file without file extension is explicitly requested for scan.
27+
*
28+
* @return void
29+
*/
30+
public function testFileWithoutExtensionIsAcceptedWhenExplicitlyRequested()
31+
{
32+
$fileWithoutExt = self::getBaseDir().'/bin/phpcs';
33+
34+
$fakeDI = new RecursiveArrayIterator([$fileWithoutExt]);
35+
$filter = new Filter($fakeDI, $fileWithoutExt, self::$config, self::$ruleset);
36+
37+
$this->assertSame([$fileWithoutExt], $this->getFilteredResultsAsArray($filter));
38+
39+
}//end testFileWithoutExtensionIsAcceptedWhenExplicitlyRequested()
40+
41+
42+
/**
43+
* Verify that when (recursively) scanning a directory, files without extension are filtered out.
44+
*
45+
* @return void
46+
*/
47+
public function testFileWithoutExtensionIsRejectedWhenRecursingDirectory()
48+
{
49+
$baseDir = self::getBaseDir();
50+
$fakeFileList = [
51+
$baseDir.'/autoload.php',
52+
$baseDir.'/bin',
53+
$baseDir.'/bin/phpcs',
54+
$baseDir.'/scripts',
55+
$baseDir.'/scripts/build-phar.php',
56+
];
57+
$fakeDI = new RecursiveArrayIterator($fakeFileList);
58+
$filter = new Filter($fakeDI, self::getBaseDir(), self::$config, self::$ruleset);
59+
60+
$expectedOutput = [
61+
$baseDir.'/autoload.php',
62+
$baseDir.'/bin',
63+
$baseDir.'/scripts',
64+
$baseDir.'/scripts/build-phar.php',
65+
];
66+
67+
$this->assertSame($expectedOutput, $this->getFilteredResultsAsArray($filter));
68+
69+
}//end testFileWithoutExtensionIsRejectedWhenRecursingDirectory()
70+
71+
72+
}//end class

0 commit comments

Comments
 (0)