1
0
mirror of https://github.com/Luzifer/gen-dockerfile.git synced 2024-09-19 16:32:57 +00:00
gen-dockerfile/main.go
Knut Ahlers 88792c4bda
Add parameter to write Dockerfile directly
Signed-off-by: Knut Ahlers <knut@ahlers.me>
2019-09-12 08:33:40 +02:00

137 lines
3.4 KiB
Go

package main
import (
"bytes"
"fmt"
"io"
"os"
"os/exec"
"regexp"
"strings"
"text/template"
homedir "github.com/mitchellh/go-homedir"
log "github.com/sirupsen/logrus"
"github.com/Luzifer/rconfig/v2"
)
var (
cfg = struct {
ExposedPorts []string `flag:"expose,e" default:"" description:"Ports to expose (format '8000' or '8000/tcp')"`
LogLevel string `flag:"log-level" default:"info" description:"Log level (debug, info, warn, error, fatal)"`
TemplateFile string `flag:"template-file" default:"~/.config/gen-dockerfile.tpl" description:"Template to use for generating the docker file"`
Timezone string `flag:"timezone,t" default:"" description:"Set timezone in Dockerfile (format 'Europe/Berlin')"`
VersionAndExit bool `flag:"version" default:"false" description:"Prints current version and exits"`
Volumes []string `flag:"volume,v" default:"" description:"Volumes to create mount points for (format '/data')"`
Write bool `flag:"write,w" default:"false" description:"Directly write into Dockerfile"`
}{}
version = "dev"
)
func init() {
rconfig.AutoEnv(true)
if err := rconfig.ParseAndValidate(&cfg); err != nil {
log.Fatalf("Unable to parse commandline options: %s", err)
}
if cfg.VersionAndExit {
fmt.Printf("gen-dockerfile %s\n", version)
os.Exit(0)
}
if l, err := log.ParseLevel(cfg.LogLevel); err != nil {
log.WithError(err).Fatal("Unable to parse log level")
} else {
log.SetLevel(l)
}
}
func main() {
pkg, err := getPackage()
if err != nil {
log.WithError(err).Fatal("Could not get package name")
}
gitName, err := getGitConfig("user.name")
if err != nil {
log.WithError(err).Fatal("Could not get git user.name")
}
gitEmail, err := getGitConfig("user.email")
if err != nil {
log.WithError(err).Fatal("Could not get git user.email")
}
params := map[string]interface{}{
"binary": getBinaryName(pkg),
"expose": deleteEmpty(cfg.ExposedPorts),
"git_mail": gitEmail,
"git_name": gitName,
"package": pkg,
"timezone": cfg.Timezone,
"volumes": `"` + strings.Join(cfg.Volumes, `", "`) + `"`,
}
tplPath, err := homedir.Expand(cfg.TemplateFile)
if err != nil {
log.WithError(err).Fatal("Could not find users homedir")
}
tpl, err := template.New("gen-dockerfile.tpl").ParseFiles(tplPath)
if err != nil {
log.WithError(err).Fatalf("Could not parse template %q", tplPath)
}
buf := new(bytes.Buffer)
if err := tpl.Execute(buf, params); err != nil {
log.WithError(err).Fatalf("Could not render template %q", tplPath)
}
var output io.Writer = os.Stdout
if cfg.Write {
f, err := os.Create("Dockerfile")
if err != nil {
log.WithError(err).Fatal("Could not open Dockerfile for writing")
}
defer f.Close()
output = f
}
fmt.Fprintln(output, strings.TrimSpace(regexp.MustCompile(`\n{3,}`).ReplaceAllString(buf.String(), "\n\n")))
}
func getPackage() (string, error) {
cwd, err := os.Getwd()
if err != nil {
return "", err
}
return strings.Replace(cwd, os.Getenv("GOPATH")+"/src/", "", -1), nil
}
func getBinaryName(pkg string) string {
parts := strings.Split(pkg, "/")
return parts[len(parts)-1]
}
func getGitConfig(config string) (string, error) {
buf := new(bytes.Buffer)
cmd := exec.Command("git", "config", "--get", config)
cmd.Stdout = buf
err := cmd.Run()
return strings.TrimSpace(buf.String()), err
}
func deleteEmpty(s []string) []string {
var r []string
for _, str := range s {
if str != "" {
r = append(r, str)
}
}
return r
}