squizlabs / PHP_CodeSniffer

PHP_CodeSniffer tokenizes PHP files and detects violations of a defined set of coding standards.
BSD 3-Clause "New" or "Revised" License
10.63k stars 1.48k forks source link

No output when running phpcs #3880

Closed rilwis closed 10 months ago

rilwis commented 11 months ago

Describe the bug

I installed PHPCS and some other rules for a local package, which is a WordPress plugin. And when I run phpcs, it doesn't output anything.

Here is my composer.json file:

{
    "name": "elightup/slim-seo-link-manager",
    "type": "wordpress-plugin",
    "repositories": [
        {
            "type": "git",
            "url": "git@github.com:elightup/plugin-updater.git"
        },
        {
            "type": "git",
            "url": "git@github.com:elightup/plugin-search.git"
        }
    ],
    "autoload": {
        "psr-4": {
            "SlimSEOPro\\LinkManager\\": "src/",
            "SlimSEO\\": "lib"
        }
    },
    "minimum-stability": "dev",
    "prefer-stable": true,
    "config": {
        "prepend-autoloader": false,
        "allow-plugins": {
            "dealerdirect/phpcodesniffer-composer-installer": true
        }
    },
    "extra": {
        "dev-files": {
            "elightup/plugin-updater": [
                "plugin-updater.php"
            ],
            "elightup/plugin-search": [
                "plugin-search.php"
            ],
            "elightup/*": [
                ".git/",
                ".gitignore",
                "composer.json",
                "phpcs.xml"
            ]
        }
    },
    "require": {
        "elightup/plugin-updater": "dev-master",
        "deliciousbrains/wp-background-processing": "^1.0",
        "voku/stop-words": "^2.0",
        "elightup/plugin-search": "dev-master"
    },
    "require-dev": {
        "dealerdirect/phpcodesniffer-composer-installer": "^1.0",
        "wp-coding-standards/wpcs": "dev-develop",
        "phpcompatibility/phpcompatibility-wp": "^2.1"
    }
}

Custom ruleset

Here is my phpcs.xml file:

<?xml version="1.0"?>
<ruleset name="eLightUp WordPress Coding Standards">
    <!-- See https://github.com/squizlabs/PHP_CodeSniffer/wiki/Annotated-ruleset.xml -->
    <!-- See https://github.com/WordPress/WordPress-Coding-Standards -->
    <!-- See https://github.com/PHPCompatibility/PHPCompatibilityWP -->

    <!--
    #############################################################################
    COMMAND LINE ARGUMENTS
    https://github.com/squizlabs/PHP_CodeSniffer/wiki/Annotated-ruleset.xml
    #############################################################################
    -->

    <!-- Pass some flags to PHPCS:
         p flag: Show progress of the run.
         s flag: Show sniff codes in all reports.
    -->
    <arg value="ps"/>

    <!-- Check up to 8 files simultaneously. -->
    <arg name="parallel" value="8"/>

    <!-- Check PHP files only. JavaScript and CSS files are checked separately using the @wordpress/scripts package. -->
    <arg name="extensions" value="php"/>

    <!-- Check all files in this directory and the directories below it. -->
    <file>.</file>

    <!-- Exclude patterns. -->
    <exclude-pattern>/vendor/*</exclude-pattern>
    <exclude-pattern>/tests/*</exclude-pattern>
    <exclude-pattern>/.github/*</exclude-pattern>

    <rule ref="WordPress">
        <!-- Use PSR-4 naming -->
        <exclude name="WordPress.Files.FileName.NotHyphenatedLowercase" />
        <exclude name="WordPress.Files.FileName.InvalidClassFileName" />

        <!-- Only comment when neccessary -->
        <exclude name="Squiz.Commenting.FileComment.Missing" />
        <exclude name="Squiz.Commenting.FileComment.MissingPackageTag" />
        <exclude name="Squiz.Commenting.ClassComment.Missing" />
        <exclude name="Squiz.Commenting.FunctionComment.Missing" />
        <exclude name="Squiz.Commenting.FunctionComment.MissingParamTag" />
        <exclude name="Squiz.Commenting.VariableComment.Missing" />
        <exclude name="Squiz.Commenting.InlineComment.InvalidEndChar" />

        <!-- Write shorter -->
        <exclude name="Universal.Arrays.DisallowShortArraySyntax.Found" />
        <exclude name="Generic.Arrays.DisallowShortArraySyntax.Found" />
        <exclude name="Generic.PHP.DisallowShortOpenTag.EchoFound" />
        <exclude name="Generic.Commenting.DocComment.SpacingBeforeTags" />
        <exclude name="Squiz.PHP.EmbeddedPhp.NoSemicolon" />
        <exclude name="WordPress.Classes.ClassInstantiation.MissingParenthesis" />
        <exclude name="Universal.Operators.DisallowShortTernary.Found" />
        <exclude name="WordPress.PHP.DisallowShortTernary.Found" />
        <exclude name="PSR12.Classes.ClassInstantiation.MissingParentheses" />

        <!-- Optional -->
        <exclude name="PEAR.Functions.FunctionCallSignature.ContentAfterOpenBracket" />
        <exclude name="PEAR.Functions.FunctionCallSignature.CloseBracketLine" />
        <exclude name="PEAR.Functions.FunctionCallSignature.MultipleArguments" />
        <exclude name="WordPress.PHP.YodaConditions.NotYoda" />
    </rule>

    <rule ref="Generic.Arrays.DisallowLongArraySyntax" />

    <!-- Set the minimum supported WP version. This is used by several sniffs.
         The minimum version set here should be in line with the minimum WP version
         as set in the "Requires at least" tag in the readme.txt file. -->
    <config name="minimum_supported_wp_version" value="5.9"/>

    <rule ref="WordPress.WP.I18n">
        <properties>
            <property name="text_domain" type="array">
                <element value="slim-seo-link-manager"/>
                <element value="slim-seo"/>
            </property>
        </properties>
    </rule>

    <rule ref="WordPress.NamingConventions.PrefixAllGlobals">
        <properties>
            <property name="prefixes" type="array">
                <element value="SlimSEOPro\LinkManager"/>
                <element value="SlimSEO"/>
                <element value="slim_seo_link_manager"/>
                <element value="slim_seo"/>
            </property>
        </properties>
    </rule>

    <!--
    #############################################################################
    USE THE PHPCompatibility RULESET
    #############################################################################
    -->
    <config name="testVersion" value="7.2-"/>
    <rule ref="PHPCompatibilityWP"/>
</ruleset>

To reproduce

After installing dependencies, when I run the following commands nothing is outputted in the console:

./vendor/bin/phpcs -v
./vendor/bin/phpcs -h
./vendor/bin/phpcs -p .

I also run them with variations like setting the --standard="phpcs.xml" or set the folder to ./src/, etc. - still no luck.

Versions (please complete the following information)

Operating System MacOS Big Sur 11.5 (chip Apple M1)
PHP version 8.2.1
PHP_CodeSniffer version 3.8.0
Standard WordPress
Install type Composer local (works find with Composer global)

Additional context

I tried to add some die to the vendor/squizlabs/php_codesniffer folder to debug, and found that the code stops at autoload.php file, on this line:

https://github.com/squizlabs/PHP_CodeSniffer/blob/master/autoload.php#L77

It seems to load Composer's autoload, and then stops.

I don't know how to debug further.

Please take a look.

Please confirm:

jrfnl commented 11 months ago

@rilwis I've tried, but cannot reproduce your issue.

This is what I did to try and reproduce the issue:

FILE: path/to/phpcs-3880/test.php

FOUND 1 ERROR AFFECTING 1 LINE

3 | ERROR | All output should be run through an escaping function (see the Security sections in the WordPress Developer Handbooks), found '$var'. | | (WordPress.Security.EscapeOutput.OutputNotEscaped)



In other words, without more information to allow someone to reproduce your issue, there is nothing anyone can do.

It might help to know what versions of various packages are installed and on which OS, but you removed the "Versions" table from the bug report template.

P.S.: [WordPressCS 3.0.0 has been released](https://make.wordpress.org/core/2023/08/21/wordpresscs-3-0-0-is-now-available/), so I suggest you update your `require-dev` to use `^3.0` for the `wp-coding-standards/wpcs` package.
More info in the [changelog](https://github.com/WordPress/WordPress-Coding-Standards/releases/tag/3.0.0) and [upgrade guide](https://github.com/WordPress/WordPress-Coding-Standards/wiki/Upgrade-Guide-to-WordPressCS-3.0.0-for-ruleset-maintainers).
rilwis commented 10 months ago

@jrfnl

That's strange.

When I replicate your test with the same steps, I see it works as you described.

However, when I check with my code, I can't find anything wrong. I recorded a screencast so you can see what I'm doing:

https://mega.nz/file/X6w0BZQR#8z7GAtfTPlxpWTcQDWIEKrFIXKafcyGMaaE28mvkaPg

I also updated the issue with "Versions" section for more details.

fredden commented 10 months ago

@rilwis I can see that you've listed the PHP_CodeSniffer version as 3.8.0, but that version does not exist currently: https://github.com/squizlabs/PHP_CodeSniffer/tags. Please can you confirm what version you're using, and perhaps how you've installed PHP_CodeSniffer? I don't see this listed in the composer.json file supplied, so I have to assume that it's installed somewhere else on your system. If you install it directly into this project (with composer require --dev squizlabs/php_codesniffer), does this work as expected?

fredden commented 10 months ago

I've watched the video now. I wonder if this is a duplicate of https://github.com/composer/composer/issues/11555. @rilwis please can you confirm what version of Composer you are using? Please can you also compare the output of vendor/bin/phpcs -i with vendor/squizlabs/php_codesniffer/bin/phpcs -i?

Edit: upon further reflection, this can't be a duplicate of that bug, because PHP_CodeSniffer doesn't check $_SERVER['SCRIPT_NAME'].

Edit2: please can you supply the last few lines of vendor/bin/phpcs? I'm expecting this to end with include __DIR__ . '/..'.'/squizlabs/php_codesniffer/bin/phpcs';

fredden commented 10 months ago

When I replicate your test with the same steps, I see it works as you described.

The steps there include removing all the "elightup" packages. Might they be causing this issue? @rilwis please can you confirm if the bug exists with/without these packages?

jrfnl commented 10 months ago

@rilwis Just watched the video and in the video you mention something "cleaning the vendor/bin" directory (and that also shows at the end of the composer install). I'm 99% sure that will be your problem and that is something we can't help you with as PHPCS does not supply that tooling, nor have I ever heard of it before.

[1:08] I can also see in the video that before the cleaning, PHPCS is installed correctly as the Composer PHPCS installer plugin does its work and gives output - the "installed _paths set to ..." bit in the composer install output before the cleaning and as that plugin uses PHPCS natively under the hood, PHPCS is installed correctly at that point.

So my suggestion would be to get rid of whatever tooling that is "cleaning" (breaking) the vendor/bin directory as that is probably your problem.

fredden commented 10 months ago

I also noticed in the video that after modifying composer.json in your text editor, you only run composer install and don't actually re-install any files. There's a warning from Composer that its content-hash no longer matches. The "cleaned" files are probably still there; I'd recommend deleting all of vendor/ when making changes such as that, before running composer install to get Composer to put the files in place.

rilwis commented 10 months ago

Sorry for the late reply. I've just back from a holiday.

Regarding the questions, I've recorded a new video to show you a whole process:

https://mega.nz/file/amIDVBYY#LTAmlDnEaiw9M89RvcMwE-_cuk1rQmGpp4h1jMKna1k

What I did:

Note that I have phpcs installed on my machine globally, so when I run phpcs -v, it outputs things correctly. Only the local version of phpcs, which is ./vendor/bin/phpcs, doesn't output anything.

fredden commented 10 months ago

Thanks for the update @rilwis. I notice in this new video that you are still not installing the packages that you think you are. This is because you do not modify the composer.lock file when making changes to the composer.json file in your editor. There's a warning from Composer when you run composer install saying this too.

Please can you try again with this script. None of this requires you to leave the terminal / use your editor.

# set up
set -x
cd $(mktemp -d)
git clone git@github.com:elightup/slim-seo-link-manager.git .

# confirm bug is still present
composer install
vendor/bin/phpcs -i

# remove packages not available to the public
composer config --unset repo.1
composer config --unset repo.0
composer config --unset extra.dev-files
composer remove elightup/plugin-updater elightup/plugin-search

# test if bug still persists
vendor/bin/phpcs -i
vendor/bin/phpcs -v

# some diagnostics
head -n 1 vendor/bin/phpcs
type php
php --version
composer --version
composer show
composer global show
composer global depends composer-plugin-api
rilwis commented 10 months ago

@fredden

Thanks for the scripts. Here are the screenshots:

1

2

3

4

I guess it's working after removing packages. But don't know why.

jrfnl commented 10 months ago

@rilwis This sounds like it just confirms that this is not a PHPCS problem, but a problem with one or both of those two (private) packages. I suggest you report your issue there.

rilwis commented 10 months ago

After testing again with some commands, I found that when I run:

composer remove elightup/plugin-search

Then the command ./vendor/bin/phpcs -i works again.

However, when I require elightup/plugin-search, then it failed.

Digging a little deeper, in the repo elightup/plugin-search, the autoload rule loads a file bootstrap.php, which contains some code for WordPress specifically. When running vendor/bin/phpcs -i, this file is also loaded. And because this is not a WordPress installation, the bootstrap.php file causes an error and makes the script fails.

I think it can be mentioned somehow in the docs, that any autoload files must run properly in the CLI environment, in order to not break phpcs.

I think this issue can be closed now.

Thank you very much for your help!

jrfnl commented 10 months ago

I think it can be mentioned somehow in the docs, that any autoload files must run properly in the CLI environment, in order to not break phpcs.

That is not just an issue for PHPCS, but for literally every tool out there. If you have a files autoload directive, it is a given that that file should always run without side-effects.

BrianHenryIE commented 7 months ago

I had the same problem here. It was inside my own code being autoloaded with a files autoloader.


    "autoload": {

        "files": [
            "lib/functions.php"
        ]
    },

I at the top of functions.php I had:

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

which I changed to

if ( ! defined( 'ABSPATH' ) ) {
    return;
}

and things began to work again.

hinnerk-a commented 1 month ago

@BrianHenryIE Same fix here. Thanks a lot! Great job, made my day!