vim ale で phpmd, phpcs を使ってカスタマイズする

私の vim 環境では ALE (Asynchronous Lint Engine) で非同期構文チェックをしている.
デフォルトだと全ての lint tools が走るので, 特定のツールだけ走るように設定する.

今回は phpmd, phpcs について.
概要は次の通り.

動作環境

  • macOS Mojave 10.14.x
  • vim 8.1

今回やりたいこと

コードを書く時に構文解析をしたい.
php に関しては phpcs, phpmd を利用して規約チェックもしたい.

多くの場合, この辺のルールはプロジェクト毎に異なるので local に落としてきたプロジェクトディレクトリに設定する.

phpcs, phpmd どちらもカスタマイズして使う予定.
inst. 方法というよりもカスタマイズ方法に注力してまとめてゆく.

前提条件

  • composer inst. 済
    • PATH も通しておくこと
  • 躓いたら公式サイトやヘルプを眺める

事前に ale のヘルプを読めるようにしておくといいかも.

Generating Vim help files

You can add the following line to your vimrc files to generate documentation tags automatically, if you don’t have something similar already, so you can use the :help command to consult ALE’s online documentation:

” Put these lines at the very end of your vimrc file.

” Load all plugins now.
” Plugins need to be added to runtimepath before helptags can be generated.
packloadall
” Load all of the helptags now, after plugins have been loaded.
” All messages and errors will be ignored.
silent! helptags ALL

引用: Generating Vim help files

phpmd, phpcs の簡単な説明

phpmd, phpcs ができることをざっとまとめる.

phpmd

できることは次の通り.

What PHPMD does is: It takes a given PHP source code base and look for several potential problems within that source. These problems can be things like:

  • Possible bugs
  • Suboptimal code
  • Overcomplicated expressions
  • Unused parameters, methods, properties

未使用変数, 長過ぎるプロパティ名等をチェックしてくれる.

phpcs

できることは次の通り.

PHP_CodeSniffer is a set of two PHP scripts; the main phpcs script that tokenizes PHP, JavaScript and CSS files to detect violations of a defined coding standard,
and a second phpcbf script to automatically correct coding standard violations.
PHP_CodeSniffer is an essential development tool that ensures your code remains clean and consistent.

コーディング規約違反を静的に検出してくれる.

phpmd カスタマイズ

install

公式サイトに従って inst.

global inst. したいなら次のコマンドでもいいかも.

$ composer global require phpmd/phpmd

カスタマイズ

必要なルールだけチェックしてほしいのでカスタマイズする.

公式サイトにカスタマイズ方針も書かれている.

default のルールセット置き場はここ↓

  • vendor/phpmd/phpmd/src/main/resources/rulesets/

置いてある xml は次の通り.

  • cleancode.xml
  • codesize.xml
  • controversial.xml
  • design.xml
  • naming.xml
  • unusedcode.xml

各ファイルについての説明はここに書いてある↓

  • Clean Code Rules
    • The Clean Code ruleset contains rules that enforce a clean code base. This includes rules from SOLID and object calisthenics.
  • Code Size Rules
    • The Code Size Ruleset contains a collection of rules that find code size related problems.
  • Controversial Rules
    • This ruleset contains a collection of controversial rules.
  • Design Rules
    • The Design Ruleset contains a collection of rules that find software design related problems.
  • Naming Rules
    • The Naming Ruleset contains a collection of rules about names – too long, too short, and so forth.
  • Unused Code Rules
    • The Unused Code Ruleset contains a collection of rules that find unused code.

引用: Current Rulesets

ひとまず .vimrc に phpmd 実行パスを指定する.
実行パスは $ which phpmd で調査可能.

このあたりの情報は :h ale-php-phpmd で入手可能.

let g:ale_php_phpmd_executable = 'ここに $ which phpmd で得られる path を入力'

この時点で php ファイルを編集するとたとえば次のような warning が得られる.

Avoid using static access to class ‘\Illuminate\Support\Facades\Config’ in method ‘get’.

↑これは cleancode.xml の条件に引っかかって出力されたメッセージ.

特定の .xml だけを有効/無効にすることも可能.
たとえば controversial.xml のみ無効にするとこうなる↓

let g:ale_php_phpmd_ruleset = 'cleancode,codesize,design,naming'

各 rule sets 内で特定の rule を除外する手段は次のいずれか.

  • 直接 xml を編集
  • おれおれ xml を作成し, 既存 xml を呼び出し, さらに特定 rule を除外

今回は後者で対応する.

たとえば先程の static method に対する warning を除外するには <exclude name="StaticAccess" /> を利用すればいい.
試しに myphpmd.xml という新規ファイルを作成してみる.

<?xml version="1.0"?>
<ruleset
    name="My PHPMD rule set"
    xmlns="http://pmd.sf.net/ruleset/1.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd"
    xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd">
    <description>
    My PHPMD rule set
    </description>

    <!-- import rulesets -->
    <rule ref="rulesets/unusedcode.xml" />
    <rule ref="rulesets/cleancode.xml">
        <exclude name="StaticAccess" />
    </rule>
    <rule ref="rulesets/codesize.xml" />
    <rule ref="rulesets/design.xml" />
    <rule ref="rulesets/naming.xml" />
</ruleset>

もしこの ruleset を利用する場合は, 先程の phpmd ruleset 指定を変更する必要がある.

let g:ale_php_phpmd_ruleset = 'myphpmd'

こんな具合に不要な warning を除外していけば使いやくすくなるはず.

phpcs カスタマイズ

次は phpcs を ale 使う方法について.

install

composer で global に inst.

$ composer global require "squizlabs/php_codesniffer=*"

バージョンはプロジェクトに合わせて設定すること.
composer で必要な PATH は通しておくこと.

カスタマイズ

チェックする rule のカスタマイズについては PHP_CodeSniffer の wiki を参考にする.

各規約は次の場所に格納されている.

  • vendor/squizlabs/php_codesniffer/src/Standards/

規約は次のコマンドでも確認可能.

$ phpcs -i

デフォルトだと PEAR が standard として設定されているっぽい.
.vimrc で PSR-2 を指定.

let g:ale_php_phpcs_standard = 'PSR2'

これで PSR2 に従った warning や error が出力される.

phpmd 同様, 一度全ての rule を適用して不要なものを外してゆくと効率がいいかも.
個人的には PEAR, PSR2 の standard から不要な warning, error を外してゆくのがいいと思っている.

やってみる.

まず MyPSR2 というディレクトリを作成.

# ディレクトリごとコピー
$ cp -r PSR2 MyPSR2

# standards 確認
$ phpcs -i
The installed coding standards are PEAR, Zend, PSR2, MySource, Squiz, PSR1, MyPSR2 and PSR12

# MyPSR2 内にあるディレクトリの中身は不要なので空にする
$ rm -rf Docs/* Sniffs/* Tests/*

# ディレクトリ構成確認
$ ls -lah
total 24
drwxr-xr-x   6 kengo  staff   192B  2  2 20:04 .
drwxr-xr-x  11 kengo  staff   352B  2  2 20:04 ..
drwxr-xr-x   2 kengo  staff    64B  2  2 20:10 Docs
drwxr-xr-x   2 kengo  staff    64B  2  2 20:10 Sniffs
drwxr-xr-x   2 kengo  staff    64B  2  2 20:10 Tests
-rw-r--r--   1 kengo  staff    10K  2  2 20:04 ruleset.xml

次に ruleset.xml を編集してゆく.
ゴールは PEAR, PSR2 のいいとこ取りだが, 一先ず PSR2 のみ include しておく.
後々除外する warning 等が出てくるだろうから次のような構成にした.

<?xml version="1.0"?>
<ruleset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="MyPSR2" xsi:noNamespaceSchemaLocation="../../../phpcs.xsd">
    <description>MyPSR-2 coding standard</description>

    <!-- Include the whole PSR-2 standard -->
    <rule ref="PSR2">
    </rule>
</ruleset>

ここまでできたら .vimrc で MyPSR2 を指定する.

let g:ale_php_phpcs_standard = 'MyPSR2'

phpcbf もこれまで同様に設定しておくと大量に warnings が出たときに修正が楽になる.
:ALEFix コマンドはここで力を発揮する.
ただし, この自動変換はプロジェクトに依存するところが大きいので取扱い注意.

今回の作業で追記した .vimrc

少し無関係の箇所もあるけど, 一旦 .vimrc の変更点もまとめる.

"" set linters
let g:ale_linters = {
\   'php': ['phpcs', 'phpmd', 'php -l'],
\   'python': ['pylint']
\}
"" phpmd
let g:ale_php_phpmd_executable = '/path/to/phpmd'
let g:ale_php_phpmd_ruleset = 'myphpmd'
""" keymaps
""" jump to next/previous warning
nmap <silent> <C-k> <Plug>(ale_previous_wrap)
nmap <silent> <C-j> <Plug>(ale_next_wrap)
"" phpcs
let g:ale_php_phpcs_executable = '/path/to/phpcs'
let g:ale_php_phpcs_standard = 'MyPSR2'
"" phpcbf
let g:ale_php_phpcbf_executable = '/path/to/phpcbf'
let g:ale_php_phpcbf_standard = 'PSR2'
"" fixer
let g:ale_fixers = {
\   'php': ['phpcbf']
\}

まとめ

基本的には公式サイトに全部手順が書いてあるけど, 実際手を動かしてみないと分からないことが多い.
たとえば次のようなもの.

  • プロジェクト毎に作成した オレオレphpmd.xml 管理方法
    • vendor/ 配下の特定 dir. を git 管理したり ?
  • ale による静的解析やコード整形の実行タイミング

このあたりは実際に運用しながらカスタマイズしてゆけばいいかな.
今回は以上.

スポンサーリンク
336 x 280 – レクタングル(大)
336 x 280 – レクタングル(大)
  • このエントリーをはてなブックマークに追加

この記事が気に入ったら
いいね!しよう

スポンサーリンク
336 x 280 – レクタングル(大)
トップへ戻る