🥊

Lefthook の導入事例

2025/01/23に公開

開発プロセスを効率化するために導入した 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 言語で開発されており、以下の特徴を持ちます:

  1. 軽量かつ高速:
    • 単一バイナリで依存関係が不要
    • 並列処理に対応し、スクリプト実行が高速
  2. ポリグロット対応:
    • フロントエンドとバックエンドの両方をサポート
  3. シンプルな設定:
    • .lefthook.yml ファイルで簡単にフックを設定可能

次に、Lefthookhusky + lint-staged について比較をしてみます。


Lefthookhusky + lint-staged の比較

機能 Husky + lint-staged Lefthook
モノレポ対応 プロジェクトごとの個別設定 リポジトリルートに設定
並列実行 非対応 対応
バージョン管理 対応 対応
個人設定 非対応 対応
クロスプラットフォーム Node環境 対応
スクリプトの見通し .husky/* 各ファイルを確認する 設定ファイルにまとまっている

また、Lefthook には、体系的なドキュメントがあります:

さらに、ステージングファイル操作が Lefthook で完結できる点も魅力です。

次に、Lefthook のセットアップ、実行について説明します。


Lefthook セットアップ方法

  1. インストール:

    # lefthook をインストールする
    npm i -D lefthook
    
    # lefthook.yml 作成
    npx lefthook install
    
  2. 設定:

    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}
    
    💡設定時のヒント
  3. フックを反映する:

    # 設定内容を .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