はじめに
社内でちょっとしたCLIツールを作るという話になった為、私の推し言語Nimで作ることに。
NimのCLIツールを簡単に作れるフレームワークcligenを使用します。
いろんな方が既に使いかたについての記事を書いていますが、サブコマンドがあるCLIの詳しい作成方法を書いた記事が少ないのと、自分の躓いた部分の備忘録としてcligenの使い方を残しておきます。
リポジトリ
インストール
nimbleを使用してインストール。
nimble install cligen
とりあえず使ってみる
コマンドにしたい関数を定義する
今回はマルチコマンドのCLIツールを作成するため2つ定義します。
proc hoge(opt1: string, opt2: string = "English"): int =
## これはhogeの説明です。
echo "Hello"
return 0
proc fuga(): int =
## これはfugaの説明です。
echo "Goodbye"
return 0
関数の引数がそのままオプションになります。
また、デフォルト値を設定することによってそのオプションを任意にすることができます。
デフォルト値を設定しない引数は必須になります。
戻り値は終了コードとして使用します。
コマンドとして実装
import cligen
when isMainModule:
dispatchMulti(["multi"],
[hoge1, help = {"opt1":"オプション1の説明",
"opt2":"オプション2の説明"}],
[hoge2]
)
["multi"]
とすることでメインコマンドのヘルプを提供することができます。
$ ./hoge_fuga_commands
これはhogeの説明です。
Usage:
hoge_fuga_commands {SUBCMD} [sub-command options & parameters]
where {SUBCMD} is one of:
help print comprehensive or per-cmd help
hoge これはhogeの説明です。
fuga これはfugaの説明です。
hoge_fuga_commands {-h|--help} or with no args at all prints this message.
hoge_fuga_commands --help-syntax gives general cligen syntax help.
Run "hoge_fuga_commands {help SUBCMD|SUBCMD --help}" to see help for just SUBCMD.
Run "hoge_fuga_commands help" to get *comprehensive* help.
それっぽくなってはいますが、ヘルプが色々とおかしいと思います。
基本的に何も指定がない場合、cligenはライブラリの中のcligen/usage.nim
をそのまま使用するため、プロジェクトディレクトリでusage.nim
を定義してやる必要があります。
usage.nim
を定義
const clUseHdr* = "Usage:\n "
const clUse* = "$command $args\n${doc}Options:\n$options"
const clUseMultiGeneral* = """
$command {-h|--help} または引数なしでこのメッセージを表示します。
$command --help-syntax は一般的な cligen の構文ヘルプを提供します。
"$command {help サブコマンド|サブコマンド --help}" を実行して、サブコマンドのヘルプのみを表示します。
"$command help" を実行すると、包括的なヘルプを表示することができます。"""
const clUseMulti* = """${doc}Usage:
$command {SUBCMD} [sub-command options & parameters]
where {SUBCMD} is one of:
$subcmds
""" & clUseMultiGeneral
const clUseMultiPerlish* = """hoge_fuga_commands
${doc}使用方法
$command {サブコマンド} [サブコマンドのオプションとパラメーター]
サブコマンド
$subcmds
----------------------------------------------------------------
""" & clUseMultiGeneral
ライブラリの中のusage.nim
の内容をそのまま日本語訳して、少し見やすく整えました。
コマンドの実装部分の修正
内容を修正したusage.nim
をhoge_commands.nim
からinclude
を使って呼び出します。
import cligen
include usage
when isMainModule:
dispatchMulti(["multi", doc ="hoge_fuga_commands", usage = clUseMultiPerlish],
[hoge, help = {"opt1":"オプション1の説明",
"opt2":"オプション2の説明"}],
[fuga]
)
doc
で説明欄の使用方法の部分のツール名を指定できます。
usagusage = clUseMultiPerlish
でusage.nimで設定した説明を表示できます。
$ ./hoge_fuga_commands
hoge_fuga_commands
hoge_fuga_commands使用方法
hoge_fuga_commands {サブコマンド} [サブコマンドのオプションとパラメーター]
サブコマンド
help print comprehensive or per-cmd help
hoge これはhogeの説明です。
fuga これはfugaの説明です。
----------------------------------------------------------------
hoge_fuga_commands {-h|--help} または引数なしでこのメッセージを表示します。
hoge_fuga_commands --help-syntax は一般的な cligen の構文ヘルプを提供します。
"hoge_fuga_commands {help サブコマンド|サブコマンド --help}" を実行して、サブコマンドのヘルプのみを表示します。
"hoge_fuga_commands help" を実行すると、包括的なヘルプを表示することができます。
設定したマルチコマンドのヘルプメッセージを表示することができました。
実際にサブコマンドを動かしてみる
$ ./hoge_fuga_commands hoge -o:test
Hello
$ ./hoge_fuga_commands fuga
Goodbye
まとめ
日本語のドキュメントが少ないため、躓く部分が多かったです。
Nimのわかりやすい構文で、関数をそのままコマンドにできるためちょっとした社内ツール開発には使えるなと思いました。
Nimはまだまだコミュニティが小さく発展途上ですが、とても魅力的な言語だと思うのでちょっとしたプロジェクトなどで触っていきたいなと思います。
参考
NimのCLIツール作成用ライブラリcligenがとても便利
PR
ニッチな言語での開発もGOを出してくれるナイスな会社です。
そんなナイスな会社で一緒に働いてくれる方を募集しています。
詳しくは下記URLをご覧ください。