0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

gitのpre-commitでlintが自動で動くように書いてみた

0
Last updated at Posted at 2025-12-24

はじめに

phpフォーマットを変更して多くのファイルがフォーマット準拠していない状態になってしまったので、lintが自動で動くようにpre-commitを作成してみました!
その中でちょっとした問題と修正を経験したのでメモとして残していきます :pencil:

✅ 実現したかったこと

  1. .git/hookは存在するが、phpStormでトラッキングできないので.git/hook/pre-commitに直接内容を書かず、別の方法を考える
  2. すでに開発しているエンジニアでも簡単に導入できるようにする
  3. 修正したファイルのみにlintが走る
  4. php以外のファイルにはlintを走らせない
  5. WindowsでもMacでもpre-commitが走るようにする

pre-commitの実装

pre-commit

#!/bin/bash

set -e

# ステージされたPHPファイルのみ取得
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACMR | grep '\.php$' || true)

#検証対象ファイルがない場合commit阻止
if [ -z "$STAGED_FILES" ]; then
    echo "No PHP files staged for commit."
    exit 0
fi

PROJECT_ROOT=$(git rev-parse --show-toplevel)
cd "$PROJECT_ROOT" || exit 1

#php-cs-fixerが見つからない場合、異常終了
PHP_CS_FIXER="$PROJECT_ROOT/vendor/bin/php-cs-fixer"
if [ ! -f "$PHP_CS_FIXER" ]; then
    echo "Error: PHP-CS-Fixer not found"
    echo "Please run: composer install"
    exit 1
fi

HAS_ERRORS=0

# フォーマットを確認
for file in $STAGED_FILES; do
    if [ -f "$file" ]; then
        echo "Checking: $file"

        if ! PHP_CS_FIXER_IGNORE_ENV=1 php "$PHP_CS_FIXER" fix "$file" --dry-run --diff --config="$PROJECT_ROOT/.php-cs-fixer.dist.php" 2>&1; then
            HAS_ERRORS=1
        fi
    fi
done

#もしエラーがある場合は詳細を表示してcommit阻止
if [ $HAS_ERRORS -ne 0 ]; then
    echo ""
    echo "Please fix the issues above and try again."
    echo ""
    echo "To automatically fix most issues, run: composer fmt"
    echo ""
    exit 1
fi

#すべてフォーマット準拠している場合
echo "✓ All staged PHP files passed PHP-CS-Fixer validation."
exit 0

README.md

プロジェクトで使用する Git hooks が含まれています。

## セットアップ

以下のコマンドを実行して、Git hooks をインストールしてください:

`ln -s ../../.github/hooks/pre-commit .git/hooks/pre-commit`

##...(省略)

#### 動作内容

1. ステージされた PHP ファイル(`.php` 拡張子)を検出
2. 各ファイルに対して PHP-CS-Fixer を dry-run モードで実行
3. コーディング規約違反が見つかった場合、コミットを阻止

#### エラーが出た場合の対処法

コーディング規約違反が検出された場合、以下のコマンドで自動修正できます:

# Composer スクリプトを使用(推奨)
`composer fmt`

または直接実行
` php vendor/bin/php-cs-fixer fix` 

修正後、再度 `git commit` を実行してください。

#### 一時的にフックをスキップする方法

フックをスキップしてコミットする必要がある場合は、`--no-verify` オプションを使用できます:

`git commit --no-verify -m "Your commit message"`

ただし、これは推奨されません。できる限りコーディング規約に従ってください。

##...(省略)

composer.json

{
    "name": "project/repository-name",
    "require": {
    
    ... (省略)
    
     "scripts": {
        "lint": [
            "php vendor/bin/php-cs-fixer fix --dry-run --diff --format txt"
        ],
        "post-install-cmd": [
            "@install-hooks"
        ],
        "post-update-cmd": [
            "@install-hooks"
        ],
        "install-hooks": [
            "bash -c 'if [ ! -L .git/hooks/pre-commit ]; then ln -sf ../../.github/hooks/pre-commit .git/hooks/pre-commit && echo \"Git hooks installed successfully.\"; fi'"
        ]
    }

🚀 問題点、改善点

phpコマンドが見つからないエラーになる

開発環境によってはローカルにPHPがインストールされていないケースもあるため、エラーが発生する課題がありました。
対策: phpコンテナ内のphp-cs-fixer を利用する

windows環境でのシンボリックリンク問題

.github/hooks/pre-commitから.git/hooks/pre-commitへシムリンクをはるように記載していましたが、windowsではコンテナ内の.github/hooks/pre-commitを参照できなかった。
WindowsのGit Bash等ではシンボリックリンクの扱いに権限が必要な場合があり、コンテナ内からホストのパス解決が困難

  • 対策: ファイルをコピーするよう変更する
セットアップタイミング

composer update, composer installでセットアップできるようにしましたが、頻繁に実行するにはdocker compose upでは?という意見をもらいました。

  • 対策: docker compose upでセットアップができるように変更する
phpStormでpre-commitをスキップするにはどうすればいいかREADMEに書いて欲しい

私はいつもターミナルからコマンドを叩いてcommitするため、phpStormユーザからの視点が外れていました。

  • 対策: phpStormでスキップする際の方法をREADMEに記載する

##📂 最終的な構成設定

pre-commit

##.. 省略

# phpコンテナが立ち上がっていることを確認
if ! docker compose ps php | grep -q "Up"; then
    echo "Error: Docker container 'php' is not running"
    echo "Please run: docker compose up -d"
    exit 1
fi

HAS_ERRORS=0

for file in $STAGED_FILES; do
    if [ -f "$file" ]; then
        echo "Checking: $file"

        #コンテナ内のphp-cs-fixerを利用するよう変更
        # -T (No TTY option) : the input device is not a TTYエラーを防ぐため。入出力用画面は用意せず、結果のみテキストで返してくれる
        if ! docker compose exec -T php env PHP_CS_FIXER_IGNORE_ENV=1 php vendor/bin/php-cs-fixer fix "$file" --dry-run --diff --config=.php-cs-fixer.dist.php 2>&1; then
            HAS_ERRORS=1
        fi
    fi
done
##.. 省略
docker-compose.yml

コンテナ起動時に自動で最新のフックを適用します。

  php:
    command:
      - /bin/bash
      - -c
      - |
        cp -f ./.github/hooks/pre-commit .git/hooks/pre-commit
        chmod +x .git/hooks/pre-commit
        ./docker/php/entrypoint.sh
##..省略

README.mdの工夫

なぜこのような構成にしたのかを明文化しました。

なぜ .github/hooks に配置しているのか?
Git hooks 本来のディレクトリ(.git/hooks/)はバージョン管理対象外。
バージョン管理: チーム全体で設定を共有し、変更履歴を追跡可能にするため。
IDEでの編集: PhpStormなどで直接編集・レビュー可能にするため。

一時的にフックをスキップする方法
コマンドライン: git commit --no-verify
phpStorm: コミットダイアログで「Run Git hooks」のチェックを外す。

おわりに

docker compose upでpre-commitの設定ができるようになったことで、php以外のフォーマットチェックや他の検証もエンジニアの負担が少なく導入できそうですね。
参考になれば幸いです :apple:

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?