Python pre-commitの使い方

Pythonのpre-commitは、Gitのpre-commitフックを簡単に管理するためのモジュールです。pre-commitを使用すれば、Git管理下のファイルを編集した際にflake8blackといったリンター・フォーマッターを適用したり、秘密鍵が管理下に含まれていないかなどの様々な処理を簡単にフックに登録することができます。

目次

基本的な使い方

インストール

まず、pre-commitはpipコマンドでインストールできます。

$ pip install pre-commit

インストールできたら、pre-commitというコマンドが使用できるようになります。

$ pre-commit --version
pre-commit 2.17.0

設定ファイルの作成

サンプルの設定ファイルはコマンドで作成することができます。設定ファイルの書き方については後述します。

$ pre-commit sample-config > .pre-commit-config.yaml
$ cat .pre-commit-config.yaml 
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
repos:
-   repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v3.2.0
    hooks:
    -   id: trailing-whitespace
    -   id: end-of-file-fixer
    -   id: check-yaml
    -   id: check-added-large-files

フックの登録

まず、説明のためにGitリポジトリを新たに作成します。

$ git init
Initialized empty Git repository in (PATH/TO/YOUR/REPOSITORY)

後は、Gitリポジトリの中でpre-commit installサブコマンドでフックを登録できます。

$ pre-commit install
pre-commit installed at .git/hooks/pre-commit

ソースファイルのコミット

それでは、簡単なソースファイルをコミットしてみましょう。なお、敢えて末尾に空白を入れてみます。

$ echo "print(1) " > sample.py
$ git add sample.py 
$ git add .pre-commit-config.yaml 
$ git commit -m "first commit"
[INFO] Initializing environment for https://github.com/pre-commit/pre-commit-hooks.
[INFO] Installing environment for https://github.com/pre-commit/pre-commit-hooks.
[INFO] Once installed this environment will be reused.
[INFO] This may take a few minutes...
Trim Trailing Whitespace.................................................Failed
- hook id: trailing-whitespace
- exit code: 1
- files were modified by this hook

Fixing sample.py

Fix End of Files.........................................................Passed
Check Yaml...............................................................Passed
Check for added large files..............................................Passed

するとtrailing-whitespaceフックによってsample.pyに問題が見つかりました。git log サブコマンドで確認すると、コミット自体が中断されていることがわかります。

$ git log
fatal: your current branch 'master' does not have any commits yet

また、trailing-whitespaceはフォーマッター機能であるため、自動的にsample.pyの修正まで行ってくれます。WEBページ上では表現しにくいですが、お手元で実行すれば末尾の空白が消えていることが確認できるはずです。

$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	new file:   .pre-commit-config.yaml
	new file:   sample.py

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   sample.py

後は再度、変更を追加してコミットすれば完了です。

$ git add sample.py 
$ git commit -m "first commit"
Trim Trailing Whitespace.................................................Passed
Fix End of Files.........................................................Passed
Check Yaml...............................................................Passed
Check for added large files..............................................Passed
[master (root-commit) 7f50631] first commit
 2 files changed, 11 insertions(+)
 create mode 100644 .pre-commit-config.yaml
 create mode 100644 sample.py
$ git log
commit 7f506317da543561a1303bc9f903c8232ecbee78 (HEAD -> master)
Author: author <you@example.com>
Date:   Fri Feb 18 20:36:22 2022 +0900

    first commit

なお、各種フックは差分をコミットするファイルにのみ適用されます。

サブコマンド群

autoupdateサブコマンド

pre-commit autoupdateサブコマンドは、設定ファイルで管理されているフックのリポジトリを最新化します。

$ pre-commit autoupdate
Updating https://github.com/pre-commit/pre-commit-hooks ... [INFO] Initializing environment for https://github.com/pre-commit/pre-commit-hooks.
updating v3.2.0 -> v4.1.0.
$ cat .pre-commit-config.yaml 
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
repos:
-   repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v4.1.0
    hooks:
    -   id: trailing-whitespace
    -   id: end-of-file-fixer
    -   id: check-yaml
    -   id: check-added-large-files

runサブコマンド

pre-commit runサブコマンドは、フックを手動で実行します。対象のファイルはコミット時と同様に差分を追加したファイルのみですが、--all-filesオプションでGit管理下の全てのファイルを対象としたり、--filesオプションで特定のファイルを対象にしたりすることができます。Git管理されていないファイルは対象になりません。

$ echo "print(1) " > sample.py
$ pre-commit run -a
trim trailing whitespace.................................................Failed
- hook id: trailing-whitespace
- exit code: 1
- files were modified by this hook

Fixing sample.py

fix end of files.........................................................Passed
check yaml...............................................................Passed
check for added large files..............................................Passed

$ echo "print(1) " > sample_new.py
$ pre-commit run -a
trim trailing whitespace.................................................Passed
fix end of files.........................................................Passed
check yaml...............................................................Passed
check for added large files..............................................Passed

uninstallサブコマンド

pre-commit uninstallサブコマンドは、Gitリポジトリの管理下のフックを削除します。

オススメのフックと設定方法

この節ではオススメのフックを紹介します。設定方法は、各小節のYAMLコードを.pre-commit-config.yamlに追加するだけです。

なお、フックのリビジョンを最新化する場合は、手動で書き換えるか、設定ファイルの更新後にpre-commit autoupdateを実行してください。

black

blackはコードフォーマッターの一つです。設定項目が非常に少なく、改行の仕方やシングルクォート・ダブルクォートの使い分けなど、書き方の揺らぎを強制的に統一してしまうという特徴があります。フォーマットの好みに関する議論を回避して、一通りの書き方に統一してしまいたい場合にオススメです。

repos:
# 中略
-   repo: https://github.com/psf/black
    rev: 22.1.0
    hooks:
    -   id: black

Bandit

Banditはセキュリティリスクのあるコードを検知してくれるツールです。

-   repo: https://github.com/PyCQA/bandit
    rev: 1.7.2
    hooks:
    -   id: bandit

バージョン情報

筆者は以下のバージョンで動作を確認しました。

  • pre-commit==2.17.0
よかったらシェアしてね!
  • URLをコピーしました!

この記事を書いた人

ITベンチャーでデータ分析、AI開発、システム設計、提案、営業、組織管理、公演、採用などなど多数の役割に従事してきました。

様々な職業や背景の方々と交流するうちに、幅広い分野で問題を解決したり価値を生み出したりするためには、個別の知識だけでなく、汎用的に物事を考える力を伸ばしていく必要があると考えるようになりました。

更に、自分自身の考える力だけでなく、より多くの人々の考える力のトレーニングを応援することで、社会全体を良くしていけるのではないかと考えて、このサイトを作りました。

目次
閉じる