16
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Emacs LispをTravis CIしてみる勉強ノート

Last updated at Posted at 2015-01-12

何の因果か最近Emacs Lispを書くことになりました。

Emacsみたいなこわいエディタの話をしているのは必然的にこわいひとが多いです。
ドラクエで例えるとキラーマシンみたいな方ばっかです。
そんな中、ひのきのぼう/たびびとのふく/Lv1 でぷるぷるしながら調べたこと試したことをまとめて公開します。

新たな勇者のぼうけんの、最初の一歩を手伝えれば幸いです。

#注意
Emacs Lispは初心者、それ以外は今回はじめて触ったという体たらくで書いた記事です。

というか、主にこのページの劣化焼き直しです。
Emacs Lispのテスト、依存性管理、CI - 備忘録
この記事を読む方は先にこちらのページをひと通り読みましょう。不自由なく理解できた方は以下を読む必要はありません。

#ERTとは

ERT is an Emacs Lisp library for regression/unit testing.
EmacsWiki: Ert Test Library

Emacs24には標準で入ってます。
ELErejeep/ert-runner.elのような便利糖衣もあって、この記事でやってる程度のことは全部できるっぽいですが試してません。

##つかいかた
適当なelファイル(例えばhoge-test.el)にテストコードを書いて、emacsからM-x ertで対話的に実行できます。

複数のテストを一括でやったりCIで自動実行したりするためには、emacsのバッチモードが使えます。
$ emacs -Q -batch -l hoge-test.el -f ert-run-tests-batch-and-exit
参考:Initial Options - GNU Emacs Manual (emacs自体のオプション)
Action Arguments - GNU Emacs Manual (-batchのオプション)

##かきかた
###いあいあ えると

hoge-test.el
(require 'ert)
(require 'hoge)
(eval-when-compile
  (require 'cl))

のようにertとテストしたいファイルをrequireします。
マクロは単にrequireしただけだとバイトコンパイル時にうまく置換されないようなので(eval-when-compile)で囲います。
参考:12.3 マクロとバイトコンパイル

具体的なテストはert-deftestを使って書きますが、defunスペシャルフォームとほぼ同じ書き方です。
###おまたせしました すごいやつ

hoge-test.el
(ert-deftest hoge-test ()
  "Test of `hoge'."
  (should (equal EXPECTED
                 ACTUAL)))

shouldマクロだよ。ACTUAL部に実際の処理を、EXPECTED部に予期される返り値を書くことで値を比較してエラーを吐いたりしてくれるすごいやつだよ。

最低限これだけ覚えておけばテストが書けますやったね。
shouldに備わった 108式まである 便利機能の詳細は以下のページを参照。
How to Write Tests - Emacs Lisp Regression Testing

###お前もERTか?ERTなら俺が相手だ

hoge.el
(ert-run-tests-batch-and-exit)

この式を評価すれば先述したバッチ処理がemacs内から呼べます。
具体的にはロードされてるelファイルのert-deftestで定義されたテストをぜんぶ実行します。
複数のテストに共通する初期設定などを1ファイルで行い、そのあと各テストを呼ぶようなときに使えそうです。

#Cask
##Caskとは
Emacs用の非公式パッケージマネージャです。普段使いされてる方も多いようです。
今回は依存ライブラリをすごい勢いで解決してくれます。
インストールは公式にある通り、
$ curl -fsSkL https://raw.github.com/cask/cask/master/go | pythonでOK。
以下パスも通した体で行きます。

##つかいかた
$ cask$ cask install で、カレントディレクトリのCaskファイルに応じて依存関係を解決してくれます。
その後 $ cask exec emacs -Q -batch -L . -l hoge-test.el -f ert-run-tests-batch-and-exit のようにバッチ処理。
先のバッチ処理に-L .なるオプションが加わりましたが、.(カレントディレクトリ)をロードパスに加える指示です。
詳細はこのへん参照。

あとcaskは、環境変数$EMACSに応じてEmacsのバージョンを変えてくれます。
あとで.travis.ymlでこの機能使うので頭の片隅に。

##かきかた
ワーキングディレクトリにCaskファイルを作って以下を記述。

Cask
(source gnu)
(source melpa)
(source marmalade)

(files "hoge.el")

(development
 (depends-on "ert")
 (depends-on "cl")
)

基本Emacs Lispです。
(Emacs24.3以降しか相手にしないならclもertも標準で入ってるのでわざわざ書かなくてもいい・・・?)
cask固有の指示方法の詳細はCask Domain Specific Language — Cask 0.7.2参照。

実用的にはfileをちまちま指定せず特定ディレクトリにまとめて*.elのように指示するか、packageにするんでしょうか。
そのへんさっぱりわかりません。今後の課題(逃げ口上)。

#Travis CI
##Travis CIとは
Githubと連携した継続的インテグレーション(CI)サービスです。フリーミアム。
githubにpushするだけでweb-hookを受け取ってテストを走らせて結果を通知してくれます。

2015年1月現在、対応言語は驚きの20種類。

C C++ Clojure C# D Erlang F# Go Groovy Haskell
Java JavaScript (with Node.js) Julia Objective-C 
Perl PHP Python Ruby Rust Scala Visual Basic

はい、Lispはありませんね。
でもテスト自体はERTに任せられるので、ERTをmakeから叩けば万事OKのようです。

ターミナルからいろいろしたい人のためにgemも用意されています。
gem install travisしてtravis login --autoするだけの簡単作業で256倍便利に。
Webのアカウント登録もgithubのログイン情報使って勝手にやってくれたしこっちでも勝手にやってくれるし便利すぎて薄気味悪い

##とらびす だーくねす

.travis.yml
language: emacs-lisp
env:
  - EMACS=emacs23
  - EMACS=emacs24
  - EMACS=emacs-snapshot
matrix:
  allow_failures:
    - env: EMACS=emacs-snapshot
before_install:
  # Install Emacs
  - sudo add-apt-repository -y ppa:cassou/emacs
  - sudo add-apt-repository -y ppa:ubuntu-elisp
  - sudo apt-get update -qq
  - sudo apt-get install -qq $EMACS
  # Install Cask
  - curl -fsSkL --max-time 10 --retry 10 --retry-delay 10
        https://raw.github.com/cask/cask/master/go | python
  - export PATH="$HOME/.cask/bin:$PATH"
  - cask
script:
  make

今までに解説したコマンドが総動員ですね。
env:で指定した環境変数ごとに1回ずつ一連のコマンドを実行する、ということが分かればぜんぶ読めます。

最新のemacsを拾ってくるにあたり、Travis CI側の環境がUbuntu 12.04LTSなのでppa形式でリポジトリを追加しています。
元記事様ではppa:cassou/emacsを採用していたようですが去年1月6日に更新を停止されたためこちらに切り替え。

では次肝心のmake。

##むーんぷりずむぱわーめいくふぁいる

Makefile
EMACS ?= emacs
CASK ?= cask

all:
        ${MAKE} clean
        ${MAKE} test
        ${MAKE} compile
        ${MAKE} test
        ${MAKE} clean

compile:
        ${CASK} exec ${EMACS} -Q -batch -L . -eval "(batch-byte-compile)" hoge.el
test:
        ${CASK} exec ${EMACS} -Q -batch -L . -l hoge-test.el -f ert-run-tests-batch-and-exit
clean:
        rm -f hoge.elc

.PHONY: all compile test clean

Makefileのお約束としてインデントはTAB文字じゃないと動きません。コピペ実行あぼん注意。
元記事様ではバイトコンパイル時に1つでもwarningが出たらmake失敗にしていたようですが、こちらはwarningのまま放置する感じです。

##でびる めいく らい
makeファイルを書いたらひとまずローカルでmakeすればテストが走ります。
エラーを全部直して一安心、いざgit pushしたらTravis側ではErrorとWarningが洪水だったりする。

頑張れ。

#まとめ
ここまでひと通りやったらあとはgithubにpushすればいいです。
初回push後Travis側の処理が終わったら通知が来ます。
その後はMakeがエラー吐けば通知が来ます。
治せれば通知が来ます。
治ってから次にエラーが発生するまでは静かに暮らせます。「植物の心」のような人生を送るためにもローカルでmake回しまくりましょう。

  • pushするまでもなく、ローカルの段階でmakeが通らなければgit commit出来ないような仕組みがあると便利そうですね。
  • gitのpre-commit hook機能で実現できそう。

通知形式はデフォルトではgithub登録アドレスへのメールですが、Web-hookを吐くのでなんでもできそうです。

16
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?