Skip to content

Commit 3023b6c

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 <[email protected]>
1 parent b096c44 commit 3023b6c

File tree

3 files changed

+97
-2
lines changed

3 files changed

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

0 commit comments

Comments
 (0)