🧰

Clojure CLI 向けツールの作り方

2021/12/18に公開

この記事は Clojure Advent Calendar 2021 13日目の穴埋めに向けたものです。

大変長らくお待たせしました!

全Clojurian待望の(?) clj-xmas を Clojure CLI のツールに対応させました!
これでクリスマスツリーをいつでも簡単に植え放題ですよ!!

https://github.com/liquidz/clj-xmas

# インストールして
clojure -Ttools install com.github.liquidz/clj-xmas '{:git/tag "1.0.0"}' :as merry
# 植えるだけ
clojure -Tmerry xmas


Whoo-hoo-hoo!

今回の記事で言いたかったことの9割は言えました。ありがとうございました。

余談

余談ではありますが、折角の機会なので CLI ツールの作り方を簡単に紹介だけしておこうと思います。
とは言え以下にほぼすべてまとまっているので、ほぼほぼ繰り返しになっていることはご承知おきください。

https://clojure.org/reference/deps_and_cli#tool_install

Clojure CLI ツールとは?

CLI ツールは v1.10.3.933 で追加されたGitベースのプログラムを任意の名前でインストールすることが機能です。

8日目の athos さんの記事でも触れられているので見覚えのある方も多いかと思います。
https://zenn.dev/athos/articles/f43a0bd988baaf

デフォルトではツールをインストールしたり、一覧表示したりするためのツールである clojure/tools.toolstools という名前でインストールされています。
試しに以下のコマンドを実行してみると、例えば以下のようにインストール済みのツール一覧が表示されます。

$ clojure -Ttools list
TOOL           LIB                                   TYPE    VERSION
antq           com.github.liquidz/antq               :local
error-checker  com.github.liquidz/clj-error-checker  :local
tools          io.github.clojure/tools.tools         :git    v0.2.2

最小のCLIツール

では簡単なツールを作ってみましょう。
まずは以下2つのファイルを用意してください。

  • deps.edn
    {:tools/usage {:ns-default hello}}
    
  • hello.clj
    (ns hello)
    
    (defn world
      [_]
      (println "hello clojure cli tool world"))
    

ツールの実体はこれだけです!
インストールするツールは deps.edn で参照できるものであれば良いので :local/root でローカルパスも指定できます。
今回は用意した deps.edn のあるディレクトリで以下のコマンドを実行してみてください。

$ clojure -Ttools install hello/world "{:local/root \"$(pwd)\"}" :as hello
Installed hello

これでCLIツールはインストールできたので、任意のディレクトリで以下を実行してみてください。

$ clojure -Thello world
hello clojure cli tool world

動きましたね!
要は deps.edn で指定した :tools/usage 配下の :ns-default に ns 名を定義してあげれば、
その ns に定義されている関数を -T オプションを介して実行できるだけです。

ちなみに余談の余談ですが、インストールされたツールの情報は $HOME/.clojure/tools 配下に 指定した名前.edn として格納されます。
ちらっと先程インストールしたツールを見てみると、例えば以下のようになっているはずです。

$ cat ~/.clojure/tools/hello.edn
{:lib hello/world, :coord {:local/root "/private/tmp/foo"}}

なお不要になったツールは以下のコマンドで削除できます。

$ clojure -Ttools remove :tool hello
Tool removed

あとはツールとして提供したい機能をご自由に実装するだけです。
なお今回の例では :local/root を使ってインストールしていますが、実際に公開する場合は liquidz/antqliquidz/clj-xmas の例のように Git のタグを切っておいて、それを参照するのが良いと思います。

# antq の例
clojure -Ttools install com.github.liquidz/antq '{:git/tag "1.3.0"}' :as antq
# clj-xmas の例
clojure -Ttools install com.github.liquidz/clj-xmas '{:git/tag "1.0.0"}' :as merry

最後に

Clojure CLI ツールはとても簡単な仕組みなので、既存の便利コードなども簡単にツール化できるかと思います。
こんな便利(?)ツールあるよ!作ったよ!というがあれば是非教えてください!

また、まだ Leiningen を使っていて Clojure CLI には手を出していなければ、ツール(植樹🎄)を機会として触ってみるのも面白いかと思います。

以上、余談まででした。

Discussion