Giter Site home page Giter Site logo

phpstan.el's Introduction

phpstan.el

MELPA: phpstan MELPA stable: phpstan

Emacs interface to PHPStan, includes checker for Flycheck.

Support version

  • Emacs 24+
  • PHPStan latest/dev-master (NOT support 0.9 seriese)
  • PHP 7.1+ or Docker runtime

How to install

Install from MELPA

  1. If you have not set up MELPA, see Getting Started - MELPA.
  2. M-x package-install flycheck-phpstan

How to use

For Flycheck user

(defun my-php-mode-setup ()
  "My PHP-mode hook."
  (require 'flycheck-phpstan)
  (flycheck-mode t))

(add-hook 'php-mode-hook 'my-php-mode-setup)

For Flymake user

(add-hook 'php-mode-hook #'flymake-phpstan-turn-on)

Using Docker (phpstan/docker-image)

Install Docker and phpstan/phpstan image.

If you always use Docker for PHPStan, add the following into your .emacs file (~~/.emacs.d/init.el~)

(setq-default phpstan-executable 'docker)

Put the following into .dir-locals.el files on the root directory of project.

((nil . ((php-project-root . git)
         (phpstan-executable . docker)
         (phpstan-working-dir . (root . "path/to/dir"))
         (phpstan-config-file . (root . "path/to/dir/phpstan-docker.neon"))
	 (phpstan-memory-limit . "1G")
         (phpstan-level . 7))))

Using composer (project specific)

If your project Composer relies on phpstan, you do not need to set anything.

((nil . ((php-project-root . git)
         (phpstan-executable . docker)
         (phpstan-working-dir . (root . "path/to/dir"))
         (phpstan-config-file . (root . "path/to/dir/phpstan-docker.neon"))
         (phpstan-level . 7))))

Using Composer

Please install phpstan/phpstan package for each user environment or project by using Composer.

If you are unfamiliar with resolving dependencies, the following shell commands are recommended.

$ composer global require phpstan/phpstan

NOTICE: phpstan/phpstan-shim is deprecated. Please read PHPStan 0.12 Released!.

Using PHAR archive

NOTICE: phpstan.el requires PHPStan **0.10+**. We strongly recommend using the latest PHPStan.

Please download phpstan.phar from Releases · phpstan/phpstan.

Settings

Variables for phpstan are mainly controlled by directory variables (.dir-locals.el).

Frequently (root. "path/to/file") notation appears in these variables. It is relative to the top level directory of the project. In general, the directory containing one of .projectile, composer.json, .git file (or directory) is at the top level.

Please be aware that the root directory of the PHP project may NOT match either of PHPStan’s %rootDir% and/or %currentWorkingDirectory%.

Typically, you would set the following .dir-locals.el.

((nil . ((php-project-root . auto)
         (phpstan-executable . docker)
         (phpstan-working-dir . (root . "path/to/dir/"))
         (phpstan-config-file . (root . "path/to/dir/phpstan-custom.neon"))
         (phpstan-level . max))))

If there is a phpstan.neon file in the root directory of the project, you do not need to set both phpstan-working-dir and phpstan-config-file.

API

Most variables defined in this package are buffer local. If you want to set it for multiple projects, use setq-default.

Local variable phpstan-working-dir

Path to working directory of PHPStan.

STRING
Absolute path to `phpstan’ working directory.
  • ex) ~”/path/to/phpstan.phar”~
(root . STRING)
Relative path to `phpstan’ working directory from project root directory.
  • ex) (root . "path/to/dir")
nil
Use (php-project-get-root-dir) as working directory.

Local variable phpstan-config-file

Path to project specific configuration file of PHPStan.

STRING
Absolute path to phpstan configuration file.
(root . STRING)
Relative path to phpstan configuration file from project root directory.
NIL
Search phpstan.neon(.dist) in (phpstan-get-working-dir).

Local variable phpstan-level

Rule level of PHPStan analysis. Please see README #Rule levels of PHPStan. 0 is the loosest and you can also use max as an alias for the highest level. Default level is 0.

Local variable phpstan-executable

STRING
Absolute path to `phpstan’ executable file.
  • ex) ~”/path/to/phpstan.phar”~
SYMBOL docker
Use Docker using phpstan/docker-image.
(root . STRING)
Relative path to `phpstan’ executable file from project root directory.
  • ex) (root . "script/phpstan")
(STRING . (ARGUMENTS ...))
Command name and arguments.
  • ex) ("docker" "run" "--rm" "-v" "/path/to/project-dir/:/app" "your/docker-image")
nil
Auto detect phpstan executable file by composer dependencies of the project or executable command in PATH environment variable.

Custom variable phpstan-flycheck-auto-set-executable

Set flycheck phpstan-executable automatically when non-NIL.

Custom variable phpstan-memory-limit

Use phpstan memory limit option when non-NIL.

STRING
Specifies the memory limit in the same format php.ini accepts.
  • ex) ~”1G”~
nil
Use memory limit in php.ini

Custom variable phpstan-docker-image

Docker image URL or Docker Hub image name or NIL. Default as ~”ghcr.io/phpstan/phpstan”~. See Docker - PHPStan Documentation and GitHub Container Registory - Package phpstan.

phpstan.el's People

Contributors

alypeng avatar conao3 avatar fuco1 avatar herbertjones avatar jcs090218 avatar kermorgant avatar markredeman avatar yisraeldov avatar yosatak avatar zonuexe avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

phpstan.el's Issues

[flycheck] Maybe remove :enabled check

Currently the logic looks for the phpstan.neon file to enable the checker.

I store this file inside app/ or tests/ directories with a bit different configurations for each scenario and thus the check would never trigger. I'm not sure if it's worth to have this check as phpstan also works without config and people often don't have any, especially on smaller projects.

What I do now is I pass the config via the -c option dynamically (I set this as buffer-local-variable in my php init hook). I have a pull request in the making that will add this option to flycheck as well.

WDYT?

Relative phpstan executable generates elisp errors.

My .dir-locals.el file looks like this:

((php-mode
  (flycheck-checker . phpstan)
  (php-project-root . git)
  (phpstan-executable . (root . "untracked/vendor/bin/phpstan"))
  ))

When I open one of my PHP files, I get presented with this error from flycheck:

Error while checking syntax automatically: (error "Invalid result from evaluation of (phpstan-get-command-args): (47 104 111 109 101 47 107 101 110 110 101 116 104 47 101 120 97 109 112 108 101 47 117 110 116 114 97 99 107 101 100 47 118 101 110 100 111 114 47 98 105 110 47 112 104 112 115 116 97 110 \"analyze\" \"--errorFormat=raw\" \"--no-progress\" \"--no-interaction\" \"-c\" \"/home/kenneth/example/phpstan.neon.dist\" \"-l\" \"0\")")

If I change the .dir-locals.el to use the equivalent absolute path, it works fine:

((php-mode
  (flycheck-checker . phpstan)
  (php-project-root . git)
  (phpstan-executable . "/home/kenneth/example/untracked/vendor/bin/phpstan")
  ))

I would expect these two cases to have equivalent behaviour.

Confused about `phpstan-working-dir`

Hi, thanks for this great package!

I'm a bit confused about the usage of the phpstan-working-dir variable.

I'm trying to setup phpstan.el so that I don't have to have a phpstan.neon file in a project.
I got this working by setting (setq phpstan-working-dir ".") so that the enabled check passes, however this seems very hacky.

Could you explain to me the use of phpstan-working-dir? The documentation mentions it should be different than the project root but doesn't give an explicit example.


In addition, I think I've found a bug while trying to figure out the use case of phpstan-working-dir. I tried the same "hack" (not having a phpstan.neon file and setting (setq phpstan-working-dir ".")) when using Docker.
In this case phpstan-get-config-file returns NIL which is passed to phpstan-normalize-path however since prefix is set to /app the function throws an error

Debugger entered--Lisp error: (wrong-type-argument arrayp nil)
  replace-regexp-in-string("\\`/home/mark/Projects/testing-phpstan/" "" nil t t)

This is easily fixed by changing the function:

(defun phpstan-normalize-path (source-original &optional source)
  "Return normalized source file path to pass by `SOURCE-ORIGINAL' OR `SOURCE'.

If neither `phpstan-replace-path-prefix' nor executable docker is set,
it returns the value of `SOURCE' as it is."
  (let ((root-directory (expand-file-name (php-project-get-root-dir)))
        (prefix
         (or phpstan-replace-path-prefix
             (cond
              ((eq 'docker phpstan-executable) "/app")
              ((and (consp phpstan-executable)
                    (string= "docker" (car phpstan-executable))) "/app")))))
-    (if prefix
+    (if (and prefix source-original)
        (expand-file-name
         (replace-regexp-in-string (concat "\\`" (regexp-quote root-directory))
                                   ""
                                   source-original t t)
         prefix)
      (or source source-original))))

I'm happy to send a PR to fix the above issue however, it seems quite hacky.

Flymake

I'm creating this issue just to be notified if/when flymake support gets implemented

phpstan-flycheck will block phpmd and phpcs from running.

I'm not sure if this is an issue with flycheck or the phpstan-flycheck

the other php flychecks don't run.

(flycheck-add-next-checker 'php 'phpstan)

That pretends it to the list of next checkers for php.

but even if I change it to append it still doesn't work. It will run all the other checkers but not get to phpspec.

If I modify flycheck.el and manually add phpstan to next-checkers of php and php-cs.

Then it works. It seems like flycheck doesn't honor the next-checkers list and they know it.

Unable to enable phpstan.

Just installed the latest phpstan-el (10-3-2020 Latest commit a1c30ca) and flycheck-phpstan.

Now (phpstan-get-executable) says : ("/home/rgr/.config/composer/vendor/bin/phpstan") since I installed using "composer g require phpstan/phpstan". But its listed as disabled with a different executable. I enabled (C-u C-c ! x). I added it to to flycheck-checkers. But I cant get it enabled.

Bildschirmfoto vom 2020-03-10 14-50-22

Am I missing something obvious?

"Flycheck cannot use this syntax checker for this buffer."

Relevant lines in my init.el:

(defun my/php-mode-hook ()
  "Gets run on php-mode load."
  (make-local-variable 'company-backends)
  (add-to-list 'company-backends 'company-phpactor)
  (flycheck-select-checker 'phpstan)
  (setq php-mode-coding-style 'psr2
        c-basic-offset 4)
  (when (eq 0 (buffer-size))
    (insert "<?php\n\n")))

(use-package php-mode :ensure t
  :init (add-hook 'php-mode-hook #'my/php-mode-hook))
(use-package flycheck-phpstan :ensure t :after (php-mode flycheck))

The buffer that appears when I open PHP file:

Syntax checker in buffer MyFile.php in php-mode:

  phpstan (disabled)
    - major mode: `php-mode' supported
    - may enable: Automatically disabled!
    - executable: Found at /usr/local/bin/php

Flycheck cannot use this syntax checker for this buffer.

Flycheck Mode is enabled.  Use C-u C-c ! x to enable disabled
checkers.

--------------------

Flycheck version: 32snapshot (package: 20180422.2106)
Emacs version:    26.1
System:           x86_64-apple-darwin17.5.0
Window system:    ns

PHPStan Project Version - installed using project's composer.
PHPStan - PHP Static Analysis Tool dev-master@de7fd7d

phpstan.neon, but no phpstan executable chokes flyspell

Seems that if flycheck-phpstan finds a config file, but can't find a phpstan executable, it manages to error in a way that makes flycheck toss its cookies and never show any new errors for the buffer.

I install phpstan in vendor/bin and don't have any global install, which works fine. But in a project where there's a phpstan.neon, but phpstan haven't been installed, flycheck dies after the first check, and then seems to be in a permanent running state (at least according to doom-modeline).

Disabling the phpstan checker makes thing work when opening new buffers.

Running flycheck-compile and selecting the phpstan checker gives a "PHPStan executable not found" error, which I've traced to phpstan-get-executable.

I'm a bit surprised that flycheck apparently keels over because of the error thrown, I would have thought it would ignore the checker and carry on, but apparently not. On the other hand, it does force checker writers to handle errors and not rely on flycheck picking up the pieces.

I would think a possible solution would be having flycheck-phpstan--enabled-and-set-variable check if the executable could be found and return nil in case of error.

error : "Could not open input file: analyze"

Hi,

Thank you for your work on this package.

I'm been using spacemacs (develop branch) and phpstan separately for some time, but after having discovered this package, I wanted to give it a try.

I tried with phpstan installed globally and falled back to docker, but had the same error on both attempts

Suspicious state from syntax checker phpstan: Flycheck checker phpstan returned non-zero exit code 1, but its output contained no errors: Could not open input file: analyze

Can that error message tell what is wrong with my setup ?

I'm using this in .dir-locals.el

((nil . ((php-project-root . git)
         (phpstan-executable . docker)
         (phpstan-working-dir . (root . "."))
         (phpstan-config-file . (root . "./phpstan.neon"))
         (phpstan-level . 7))))

Then, I've begun a private php layer where I initialize some things and which could contain the source of this error, but it is more a spacemacs thing so I'lle leave it out for now.

Fails when open a phpfile not in a project

phpstan-get-config-file will try to call expand-file-name with a nil directory if a project directory is not found.

Debugger entered--Lisp error: (wrong-type-argument stringp nil)
  expand-file-name(nil)
  locate-dominating-file(nil "phpstan.neon")
  phpstan-get-config-file()
  flycheck-phpstan--enabled-and-set-variable()
  #[0 "\300 \207" [flycheck-phpstan--enabled-and-set-variable] 1]()
  #[0 "\302\300!\205��\303\300!\205��\301?\206��\301 \207" [phpstan #[0 "\300 \207" [flycheck-phpstan--enabled-and-set-variable] 1] flycheck-find-checker-executable flycheck-temp-files-writable-p] 2]()
  #[0 "\303\300!\203��\301?\206��\304\300!�\301 )\207\305\306\307\310\300$\210\311\207" [phpstan #[0 "\302\300!\205��\303\300!\205��\301?\206��\301 \207" [phpstan #[0 "\300 \207" [flycheck-phpstan--enabled-and-set-variable] 1] flycheck-find-checker-executable flycheck-temp-files-writable-p] 2] default-directory flycheck-valid-checker-p flycheck-compute-working-directory lwarn flycheck :warning "%S is no valid Flycheck syntax checker.\nTry to reinstall the package defining this syntax checker." nil] 5]()
  flycheck-may-enable-checker(phpstan)
  flycheck-may-use-checker(phpstan)
  flycheck-may-use-next-checker(phpstan)
  #[257 "\300�!\205\n�\301\302�\"\207" [flycheck-may-use-next-checker throw seq--break] 4 "\n\n(fn ELT)"](phpstan)
  mapc(#[257 "\300�!\205\n�\301\302�\"\207" [flycheck-may-use-next-checker throw seq--break] 4 "\n\n(fn ELT)"] (phpstan phpstan (warning . php-phpmd) (warning . php-phpcs)))
  seq-do(#[257 "\300�!\205\n�\301\302�\"\207" [flycheck-may-use-next-checker throw seq--break] 4 "\n\n(fn ELT)"] (phpstan phpstan (warning . php-phpmd) (warning . php-phpcs)))
  seq-find(flycheck-may-use-next-checker (phpstan phpstan (warning . php-phpmd) (warning . php-phpcs)))
  flycheck-get-next-checker-for-buffer(php)
  flycheck-finish-current-syntax-check(nil "~/")
  flycheck-report-buffer-checker-status([cl-struct-flycheck-syntax-check #<buffer test.php> php #<process flycheck-php> "~/"] finished nil)
  apply(flycheck-report-buffer-checker-status [cl-struct-flycheck-syntax-check #<buffer test.php> php #<process flycheck-php> "~/"] (finished nil))
  #[128 "\301\302\300�#\207" [[cl-struct-flycheck-syntax-check #<buffer test.php> php #<process flycheck-php> "~/"] apply flycheck-report-buffer-checker-status] 5 "\n\n(fn &rest ARGS)"](finished nil)
  flycheck-finish-checker-process(php 0 ("/tmp/flycheck27758vYe/test.php" "/tmp/flycheck27758vYe") "No syntax errors detected in /tmp/flycheck27758vYe/test.php\n" #[128 "\301\302\300�#\207" [[cl-struct-flycheck-syntax-check #<buffer test.php> php #<process flycheck-php> "~/"] apply flycheck-report-buffer-checker-status] 5 "\n\n(fn &rest ARGS)"] "~/")
  flycheck-handle-signal(#<process flycheck-php> "finished\n")

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.