0
1

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編)

Posted at

はじめに

このガイドでは、Gitコミット時に自動でコードの整形(フォーマット)や静的解析を行うためのツール「pre-commit」の導入方法について、初心者の方にも分かりやすく解説します。

pre-commitとは?

pre-commitは、Gitの「フック」という仕組みを利用して、コミットを行う直前に特定の処理を自動で実行するためのフレームワークです。これはオープンソースで開発されており、Pythonコミュニティを中心に、多くのプロジェクトでコード品質の維持に活用されています。

pre-commitの仕組み

pre-commitは、Gitのクライアントサイドフックの一つであるpre-commitフックを利用します。このフックは、git commitコマンドが実行された際に、コミットメッセージの編集画面が表示される前に自動で実行されます。

  1. Gitフックのインストール: pre-commit installコマンドを実行すると、.git/hooks/pre-commitというスクリプトが作成されます。このスクリプトが、実際のpre-commitの処理を呼び出します。
  2. 設定ファイルの読み込み: コミットが実行されると、pre-commitはプロジェクトルートにある.pre-commit-config.yamlファイルを読み込み、定義されたフック(チェック処理)のリストを取得します。
  3. 仮想環境の作成とツールのインストール: 各フックは、それぞれ独立した仮想環境(PythonのvenvやNode.jsのnodeenvなど)内で実行されます。これにより、プロジェクトの依存関係とフックが使用するツールの依存関係が衝突するのを防ぎます。フックが初めて実行される際には、必要なツールがこの仮想環境内に自動でインストールされます。
  4. フックの実行: 定義されたフックが順番に実行されます。通常、フックはコミット対象のファイル(ステージングエリアにあるファイル)に対して処理を行います。
  5. 結果の判定: すべてのフックが成功(終了コード0)した場合のみ、コミットプロセスが続行されます。一つでもフックが失敗(終了コードが0以外)した場合、コミットは中断され、エラーメッセージが表示されます。

この仕組みにより、開発者はコミット前にコードの問題を自動で検出し、修正することができます。これにより、不完全なコードやスタイル違反のあるコードがリポジトリに混入するのを防ぎ、チーム全体のコード品質を向上させます。

なぜpre-commitを使うのか?(メリット・デメリット)

メリット

  • コード品質の向上: コミット前に自動でコードチェックを行うことで、バグの混入を防ぎ、コードの品質を高く保つことができます。
  • コードスタイルの統一: チーム内で統一されたコードスタイルを強制することで、誰が書いても読みやすいコードベースを維持できます。
  • レビューコストの削減: 人間によるコードレビューの前に基本的なチェックが自動で行われるため、レビュー担当者の負担を減らすことができます。
  • 開発体験の向上: 開発者は、手動でフォーマッターやリンターを実行する手間が省け、コードの品質に関するフィードバックを即座に得られます。
  • CI/CDとの連携: pre-commitフックでパスするコードは、CI/CDパイプラインでもパスする可能性が高く、CI/CDの失敗を減らすことができます。

デメリット

  • 初期設定の手間: プロジェクトに初めて導入する際や、新しいフックを追加する際には、設定ファイル(.pre-commit-config.yaml)の記述やツールのインストールに多少の手間がかかります。
  • コミット速度の低下: フックの数や処理内容によっては、コミットにかかる時間が長くなることがあります。特に、初めてフックを実行する際の環境構築には時間がかかる場合があります。
  • 学習コスト: pre-commitの概念やYAMLファイルの書き方など、ある程度の学習が必要です。
  • 強制力: コードの品質を保つ上でメリットとなる強制力ですが、開発者によっては煩わしいと感じる場合もあります。

導入手順

ステップ1: pre-commitのインストール

まず、pre-commitをプロジェクトの依存関係に追加し、インストールします。

  1. requirements.txtの編集:
    プロジェクトのルートディレクトリにあるrequirements.txtファイルに、以下の行を追加します。

    pre-commit
    

    これにより、プロジェクトに必要なPythonパッケージとしてpre-commitが指定されます。

  2. 依存関係のインストール:
    requirements.txtを編集したら、以下のコマンドを実行して、プロジェクトの依存関係をインストールします。

    pip install -r requirements.txt
    

    このコマンドにより、pre-commitを含むすべての必要なパッケージが仮想環境にインストールされます。

ステップ2: .pre-commit-config.yamlの作成

次に、pre-commitがどのようなチェックを行うかを定義する設定ファイルを作成します。プロジェクトのルートディレクトリに.pre-commit-config.yamlという名前でファイルを作成し、以下の内容を記述してください。

YAMLファイルの基本的な書き方

.pre-commit-config.yamlはYAML形式で記述されます。YAMLは、人間が読み書きしやすいデータ形式で、主に設定ファイルに使われます。基本的なルールは以下の通りです。

  • インデント: スペースを使ってインデント(字下げ)を行います。タブは使用できません。通常、2スペースまたは4スペースでインデントします。
  • キーと値: キー: 値の形式でデータを記述します。キーと値の間にはスペースが必要です。
  • リスト: -(ハイフンとスペース)を使ってリストの要素を表現します。
  • コメント: #(ハッシュ記号)から始まる行はコメントとして扱われ、無視されます。

これらのルールを守って記述することで、pre-commitが正しく設定ファイルを読み込むことができます。

# .pre-commit-config.yaml
repos:
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v4.6.0
    hooks:
      - id: trailing-whitespace # 行末の不要な空白を自動削除
      - id: end-of-file-fixer   # ファイル末尾に改行がない場合、自動で追加
      - id: check-yaml          # YAMLファイルの構文チェック
      - id: check-added-large-files # 追加された大きなファイルがないかチェック
  - repo: https://github.com/psf/black
    rev: 24.4.0
    hooks:
      - id: black
        files: \.py$ # Pythonファイルのみを対象
  - repo: https://github.com/PyCQA/flake8
    rev: 7.0.0
    hooks:
      - id: flake8
        files: \.py$ # Pythonファイルのみを対象
  - repo: https://github.com/pre-commit/mirrors-mypy
    rev: v1.10.0
    hooks:
      - id: mypy
        args: [--no-strict-optional, --ignore-missing-imports]
        files: \.py$ # Pythonファイルのみを対象

各ツールの説明

  • pre-commit-hooks:
    pre-commitが公式に提供している汎用的なフック集です。

    • trailing-whitespace: コードの行末にある不要な空白を自動的に削除します。
    • end-of-file-fixer: ファイルの末尾に改行がない場合に、自動で追加します。Gitがファイルの変更を正しく認識するために重要です。
    • check-yaml: YAMLファイルの構文が正しいかチェックします。
    • check-added-large-files: コミットしようとしているファイルの中に、意図せず大きなファイル(例: バイナリファイル)が含まれていないかチェックします。
  • black:
    Pythonコードを自動で整形(フォーマット)するツールです。blackを使うことで、チーム内でコードの見た目を統一し、可読性を高めることができます。

    • files: \.py$: この設定により、.pyで終わるPythonファイルのみがblackの対象となります。
  • flake8:
    Pythonコードのスタイルガイド(PEP 8)からの逸脱や、潜在的なバグをチェックする静的解析ツールです。コードの品質を向上させるのに役立ちます。

    • files: \.py$: この設定により、.pyで終わるPythonファイルのみがflake8の対象となります。
  • mypy:
    Pythonコードの型ヒント(Type Hinting)が正しく使われているかをチェックする静的型チェッカーです。型エラーを早期に発見し、コードの信頼性を高めます。

    • args: [--no-strict-optional, --ignore-missing-imports]: mypyの実行時に渡す引数です。プロジェクトの状況に合わせて調整してください。
    • files: \.py$: この設定により、.pyで終わるPythonファイルのみがmypyの対象となります。

ステップ3: pre-commitフックのインストール

設定ファイルを準備したら、以下のコマンドを実行して、Gitリポジトリにpre-commitフックをインストールします。

pre-commit install

このコマンドを実行すると、.git/hooks/pre-commitというファイルが作成され、コミット時にpre-commitが自動で実行されるようになります。

トラブルシューティング

コミットが失敗した場合

pre-commitフックが失敗した場合、コミットは中断され、エラーメッセージが表示されます。

  • files were modified by this hookと表示された場合:
    これは、trailing-whitespaceend-of-file-fixerなどのフックが、ファイルを自動的に修正したことを意味します。修正されたファイルはまだステージングされていないため、以下の手順で再度コミットを試みてください。

    1. git statusを実行して、修正されたファイルを確認します。
    2. git add <修正されたファイル名>(またはgit add .)を実行して、修正をステージングします。
    3. 再度git commitを実行します。
  • blackflake8mypyなどのフックが失敗した場合:
    これは、コードにスタイル違反や型エラー、潜在的なバグなどが存在することを示しています。表示されたエラーメッセージを参考に、コードを修正してください。修正後、再度git addgit commitを実行します。

pre-commitの環境初期化に時間がかかる場合

pre-commitは、初めてフックを実行する際に、各ツールの実行環境を初期化します。これには時間がかかる場合がありますが、一度初期化が完了すれば、次回以降は高速に実行されます。

まとめ

pre-commitを導入することで、Gitコミット時に自動でコードの品質チェックが行われるようになり、より堅牢で統一されたコードベースを維持できるようになります。最初は戸惑うかもしれませんが、慣れてしまえば開発効率を大きく向上させる強力なツールとなるでしょう。

Happy Coding!

0
1
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
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?