Gitのcommit時などに自動でlinterなどを動かしてコードを直したり警告を出したりしてくれる pre-commitでシェルスクリプトの文法チェッカーである ShellCheckを使う方法について。
- pre-commit
- ShellCheck
- pre-commitのSupported hooksに載っているもの
- shellcheck公式のpre-commit hook
- 直接自分でコマンドを走らせる
- まとめ
pre-commit
pre-commitはPython製のGit hookを使ってcommit時などにlinter等を実行するツールです。
Python製ですが他の言語の文法チェックなども行えます。
pipで
$ pip install pre-commit
とインストールすることも出来ますし、 Homebrewで
$ brew install pre-commit
でもインストールできます。
ShellCheck
ShellCheck はシェルスクリプトの文法チェッカーで一番有名なツールだと思います。 (このツール自体はHaskell製。)
インストールはapt
やyum
などLinuxでのパッケージマネージャーを使っても出来ますし、Homebrewを使ってインストールすることも出来ます。
その他いろいろな方法でインストールできますし、
shellcheck.net
でWeb上のエディタでチェックすることも出来ます。
加えて、下にも書きますが、Pythonのパッケージマネージャーのpip
でもインストールすることが出来ます。
pre-commitのSupported hooksに載っているもの
公式のページにリストされているhooksを見てみると
以下の3つがShellCheckを含んでいるようです。
- shellcheck-py/shellcheck-py: python3/pip3 wrapper for installing shellcheck
- jumanjihouse/pre-commit-hooks: git pre-commit hooks that work with http://pre-commit.com/
- syntaqx/git-hooks: A collection of git hooks for use with pre-commit
jumanjihouse/pre-commit-hooks or syntaqx/git-hooks
下2つに関して見てみると、例えばjumanjihouse/pre-commit-hooksの方は .pre-commit-hooks.yaml を見てみると
1 2 3 4 5 6 7 8 |
|
な感じになっていて、スクリプトを別途呼び出しています。 このスクリプトの中身は
1 2 3 4 5 6 7 8 9 10 11 |
|
な感じでshellcheck
を呼び出しているだけです。
警告があるようにshellcheck
自体は自分で入れる必要があります。
個人的な開発ではshellcheckを入れておけば良いのでこの辺を使うのもありですが、できればpre-commit install
などで必要なツールは勝手に入れてくれるようにしてもらいたいところ。
一方でpre-commitを自分で作ることはこれまでしたことありませんでしたが、これらのレポジトリのものはスクリプトを実行するだけのもので、それをいくつか用意して1つのパッケージ化したような感じです。
おそらくそれぞれ個人的な用途で作ったもので、中身も網羅的というよりはおそらくこの人達が必要だったんだろうな、という感じのものの集まりで、他にもこういったレポジトリがいくつかSupported hooksのページには載っています。
Suported hooksには自分で作ったものを載せたければPull Requestして載せてもらう感じで結構なんでも載せてくれる感じみたいです。
色々あるのでちょっとノイズなものもありますが、自分用にちょっとpre-commitを用意しようと思う場合にはこれらは参考になるかも。
shellcheck-py
shellcheck-py/shellcheck-py はこのレポジトリ自体はpre-commitのためのレポジトリ、の前にshellcheck-pyのPythonパケージレポジトリになっています。
このshellcheck-pyはpipで
$ pip shellcheck-py
でインストールでき、Pythonのインストール先のbin
ディレクトリにshellcheck
コマンドがインストールされます。
Pythonで作り直したものかと思いきや
shellcheck-py/setup.py at main · shellcheck-py/shellcheck-py
を見てみるとshellcheck
をダウンロードしてきて、そのバイナリファイルをそのままコピーしてインストールしているだけのようです。
こういう方法がありなのか、と言う感じですが、この方法を使えば原理的にあらゆるコマンドをpipでインストールできるようになります。 自分で使うところはあるかわからないですがちょっと覚えておきたいところ。
で、このレポジトリにはpre-commitから呼べるように
.pre-commit-hooks.yamlが用意されていてlanguage
がpython
になっているので、このhookを自分の.pre-commimt-config.yaml
に
1 2 3 4 5 |
|
みたいな感じで書いておけばpre-commit install
でpre-commitの作る仮想環境の中にshellcheck
コマンドがインストールされます。
なので現状ではこのhookが一番良いのではないかな、と思ってます。
shellcheck公式のpre-commit hook
上のSupported hooksには載っていませんがShellCheckの作者がpre-commit用のhookを作っています。
こちらはどうやっているかというと
.pre-commit-hooks.yaml
を見てみるとlanguage
がdocker_image
になっています。
shellcheckの入ったdockerイメージを使うので、これもshellcheckを別途インストールする必要はありません。 仮想環境にもインストールはされない状態です。
一方でdocker
が使える状態になってないと使えません。
dockerが使える環境であれば一番クリーンな状態のまま使うことは出来ますが、
ちょっとした環境でやりたい時にdocker
がないと走らせられないことになります。
直接自分でコマンドを走らせる
最初のスクリプトを走らせるだけのものがありましたが、
それらはshellcheck
を自分でインストールしておく必要がありました。
もしshellcheck
を別途インストールするのであれば、直接それを使うhookを作ってしまった方がシンプルかと思います。
1 2 3 4 5 6 7 8 9 |
|
こんな感じのrepo
をlocal
にしたhooks
にshellcheck
を作ってあげれば良いだけ。
types
などのオプションはhooks
が用意されているレポジトリを使う際に自分で指定することが無いのでちょっと調べる必要がありますが、
上記のshellcheck
を含むレポジトリの
.pre-commit-hooks.yamlを参考にしたり
pre-commitのドキュメントを読んだりすればそれほど難しいものではないです。
まとめ
shellcheckをpre-commitで使う方法ですが、 shellcheck-py/shellcheck-py を使って、
1 2 3 4 5 |
|
でshellcheck
コマンドもpre-commitによって管理してもらうようにするのが一番便利だと思いました。
shellcheck
は必ず環境に入っている前提だ、という場合には
1 2 3 4 5 6 7 8 9 |
|
として直接環境のshellcheck
を使うようにしてあげるのもありかな、と思います。