2018-04-10 11:05:17 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"fmt"
|
2019-09-12 05:17:22 +00:00
|
|
|
"io"
|
2018-04-10 11:05:17 +00:00
|
|
|
"os"
|
|
|
|
"os/exec"
|
|
|
|
"regexp"
|
|
|
|
"strings"
|
|
|
|
"text/template"
|
|
|
|
|
|
|
|
homedir "github.com/mitchellh/go-homedir"
|
|
|
|
log "github.com/sirupsen/logrus"
|
2019-09-12 05:12:18 +00:00
|
|
|
|
|
|
|
"github.com/Luzifer/rconfig/v2"
|
2018-04-10 11:05:17 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
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')"`
|
2019-09-12 05:17:22 +00:00
|
|
|
Write bool `flag:"write,w" default:"false" description:"Directly write into Dockerfile"`
|
2018-04-10 11:05:17 +00:00
|
|
|
}{}
|
|
|
|
|
|
|
|
version = "dev"
|
|
|
|
)
|
|
|
|
|
|
|
|
func init() {
|
2019-09-12 05:12:18 +00:00
|
|
|
rconfig.AutoEnv(true)
|
2018-04-10 11:05:17 +00:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
|
2019-09-12 05:17:22 +00:00
|
|
|
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")))
|
2018-04-10 11:05:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
}
|