Gleam言語でCLIコマンドを作る(gleescript)

に公開

はじめに

gleescript というライブラリを使うことで、Gleam言語で書かれたプログラムを手軽に catls などのコマンドと同じように使うことができるようになります。
https://hexdocs.pm/gleescript/1.4.0/index.html

このライブラリで生成されるファイルはescriptというErlangのプログラムを単一ファイルで実行する仕組みです。
https://www.erlang.org/docs/22/man/escript

この仕組みはElixir言語でも利用されています。
https://hexdocs.pm/mix/1.18.3/Mix.Tasks.Escript.Build.html

gleescript ライブラリを追加し、モジュールを実行するだけで簡単にescriptに変換できます。

ライブラリのREADMEから引用
gleam add gleescript
gleam run -m gleescript
#  Compiling your_project
#   Compiled in 0.26s
#    Running gleescript.main
#  Generated ./your_project
 
./your_project
# Hello from your_project!

デモ

デモが必要なほど難しいものではないですが、Gleamのプログラムに gleescript を適用してみました。

Gleamで pwd コマンドを実装した gleepwd というプログラムを用意しました。
(ライブラリの関数を呼ぶだけのシンプルなものです)
https://github.com/yellowsman/gleepwd

  1. プログラムの動きを確認
gleam run
   Compiled in 0.08s
    Running gleepwd.main
/Users/John.Doe/Project/sandbox/gleam/gleepwd

pwd
/Users/John.Doe/Project/sandbox/gleam/gleepwd
  1. gleescript ライブラリを追加
gleam add gleescript
  Resolving versions
Downloading packages
 Downloaded 5 packages in 0.07s
      Added gleescript v1.4.0
  1. 実行ファイルを生成
gleam run -m gleescript
  Compiling argv
  Compiling gleam_erlang
  Compiling snag
  Compiling tom
  Compiling gleescript
warning: Deprecated value used
   ┌─ /Users/John.Doe/Project/sandbox/gleam/gleepwd/build/packages/gleescript/src/gleescript.gleam:77:35
   │
77 │   let assert Ok(result) = dynamic.result(Ok, Ok)(result)
   │                                   ^^^^^^ This value has been deprecated

It was deprecated with this message: Please use the gleam/dynamic/decode
module
   Compiled in 0.18s
    Running gleescript.main
  Generated ./gleepwd
  1. 生成されたescriptを確認
eza --no-user -l gleepwd
.rwxrwxrwx@ 450k  6 Apr 16:14 gleepwd
  1. 生成されたescriptを実行する
./gleepwd
/Users/John.Doe/Project/sandbox/gleam/gleepwd

ライブラリを追加してモジュールを追加するだけでescriptを生成してgleamコマンドを指定しなくてもプログラムを実行できるようになりました。

出力先を指定する

gleescript は生成されるファイルの出力先を指定することができます。

ライブラリのREADMEから引用
gleam run -m gleescript -- --out=./some/directory
#  Compiling your_project
#   Compiled in 0.26s
#    Running gleescript.main
#  Generated ./some/directory/your_project

./some/directory/your_project
# Hello from your_project!

こちらの方法を使ってプログラムどこからでも呼べるようにします。

  1. プログラムの置き場を作る
# 今回は ~/.local/share/myprogram/gleam を作成
mkdir -p ~/.local/share/myprogram/gleam
  1. PATHを指定

さきほど作ったディレクトリにパスを通しておきます。
環境によってやり方が異なるので省略。

  1. escriptを生成する
gleam run -m gleescript -- --out=(string join / $HOME .local/share/myprogram/gleam) # fish shellでの例
   Compiled in 0.07s
    Running gleescript.main
  Generated /Users/John.Doe/.local/share/myprogram/gleam/gleepwd
  1. 生成されたファイルを確認する
eza --no-user -l (string join / $HOME .local/share/myprogram/gleam)
.rwxrwxrwx@ 450k  6 Apr 15:34 gleepwd
  1. ホームディレクトリで実行する
cd ~ && gleepwd
/Users/John.Doe # 実行結果がホームディレクトリのパスに変更されている

注意したいのは、--out オプションでは ~ によるホームディレクトリ指定が効かないことです。
プログラムは成功したような出力になるのですが、実際はファイルが作成されていませんでした。
相対パスは有効でしたので、../../target_directory のような書き方は有効です。

成功したように見えるが実際はファイルが作成されていない
gleam run -m gleescript -- --out="missing directory path"
   Compiled in 0.05s
    Running gleescript.main
  Generated missing directory path/gleepwd

Discussion