(define -ayalog '())

括弧に魅せられて道を外した名前のないプログラマ

Boot を Leiningen プロジェクトの中で使う

一緒にお仕事している Clojure デキルマンに Boot を闇ツール扱いされる今日この頃です。

日本ではあまり使っている人が多くない*1 Boot ですが、あやぴー的にはかなり気に入っています。ちなみに先日バージョン 2.0.0 がリリースされています。

まぁ、 Boot いいよ、とは言うものの正直 Leiningen で満足しているし、何も不便ないよという人たちも多いかもしれません。しかしながら、 Leiningen がもう少し柔軟にタスクのようなものを定義できたら…とか思うこともたまにはあると思います。 Boot はそういうことに長けていますが、それだけのために今の Leiningen のプロジェクト設定を全て捨てて Boot を使いはじめるというのはなかなかの苦痛だと思います。なので、今日紹介するのは Leiningen のプロジェクトをベースに Boot のタスクを使えるようにするという方法です。

Leiningen の project.clj が単純なマップであることは言うまでもないですが、であれば簡単に Clojure で読み込んでそのデータをそのまま使えるということは想像に難くないと思います。そして Boot の build.boot には Clojure のコードを普通に書けます。言いたいことは分かりますよね?

次のようなコードを build.boot の中で書くと簡単に project.clj の依存性などを Boot から参照して使うことができます。

(def lein-proj 
  (->> 
    "project.clj" 
    slurp 
    read-string 
    (drop 3) 
    (partition 2) 
    (map vec) 
    (into {})))

(set-env!
 :source-paths   (into #{} (:source-paths lein-proj))
 :resource-paths (into #{} (:resource-paths lein-proj))
 :dependencies   (into [] (:dependencies lein-proj)))

弊社プロジェクト内での使い方はもう少し違いますが、これをベースにした考え方で共存させています。

Boot is 闇?

たまにこの共存をしているがために起こる問題があります。だいたいは Leiningen と Boot の依存性の解消方法が違うためです。例えば midje を使っていて、使われる slingshot のバージョンが違うからテストが通らないという事件があったり…。
こういう場合は lein deps :tree と boot show -p を使ったりしてどのバージョンが使われているかを確認したりする必要があります。まぁ謎のエラーが起こったらだいたい依存性周りで変なバージョンが入っている可能性があるので、確認すれば案外素直に解決できるかと思います。

ちなみに

なんで弊社、 Boot だけにしないで Leiningen を一緒に使っているかというと、僕は何も問題ないんだけど一緒にやっている Clojure デキルマンの環境*2では Boot がありえないくらい遅いというのと、何故か CircleCI*3 環境でテストが遅いということで Boot は僕のために置いているという感じ。
ただ、デキルマン的にも Boot でタスクをカジュアルに定義出来るのは便利だと思っているらしいので、それだけでも十分にメリットありそう。

*1:もしかしたら僕以外いないのかもしれない…

*2:Mac

*3:Ubuntu?