背景
ESLintやPrettierでファイルはちゃんとフォーマットしているのにコミットメッセージは人によってめちゃくちゃだったりします。
ルールも決まっていないと後から読み返したときに何をしたんだこれとなるのですが、とはいえ毎回「どんなルールだったっけ」とプロジェクトごとに見返すのもめんどくさいです。
あと、コミットしてから「あ、フォーマットするの忘れてた」となって再コミットするのもダサいです。
これらを全て解決する方法が求められていました。
Husky
huskyはgitで何らかの操作を行った際に割り込んで処理が行える仕組みを提供します。
例えば、コミットする際にはgit commitが実行される前にyarn lintやyarn testを実行するなどといった操作ができるようになります。
こうすればコミットされた内容はCIでのテストをパスすることが保証されるようになります。
この仕組みの便利なところはESLintとPrettierの基準を満たすかどうかをチェックしているのではなく、実際にこの時点で整形してくれることにあります、とても便利。
とはいえテストが通らないコミットができないのは困るので、テスト自体は通らなくても良いですがESLintとPrettierの整形は通って欲しい感じになります。
Huskyはつい最近アップデートがあったようで、使い方が大きく変更されています。ネットで検索しても違うコマンドが載っていたりして困ります。
導入
プライベートレポジトリでないなら以下の二つをインストールします。
yarn add -D husky pinstyarn husky initプライベートの場合は
pinstは不要のようです
yarn husky initについては不要かもしれませんが、一応実行しました。
これでpackage.jsonのscriptsに"prepare": "husky"が追加されていればOKです。
.├── .husky/│ ├── _/│ └── pre-commit└── package.jsonこの時点で上のような構成になっていると思います。
lint-staged
コミット前にESLintを実行させることができます。
yarn add -D lint-stagedとしてパッケージを追加し.lintstagedrc.yamlを作成します。
---'**/*.ts': - yarn lint - yarn formatこう書くとコミット内容に.tsのファイルがあればyarn lintとyarn formatを実行してくれます。
最後にこの処理がgit commitが実行される前に実行されてほしいので.husky/pre-commitを編集します。
yarn testyarn lint-stagedここの
yarn testは必ずしも必要ではない、大事なのはyarn lint-stagedが実行されること
.├── .husky/│ ├── _/│ └── pre-commit├── .lintstagedrc.yaml└── package.jsonするとこんな感じになると思います。
commitlint
commitlintはコミットメッセージが.commitlintrc.yamlに設定されたルールに則っているかをチェックするパッケージです。
yarn add -D @commitlint/cli @commitlint/config-conventionalインストールができたら.commitlintrc.yamlを作成します。
---extends: - '@commitlint/config-conventional'今回は特に何も入れていませんが、ここにプロジェクトごとのルールを追記することができます。
最後にコミットメッセージを書き込んだ後にチェックを行うので.husky/commit-msgのファイルを作成します。
yarn commitlint --edit ${1}こうすれば最後のコミットメッセージを読み込んでcommitlintが実行されます。
.├── .husky/│ ├── _/│ ├── commit-msg│ └── pre-commit├── .commitlintrc.yaml├── .lintstagedrc.yaml└── package.jsonするとここまでのファイル構成はこうなります。
実際にどんな挙動をするか確かめたい場合はcommit-msgの最後にexit 1を入れれば必ず失敗するので実際にコミットログが作成されません。
その状態でgit commit -m "testing pre-commit code"みたいな感じで実行すればどうなるかがわかります。
正常に動作していればcommitlintがエラーを返すはずです。
もしcommitlintがちゃんと動いていないようであればHuskyがhookに失敗しているのでyarn installでhuskyをインストールしてください。
cz-commitlint
cz-commitlintはcommitlintの拡張で、対話式でコミットメッセージが作成できるパッケージです。
commitlintと組み合わせて入力ミスを防ぎつつ、フォーマットに則ったコミットメッセージが書けます。
yarn add -D @commitlint/cz-commitlint commitizenエラーが発生する場合は
inquirer@8もインストールしてください
インストールが完了したらpackage.jsonを編集して、
{ "scripts": { "commit": "git-cz" }, "config": { "commitizen": { "path": "@commitlint/cz-commitlint" } }}を追記します。こうするとyarn commitで対話式のコミットメッセージが書けます。
git commit
とはいえgit commitに慣れているので、このコマンドを実行したときにもyarn commitと同様の効果が得られてほしいです。
そこで.husky/prepare-commit-msgを作成して以下の内容を書き込みます。
exec < /dev/tty && yarn cz --hook || trueこれはyarn czを実行してその結果がtrueであればexec 0を返すコードです。
Huskyは0以外の値を返すとエラーとしてコミットがなかったことになります。
ttyを入れないと対話式にならない(何も入力できない)
├── .husky/│ ├── _/│ ├── prepare-commit-msg│ ├── commit-msg│ └── pre-commit├── .commitlintrc.yaml├── .lintstagedrc.yaml└── package.json最終的にファイルの構成は上のようになります。
これでコミットメッセージに悩まされる日々から無事に開放されました、やったね。
でもこのレポジトリにはこの機能を実装していないという矛盾(おい
記事は以上。