go-bindataを使っていた部分をgo-assetsに置き換える

最近こういうことがあった. というわけでもしgo-bindataを使っている場合にはgo-assetsあたりに乗り換えたほうがいい.

例えば静的ファイル等を http.FileServer で配るだけなら,最初からgo-bindataではなくgo-assetsを使っている方が多いのではないだろうか. そうではなく,わざわざgo-bindataを使っていたのは,ファイルの中身をパースしたかったりするからなのではないだろうか?

というわけでgo-assetsを使って,go-bindataと同じようにファイルの中身をパースしてみる.

Assetsを作る

go-assetsはともかく,とりあえずgo-assets-builderを入れよう.

github.com

$ go get -u github.com/jessevdk/go-assets-builder

で,generateコマンドを変更する.

//go:generate go-bindata -o=config/bindata.go -pkg=config -prefix=config/ config/settings.yml

こんなのを

//go:generate go-assets-builder --output=config/bindata.go -s="/config" -p=config config/settings.yml

こうする.

これで go generate すると新しい config/bindata.go ができあがる.

Assetsを参照する

go-bindataでは,このようになっているとする.

buf, err := Asset("settings.yml")
if err != nil {
    panic(err)
}

m := make(map[interface{}]interface{})
err = yaml.Unmarshal(buf, &m)
if err != nil {
    panic(err)
}

こいつをgo-assetsを使ったパターンに書き換える.

file, err := Assets.Open("/settings.yml")
if err != nil {
    panic(err)
}

by := new(bytes.Buffer)
io.Copy(by, file)
buf := by.Bytes()

m := make(map[interface{}]interface{})
err = yaml.Unmarshal(buf, &m)
if err != nil {
    panic(err)
}

こんな感じになる.

Assets.Open した http.Fileio.Reader を持っているので,bytes.Bufferio.Copy してやれば []byte に変換できる. あとは簡単で,普通に Unmarshal できる. jsonでもこれと同じ要領でいけるだろう.