Golangの構造体の情報をダンプするライブラリを作った。
使い方
こういう感じの設定用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()でできるが、すべてのキーを取得するようなことはできないので。
同様のライブラリはいくつかあるが、アクティブに更新されているものは見つけられなかった。
- https://github.com/moznion/go-struct-custom-tag-parser
- https://github.com/execjosh/structtag
- https://github.com/go-mods/tags
実装自体がシンプルなためあまり問題になることはないと思うが、できれば標準ライブラリでサポートしてほしい…