Leiningenの3分間コネタTipsを書きます。
以下の例はLeiningen 2.4.2で確認しました。執筆時点でheroku-buildpack-clojureがLeiningen 2系で指定しているバージョンと同じはずです。
やりたいこと
たとえばWebアプリでは、実行前に静的ファイルを生成したいことがあります。LESSからCSSを生成したり、CSSやJavaScriptを縮小(minify)したりする場合などです。一般的なタスクについては、Leiningenのプラグインなどが揃ってきています。
しかし、処理がプロジェクト特有で適切なプラグインがない場合には、プロジェクト内に専用のタスクを作ることになります。
私の場合は、プロジェクト内で定義された文字列のリストから、そのいずれかにマッチする正規表現を生成してJavaScriptファイルに埋め込む処理を、タスク化することにしました。先頭からトライ木状にマッチする効率のよい正規表現の生成には、Maven Centralに登録されているregexp-trieというJavaライブラリを選びました。
以上のやりたいことを、箇条書きでまとめます。
- プロジェクト専用のタスクを作る
- タスクからMaven CentralのJavaライブラリを使う
タスクを作る
プロジェクト専用のタスクを作る方法は、Leiningenオフィシャルのプラグイン作成ドキュメント「Leiningen Plugins」に「Project-specific Tasks」として書かれています。
まずはこれにのっとって、Hello World代わりに「yo」というタスクを作ってみます。
プロジェクトのルートディレクトリにいるものとします。まず、tasks/leiningenディレクトリを作ります。
$ mkdir -p tasks/leiningen
yoというタスクなら、tasks/leiningenのyo.cljにleiningen.yoという名前空間でyo関数を書きます。
(ns leiningen.yo)
(defn yo [project] ; projectにはproject.cljでの定義が渡ってくる
(println "Yo") ) ; とりあえず文字列を表示するだけ
プロジェクトのルートディレクトリの.lein-classpathに、tasksディレクトリを追加します。.lein-classpathファイルがないのであれば、「tasks」とだけ書いておきます。
$ echo tasks > .lein-classpath
もし.lein-classpathがすでにあるのであれば、クラスパス形式で追記します。
これだけでタスクが作られました。実行してみます。
$ lein yo
Yo
簡単ですね。
ちなみに、leiningenのデフォルトテンプレートで作られる.gitignoreには、初期状態で/.lein-*
という行が含まれます。gitを使う人はご注意を。
Maven Centralのライブラリを使う
さて、project.cljの:depenciesにすでに[me.geso/regexp-trie "0.1.10"]
を登録してプロジェクト本体で使っているものとします。このregexp-trieをfooというタスクのtasks/leiningen/foo.cljからimportしてみます。
(ns leiningen.foo
(:import [me.geso.regexp_trie RegexpTrie]) )
;; 以下略
しかし、実行したらClassNotFoundExceptionになってしまいました。
$ lein foo
clojure.lang.Compiler$CompilerException: java.lang.ClassNotFoundException: me.geso.regexp_trie.RegexpTrie, compiling:(leiningen/foo.clj:1:1)
(以下略)
Maven Centralのライブラリは参照できないようです。
そこで、Leiningenが使っているpomegranateのadd-dependenciesを呼んでregexp-trieをクラスパスに追加してから、importしてみます。
(ns leiningen.foo
(:use [cemerick.pomegranate :only [add-dependencies]]) ) ; まずpomegranateをuse
(add-dependencies ; ライブラリを追加
:coordinates '[[me.geso/regexp-trie "0.1.10"]] ; project.cljと似た感じで
:repositories cemerick.pomegranate.aether/maven-central ) ; maven-centralはpomegranate内で定義されている
(import [me.geso.regexp_trie RegexpTrie]) ; ここでregexp_trieをimport
;; 以下略
実行してみます。
$ lein foo
エラーなく実行できました。よかった。
別解
Leiningenプラグインのlein-execを使えば、lein exec hoge.clj
のようにClojureのスクリプトを実行できます。ただし、今回はタスクとしてまとめたかったので、lein-execは採用しませんでした。
なお、上で書いたpomegranateでMaven Centralライブラリを呼べるようにする方法は、lein-execを参考にしました。