core.hooksPath を使って、コミットするときに文章中の軽微なミスを検出する仕組みを考える
core.hooksPath
を使って、コミットするときに textlint を実行し、文章中の軽微なミスを検出する Git Hooks を作った。
この Git Hooks を利用すると、事前に定義した textlint のルールに基づいて、絶対に修正したい用語を使っている場合はコミットを中断し、文脈で判断する必要がある場合はコミットするかを選ぶことができる。
背景
仕事でライティングをしているとき、製品名やサービス名を typo したりカタカナ語の長音の有無が揺れていたりといった軽微なミスをすることが多々ある。
そのようなミスは機械的に検出しやすいため、CI 上で textlint を動かして、Pull Request のレビュー前に検出できる仕組みを構築している。
一方で、自分だけが良くしてしまうミスもある。たとえばページ内で類義語が揺れていたり、テクニカルライティングの技法として伝わりづらい表現を使ってしまったりすることがある。
こういった個人的にやらかしてしまうミスを、CI 上で実行している textlint のルールファイルに反映することは心苦しく感じている。
実現したいこと
個人的なミスを検出する仕組みでは、次のことを実現したい。
- プッシュする前に textlint を実行することを忘れるため、コミットしてしまう前に気づきたい
- 編集するコンテンツは複数のリポジトリに分かれているため、リポジトリごとに仕組みを管理したくない
たとえば、textlint の実行環境やルールは各リポジトリで共有したい - 使わないと決めた用語を使っている場合はコミットを中断し、文脈で使うかを判断する必要がある場合はコミットするかを選べるようにしたい
実現方法
調べてみると、azu さんのsecretlint/git-hooks が参考になりそうだった。
この構成を参考にして、コミットしてしまう前に textlint を実行する仕組みを作ることにした。
- Git Hooks の pre-commit を使うと、プッシュする前に textlint を実行できる
- Git Hooks を
core.hooksPath
に設定すると、スクリプトをリポジトリごとに管理する必要がない
ただし、グローバルな Git Hooks は複数定義できないため、適用したいリポジトリにだけ--local
オプションをつけてcore.hooksPath
を設定する
リポジトリ内に個別の Git Hooks(.git/hooks
)が設定されているリポジトリの場合、先にリポジトリ内の Git Hooks を実行する - Docker を使って textlint の実行すれば、textlint の実行環境やルールを共有できる
私は Node.js のバージョン管理ツールを使っているため、グローバルインストールすると、Node.js のバージョンを切り替えるたびにインストールが必要になる
また、textlint では、ルールごとにエラー結果を Warning にしてステータスコード 0 を返すことができる。
textlint のルールには、正規表現を使って特定のパターンを検出する、@textlint-rule-prh
と @textlint-rule/textlint-rule-pattern
というよく似た 2 つのルールがある。
このルールを使い分けて、それぞれ別のステータスコードを返すようにする。
@textlint-rule-prh
:Error としてステータスコード 1 を返す
使わない決めた用語を使っている場合のパターンを記載する@textlint-rule/textlint-rule-pattern
:Warning としてステータスコード 0 を返す
文脈で使うかを判断する必要がある場合はコミットするかを選べるようにする
類義語の揺れの検知には @textlint-ja/textlint-rule-no-synonyms
を使うことにした。
どの用語を使うかは文脈で判断する必要があるため、Warning を返すようにした。
利用イメージ
Docker 上で textlint を実行するため、事前に Docker を起動しておく。
コミットするタイミングで、prh.yml
で定義したパターンに一致する場合は、エラーで止める。
textlint-rules-pattern
の patterns
で定義したパターンに一致する場合は、コミットするかどうかを尋ねる。
Docker イメージのバージョンが同じ場合は、次回起動時には Docker イメージはビルドされない。
所感
- 自分がやってしまいがちなミスのチェックリスト代わりにはなりそう。
ただし、チーム内で合意で決まったルールは、チームの textlint のルールファイルに反映したほうが良い。 - ルール設定ファイルを変更した場合、Docker イメージのバージョンを上げる必要がある。
この辺は自動化できるのだろうか。Docker は手探りで勉強しているのでわからない。