Rockstar04/SublimeLinter-contrib-phpstan

Doesn't seem to lint

Closed this issue · 6 comments

// SublimeLinter Settings - User
{
    "debug": true,

    "lint_mode": "background",
    "linters": {
        "phpstan": {
            "paths": {
                "linux": [],
                "osx": ["/opt/homebrew/bin/phpstan"],
                "windows": []
            }
        }
    }
}
// Sublime console
....pathAutoLoad = configPath.replace("/phpstan.neon", "/vendor/autoload.php")
AttributeError: 'NoneType' object has no attribute 'replace'
SublimeLinter: backend.py:283         Linting 'DevotionalController.php' with phpstan took 0.00s
    def cmd(self):
        cmd = ["phpstan", "analyse"]
        opts = ["--error-format=json", "--no-progress", "--level=9"]

I added the --level=9 to the linter.py to see if it was the level.

/opt/homebrew/bin/phpstan analyse app/Http/Controllers/DreamController.php --level=9
 1/1 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%

 ------ -------------------------------------------------------------------------------------------------------------
  Line   DreamController.php
 ------ -------------------------------------------------------------------------------------------------------------
  19     Method App\Http\Controllers\DreamController::index() has no return type specified.
  22     Cannot call method cannot() on mixed.
  28     Cannot call method dreams() on mixed.
  40     Cannot call method cannot() on mixed.
  51     Cannot call method cannot() on mixed.
  56     Cannot call method dreams() on mixed.
  65     Cannot call method cannot() on mixed.
  69     Cannot call method dreams() on Illuminate\Contracts\Auth\Authenticatable|null.
  76     Cannot call method cannot() on mixed.
  86     Cannot call method cannot() on mixed.
  90     Parameter #1 $attributes of method Illuminate\Database\Eloquent\Model::update() expects array, mixed given.
  98     Method App\Http\Controllers\DreamController::destroy() has no return type specified.
  100    Cannot call method cannot() on mixed.
  111    Method App\Http\Controllers\DreamController::isLord() has no return type specified.
  111    Method App\Http\Controllers\DreamController::isLord() is unused.
 ------ -------------------------------------------------------------------------------------------------------------



 [ERROR] Found 15 errors

Running the same level in the terminal does work... I don't know much about SublimeText api to create plugins. I'm not sure if the opts = [] it is where I should add the --level=9 just to test if the linter is actually working. But, it seems that SublimeLinter indeed is calling the plugin...

SublimeLinter: backend.py:283         Linting 'DevotionalController.php' with phpstan took 0.00s
Screenshot 2024-10-09 at 9 47 03 PM

Let me know how I can help.

I want to give an update of my troubleshooting

    def cmd(self):
        cmd = ["phpstan", "analyse"]
        opts = ["--error-format=json", "--no-progress"]

        # configPath = self.find_phpstan_configuration(self.view.file_name())

        # if configPath:
        #     opts.append("--configuration={}".format(quote(configPath)))

        # autoload_file = self.find_autoload_php(configPath)

        # if autoload_file:
        #     opts.append("--autoload-file={}".format(quote(autoload_file)))

        #     cmd[0] = autoload_file.replace("/autoload.php", "/bin/phpstan")
        # else:
        #     print("⚠️ Fallback on PHPStan installed globally")

        return cmd + ["${args}"] + opts + ["--", "${file}"]

I commented out these line and the Errors started showing up in the editor.

Hello,

Now this plugin tries to find a file phpstan.neon in the folder of the linted file or in one parent directory. Once found, it assumes that /vendor is beside phpstan.neon to resolve /vendor/autoload.php. Modern PHP projects are structured that way and it eases a lot the code of this plugin.

If your PHP project does not follow that structure, indeed it might be better to hardcode the path of phpstan.neon and /vendor/autoload.php in the plugin.

You can know the value of any resolved values by using the keyword print() in the plugin for the related value, then it would be shown in the console.

Hello,

Now this plugin tries to find a file phpstan.neon in the folder of the linted file or in one parent directory. Once found, it assumes that /vendor is beside phpstan.neon to resolve /vendor/autoload.php. Modern PHP projects are structured that way and it eases a lot the code of this plugin.

If your PHP project does not follow that structure, indeed it might be better to hardcode the path of phpstan.neon and /vendor/autoload.php in the plugin.

You can know the value of any resolved values by using the keyword print() in the plugin for the related value, then it would be shown in the console.

Interesting because the project I'm working with is the latest laravel project. Indeed I do have ./vendor/autoload.php.

I do not use Laravel but I just tested with a fresh new Laravel project and it works well.

I see in your log this message:

....pathAutoLoad = configPath.replace("/phpstan.neon", "/vendor/autoload.php")
AttributeError: 'NoneType' object has no attribute 'replace'

It seems it cannot find phpstan.neon and then it fails when trying to resolve /vendor/autoload.php.

I need to strengthen this to avoid this error when phpstan.neon is not found.

I do not use Laravel but I just tested with a fresh new Laravel project and it works well.

I see in your log this message:

....pathAutoLoad = configPath.replace("/phpstan.neon", "/vendor/autoload.php")
AttributeError: 'NoneType' object has no attribute 'replace'

It seems it cannot find phpstan.neon and then it fails when trying to resolve /vendor/autoload.php.

I need to strengthen this to avoid this error when phpstan.neon is not found.

Yeah, in my case I did brew install phpstan and have the executable somewhere else. I updated the SublimeLinter settings to point to the correct executable rather than having an extra file in the repo. I can also use the SublimeLinter settings to pass flags to the phpstan executable.

I suggest installing PHPStan per project, as explained in the official documentation of PHPStan.
I also used a globally installed PHPStan before but that is not as handy as a local one (brew is a bit troublesome to update everything also..). Also, it is better for everyone working on the project, to share the same linter and config.

Can we consider this issue as closed?