この記事は Git Advent Calendar 2019 10日目の記事です。
はじめに
最近、gitのhooksでpre-commitを使い始めた
なかなか良いことが多かったので書いてみる
モチベーション
- PHPという自由な言語なので、他人のコードを読む時に苦しみたくない
- コードレビューの時にスペースがないとかくだらないことをチェックしたくない
- シンタックスエラーを事前に検知したい
やったこと
-
php -l
でのシンタックスチェック -
phpmd
でのお作法チェック -
php-cs-fixer
での自動修正
上記3点をcommit時にチェック。違反や引っかかることがあった時に、__commitできない__という結構厳しめのルール設定
php -lについて
- phpのシンタックスエラーをチェックしてくれる
<?php
$a = "test"
echo $a;
?>
$ php -l file.php
Parse error: syntax error, unexpected 'echo' (T_ECHO) in test.php on line 5
Errors parsing test.php
このようにあらかじめエラーを見つけてくれる
phpmdについて
インストール方法
$ brew install phpmd
$ phpmd --version
PHPMD 2.7.0snapshot201907302127
このように表示されればOK
使用法
- 使っていない変数のチェック
- 長すぎる変数名
- 複雑すぎるクラス
などなど様々なバグの温床をあらかじめ見つけてくれる
使い方は以下のように2通り
$ phpmd file.php text unusedcode,codesize,naming
or
$ phpmd file.php text phpmd-ruleset.xml
phpmdコマンドの後ろにファイル名またはディレクトリ、レポートフォーマット(text or xml)、使用ルールまたはルール記述xmlファイルの指定という風に書く。
ルールセットについて
上記のようにxmlファイルでルールを設定することができる。
<?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>
<rule ref="rulesets/codesize.xml">
<exclude name="CyclomaticComplexity" />
</rule>
<rule ref="rulesets/controversial.xml" />
<rule ref="rulesets/unusedcode.xml" />
<rule ref="rulesets/naming.xml">
<exclude name="ShortVariable" />
<exclude name="ShortMethodName" />
</rule>
<rule ref="rulesets/design.xml">
<exclude name="CouplingBetweenObjects" />
</rule>
</ruleset>
このように、<rule>タグで使用ルールを指定。<exclude>タグでルール内の細かいルールの除外をする。
例えば、
<rule ref="rulesets/naming.xml">
<exclude name="ShortVariable" />
<exclude name="ShortMethodName" />
</rule>
この場合、ネーミングに関するルールを使用するが、短すぎる(3文字以内)の変数名は引っかかるというルールを除外している。
php-cs-fixerについて
インストール方法
// composerのあるディレクトリに移動
$ cd path/to/your/project
$ composer install
$ ./vendor/bin/php-cs-fixer --version
PHP CS Fixer 2.16.0 Yellow Bird by Fabien Potencier and Dariusz Ruminski
こうなればOK。
使い方
$ ./vendor/bin/php-cs-fixer fix file.php
このようにすると、これが
<?php
$a="test";
echo $a
?>
こうなる
<?php
$a = "test";
echo $a;
これでコードの統一性がある程度出るし、変な指摘をしないで済む。
ルールについて
.php_cs.dist
というファイルで設定できる
<?php
return PhpCsFixer\Config::create()
->setRiskyAllowed(true)
->setRules([
'@PSR2' => true, //基準となるルールの設定
'array_syntax' => ['syntax' => 'short'], //配列の書き方について
'global_namespace_import' => ['import_classes' => true, 'import_constants' => true, 'import_functions' => true], //namespaceの書き方について
'concat_space' => ['spacing' => 'one'] //文字列連結の際のスペースについて
])
->setFinder(PhpCsFixer\Finder::create()
->exclude('vendor')
->in(__DIR__)
);
これ以外にもこれを使えば便利に比較することができる。
pre-commitの設定
$ cd path/to/your/project/.git/hooks
$ touch pre-commit
$ vim pre-commit
#!/bin/sh
against=HEAD
IS_ERROR=0
for FILE in `git diff-index --name-status $against -- | grep -E '^[AUM].*\.php$'| cut -c3-`; do
if php -l $FILE; then
./vendor/bin/php-cs-fixer fix $FILE
git add $FILE
if ! phpmd $FILE text phpmd-ruleset.xml; then
IS_ERROR=1
fi
else
IS_ERROR=1
fi
done
exit $IS_ERROR
.phpファイルのみだけがチェック対象。
導入後
- コードレビューでクリティカルな指摘に集中できるようになった
- コーディングスタイルが整うようになり、可読性が上がった
- 潜在的なバグが減らせた(と思ってる)
- 一度にcommitするとしんどいからcommit粒度が細かくなり、振り返りやすくなった
良いことだらけ。
ぜひ良いコミットライフを!