すべてのcommitにcommitlintを実行する
モチベ
これまで恥ずかしながらコミットメッセージは雰囲気で書いていた。
ただそろそろちゃんと書くようにしないとと思い、まずはコミットメッセージ用のlinterを入れてみようと検討した。
調べた感じ commitlint が良さそうだったので、今回はそれを入れてみる。
公式の手順だと、commitlintとhuskyをプロジェクトごとにインストールする形になっている。
https://commitlint.js.org/guides/local-setup.html
今回の場合、特定のプロジェクトやチームに導入したいというよりも、自分の習熟のために導入したかった。
そのため自分のローカルにおいてはどのプロジェクトに対しても、常にcommitlintを実行するように設定してみた。
設定
各種バージョン
1[koh@Kohs-MacBook-Pro] ~
2% sw_vers
3ProductName: macOS
4ProductVersion: 15.1.1
5BuildVersion: 24B91
6[koh@Kohs-MacBook-Pro] ~
7% node -v
8v22.6.0
9[koh@Kohs-MacBook-Pro] ~
10% commitlint -v
11@commitlint/cli@19.6.1
12[koh@Kohs-MacBook-Pro] ~
13%
設定は以下のようにした。
1mkdir ~/.config/git/hooks/ # ディレクトリは任意のパスでいい
2git config --global core.hooksPath \~/.config/git/hooks
3vi ~/.config/git/hooks/commit-msg
4chmod +x ~/.config/git/hooks/commit-msg
commit-msgファイルには以下のように記述する。
1#!/usr/bin/env bash
2
3# install commitlint if not installed
4if ! command -v commitlint &> /dev/null; then
5 echo "commitlint not found, installing..."
6 npm install -g @commitlint/cli @commitlint/config-conventional
7fi
8
9# set config
10# SEE: https://github.com/conventional-changelog/commitlint/tree/master/@commitlint/config-conventional
11CONFIG="
12extends:
13 - '@commitlint/config-conventional'
14"
15
16# exec commitlint
17commitlint --edit "$1" --config <(echo "$CONFIG")
インストール
@commitlint/cli
と @commitlint/config-conventional
をインストールする。
後者の方は設定したいルールによって変更する。
https://github.com/conventional-changelog/commitlint/tree/master/%40commitlint
の config-*
の中から選ぶ。
今回はGetting startedで指定されていたconventionalを選択した。
具体的なルールは以下。
https://github.com/conventional-changelog/commitlint/tree/master/@commitlint/config-conventional
設定ファイル
commitlintは実行時に設定ファイルが必要になる。
https://commitlint.js.org/reference/configuration.html
現時点では設定がシンプルかつ、管理するファイルを減らしたかった。
そのためスクリプト内でプロセス置換する形で設定を渡している。
設定の読み込み時に cosmiconfig を使用しており、設定ファイルの拡張子がない場合はYAML形式でパースされる。
そのためプロセス置換で設定ファイルを作成する場合は、YAML形式で記述する。
hookでの実行
gitのcommit-msg hookを利用する。
https://git-scm.com/docs/githooks#_commit_msg
第一引数にコミットメッセージのファイルパスが渡されるので、それを利用する。
具体的には .git/COMMIT_EDITMSG
が第一引数になる。
動作確認
これにより、ローカルのすべてのプロジェクトでcommitlintが実行される。
1[koh@Kohs-MacBook-Pro] ~/work
2% mkdir commit_test && cd commit_test
3[koh@Kohs-MacBook-Pro] ~/work/commit_test
4% git init .
5Initialized empty Git repository in /Users/koh/work/commit_test/.git/
6[koh@Kohs-MacBook-Pro] ~/work/commit_test
7% echo foobar >> test.txt && git add test.txt && git commit -m "foobar"
8⧗ input: foobar
9✖ subject may not be empty [subject-empty]
10✖ type may not be empty [type-empty]
11
12✖ found 2 problems, 0 warnings
13ⓘ Get help: https://github.com/conventional-changelog/commitlint/#what-is-commitlint
14
15zsh: exit 1 git commit -m "foobar"
16[koh@Kohs-MacBook-Pro] ~/work/commit_test
17% git commit -m "feat: foobar"
18[main (root-commit) 9dd1ceb] feat: foobar
19 1 file changed, 1 insertion(+)
20 create mode 100644 test.txt
21[koh@Kohs-MacBook-Pro] ~/work/commit_test
22%
新規のプロジェクトでも、commitlintが実行されている。
まとめ
とりあえずはこの設定で試してみようと思う。
大リーグボール養成ギプスのように、常にlinter実行することで慣れると嬉しい。