やりたいこと
PHPMD(https://phpmd.org/) を利用する際に既存ルールを無視、あるいは閾値変更を行う
環境
PHP7.0
PHPMD 2.6.0
本題
PHPMDのチェックルールは以下の方法で定義されます。
- 実行時のオプション引数
- 実行時のオプション引数で設定するxmlファイル
- PHPMDインストールの際に作成されるデフォルトのruleset
ルール変更に関しては2番のxmlファイルを作成して行うのが一番使いやすいと思います。
設定ファイルの変更であれば、バージョン管理で簡単に変更履歴を追うことができるので。
ルールの変更に際して必要なのは
- xmlファイルの作成
- 必要なルールの読み込み
- 不要なルールの除外
- 変更したいルールの除外と読み込み
です。
xmlファイルの作成
公式サイト(https://phpmd.org/documentation/creating-a-ruleset.html) から雛型を借りてきます。
<?xml version="1.0"?>
<ruleset name="My first 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 custom rule set that checks my code...
</description>
</ruleset>
ファイル名は実行時に引数で指定するので、分かりやすい名前であればOKです。
phpmd.xml, ruluset.xml などが妥当だと思います。
PHPMDの実行時にこのファイルを指定することで、指定のルールセットを実行できるようになります。
必要なルールの読み込み
上記で作ったxmlファイルに必要なルールを読み込む設定を追加します。
ルールに関してはあらかじめルールセットという形でまとめて提供されています。
デフォルトで用意されているルールセットは
- cleancode.xml
- codesize.xml
- controversial.xml
- design.xml
- naming.xml
- unusedcode.xml
の6つです。
ルールの読み込みは<ruleset></ruleset>
内で行います。
<ruleset ...省略>
<rule ref="rulesets/codesize.xml" />
</ruleset>
上記のように<rule>
として、参照元を指定します。
refで指定している場所はプロジェクト内にcomposerでインストールした際には
vendor/phpmd/phpmd/src/main/resources/
になっているので、元ファイルを参照する際にはここで見れます。
またルールの読み込みは1つ1つのルール単位で行うことも可能です。
<rule ref="rulesets/cleancode.xml/BooleanArgumentFlag" />
上記のようにルール単体での指定も行えます。
cleancode.xmlの中には他に
- ElseExpression (else利用を禁止する)
- StaticAccess (static呼び出しを禁止する)
というルールがありますが、使うべき場面もあるので外すようにしています。
ルールセット中で適用したいルールが少ない場合はこのように適用したいルールのみを指定する方がわかりやすいです。
不要なルールの除外
ルールセット中から不要なルールを除外します。
先に行ったcleancode.xmlからの読み込みを、不要なものを除外するパターンで書くと以下のようになります。
<rule ref="rulesets/cleancode.xml">
<exclude name="ElseExpression" />
<exclude name="StaticAccess" />
</rule>
<rule>
内に <exclude>
ディレクティブを加えます。
これでルールセット内から不要なルールを除外することができます。
変更したいルールの除外と読み込み
最後に本題の一部ルール変更を行う場合です。
記法に少し注意が必要です。
<rule ref="rulesets/naming.xml">
<exclude name="ShortVariable" />
</rule>
<rule ref="rulesets/naming.xml/ShortVariable">
<properties>
<property name="minimum" value="2" />
</properties>
</rule>
上記はnaming.xml内のShortValiable(短い変数名の禁止)の閾値を上げる例です。
まず変更したいルールを除外してルールセットの読み込みを行います。
そして、ルール単体で読み込んだ上でプロパティを書き換え、最低文字数を元々の3から2に引き下げます。
公式ドキュメントにある通りですが、除外しての読み込みを行わないと、ルールは変更ではなく追加になってしまいます。
除外を外すと変数の文字数3文字以上の制限と2文字以上の制限両方が有効なルールとなってしまうので、注意しなければいけないポイントです。
まとめ
PHPMDのルールを変更することで、プロジェクトに合わせて柔軟に良くない匂いのプログラムを検知することができます。
重いのが辛いところですが、人が見なくてもいい問題を検知して教えてくれるので有効活用できると生産性が上がると思います。