既存コードベースにもPHP_CodeSnifferを導入して 楽したい!

9K Views

October 08, 23

スライド概要

PHP Conference Japan 2023 の登壇資料です

シェア

またはPlayer版

埋め込む »CMSなどでJSが使えない場合

関連スライド

各ページのテキスト
1.

#phpcon2023 既存コードベースにも PHP_CodeSnifferを導入して 楽したい! PHP Conference Japan 2023 荒巻 拓哉 ©2023 RAKUS Co., Ltd.

2.

#phpcon2023 目次 ● PHP_CodeSniffer とは? ● 導入の背景 ● 導入にあたっての障壁 ● 障壁の乗り越え方

3.

#phpcon2023 自己紹介 氏名: 荒巻 拓哉 所属: 株式会社ラクス 配配メール 開発チーム 仕事: 設計、実装、レビュー、 CIのお世話 \スポンサーブースあります!/ @takaram71 @takaram 3

4.

#phpcon2023

5.

#phpcon2023 ● 2007年リリース ○ 16年前 ○ PHP 5.2 × 名前空間 × 無名関数

6.

#phpcon2023 PHP_CodeSniffer とは? ● PHP向けのLinter ● インデントや変数名の命名規則などのチェック ● 複数のルール (Sniff) を組み合わせてカスタマイズできる

7.

#phpcon2023 <? if ($n> 1) echo "Hello!"; ?>

8.
[beta]
#phpcon2023

短縮形の開始タグ

<?

演算子の前の空白がない

if ($n> 1) echo "Hello!";
?>

{} を省略
閉じタグを書いている

9.

#phpcon2023 ---------------------------------------------------------------------FOUND 4 ERRORS AFFECTING 3 LINES ---------------------------------------------------------------------1 | ERROR | [x] Short PHP opening tag used; expected "<?php" but | | found "<?" | | (Generic.PHP.DisallowShortOpenTag.Found) 3 | ERROR | [x] Inline control structures are not allowed | | (Generic.ControlStructures.InlineControlStructure.NotAllowed) 3 | ERROR | [x] Expected at least 1 space before ">"; 0 found | | (PSR12.Operators.OperatorSpacing.NoSpaceBefore) 5 | ERROR | [x] A closing tag is not permitted at the end of a PHP | | file (PSR2.Files.ClosingTag.NotAllowed) ---------------------------------------------------------------------PHPCBF CAN FIX THE 4 MARKED SNIFF VIOLATIONS AUTOMATICALLY ----------------------------------------------------------------------

10.

#phpcon2023 ---------------------------------------------------------------------FOUND 4 ERRORS AFFECTING 3 LINES ---------------------------------------------------------------------1 | ERROR | [x] Short PHP opening tag used; expected "<?php" but | | found "<?" | | (Generic.PHP.DisallowShortOpenTag.Found) 3 | ERROR | [x] Inline control structures are not allowed | | (Generic.ControlStructures.InlineControlStructure.NotAllowed) 3 | ERROR | [x] Expected at least 1 space before ">"; 0 found | | (PSR12.Operators.OperatorSpacing.NoSpaceBefore) 5 | ERROR | [x] A closing tag is not permitted at the end of a PHP | | file (PSR2.Files.ClosingTag.NotAllowed) ---------------------------------------------------------------------PHPCBF CAN FIX THE 4 MARKED SNIFF VIOLATIONS AUTOMATICALLY ----------------------------------------------------------------------

11.

#phpcon2023 PSR12.Operators.OperatorSpacing.NoSpaceBefore 規約名 カテゴリ ルール名 エラーコード

12.

#phpcon2023 PSR12.Operators.OperatorSpacing.NoSpaceBefore 規約名 カテゴリ ルール名 カスタムルールセットの設定に利用 エラーコード

13.

#phpcon2023 なんで導入したの? ● コーディング規約のルールが多すぎて、目視のチェックが辛い ○ 80種類以上 ● 実装担当者・レビュー担当者それぞれがチェックしていて無駄 ● 見落としが多発

14.

#phpcon2023 導入した結果…… ● 特にコードレビューで負担が減った! ○ CIの実行結果を確認すればOK 詳細はチームメンバーが PHPerKaigi2023 で 話してくれたので、そちらに譲ります ● https://youtu.be/QcbJN19lGvU ● https://speakerdeck.com/mrstsgk/codereviewlife

15.

#phpcon2023 そんなに簡単に導入できたの?

16.

#phpcon2023

17.

#phpcon2023 導入までの技術的障壁 ● 定義済みのルールセットを利用できない ● 既存コードがコーディング規約に沿っていない

18.

#phpcon2023 定義済みのルールセットを利用できない ● PSR-12 を含むいくつかのルールセットが提供されている ● チーム独自のコーディング規約なので、それらは利用不可

19.

#phpcon2023 既存コードが規約に沿っていない ● コーディング規約に合わせたルールを作っても 既存コードがチェックに引っかかる ○ PHPStan などにある baseline 機能は未実装 ● CIに載せると常時エラーになってしまう…… ○ 割れ窓になる

20.

#phpcon2023 障壁の乗り越え方

21.

#phpcon2023 定義済みのルールセットを利用できない ● 地道に定義するしかない ○ プロジェクト用の定義ファイル (XML) を作成 ● PSR-12をベースに、差分を追加・削除 ○ 0からやるよりは楽? ○ slevomat/coding-standard のルールも利用 ○ PSR-12のルール内容はXMLファイル参照 ■ src/Standards/PSR12/ruleset.xml

22.

#phpcon2023 https://www.php-fig.org/psr/psr-12/

23.

#phpcon2023 https://github.com/squizlabs/PHP_CodeSniffer/blob/3.7.2/src/Standards/PSR12/ruleset.xml

24.

#phpcon2023 定義済みのルールセットを利用できない ● 既存のルールで対応できない規約もある ● 自作ルールを作成して対応

25.

#phpcon2023 自作ルールの作成 ● 以下のコードを参考に作成 ○ PHP_CodeSniffer 組み込みのルール ○ slevomat/coding-standard ● ネット上には情報が少なめ ● 積極的にオススメはしません…

26.

#phpcon2023 自作ルールの作成:ハマったポイント ● ディレクトリ構成がある程度決まっている src/ └(RuleSetName)/ ├Sniffs/ │ └(CategoryName)/ │ └(SniffName)Sniff.php └ruleset.xml

27.

#phpcon2023 自作ルールの作成:ハマったポイント ● 解析するソースコードの字句解析結果が渡される ● 構文解析はされてない ○ 例)2種類のuseの区別が(簡単には)つかない ■ 名前空間のインポート ■ トレイトの利用 ○ 類似のルールの実装を参考に

28.

#phpcon2023 自作ルールの作成 ● 自作ルールセットのXMLと合わせてcomposerパッケージ化 ○ 社内GitLabで管理 ○ GitLabからダウンロードするように設定 ■ 利用する側のcomposer.jsonに"repositories"を追加 ■ https://getcomposer.org/doc/05-repositories.md#vcs

29.

#phpcon2023 既存コードが規約に沿っていない ● CIでは新規のエラーしか検知しないようなスクリプトを作成 ● 既存のOSSもなくはないが…… ○ メンテされていない ○ // phpcs:ignore をつけて回る

30.

#phpcon2023 新規エラーのみを検知 1. 修正・新規ファイルをリストアップ 2. 新旧ブランチでそれぞれPHP_CodeSnifferを実行 3. 新ブランチで増加したエラーコードをリストアップ 4. 3.のエラーのみを検査対象にした設定ファイルを生成 5. 新ブランチで4.のファイルを使って実行

31.

#phpcon2023 新規エラーのみを検知 ● 1つ減って1つ増えた場合は検知できない ○ これは許容 ● 増加したエラーは全て報告される ○ エラー数20→21に増えると、21個全て出力 ○ 増えた1個だけ修正してCIが通ればOK

32.

#phpcon2023 新規エラーのみを検知 SlevomatCodingStandard.TypeHints.ParameterTypeHint ● エラーコードが2種類 ○ MissingAnyTypeHint ■ ×型宣言 ×PHPDocの型情報 ○ MissingNativeTypeHint ■ ×型宣言 ○PHPDocの型情報 ● 既存メソッドにPHPDocをつけるとAny→Nativeに変わる ○ 両者の合計が増えたときのみエラーにする対応を追加

33.

#phpcon2023 まとめ

34.

#phpcon2023 まとめ ● PHP_CodeSnifferの導入で楽になった! ● 既存プロジェクトへの導入には壁もある ● 工夫すれば乗り越えられる💪

35.

補足 #phpcon2023 ツールの選定 ● php-cs-fixer ○ “fixer”の名の通り、自動修正が前提 ○ 「1行あたりの文字数制限」のような、自動修正が難しいルールは 非対応