この記事は Git Advent Calendar 2016 - Qiita の8日目の記事です。
スペルチェッカー - aspell
スペルチェックをするために aspell というスペルチェッカーを使用します。
インストール on macOS
macOS では Homebrew 🍺 を使ってインストールします。
# To install aspell $ brew install aspell # make sure that the aspell has been installed. $ which aspell /usr/local/bin/aspell
インストール on Debian
Debian しか使っていないものでして…
# To install apell $ apt-get install aspell -y # make sure that the aspell has been installed. $ which aspell /usr/bin/aspell
使い方
list
コマンドを使用して、STDIN から文字列を流します。
# Test (Typo beautifl) $ echo What a beautifl sky | aspell list beautifl
上の例では beautiful をわざとタイポしています。
Git フック
どのタイミングで検証をするかはやはり Git フックで対応することになりますが、pre-commit などのクライアントサイドフック はよくあるので今回はサーバーサイドフックを使用します。
サーバーサイドフック
サーバーサイドフックスクリプトは知らない人は結構いる気がします。GitHub で特定のブランチのフォースプッシュを禁じる設定があると思いますが、あれはサーバーサイドフックが設定されているからです。
クライアントサイドフックの他に、いくつかのサーバーサイドフックを使うこともできます。これは、システム管理者がプロジェクトのポリシーを強制させるために使うものです。これらのスクリプトは、サーバへのプッシュの前後に実行されます。pre フックをゼロ以外の値で終了させると、プッシュを却下してエラーメッセージをクライアントに返すことができます。つまり、プッシュに関するポリシーをここで設定することができるということです。
サーバーサイドフックには下記の3種類存在しています。
- pre-receive
- post-receive
- update
pre-receive, post-receive フック
クライアントからのプッシュを処理するときに最初に実行されるスクリプトが pre-receive で、処理が終了した後に実行されるのが post- receiveです。スクリプトは、プッシュされた参照のリストを標準入力から受け取り、ゼロ以外の値で終了させるとプッシュが却下されます。post-receive フックについては処理の完了通知などに使うことができます。
update フック
update フックは pre-receive フックと似ていますが、pre-receive と違うのは複数のブランチへのプッシュがあったときにブランチ単位でそれぞれ一度ずつ実行されます。
スペルチェック方法
1. pre-receive
下記のスクリプトを .git/hooks/pre-receive に記述します。
#!/bin/sh which aspell > /dev/null if [ ! $? -eq 0 ] ; then exit 0 fi while read oldrev newrev refname do misspelled=`git log --format=%B -n 1 "$newrev" | aspell list` if [ -n "${misspelled}" ] ; then echo >&2 "Possible misspelled words in the commit message:" for e in $misspelled; do echo >&2 " - ${e}"; done exit 1 fi done
2. コミットメッセージ例
今回、下記のようなコミットメッセージを用意しました。beautiful をタイポしています。
$ git log commit f4eb3de Author: Shintaro Kaneko <kaneshin0120@gmail.com> Date: Thu Dec 8 14:03:37 2016 +0000 Initial commit: What a beautifl sky
3. git push
下記のようにプッシュを行うと、メッセージとともにプッシュがリジェクトされます。
$ git push origin master Counting objects: 1, done. Writing objects: 100% (1/1), 190 bytes | 0 bytes/s, done. Total 1 (delta 0), reused 0 (delta 0) remote: Possible misspelled words in the commit message: remote: - beautifl To /home/kaneshin/foo/rem ! [remote rejected] master -> master (pre-receive hook declined) error: failed to push some refs to '/home/kaneshin/foo/rem'
おわりに
pre-commit とかでは個人の環境に依ってしまうので、サーバーサイドフックでカバーできるところは積極的にカバーしていきたいものです。