Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion phpcs.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@

<file>autoload.php</file>
<file>requirements.php</file>
<file>bin</file>
<file>bin/phpcs</file>
<file>bin/phpcbf</file>
<file>scripts</file>
<file>src</file>
<file>tests</file>
Expand Down
25 changes: 24 additions & 1 deletion src/Filters/Filter.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,15 @@ class Filter extends RecursiveFilterIterator
*/
protected $basedir = null;

/**
* Whether the basedir is a file or a directory.
*
* TRUE if the basedir is actually a directory.
*
* @var boolean
*/
protected $isBasedirDir = false;

/**
* The config data for the run.
*
Expand Down Expand Up @@ -82,6 +91,10 @@ public function __construct($iterator, $basedir, Config $config, Ruleset $rulese
$this->config = $config;
$this->ruleset = $ruleset;

if (is_dir($basedir) === true || Common::isPharFile($basedir) === true) {
$this->isBasedirDir = true;
}

}//end __construct()


Expand Down Expand Up @@ -172,7 +185,17 @@ protected function shouldProcessFile($path)
$fileName = basename($path);
$fileParts = explode('.', $fileName);
if ($fileParts[0] === $fileName || $fileParts[0] === '') {
return false;
if ($this->isBasedirDir === true) {
// We are recursing a directory, so ignore any
// files with no extension.
return false;
}

// We are processing a single file, so always
// accept files with no extension as they have been
// explicitly requested and there is no config setting
// to ignore them.
return true;
}

// Checking multi-part file extensions, so need to create a
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php
/**
* Tests for the \PHP_CodeSniffer\Filters\Filter class.
*
* @copyright 2025 PHPCSStandards Contributors
* @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
*/

namespace PHP_CodeSniffer\Tests\Core\Filters\Filter;

use PHP_CodeSniffer\Filters\Filter;
use PHP_CodeSniffer\Tests\Core\Filters\AbstractFilterTestCase;
use RecursiveArrayIterator;

/**
* Tests handling of files without extension.
*
* @covers \PHP_CodeSniffer\Filters\Filter
*/
final class ShouldProcessFileWithoutExtensionTest extends AbstractFilterTestCase
{


/**
* Verify that if a file without file extension is explicitly requested for scan, it is accepted.
*
* @return void
*/
public function testFileWithoutExtensionIsAcceptedWhenExplicitlyRequested()
{
$fileWithoutExt = self::getBaseDir().'/bin/phpcs';

$fakeDI = new RecursiveArrayIterator([$fileWithoutExt]);
$filter = new Filter($fakeDI, $fileWithoutExt, self::$config, self::$ruleset);

$this->assertSame([$fileWithoutExt], $this->getFilteredResultsAsArray($filter));

}//end testFileWithoutExtensionIsAcceptedWhenExplicitlyRequested()


/**
* Verify that when (recursively) scanning a directory, files without extension are filtered out.
*
* @return void
*/
public function testFileWithoutExtensionIsRejectedWhenRecursingDirectory()
{
$baseDir = self::getBaseDir();
$fakeFileList = [
$baseDir.'/autoload.php',
$baseDir.'/bin',
$baseDir.'/bin/phpcs',
$baseDir.'/scripts',
$baseDir.'/scripts/build-phar.php',
];
$fakeDI = new RecursiveArrayIterator($fakeFileList);
$filter = new Filter($fakeDI, self::getBaseDir(), self::$config, self::$ruleset);

$expectedOutput = [
$baseDir.'/autoload.php',
$baseDir.'/bin',
$baseDir.'/scripts',
$baseDir.'/scripts/build-phar.php',
];

$this->assertSame($expectedOutput, $this->getFilteredResultsAsArray($filter));

}//end testFileWithoutExtensionIsRejectedWhenRecursingDirectory()


}//end class
Loading