Lefthook の導入事例
開発プロセスを効率化するために導入した Git フックマネージャー
の Lefthook
を紹介します。
Lefthook
導入の背景
モチベーション1: 手動確認の限界
acomo
ではレビュー前にビルド成功や型チェックを手動確認していましたが、以下の課題がありました:
- レビュー後のエラー発覚: 修正作業後にリントや型エラーが見つかる
- 影響の広がり: エラーのあるブランチがマージされ環境に悪影響が出る
これを未然に防ぐため、自動的にチェックを行い早期発見する仕組みが必要でした。
モチベーション2: 他アプローチでの課題
初めに CI/CD パイプライン
(例: GitHub Actions
)を試しましたが、以下の課題がありました:
- パイプライン競合: 他ジョブとの競合頻度が増加
- 生産性: 結果待ち時間の発生
-
通知: 作業者に通知を送る仕組みの手間(
Slack
に送りたい場合のユーザ名変換など)
より簡単かつ早い段階で問題を検出するために、Git フック
の活用を検討しました。
ただし、従来利用していた husky
+ lint-staged
はモノレポで設定が煩雑なため、代わりにシンプルな Lefthook
を導入しました。
次に、Git フック
の基本について説明します。
Git フック
の基本
Git フック
は、特定の Git 操作(例:コミット、プッシュ、マージなど)の前後にスクリプトを自動実行する Git
の機能です。
-
フックの配置場所:
.git/hooks/
ディレクトリ内- 💡
git init
時にサンプルスクリプトが格納されている
- 💡
-
フックの種類:
-
pre-commit
: コミット前に実行 -
post-merge
: マージ後に実行 -
commit-msg
: コミットメッセージの検証
-
Git フックマネージャー
の役割
Git フックマネージャー
は、Git フック
を便利に管理するツールで、以下の役割があります:
-
バージョン管理: フックスクリプトをリポジトリ内で管理し、チーム共有が可能
- 💡
.git/hooks/
ディレクトリはリポジトリの管理対象外なため
- 💡
- セットアップの簡略化: 簡単にフックを設定可能
- 結果の要約表示: 実行したスクリプトの要約表示
次に、Lefthook
について説明します。
Lefthook
高速で柔軟な Lefthook
は、高速で柔軟な Git フックマネージャー
です。Go 言語で開発されており、以下の特徴を持ちます:
-
軽量かつ高速:
- 単一バイナリで依存関係が不要
- 並列処理に対応し、スクリプト実行が高速
-
ポリグロット対応:
- フロントエンドとバックエンドの両方をサポート
-
シンプルな設定:
-
.lefthook.yml
ファイルで簡単にフックを設定可能
-
次に、Lefthook
と husky
+ lint-staged
について比較をしてみます。
Lefthook
と husky
+ lint-staged
の比較
機能 | Husky + lint-staged | Lefthook |
---|---|---|
モノレポ対応 | プロジェクトごとの個別設定 | リポジトリルートに設定 |
並列実行 | 非対応 | 対応 |
バージョン管理 | 対応 | 対応 |
個人設定 | 非対応 | 対応 |
クロスプラットフォーム | Node環境 | 対応 |
スクリプトの見通し |
.husky/* 各ファイルを確認する |
設定ファイルにまとまっている |
また、Lefthook
には、体系的なドキュメントがあります:
さらに、ステージングファイル操作が Lefthook
で完結できる点も魅力です。
次に、Lefthook
のセットアップ、実行について説明します。
Lefthook
セットアップ方法
-
インストール:
# lefthook をインストールする npm i -D lefthook # lefthook.yml 作成 npx lefthook install
-
設定:
lefthook.ymlの例pre-push: commands: textlint: glob: "*.md" run: npm run lint:text:fix {push_files} markdownlint: glob: "*.md" run: npm run lint:markdown:fix {push_files}
💡設定時のヒント
-
Git フック名
-
Git
公式ドキュメントを確認
-
-
lefthook uninstall
-
lefthook
の影響を受ける Git フックをクリア
-
-
lefthook run {フック名}
-
lefthook run pre-push
のように、{フック名}
に設定したスクリプトを手動実行できる
-
-
ファイルテンプレート
- 実行時、適切なファイルに置き換えられるテンプレート機能がある(例:
{staged_files}
)
- 実行時、適切なファイルに置き換えられるテンプレート機能がある(例:
- コマンド
- オプション
- 参考例
-
Git フック名
-
フックを反映する:
# 設定内容を .git/hooks に反映する # 🐱重要🐱: 変更 → 反映を忘れずに行うこと!!! npx lefthook install
これで、
git フック
時に対応するスクリプトが実行されるようになりました。実行例
acomo-zenn on feature/lefthook [⇡] is 📦 v1.0.0 via v20.17.0 at 16:47:23 ❯ git push ╭─────────────────────────────────────╮ │ 🥊 lefthook v1.10.9 hook: pre-push │ ╰─────────────────────────────────────╯ ┃ markdownlint ❯ > acomo-zenn@1.0.0 lint:markdown:fix > npm run lint:markdown -- --fix articles/progress-acomo-2025-01-21-09-33-25.md > acomo-zenn@1.0.0 lint:markdown > markdownlint-cli2 articles/**/*.md README.md --fix articles/progress-acomo-2025-01-21-09-33-25.md markdownlint-cli2 v0.17.2 (markdownlint v0.37.4) Finding: articles/**/*.md README.md articles/progress-acomo-2025-01-21-09-33-25.md Linting: 3 file(s) Summary: 0 error(s) ┃ textlint ❯ > acomo-zenn@1.0.0 lint:text:fix > npm run lint:text -- --fix articles/progress-acomo-2025-01-21-09-33-25.md > acomo-zenn@1.0.0 lint:text > textlint articles/**/*.md README.md --fix articles/progress-acomo-2025-01-21-09-33-25.md ──────────────────────────────────── summary: (done in 1.45 seconds) ✔️ markdownlint ✔️ textlint Enumerating objects: 11, done. Counting objects: 100% (11/11), done. Delta compression using up to 12 threads Compressing objects: 100% (6/6), done. Writing objects: 100% (6/6), 2.03 KiB | 2.03 MiB/s, done. Total 6 (delta 4), reused 0 (delta 0), pack-reused 0 remote: Resolving deltas: 100% (4/4), completed with 4 local objects. To github-prg:example.com/acomo-zenn.git 31323da..6b62658 feature/lefthook -> feature/lefthook
最後に概要があり、結果がとても分かりやすい。
問題があった場合は、
git
操作は中断されるため、クリーンな状態に保つことができる。
まとめ
Lefthook
を導入することで、作業の効率化やミスの削減が期待できます。モノレポ対応や並列処理による高速化も魅力的です。
効率的なフック設定とトラブルの早期検出により、コード品質の向上と安心感を持った開発が可能になります。さらに、柔軟な設定や豊富なオプションで、プロジェクトに合わせた最適なカスタマイズが行えます。
「手作業での都度確認で、やり忘れが頻発している」と感じる方々に、本記事がお役に立てれば幸いです。
Discussion