特定のフラグが必須であることを設定する方法はありますか、それとも自分でフラグの存在を確認する必要がありますか?
flag
パッケージは、必須フラグまたは必須フラグをサポートしていません(フラグは明示的に指定する必要があります)。
できることは、(すべての)フラグに適切なデフォルト値を使用することです。そして、フラグが適切なデフォルトがないようなものである場合は、アプリケーションの開始時に値を確認し、エラーメッセージで停止します。とにかく(必要なフラグだけでなく)フラグ値の検証を行う必要があります。したがって、これは(大きな)オーバーヘッドを意味するものではなく、これは一般的に良い習慣です。
既に述べた のように、flag
パッケージはこの機能を直接提供せず、通常は賢明なデフォルトを提供することができます(そしてそうすべきです)。少数の明示的な引数(たとえば、入力ファイル名と出力ファイル名)のみが必要な場合は、位置引数を使用できます(たとえば、flag.Parse()
の後にflag.NArg()==2
を確認してからinput, output := flag.Arg(0), flag.Arg(1)
)。
ただし、これが理にかなっていない場合があります。任意の順序で受け入れたいいくつかの整数フラグを言います。整数値は妥当ですが、デフォルトはありません。次に、 flag.Visit
関心のあるフラグが明示的に設定されているかどうかを確認する機能。これは、フラグがデフォルト値に明示的に設定されているかどうかを判断する唯一の方法だと思います(カスタムflag.Value
状態を保持するSet
実装を持つタイプ。
たとえば、次のようなものです。
required := []string{"b", "s"}
flag.Parse()
seen := make(map[string]bool)
flag.Visit(func(f *flag.Flag) { seen[f.Name] = true })
for _, req := range required {
if !seen[req] {
// or possibly use `log.Fatalf` instead of:
fmt.Fprintf(os.Stderr, "missing required -%s argument/flag\n", req)
os.Exit(2) // the same exit code flag.Parse uses
}
}
「-b」または「-s」フラグが明示的に設定されていない場合、これはエラーを生成します。
go-flags
を使用すると、必要なフラグと必要な位置引数の両方を宣言できます。
var opts struct {
Flag string `short:"f" required:"true" name:"a flag"`
Args struct {
First string `positional-arg-name:"first arg"`
Sencond string `positional-arg-name:"second arg"`
} `positional-args:"true" required:"2"`
}
args, err := flags.Parse(&opts)
好き - github.com/jessevdk/go-flags
CLIで使用するパッケージ。フラグを必須に設定するには、required
属性を提供します。そのように:
var opts struct {
...
// Example of a required flag
Name string `short:"n" long:"name" description:"A name" required:"true"`
...
}
フラグパスがある場合は、* pathに値が含まれているかどうかを確認するだけです
var path = flag.String("f", "", "/path/to/access.log")
flag.Parse()
if *path == "" {
usage()
os.Exit(1)
}
このソリューション に同意しますが、私の場合、デフォルト値は通常環境値です。例えば、
dsn := flag.String("dsn", os.Getenv("MYSQL_DSN"), "data source name")
この場合、値が呼び出し(通常はローカル開発)または環境変数(prod環境)から設定されているかどうかを確認します。
そのため、いくつかの小さな変更を加えて、私の場合はうまくいきました。
flag.VisitAll を使用して、すべてのフラグの値を確認します。
required := []string{"b", "s"}
flag.Parse()
seen := make(map[string]bool)
flag.VisitAll(func(f *flag.Flag) {
if f.Value.String() != "" {
seen[f.Name] = true
}
})
for _, req := range required {
if !seen[req] {
// or possibly use `log.Fatalf` instead of:
fmt.Fprintf(os.Stderr, "missing required -%s argument/flag\n", req)
os.Exit(2) // the same exit code flag.Parse uses
}
}