シェルスクリプトのレビューを効率化するため,シェルスクリプト専用の静的解析ツール "ShellCheck" を導入して,さらに CircleCI で自動テストすることにした.導入検証も兼ねて,個人的に使ってる dotfiles に導入してみた話をまとめる.
apt-get install shellcheck
はできなかった
CircleCI で稼働するコンテナは "Ubuntu 12.04 (Precise)" or "Ubuntu 14.04 (Trusty)" なので,README に書いてある通り apt-get install shellcheck
を circle.yml
に書いて実行したら,エラーになってしまった.apt-get update
も効果は無かった.
$ sudo apt-get install shellcheck Reading package lists... Done Building dependency tree Reading state information... Done E: Unable to locate package shellcheck sudo apt-get install shellcheck returned exit code 100 Action failed: sudo apt-get install shellcheck
Issue を確認したら「Cabal を試してみて!」や「Ubuntu 用にパッケージングするのは良いけど,手伝ってくれる人はいる?」といったコメントがポストされていたけど,その後の進展は無くて,現時点だと難しそうだな...と判断した.
Cabal を使って ShellCheck をインストールした
よって,Cabal を使うことにした.CircleCI だとデフォルトで Cabal がインストールされていて,特に意識する必要は無かった.
しかし,Cabal 経由で ShellCheck でインストールすると,遅すぎる問題があった.以下のログを見るとわかる通り,8分も実行したままになってしまう...!回避策としては ~/.cabal
を cache_directories
に設定して,コンテナ起動時にリストアできるようにし,既にインストールされている場合はスキップするようにした.
ドキュメントを見ると Cabal はデフォルトで cache_directories
の対象になっているようにも読み取れるけど,今回は明示的に書くことにした.
完成した circle.yml
machine: environment: PATH: ${HOME}/.cabal/bin/:${PATH} dependencies: cache_directories: - "~/.cabal" post: - cabal --version - cabal update - if ! type shellcheck > /dev/null; then cabal install ShellCheck; fi - shellcheck --version test: override: - shellcheck --exclude=SC2039 *.sh
静的解析エラーを検出できるようになった
(shellcheck
にパスを通す前に動かしたキャプチャだから絶対パスになっている)
CircleCI Feature Requests
ShellCheck をデフォルトで使えるようにして!とリクエストは出ていた.
まとめ
- シェルスクリプトだって CI で静的解析エラーを検知したい
- ShellCheck 便利(ルールが厳しすぎるけど...w)
- CircleCI で動かす場合は Cabal 経由でインストールすると良い(
cache_directories
も必ず使うこと)