php-cs-fixer-2.0.0が最近リリースされていました。2系へのメジャーバージョンアップです。
https://github.com/FriendsOfPHP/PHP-CS-Fixer/releases/tag/v2.0.0
ためしに触ってみることにします。
セットアップ
READMEにあるいずれかの方法でphp-cs-fixerをダウンロード、インストールすればOK。
実行してみる
$ php-cs-fixer fix --dry-run --diff -v .
PHP Fatal error: Class 'Symfony\CS\FixerInterface' not found in /path/to/.php_cs
既存の.php_cs
そのままでは実行できず。
READMEに.php_cs
のサンプルがあるのでそれをまず眺めてみることに。
<?php
$finder = PhpCsFixer\Finder::create()
->exclude('somedir')
->notPath('src/Symfony/Component/Translation/Tests/fixtures/resources.php')
->in(__DIR__)
;
return PhpCsFixer\Config::create()
->setRules(array(
'@PSR2' => true,
'strict_param' => true,
'array_syntax' => array('syntax' => 'short'),
))
->setFinder($finder)
;
変更点
UPGRADEにわかりやすく書いてあります。
https://github.com/FriendsOfPHP/PHP-CS-Fixer/blob/v2.0.0/UPGRADE.md
以下では気づいたところを主に
.php_cs
.php_cs
で使うクラスが変更されています。
-
Symfony\CS\Config\Config
→PhpCsFixer\Config
-
Symfony\CS\Finder\DefaultFinder
→PhpCsFixer\Finder
-
Symfony\CS\FixerInterface::PSR[012]_LEVEL
は廃止、PhpCsFixer\Config::setRules()
の@PSR1
,@PSR2
のキー指定に統合された
またプロジェクトルートの設定ファイルは.php_cs.dist
に、ローカルの設定は.php_cs
という位置づけになりました。
(phpunit.xmlとphpunit.xml.distの関係と同じ)
.php_cs.dist
を使うことが推奨されているようです。
level
1系ではSymfony\CS\Config\Config::level()
でnone, psr0, psr1, psr2を選択していましたが、前述のとおり2系ではSymfony\CS\FixerInterface::PSR[012]_LEVEL
は廃止され指定方法が変わっています。
-
PhpCsFixer\Config::setRules()
で@PSR1
,@PSR2
をキーにしてtrue
/false
で有効無効を切り替える
$config = PhpCsFixer\Config::create()
->setRules([
'@PSR2' => true,
]);
- psr0は単独のルールになった
- psr4が新たに追加された。これも単独のルール扱い
@PSR1
,@PSR2
は複数ルールの集合、psr0, psr4は単独ルール
.php_csを見比べる
変更点を踏まえて1系と修正した2系の.php_csを見比べてみます。
1系
<?php
$level = Symfony\CS\FixerInterface::PSR2_LEVEL;
$fixers = ['short_array_syntax', '-braces'];
$excludes = ['path/to', 'file'];
return Symfony\CS\Config\Config::create()
->level($level)
->fixers($fixers)
->finder(
Symfony\CS\Finder\DefaultFinder::create()
->in(__DIR__)
->exclude($excludes)
->notName('README.md')
->notName('*.xml')
->notName('*.yml')
);
2系
<?php
$rules = [
'@PSR2' => true,
'array_syntax' => ['syntax' => 'short'],
'braces' => false,
];
$excludes = ['path/to', 'file'];
return PhpCsFixer\Config::create()
->setRules($rules)
->setFinder(
PhpCsFixer\Finder::create()
->in(__DIR__)
->exclude($excludes)
->notName('README.md')
->notName('*.xml')
->notName('*.yml')
);
いくつか変更されていますが修正量としてはそれほど多くはなさそうです。
ルールを個別で指定しているときは1系と2系でルールの名前が変わっていたりするためやや面倒かもしれません。
2系対応版.php_csで再実行
1系ですべてパスするコードに対して実行します。
$ php-cs-fixer fix --dry-run --diff -v --config .php_cs
Loading config default from ".php_cs".
...(省略)
Legend: ?-unknown, I-invalid file syntax, file ignored, S-Skipped, .-no changes, F-fixed, E-error
Checked all files in 975.268 seconds, 7.250 MB memory used
実行結果
オプションを同じにして実行すると結果は同じくすべてパスしました。
ただし実行時間は約16分という結果になっています。
1系の場合は1分程度で終わる分量なのでそれに比べるとだいぶ遅いです。
--format junit
2.0.0で新たに追加された--format junit
オプション。
これを指定するとjunit形式のxmlが出力されます。
$ php-cs-fixer fix --dry-run --config .php_cs --format junit
Loading config default from ".php_cs".
<?xml version="1.0" encoding="UTF-8"?>
<testsuites>
<testsuite name="PHP CS Fixer" tests="1" assertions="1" failures="0" errors="0" time="6.535">
<testcase name="All OK" assertions="1"/>
</testsuite>
</testsuites>
--format junit
と--diff
や-v
と組み合わせることはできないようです。
その他
level:none設定
1系のlevel:noneの設定をしたいときに2系ではどう設定すればよいかわからず。
$config = PhpCsFixer\Config::create()
->setRules([
'@PSR1' => false,
'@PSR2' => false,
]);
とすれば設定できそうですが普通にデフォルト設定で実行されてしまいました。
.php_csは指定しないといけない?
1系のように"."指定で実行するとどうも.php_cs
の設定が反映されないようでした。
# これだと.php_csの設定が効かない
$ php-cs-fixer fix --dry-run --diff -v .
明示的に--config
で.php_cs
を指定すれば設定が効きました。
$ php-cs-fixer fix --dry-run --diff -v --config .php_cs
まとめ
- php-cs-fixer-2.0.0がリリースされた
- .php_csを設定している場合はそのままでは実行できない
- .php_csの修正量はそれほど多くはないので移行は難しくなさそう
- 2系(2.0.0)は実行速度が遅い
-
--format junit
オプションは便利そう
実行速度の遅さが気になるので今後の開発に期待したいところです。