Clojure CLIは依存解決を行ってくれるコマンドラインツールで、Clojure 1.9とともに公式からリリースされました。これまで広く使われてきたLeiningenやBootに近い立ち位置のツールです。coreやcontrib系のプロジェクトではすでにClojure CLIが使われるようになっており、third-partyのライブラリ等でも徐々に使われるようになってきています。
多くのthird-party製のClojureライブラリは、ClojarsというMaven Repositoryにデプロイされています。Leiningenでは lein deploy clojars
とするだけで簡単にデプロイできましたが、Clojure CLI自体にはそのような機能はありません。
自分が作っているClojureライブラリのプロジェクトをClojure CLIに移行したいと思い、Clojure CLIでClojarsへデプロイする方法について調べてみました。
Clojure CLI + Leiningen
一つ目は、Leiningenを併用する方法です。開発にはClojure CLIを用い、デプロイにだけLeiningenを使います。
example/
├── deps.edn
├── project.clj
└── src/
└── example/
└── core.clj
deps.edn
に加えて project.clj
を用意し、バージョンや説明などは project.clj
に書きます。
(defproject example "0.1.0-SNAPSHOT"
:description "FIXME"
:url "https://github.com/example/example"
:license {:name "The MIT License"
:url "https://opensource.org/licenses/MIT"}
:dependencies [[org.clojure/clojure "1.9.0"]])
Clojarsへデプロイします。
$ lein deploy clojars
簡単ですね。これまで主にLeiningenを使ってきた人なら、多分これが一番楽だと思います。
欠点は、
- Leiningenもインストールしておく必要がある
- 依存ライブラリを
deps.edn
,project.clj
の2箇所に書く必要がある
といったところでしょうか。
Clojure CLI + Boot
これまでBootを使ってきたなら、 build.boot
を加えましょう。
example/
├── build.boot
├── deps.edn
└── src/
└── example/
└── core.clj
デプロイ用の情報を build.boot
に書きます。
(set-env!
:dependencies '[[org.clojure/clojure "1.9.0"]]
:repositories [["clojars" {:url "https://clojars.org/repo/"
:username (System/getenv "CLOJARS_USER")
:password (System/getenv "CLOJARS_PASS")}]])
(task-options!
pom {:project 'example
:version "0.1.0-SNAPSHOT"
:description "Deploy to Clojars with Clojure CLI + Boot"
:url "https://example.com"
:scm {:url "https://github.com/example/example"}
:license {"The MIT License" "https://opensource.org/licenses/MIT"}})
(task-options! push {:repo "clojars"})
Clojarsへデプロイします。
$ CLOJARS_USERNAME=<username> CLOJARS_PASSWORD=<password> boot pom jar push
Bootに置き換えただけなので欠点は同じく、
- Bootもインストールしておく必要がある
- 依存ライブラリを
deps.edn
,built.boot
の2箇所に書く必要がある
となります。
Clojure CLI + Maven
ClojarsはMavenリポジトリなので、Mavenを併用する方法もあります。ClojureのcontribライブラリなどはMavenを使っているようです。
pom.xml
を追加します。
example/
├── deps.edn
├── pom.xml
└── src/
└── example/
└── core.clj
clojure-maven-pluginを使って、MavenからClojureコードをビルドできるようにします。
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>example</groupId>
<artifactId>example</artifactId>
<version>0.1.0-SNAPSHOT</version>
<name>example</name>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.clojure</groupId>
<artifactId>clojure</artifactId>
<version>1.9.0</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>clojars</id>
<url>https://repo.clojars.org/</url>
</repository>
</repositories>
<distributionManagement>
<repository>
<id>clojars</id>
<name>Clojars repository</name>
<url>https://clojars.org/repo</url>
</repository>
</distributionManagement>
<build>
<plugins>
<plugin>
<groupId>com.theoryinpractise</groupId>
<artifactId>clojure-maven-plugin</artifactId>
<version>1.8.1</version>
<extensions>true</extensions>
<configuration>
<sourceDirectories>
<sourceDirectory>src</sourceDirectory>
</sourceDirectories>
<temporaryOutputDirectory>true</temporaryOutputDirectory>
</configuration>
<executions>
<execution>
<id>clojure-compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Clojarsへデプロイします。
$ mvn deploy
deps.edn
のdependencyを更新した場合は、 Clojure CLIから pom.xml
を更新することができます。
$ clj -Spom
dependency以外の設定は保持されるため、何度も手動で編集する必要はありません。
欠点は、
- Mavenもインストールしておく必要がある
- 依存ライブラリを変更したら
clj -Spom
を再実行する必要がある
でしょうか。
pack.alpha + Maven
さて、ここまではbuild, pushともにLeiningen等の別ツールが行っており、2つのツールがほとんど独立して使われていました。次は、buildはClojure CLIから行い、pushだけをMavenに任せます。
Clojure CLIのパッケージングツールpack.alphaとMavenを使う方法です。
pack.alphaを使えば、Clojure CLIからjarファイルを作成することができます。(他にもいろいろ作れます)
example/
├── deps.edn
└── src/
└── example/
└── core.clj
deps.edn
に以下のようにaliasを定義しておきます。
{:aliases {:jar {:extra-deps {pack/pack.alpha
{:git/url "https://github.com/juxt/pack.alpha.git"
:sha "a5d64ce2fe48f87445f35a2743a94ca9a2e3ca94"}}
:main-opts ["-m" "mach.pack.alpha.skinny" "--no-libs"
"--project-path" "example.jar"]}}}
$ clj -Ajar
によって、 example.jar
というjarファイルが作成されます。
$ clj -Spom
として、 deps.edn
をもとに pom.xml
を自動生成します。
pom.xml
を手動で編集し、バージョンや説明、URLなどを書き加えます。 deps.edn
で依存ライブラリを変更したときは、再度 clj -Spom
を実行します。2回目以降は依存ライブラリの更新だけが反映されるため、何度も手動で編集する必要はありません。
そして、Mavenを使ってClojarsにデプロイします。
$ mvn deploy:deploy-file -Dfile=example.jar -DrepositoryId=clojars -Durl=https://clojars.org/repo -DpomFile=pom.xml
欠点は、
- Mavenもインストールしておく必要がある
- 依存ライブラリを変更したら
clj -Spom
を再実行する必要がある
でしょうか。
pack.alpha + deps-deploy
最後に、Clojure CLIのみでbuildからpushまで完結させる方法です。
pack.alphaに加えて、deps-deployを使います。
example/
├── deps.edn
└── src/
└── example/
└── core.clj
deps.edn
は以下のようにしておきます。
{:aliases {:jar {:extra-deps {pack/pack.alpha
{:git/url "https://github.com/juxt/pack.alpha.git"
:sha "a5d64ce2fe48f87445f35a2743a94ca9a2e3ca94"}}
:main-opts ["-m" "mach.pack.alpha.skinny" "--no-libs"
"--project-path" "example.jar"]}
:deploy {:extra-deps {deps-deploy {:mvn/version "RELEASE"}}
:main-opts ["-m" "deps-deploy.deps-deploy" "deploy"
"example.jar"]}}}
jarファイルと pom.xml
を作ります。初回は pom.xml
の編集も忘れずに行いましょう。
$ clj -Ajar
$ clj -Spom
そして、deps-deployを使ってClojarsへデプロイします。
$ CLOJARS_USERNAME=<username> CLOJARS_PASSWORD=<password> clj -Adeploy
Clojure CLI以外のツールをインストールしておく必要がない点が良いですね。
欠点は、
- 依存ライブラリを変更したら
clj -Spom
を再実行する必要がある - deps-deployがあまりこなれていない気がする(GPG signingなどできない)
でしょうか。
おわりに
Clojure CLIをメインに開発を進める場合に、Clojarsへデプロイする方法をいくつか紹介しました。
いずれの方法においても、dependency変更時には複数ファイルの編集や pom.xml
の再生成が必要となり、LeiningenやBootだけのプロジェクトと比べて少しステップが増えてしまう、というのが現状のようです。個々のタスクごとに小さいツールが存在するのはClojureらしいともいえますが、ライブラリのリリース時などにミスが発生しそうではあります。
デファクトスタンダードはまだなさそうなので、自分の好きな方法でデプロイすれば良いかと思います。これを機に、私も自分が作っているライブラリなどをClojure CLIに移行していきたいと考えています。