この記事はITC Advent Calendar(1) 24日目の記事です
その一
https://adventar.org/calendars/2563
その二
https://adventar.org/calendars/2640
初めまして、がっちゃんです
本年度のITC( https://itc.moe )の部長やってます
今回は思いつきで始めたGolang で CLI ツールを作る。
で使った、 urfave/cli というパッケージについてちょこっと解説記事を書くことにしました。
なぜ使おうと思ったか
Golang初心者だったので、検索して一発目に出てきたパッケージを使うことにした
どんなパッケージ?
概要
簡単にcliツールを作ることができる、cliのフレームワークと言ってもいいほど高機能なパッケージ
いいところ
一言で言うと、cliツールに必要な要件がめっちゃ整理されてて使いやすい
- helpは自動で生成される&必要なところだけ構造体に代入するだけでよしなに成形して表示してくれる
- コマンド(
git commitのcommit部分など)、サブコマンド(git stash popのpop部分など)を簡単に構造体で定義でき、名前と関数を登録するだけでできる - オプションは
Flagとして定義でき、エイリアス(--versionを-vでいけるようにするやつ)もまとめて定義できる-
FlagはStringFlagとBoolFlagを利用することができ、初期値の設定ができたり簡単にデータ取得ができたりする。
-
- コードが読みやすい(当社比)
使い方の解説
インストール
$ go get github.com/urfave/cli
でパッケージをインストールしておく
基準となるポイントを作る
package main
import (
"os"
"github.com/urfave/cli"
)
func main() {
app := cli.NewApp()
app.Run(os.Args)
}
appの中に基本的な情報が入っており、これを編集・実行する形となる
名前と使い方とバージョンを登録して、実行してみる
入力された引数の文字列を表示するサンプルアプリをつくる
package main
import (
"os"
"github.com/urfave/cli"
)
func main() {
app := cli.NewApp()
app.Name = "sampleApp"
app.Usage = "This app echo input arguments"
app.Version = "0.0.1"
app.Run(os.Args) // 忘れない!(よくやらかす)
}
保存して実行!
$ go run main.go
NAME:
sampleApp - This app echo input arguments
USAGE:
main [global options] command [command options] [arguments...]
VERSION:
0.0.1
COMMANDS:
help, h Shows a list of commands or help for one command
GLOBAL OPTIONS:
--help, -h show help
--version, -v print the version
Actionと呼ばれる処理を登録してない場合、自動で作成されたコマンドのヘルプが表示される。
処理を登録する
Goの関数を登録することで処理を追加することができる
package main
import (
"os"
"fmt"
"github.com/urfave/cli"
)
func main() {
app := cli.NewApp()
app.Name = "sampleApp"
app.Usage = "This app echo input arguments"
app.Version = "0.0.1"
app.Action = func (context *cli.Context) error {
fmt.Println(context.Args().Get(0))
return nil
}
app.Run(os.Args)
}
コマンドの引数を受け取って、fmt#Printlnで表示するだけの処理を追加。
Actionの引数
func (context *cli.Context) error {}
としているが、contextが何者なのかを軽く説明
contextの中にはアプリについての情報やコマンド引数の値などが格納されている構造体である。
中でも**Context#Args()とContext#String(), Context#Bool()**はよく使う。
Context#Args()
コマンド引数のリストを取得するメソッド。
返り値はArgsで、実態はstringのSliceである。
ここからデータを取得するときは、Args#Get()を利用する。
Context#String(), Context#Bool()
コマンドに指定したオプションの値を取得するメソッド。
返り値はそれぞれ、 stringとboolの値が返る
上記のコードではオプションを付けていなかったので、オプションの作り方を以下で紹介しておく
package main
import (
"os"
"fmt"
"github.com/urfave/cli"
)
func main() {
app := cli.NewApp()
app.Name = "sampleApp"
app.Usage = "This app echo input arguments"
app.Version = "0.0.1"
app.Action = func (context *cli.Context) error {
if context.Bool("cat") {
fmt.Println(context.Args().Get(0) + "だにゃん♡")
} else {
fmt.Println(context.Args().Get(0))
}
return nil
}
app.Flags = []cli.Flag{
cli.BoolFlag {
Name: "cat, c",
Usage: "Echo with cat",
},
}
app.Run(os.Args)
}
オプションの定義は app#Flagsに[]cli.Flagを登録することで定義でき、
呼び出す際はcontext#{String|Bool}にオプションの名前を指定することで値を取得できる。
定義時のcli.BoolFlag, StringFlagの構造体にはデフォルトの値の指定やヘルプに表示するか否かが指定できたりして、かなり柔軟に指定できる印象。
保存して実行!
$ go run main.go "Hello world"
Hello world
$ go run main.go -c "Hello world"
Hello worldだにゃん♡
無事に引数の文字列をechoできるcliアプリができている。
あとはbuild、installすればどこでも使える自分用cliツールの完成!👍
ビルド
$ go build
# => main.go(mainパッケージ)があるディレクトリの名前のバイナリファイルが用意される。
インストール
$GOPATHを通しておけば、go installコマンドで$GOPATH/binディレクトリ下にバイナリファイルがインストールされて通常のコマンドのように叩くことができるようになる!
まとめ
以上、Golangで簡単にcliツールを作ることができるパッケージについての紹介でした。
Golang使いやすいし、なにかコマンドラインツール作って見るときはGolang + urfave/cli で作ってみることをおすすめします!