八発白中

はてなブログに引越しました。

プロジェクトのCommon Lispライブラリ管理ツール「qlot」を作りました

想像してください。

Common Lispで開発しているアプリケーションが手元にありますよね。

それを他の環境、たとえば他の開発者のPC、CI環境やWebサーバなどで動かしたいというときに起こる問題はなんですか。

大きな問題は処理系やライブラリのバージョンが違うために、自分の環境では動くのに他の環境に持っていくと動かないということです。

処理系に関してはCIMを使えば固定できますが、Common Lispにはライブラリのバージョンを固定する方法は現状ほとんど無いために問題になります。

こういった、Common Lispプロジェクトの可搬性を上げるツールとして「qlot」を作りました。

Quicklispの何が問題か

Common LispにはQuicklispという偉大なライブラリインスーラ及びライブラリの中央リポジトリがあります。依存ライブラリも含めてインストール・ロードしてくれるので、Common Lispでの開発が非常に楽になりました。

けれど、Quicklispにはいくつか問題があります。

  • 更新が月一しかない
  • 特定のライブラリのみ違うバージョンを使うことができない

更新が月に一回しかないので、GitHubに上がっている最新のClackを使いたいみたいなことができません。

また、Quicklispはライブラリを毎月のアップデートごとに管理しているので、すべてのライブラリを同じ時期のものを使うしか選択肢がありません。つまりlog4clだけ古いバージョンを使うということもできません。

"local-projects/"やASDFの設定をいじればgit cloneしたライブラリを使うことはできますが、git cloneしたことを忘れてて更新があったあとも古いバージョンをロードしてしまうみたいなことないですか。僕はつい最近もnamed-readtablesでやらかしました。

とにかく、Quicklispは使うライブラリを細かく管理するという目的ではまったく使えないのです。

qlotとは

qlotは、Common Lispライブラリをプロジェクトローカルにインストール・ロードすることができるツールです。

(正確にはプロジェクトローカルにQuicklispをインストールします。)

使い方を見せたほうが早いのでとっとと使い方を紹介します。

使い方

qlfileを置く

プロジェクトで使うライブラリをqlfileに記述します。すべてを記述する必要は無く、書かれていないものであれば最新のQuicklispのdistからロードされます。

たとえばGitHubにある最新のClackとdataflyを使いたい場合は以下のようなqlfileを用意します。

git clack https://github.com/fukamachi/clack.git
git datafly https://github.com/fukamachi/datafly.git

詳しいqlfileの書き方はGitHubのREADMEを参照してください。

単純にquicklispをプロジェクトごとに分離したい場合は空のqlfileを用意してください。

ライブラリをインストールする

qlotを通常通りにql:quickloadでロードします。

(ql:quickload :qlot)

それからqlot:installをプロジェクト名と一緒に呼び出します。

(qlot:install <プロジェクト名>)
(qlot:install :myapp)

:myappであれば(qlot:install :myapp)みたいな感じです。

インストールはこれだけです。プロジェクトルートにquicklisp/ディレクトリとqlfile.lockファイルができているのが分かると思います。

qlfile.lockはインストールした内容をスナップショットとして記録したものです。このファイルがあるとqlot:installはlockを優先します。一度こうしてインストールしておけば、他の環境でqlot:installしたときにも全く同じバージョンのライブラリを使うことが保証されます。

quicklisp/VCSから無視されるようにし、qlfileqlfile.lockを追加しておきます。

$ echo quicklisp/ >> .gitignore
$ git add qlfile qlfile.lock
$ git commit -m 'Start using qlot.'

プロジェクトをロードする

プロジェクトをロードするときはql:quickloadの代わりにqlot:quickloadを実行します。

(qlot:quickload :myapp)

これはプロジェクトローカルのQuicklispを使ってロードする関数です。

ライブラリをアップデートする

一度qlot:installしたあとqlfileを更新したり、ライブラリのバージョンを更新したいときなどはqlot:updateを実行します。

(qlot:update :myapp)

これでquicklisp/の内容とqlfile.lockが更新されます。

デプロイするとき

qlfile.lockさえ環境間で共有しておけば、qlot:installを実行するだけで同じQuicklisp環境が再現されます。

(qlot:install :myapp)

まとめ

使う関数はqlot:installqlot:quickloadqlot:updateの3つだけです。簡単でしょ?

今月のQuicklispアップデートで入る予定なので、試したい方は1、2週間くらい待つと使えるようになると思います。

ソースコードは例によってGitHubに上がっています。Starしてね!

余談: Lispイベント

今月は中旬にモントリオールでInternational Lisp Conferenceがあったり、月末にShibuya.lispのTech Talkがあったりでなかなか良い月になりそうですね。

Shibuya.lispテクニカル・トーク #8
日時: 8/30(土) 11:00 〜 18:30
場所: 株式会社ミクシィ

トークの応募は8月16日(土)までなので、何か話したい人は早めに準備して応募すると良いと思います。

僕も、qlotについてではないですが他のプロジェクトについて話すつもりでいます。みんな参加しましょう。