rakyll/statikでGoで扱うファイルリソースを一緒にビルドする

f:id:rasukarusan:20190806005142p:plain:w500

テンプレート用CSVを読み込んでその値を元に新しくCSVを作る、みたいな処理をするコマンドをGoで作った。
go installしてコマンドとして使えるようになったがいいものの、main.goがある場所じゃないとno such fileと出て実行ができなかった。テンプレートCSVが読み込めないよというエラー。

Golangではコード上で読み込むリソースを一緒にビルドする必要がある

ということでちらほら探して良さそうだったのがこれ。

github.com

go-assets-buildergo-bindataというのもあるらしいが、rakyll/statikはスター数も2000超えてるし何よりシンプルそうだった。

前提

こんなディレクトリ構造があるとする。

$GOPATH/src/github.com/Rasukarusan/go-csv
    .
    |-- csv-template
    |   `-- template.csv
    |-- main.go

main.goのコードはこんな感じ

func main() {
    fp, err := os.Open('csv-template/template.csv')
    if err != nil {
        log.Fatal(err)
    }
    defer fp.Close()
} 

準備

まずはインストール

$ go get github.com/rakyll/statik

コマンド実行

$ statik -src csv-template

コマンドを実行するとstatikディレクトリが作られる。 これで準備はOK。あとはソースコードを2行変えてフィニッシュ。

ソース変更

import(
    _ "github.com/Rasukarusan/go-csv/statik"
    "github.com/rakyll/statik/fs"
)

func main() {
    FS, _ := fs.New()
    fp, err := FS.Open('/template.csv')
    if err != nil {
        log.Fatal(err)
    }
    defer fp.Close()
}

os.Openするところをfsに変えるだけ。
あとちょっと注意するのはFS.Openに渡す引数でディレクトリを含めなくていいところ。

終わり

これでコマンド実行時のPATHの依存から開放された。
それにしてもGoで欲しい機能があったら大体すでに作られてるからほんと楽。phpみたいにcomposer installしてとか一々しなくていいしディレクトリが汚れないのでとってもクリーン&スピーディに開発できる。