Golangの構造体の情報をダンプするライブラリを作った

Golangの構造体の情報をダンプするライブラリを作った。

github.com

使い方

こういう感じの設定用structがあったとして

type config struct {
    Home string     `env:"HOME,required"`
    Port int        `env:"PORT" envDefault:"3000"`
    Bar  *subconfig `envPrefix:"SUB_"`
}

type subconfig struct {
    Password     string `env:"PASSWORD,unset,required"`
    IsProduction bool   `env:"PRODUCTION"`
}

ダンプしてJSONで出力できる。

func main() {
    var c config
    ss := tipper.Dump(c)
    //ss := tipper.DumpT[config]()
    fmt.Println(ss[0].Fields[0]) //=> "{Password string [{env PASSWORD [unset required]}]}"
    fmt.Println(ss)
}
[
  {
    "name": "main.subconfig",
    "fields": [
      {
        "name": "Password",
        "type": "string",
        "tags": [
          {
            "key": "env",
            "name": "PASSWORD",
            "options": [
              "unset",
              "required"
            ]
          }
        ]
      },
      // ...

ユースケース

Golangのプログラムでconfig構造体にフィールドを追加したが、ECSタスク定義に環境変数を追加していなかったためデプロイしたらCIがこけた」ということがたまにあるので、プログラム自身に必要な環境変数を出力させて、テストでECSタスク定義の環境変数と比較する…というようなユースケースを考えている。

上記の例だと、必須な環境変数の一覧をjqでとれる。

$ go run main.go | jq -r '.[].fields[] | select(.tags).tags[] | select(.key == "env" and (.options // [] | contains(["required"]))).name'
PASSWORD
HOME

おまけ: Struct Tagのパース

このライブラリではStruct Tagのパースに https://github.com/fatih/structtag を使っている。 キーから値を取得するだけなら、refrect.StructTag.Get()でできるが、すべてのキーを取得するようなことはできないので。

github.com

同様のライブラリはいくつかあるが、アクティブに更新されているものは見つけられなかった。

実装自体がシンプルなためあまり問題になることはないと思うが、できれば標準ライブラリでサポートしてほしい…