Go 標準の flag パッケージでも Usage をカスタマイズできる

はじめに

Go で CLI ツールを作るときに Go 標準の flag パッケージ を使うとコマンドライン引数でのフラグ(オプション引数)をいい感じにパースして変数に格納できるので大変便利である。

また、 flag パッケージを使うとデフォルトで -h オプションで Usage(使い方)を表示してくれるようになり、これまた大変便利である。

$ ./my-awesome-command -h
Usage of ./my-awesome-command:
  -option1 string
        help message for option1
  -option2 float
        help message for option2

しかし、作成するツールがフラグとは別に通常の(典型的には必須の)引数を要求する場合、 Usage の文字列をカスタマイズしたほうが親切である。 たとえば、以下のようなメッセージを表示したくなる。

Usage: ./my-awesome-command [options...] arg1 arg2
  -option1 string
        help message for option1
  -option2 float
        help message for option2

このような要求を満たす場合、より柔軟な設定ができるサードパーティのパッケージを導入する必要があると思っていたのだが、タイトルの通り標準の flag パッケージでも Usage をカスタマイズできることが分かった。

本題

やり方は、func() 型の flag.Usage 変数に func() を再代入するだけ。 上記の例の Usage を表示したい場合は、以下のようにすればいい。

flag.Usage = func() {
    fmt.Fprintf(os.Stderr, "Usage: %s [options...] arg1 arg2\n", os.Args[0])
    flag.PrintDefaults()
}

flag.PrintDefaults() で各オプションと説明の文章の表示ができる。

また、flag.Usage() を呼ぶことで Usage を出力できるので、エラー終了時などに呼んでおけば手間の割にコマンドのユーザに親切だろう。

元ネタ

stackoverflow.com