日常のワークフローにおいて、コードを綺麗に保つことは重要ながら難しいことです。
「後で直す」と頭の片隅に残しつつ、どうしてもその時間が取れないというシーンは多々あります。
そういったシチュエーションで便利なのがPythonのpre-commitです。今回はpre-commitと、それに付随して使うことで効果的になるblack、isort、mypy、そしてbanditについて簡単に使い方と効果を紹介していきます。
pre-commitとは
pre-commitはPython製ツールで、pre-commitフックを管理・維持するためのものです。
pre-commitフックは、Gitのようなバージョン管理システムでコミットが行われる前に自動的に実行されるスクリプトです。これらのスクリプトは、コードがコミットされる前に特定の基準を満たしているかチェックするために使われます。
例)lint(コードの文法エラー確認等)に合格しているか、スタイルガイドに準拠しているか、単体テストに合格しているか、など。
pre-commit がどのように機能し、なぜ有効なのかを簡単に説明します。
pre-commitインストール
pre-commitのインストールはpip、conda、あるいはhomebrew(macOSの場合)を使いましょう。
pip install pre-commitcondaの場合は以下です。
conda install -c conda-forge pre-commithomebrewを使う場合は以下です。
brew install pre-commitpre-commitが動作する流れ
- 設定
まず、.pre-commit-config.yamlファイルをリポジトリに追加します。このファイルで使用するフックを指定します。 - インストール
フックを定義したら、pre-commit installコマンドでフックをインストールします。これにより、コミット前に指定したスクリプトを実行するようgitのフックが設定されます。 - 実行
変更をコミットしようとすると、.pre-commit-config.yamlファイルで指定したフックが実行されます。いずれかのフックが失敗するとコミットは中断され、指定した条件を満たすコードのみがコミットされるようになります。 - 更新
フックはpre-commit autoupdateコマンドを使って新しいバージョンに更新できます。
pre-commitのメリット
- 一貫性
プロジェクトのすべてのコントリビューターが同じコーディング規約に従うことを保証できます。 - 品質
開発プロセスの早い段階で問題を発見し、バグやスタイルの不一致がメインブランチに反映される可能性を減らします。 - 自動化
一度セットアップすればチェックは自動的に実行されるため、スタイルや些細な問題に対する手作業によるコードレビューの必要性が減ります。 - 柔軟性
pre-commitはflake8やblackのような一般的なlinterからカスタムスクリプトまで、幅広いフックをサポートしています。 - 統合
一般的なCI/CDツールとシームレスに動作し、ローカルとCI/CDパイプラインの両方で同じチェックが実行されることを保証します。
よく使われるフック
black= 一貫したコード書式を保証するコードフォーマッター(整形)flake8= Pythonコードの文法エラーや論理エラーをチェックするlinterisort= Pythonのインポートを一貫性のある方法でソートmypy= Pythonの静的型チェッカーbandit= セキュリティ脆弱性のスキャン- カスタムスクリプト = 独自のスクリプトを書いてフックとして使用可能
black, flake8, isort, mypy, banditと組み合わせる
それでは実際に表題の5つのフックを組み合わせていく実例を紹介します。
今回は各ツールの詳細については割愛します。(別のコンテンツで紹介します)
セットアップ
まず、pre-commitがインストールされていることを確認してください。
pre-commit --version.pre-commit-config.yamlファイル作成
リポジトリのルートに、以下の内容の.pre-commit-config.yamlファイルを作成します。
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v3.5.0 # 最新版を指定
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- repo: https://github.com/psf/black
rev: 23.10.0 # 最新版を指定
hooks:
- id: black
language_version: python3.11 # Pythonのバージョンを指定
- repo: https://github.com/pycqa/flake8
rev: 6.1.0 # 最新版を指定
hooks:
- id: flake8
- repo: https://github.com/pycqa/isort
rev: v5.11.2 # 最新版を指定
hooks:
- id: isort
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.6.1 # 最新版を指定
hooks:
- id: mypy
- repo: https://github.com/PyCQA/bandit
rev: 1.7.5 # 最新版を指定
hooks:
- id: bandit
args: ["-r", "."] # 再帰的に現在のディレクトリをスキャンGitフックスクリプトをインストールする
pre-commit installこのコマンドを実行すると以下のようなファイルが作成されます。
pre-commit installed at .git/hooks/pre-commitgitリポジトリでないと作成できないので、git管理しているプロジェクトのルートディレクトリで実行しましょう。
動作確認
ここまで設定したら動かしてみましょう。例として、README.mdを作成してコミットします。
$ touch README.md
$ git add README.md
$ git commit -m 'add readme'この時点で、以下のように.pre-commit-config.yamlに書いた内容がインストールされます。
[INFO] Initializing environment for https://github.com/pre-commit/pre-commit-hooks.
[INFO] Initializing environment for https://github.com/psf/black.
[INFO] Initializing environment for https://github.com/pycqa/flake8.
[INFO] Initializing environment for https://github.com/pycqa/isort.
[INFO] Initializing environment for https://github.com/pre-commit/mirrors-mypy.
[INFO] Initializing environment for https://github.com/PyCQA/bandit.
[INFO] Installing environment for https://github.com/pre-commit/pre-commit-hooks.
...[中略]...
trim trailing whitespace.................................................Passed
fix end of files.........................................................Passed
black................................................(no files to check)Skipped
flake8...............................................(no files to check)Skipped
isort................................................(no files to check)Skipped
mypy.................................................(no files to check)Skipped
bandit...............................................(no files to check)Skipped今回は特にチェック対象となるファイルがなかったため、すべてPassed(成功)かSkipped(スキップ)となります。
pre-commitを参考にどのように修正していくか
- 1度セットアップすると、変更をコミットしようとするたびに
pre-commitフックが実行されます。 - いずれかのツールが問題を報告した場合、コミットは停止され、フィードバックされます。
- 報告された問題に対処し、再度変更を追加してコミットする必要があります。
効率的にコードの品質を上げるpre-commitを活用しよう
pre-commitはPythonプロジェクトのコード品質を維持する強力なツールです。
レビューを自動化し、コーディング規約を強制することで、クリーンで一貫性があるコードを作成するのに役立ちます。小さな個人プロジェクトでも、大規模なチーム開発のアプリケーションでも、pre-commitは早い段階で取り入れるべきツールだと断言できます。
black、flake8などの複数のツールとpre-commitを統合することで、一括管理できるため、チェックの忘れ防止にも効果的です。安全性が保証と全体的な開発体験の向上を目指して、ぜひpre-commitの導入を検討してみてください。





