Go言語にはCLIを作るときに便利なコマンドラインオプションパーサのflagパッケージがありますが、サブコマンドを使えない等の制約があったのでoptargならできるという噂を聞きつけ、使ってみました。
早速使ってみます。
main.go
package main
import (
"fmt"
"github.com/jteeuwen/go-pkg-optarg"
)
func main() {
//コマンドに必要なフラグを定義
optarg.Add("s", "source", "この引数は大事です", "")
//値を保持する変数
var src string
//引数をパースします
for opt := range optarg.Parse() {
switch opt.ShortName {
case "s":
src = opt.String()
}
}
fmt.Printf("sourceに指定された文字列は %s \n\n", src)
}
これを実行してみます。
$ go run main.go -s hoge
sourceに指定された文字列は hoge
$ go run main.go --source hoge
sourceに指定された文字列は hoge
$ go run main.go --sourc hoge
Unknown option '--sourc' specified.
Usage: go run main.go [options]:
--source, -s: この引数は大事です
このようにオプションフラグが認識され、存在しない場合はUsageが表示されます。
オプションフラグがついてない引数に関してはoptarg.Parse()
を実行した後にoptarg.Remainder
というsliceで取得することができます。
main.go
package main
import (
"fmt"
"github.com/jteeuwen/go-pkg-optarg"
)
func main() {
//コマンドに必要なフラグを定義
optarg.Header("サブコマンド cmdA")
optarg.Add("s", "source", "cmdAに使用するオプション", "")
optarg.Header("サブコマンド cmdB")
optarg.Add("P", "port", "cmdBに使用するオプション", 80)
//引数をパースします
ch := optarg.Parse()
<- ch
if len(optarg.Remainder) == 1 {
cmd := optarg.Remainder[0]
switch cmd {
case "cmdA":
cmdA()
case "cmdB":
cmdB()
}
} else {
optarg.Usage()
}
}
func cmdA() {
var src string
//引数をパースします
for opt := range optarg.Parse() {
switch opt.ShortName {
case "s":
src = opt.String()
}
}
fmt.Printf("cmdAのsourceに指定された文字列は %s \n\n", src)
}
func cmdB() {
var port int
//引数をパースします
for opt := range optarg.Parse() {
switch opt.ShortName {
case "P":
port = opt.Int()
}
}
fmt.Printf("cmdBのportに指定された文字列は %d \n\n", port)
}
これを実行すると
$ go run main.go cmdA --source hoge
cmdAのsourceに指定された文字列は hoge
$ go run main.go cmdB --port 90
cmdBのportに指定された文字列は 90
$ go run main.go
Usage: main.go [options]:
[サブコマンド cmdA]
--source, -s: cmdAに使用するオプション
[サブコマンド cmdB]
--port, -P: cmdBに使用するオプション (defaults to: 80)
このようにサブコマンド毎に挙動を分けることも簡単にできました。
またHelpも綺麗に表示することができて便利ですね。
また今回は試してないですが-abc
等と複数のオプションフラグを繋げることも可能なようです。
詳しくは公式のREADMEを読んでみてください。
なかなかよいパッケージな気がしますね!