Elixirでコマンドラインツールを作る
How to create a command line utility with Elixir and mixというサイトを参考にしてElixirでコマンドラインツールを作ってみる.
自分で書いた日記
をまとめて再構成している.
宣伝
Sapporo.beamという集まりがある.
毎週木曜日にErlangVMの話題について札幌やインターネットでわいわいするところ.
この記事に興味がある人なら楽しめると思う.きてね.
実行できるようにする
プロジェクトを作成する
/Users/niku/projects% elixir -v
Elixir 0.14.3
/Users/niku/projects% mix new timer
ビルド
何もない状態でビルドしてみる.以前はmix escriptize
というコマンド前だったのだけど,v0.14.3になる前に変更されたようだ.
/Users/niku/projects% cd timer
/Users/niku/projects/timer% mix escript.build
Compiled lib/timer.ex
Generated timer.app
** (Mix) Could not generate escript, please set :main_module in your project configuration (under `:escript` option) to a module that implements main/1
うむ.escript
の中にmain_module
を指定してねと書いてある.
これも以前は escript_main_module
という名前だったのだけど,v0.14.3になる前に変更されたようだ.
そこでmix.exs
に足してやる.
# in mix.exs
def project do
[app: :timer,
version: "0.0.1",
elixir: "~> 0.14.3",
escript: [ main_module: Timer ], # add here
deps: deps]
end
もういちどビルドしてみる.
/Users/niku/projects/timer% mix escript.build
Compiled lib/timer.ex
Generated timer.app
Generated escript timer
通った.
実行
ビルドによりtimer
というファイルができているので実行してみる.
/Users/niku/projects/timer% ./timer
** (UndefinedFunctionError) undefined function: Timer.main/1
(timer) Timer.main([])
(elixir) lib/kernel/cli.ex:70: anonymous fn/3 in Kernel.CLI.exec_fun/2
Timer.main(引数1)
が定義されていないとのこと.はい.定義します.
lib/timer.ex
に足す.
# in lib/timer.ex
defmodule Timer do
def main(args) do
IO.puts("Hello world!")
end
end
再コンパイル,再実行してみる.
/Users/niku/projects/timer% mix escript.build
Compiled lib/timer.ex
Generated timer.app
Generated escript timer
/Users/niku/projects/timer% ./timer
Hello world!
おっ,よしよし.Hello worldが表示された.
利用
v1.3からはURL経由でのescript.install
ができるようになった.
mix escript.install https://example.com/myescript
2016-07-01現在は未リリースだが,v1.4からはGit,Github,パッケージマネージャーのhex.pm経由でのインストールができるようになった.
mix escript.install git https://path/to/git/repo
mix escript.install github github user/project
mix escript.install hex hex_package
これで公開されているコマンドラインツールを簡単に利用できるようになる.
以下では github/niku
の escript_sandbox
に n
というコマンドを定義したコードを置き それを利用した例だ.
(n は Hello~
という内容を標準出力するプログラムにしている)
/Users/niku/src/elixir-head% bin/mix --version
Erlang/OTP 18 [erts-7.3] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe]
[kernel-poll:false] [dtrace]
Mix 1.4.0-dev (b10c4c1)
/Users/niku/src/elixir-head% bin/mix escript.install github niku/escript_
sandbox
* Getting new package (https://github.com/niku/escript_sandbox.git)
Cloning into '/private/var/folders/3x/_15gn8l57x57gr8g6cbtz6lr0000gn/T/mix-local-installer-fetcher-jzVCoQ/deps/new package'...
remote: Counting objects: 30, done.
remote: Compressing objects: 100% (19/19), done.
remote: Total 30 (delta 7), reused 25 (delta 5), pack-reused 0
Checking connectivity... done.
Compiling 1 file (.ex)
Generated n app
Generated escript n with MIX_ENV=prod
Are you sure you want to install escript "n"? [Yn]
* creating /Users/niku/.mix/escripts/n
/Users/niku/src/elixir-head% echo $PATH
/Users/niku/.mix/escripts:(...snip...)
/Users/niku/src/elixir-head% n
Hello~
このくらい手軽になるとコマンドラインツールとしても使いやすい.