初めに
個人開発で Docker を使っているのですが、毎回 Dockerfile を作るのが めんどくさくなったのでテンプレを用意しました。
とりあえずソースコードです https://github.com/komisan19/kuzira
使い方
init
コマンドを叩くと空の Dockerfile が作成でき、
create
コマンド+言語を指定するとテンプレートの言語が作成されます。
$ kuzira init
$ ls Dockerfile
Dockerfile
---
$ kuzira create go
create Dockerfile for Golang
仕組み
CLI は以下のライブラリを使っていますが、テンプレートは embed を使ってみました。 https://github.com/urfave/cli
go:embed
Go1.16 から追加された機能です。
go:embed はその意味の通り埋め込みができます。1.16 以前もos
やio/ioutil
で読み込みなどできましたが、embed を使うとgo build
時にバイナリに埋め込むことができます。
工夫点
上記でも記載しましたが、go:embed を使っています。 そのため、今回はこのような形でテンプレートファイルをおいて参照するようにしました。
.
├── README.md
├── action
│ ├── cli.go
│ └── cookbook
│ ├── go-dockerfile
│ └── python-dockerfile
---
cookboo k内にテンプレートファイルを置くようにしました。 そして cli.go にこのような形で書きました。
package action
import (
"embed"
"fmt"
"github.com/urfave/cli"
"log"
"os"
)
//go:embed cookbook/*
var cookbook embed.FS
func Create(c *cli.Context) {
switch os.Args[2] {
case "go":
rd, err := cookbook.ReadFile("cookbook/go-dockerfile")
if err != nil {
log.Fatal(err)
}
err = os.WriteFile("Dockerfile", rd, 0644)
if err != nil {
log.Fatal(err)
}
fmt.Println("create Dockerfile for Golang")
...
}
embed の特徴はここです
//go:embed cookbook/*
var cookbook embed.FS
//go:embed cookbook/*
を指定することでその参照したいファイルを選択できます。
例えば//go:embed index.html
とすることで実行ファイルの index.html を参照することができます。参照ができたら、以下のように書くことでファイルの中身を読み込むことができます。
rd, err := cookbook.ReadFile("cookbook/go-dockerfile")
改善点
今後はこのあたりを改善していこうと思います。
- テンプレートが少ない(Go,python のみ)
- 言語が増えると switch が増えてしまう
- 自分でカスタマイズできない。
まとめ
久しぶりに CLI を作成したのですが、embed ができてからテンプレートの埋め込みがだいぶ楽になりました。 まだまだ改善点が多いですが、今後も CLI を作っていこうと思います。