あらすじ及び結論
-h
とか--list
とか、そういうやつが欲しかった。ふつのコマンドでよく使うし標準で専用のメソッドなりがあるのかと思ったがそんなことはない?見つけたのは以下のやつ。ちょっと古い||もっといい方法があるのかもしれませんが
github.com
rootCmd.BoolVarP(&verbose, "verbose", "v", false, "verbose output")
このようにBoolVarP
して成否判定やってみてけろ、ということらしい。たとえば今回は「viper
で設定ファイルにある宛先メールアドレスをリストでほしい」という自作コマンドの要望上で欲しかった機能で、サブコマンドconfig
を使って次のようにして表示したかったのです。ショートフラグ非対応なのは趣味です
<メインのコマンド> config --sendto
こうなった
サブコマンドのgoファイル。cobra add <サブコマンド名>
で生成されたやつ
package cmd
import (
"fmt"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
var sendtoFlag bool
var configCmd = &cobra.Command{
Use: "config",
Short: "設定ファイルでよく参照しそうな中身を表示",
Long: `設定ファイルでよく参照しそうなものを表示します。
--sendto 送信先のメールアドレスいちらん
`,
Run: func(cmd *cobra.Command, args []string) {
mails, _ := cmd.Flags().GetBool("sendto")
if mails && len(cmd.Flags().Args()) == 0 {
for _, address := range viper.GetStringSlice("sendto") {
fmt.Println(address)
}
} else {
fmt.Printf("不正な引数もしくはオプションがあります。\n Args: %v\n", cmd.Flags().Args())
}
},
}
func init() {
rootCmd.AddCommand(configCmd)
configCmd.Flags().BoolVarP(&sendtoFlag, "sendto", "", false, "送信先のメールアドレス")
}
yamlはこんなのとする。同じ階層にあるのと名前は以下のroot.go
参照。要らん設定たくさんあるけど省くのもめんどくさかったので載せる。記事内のsnippetでは当然sendto
しか使ってないです
applicationName: "ニャー"
debug: false
user:
name: "this is fuckin awesome name"
age: 34882349
sendto: [aaa@mail.domain, bbb@mail2.gandum, ccc@koikeya.umai]
root.go
載せる意味あんまなさそうだけどメモとして一部必要そうなところを置いておく。viper
すらも初めて触ったんですがそもそもgoの文法とかよくわかってないので使いやすいのかどうか判断がつきましぇん
.
.
.
type Config struct {
User User `yaml:user`
ApplicationName string `yaml:applicationName`
Debug bool `yaml:debug`
SendTo []string `yaml:sendto`
}
type User struct {
Name string `yaml:"name"`
Age int `yaml:"age"`
}
var config Config
var cfgFile string
.
.
.
func init() {
cobra.OnInitialize(initConfig)
}
func initConfig() {
if cfgFile != "" {
viper.SetConfigFile(cfgFile)
} else {
viper.AddConfigPath(".")
viper.SetConfigName("cfg")
viper.SetConfigType("yaml")
}
if err := viper.ReadInConfig(); err != nil {
fmt.Println("Can't read config:", err)
os.Exit(1)
}
if err := viper.Unmarshal(&config); err != nil {
fmt.Println("config file Unmarshal error")
fmt.Println(err)
os.Exit(1)
}
}
試してみるよ
$ go run main.go config --sendto
aaa@mail.domain
bbb@mail2.gandum
ccc@koikeya.umai
$ go run main.go config --sendto 193838795237984
不正な引数もしくはオプションがあります。
Args: [193838795237984]
$ go run main.go config sendto
不正な引数もしくはオプションがあります。
Args: [sendto]
$ go run main.go config --send2 nya-
Error: unknown flag: --send2
Usage:
cobra_practice config [flags]
Flags:
-h, --help help for config
--sendto 送信先のメールアドレス
exit status 1
ちゃんと--sendto
とロングオプションのみつけたときだけ取れてますねぇ。CLIツールとかCLI用ライブラリとかのお作法って知らないんですがどのライブラリもこんな感じなのかな。