5

In my team we are using codesniffer to enforce a coding style for a Symfony application, and just realized that the files without extension are not getting checked, even if we explicitly use the file as an argument. This is by design as discussed on this github issue.

That means that files like bin/console are not getting checked, even though they are valid PHP files, and the --extensions argument doesn't accept and empty argument.

Is there a way to make CodeSniffer check these files as well?

Loupax
  • 4,728
  • 6
  • 41
  • 68

4 Answers4

1

From the docs

The ignoring of file extensions for specific files is a feature of PHP_CodeSniffer and is the only way to check files without an extension. If you check an entire directory of files, all files without extensions will be ignored, so you must check each of these file separately

https://github.com/squizlabs/PHP_CodeSniffer/wiki/Advanced-Usage

So you will need to specify the file

The syntax is

phpcs --file-list=path/to/file/containing/others

Where others is a file with a file per line structure.

This check all files listed in the others file

Eg

File1 File2 Console

To check the 3 files

exussum
  • 18,275
  • 8
  • 32
  • 65
  • If that's the case, there must be a bug because it looks like that the command `php vendor/bin/phpcs ./bin/console` command behaves like I gave it an empty folder as an argument instead of a file. Will open a ticket just in case. – Loupax Nov 21 '17 at 14:36
  • Looks like there is an explicit check just to prevent that https://github.com/squizlabs/PHP_CodeSniffer/blob/master/src/Filters/Filter.php#L144 – Loupax Nov 21 '17 at 15:03
  • 1
    using `--file-list` option doesn't work for files without extension, at list in v3.3.2 – piotr_cz Nov 11 '18 at 08:45
0

I think you can specify * as wildcard extension.

If that does not work it states in the docs:

If you have asked PHP_CodeSniffer to check a specific file rather than an entire directory, the extension of the specified file will be ignored. The file will be checked even if it has an invalid extension or no extension at all. In the following example, the main.inc file will be checked by PHP_CodeSniffer even though the --extensions command line argument specifies that only .php files should be checked. Extension ignored when checking specific file

$ phpcs --extensions=php /path/to/code/main.inc

So it should work if you explicitly check a single file that has no extension.

Further it states:

The ignoring of file extensions for specific files is a feature of PHP_CodeSniffer and is the only way to check files without an extension. If you check an entire directory of files, all files without extensions will be ignored, so you must check each of these file separately.

See https://pear.php.net/manual/en/package.php.php-codesniffer.advanced-usage.php

Daniel W.
  • 31,164
  • 13
  • 93
  • 151
  • 1
    While you "think" I **know** in config `.` does NOT work. **In fact it stops working even for `.php` files if you switch from `.php` to `*` – redanimalwar Jan 25 '21 at 00:06
0

According to Issue #1754 PHP_CodeSniffer does not test PHP files with no extensions, it isn't supported out of the box. You need to write your own filter and pass it as argument.

Here's a little example, which you should tweak for your own needs. In particular, this filter is designed to find shell scripts written in PHP. It opens all extensionless files (fast for small projects, can be troublesome for large ones) looking for a specific she-bang pattern (builtin MIME detection functions weren't working for my use case). You could, for instance, add a white list of locations to look for scripts.

phpcs.xml

<?xml version="1.0"?>
<ruleset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="phpcs.xsd">
    <arg name="filter" value="lib/CustomPHP_CodeSniffer/Filters/ExtensionlessPhpScriptsFilter.php"/>
    <rule ref="PSR12"></rule>
    <file>.</file>
</ruleset>

lib/CustomPHP_CodeSniffer/Filters/ExtensionlessPhpScriptsFilter.php

<?php

namespace Lib\CustomPHP_CodeSniffer\Filters;

use PHP_CodeSniffer\Filters\Filter;
use PHP_CodeSniffer\Util\Common;

class ExtensionlessPhpScriptsFilter extends Filter
{
    private const SCRIPT_SHEBANG = '@^#!/opt/php[\d.]+/bin/php@';

    public function accept(): bool
    {
        $filePath = Common::realpath($this->current());
        $extension = pathinfo($filePath, PATHINFO_EXTENSION);
        if (is_dir($filePath) || $extension !== '') {
            return parent::accept();
        }

        if ($this->shouldIgnorePath($filePath)) {
            return false;
        }

        return $this->isPhpShellScript($filePath);
    }

    private function isPhpShellScript(string $filePath): bool
    {
        if (is_dir($filePath)) {
            return false;
        }

        $fp = fopen($filePath, 'rb');
        if (!$fp) {
            throw new \RuntimeException("Could not open file to determine type: $filePath");
        }
        $line = fgets($fp, 80);
        fclose($fp);
        if ($line === false) {
            throw new \RuntimeException("Could not read file to determine type: $filePath");
        }

        return (bool)preg_match(self::SCRIPT_SHEBANG, $line);
    }
}
Álvaro González
  • 142,137
  • 41
  • 261
  • 360
-1

I don't know if CS can do this, but I think files like bin/console are mostly up to ten lines, so there is no need to check them with codesniffer :) They should just require vendor and run some Application class from source. Also they are all same in all projects.

Just for reference, our bin/console.

#!/usr/bin/env php
<?php declare(strict_types = 1);

/** @var \Nette\DI\Container $container */
$container = require __DIR__ . '/../src/bootstrap.php';

/** @var \Symfony\Component\Console\Application $console */
$console = $container->getByType(Symfony\Component\Console\Application::class);

$services = $container->findByType(Symfony\Component\Console\Command\Command::class);

foreach ($services as $service) {
    $console->add(
        $container->getService($service)
    );
}

exit($console->run());

There is no reason to check this.

Nguyễn Văn Phong
  • 13,506
  • 17
  • 39
  • 56
  • 1
    Although I agree with you, it does not solve the OPs specific problem :-) – Daniel W. Nov 21 '17 at 14:28
  • That's true, hence i mentioned it in first sentence. :) But I also think it's important to talk about where we should use the tools and where it is make real profit :) – Lukáš Klíma Nov 21 '17 at 14:42
  • "are mostly up to ten lines"? Because **you** just pulled one up that is short? PHP is **awesome** for shell scripting, much better than bash. And not all scripts need to be structured in external files. I have `0common.php` where I keep a few functions I use in multiple scripts, but I have lots of script files with more than 10 lines and I for sure want them checked without having to give them the `.php` extension. – redanimalwar Jan 25 '21 at 00:02
  • @redanimalwar no, you just don't get that right... you talk about scripts which are do something... they are surelly longer than 10 lines... but this question talks about `bin/console` which is ENTRYPOINT of CLI application, and that is as i can say with my 10 years experience exactly SAME for even projects which i created more than 5 years ago. – Lukáš Klíma Jan 29 '21 at 10:45
  • Is `bin/console` just a common entrypoint people use? I do not want to write a single application. I just moved from bash to php and just want to have a bunch of scripts in a folder ... – redanimalwar Jan 29 '21 at 13:35
  • @redanimalwar yeah, it is, is tool for organize THAT SCRIPTS you said. https://symfony.com/doc/current/components/console.html PHP files in normal should have `.php` extensions, the only files which this is acceptible was some entrypoints like bin/console. – Lukáš Klíma Jan 29 '21 at 14:21
  • I also said in answer, that it's not direct answer to question, but it's basically about that, this is not problem at all. – Lukáš Klíma Jan 29 '21 at 14:23
  • We also check every file with most strict tools which is posible, but in case of bin/console. Its just doesn't make sense. :] – Lukáš Klíma Jan 29 '21 at 14:29
  • By peoples in community? The base problem of your arguments is that you don't know that file which was listed in question as you said... So there can't be understanding of my described point of view... – Lukáš Klíma Jan 29 '21 at 19:00