scripts/gendockerfile.go (93 lines of code) (raw):

// Licensed to Elasticsearch B.V. under one or more contributor // license agreements. See the NOTICE file distributed with // this work for additional information regarding copyright // ownership. Elasticsearch B.V. licenses this file to you under // the Apache License, Version 2.0 (the "License"); you may // not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. //go:build ignore // +build ignore package main import ( "bytes" "flag" "io" "log" "os" "os/exec" "path" "path/filepath" "sort" "strings" "text/template" ) var ( baseFlag = flag.String("base", ".", "base directory of the repo, relative to the working directory") outFlag = flag.String("o", "Dockerfile-testing", "output file, relative to this directory") diffFlag = flag.Bool("d", false, "diff file against output file instead of writing") ) func relPath(p string) string { if *baseFlag == "." { return "./" + p } rel, err := filepath.Rel(*baseFlag, p) if err != nil { panic(err) } return rel } var dockerfileTemplateFuncs = template.FuncMap{ "join": path.Join, } // This generates a Dockerfile that copies all of the go.mod and go.sum // files found and then runs "go mod download" for each module, before // copying across the rest of the source code. var dockerfileTemplate = template.Must(template.New("Dockerfile").Funcs(dockerfileTemplateFuncs).Parse(` # Code generated by gendockerfile. DO NOT EDIT. FROM golang:latest ENV GO111MODULE=on {{range .Dirs}} COPY {{join . "go.mod"}} {{join . "go.sum"}} {{join "/go/src/go.elastic.co/apm" .}}/{{end}} {{range .Dirs}}RUN cd {{join "/go/src/go.elastic.co/apm" .}} && go mod download {{end}} WORKDIR /go/src/go.elastic.co/apm ADD . /go/src/go.elastic.co/apm `[1:])) func main() { flag.Parse() // Locate all go.mod files. var moduleDirs []string if err := filepath.Walk(*baseFlag, func(path string, info os.FileInfo, err error) error { if err != nil { return err } if !info.IsDir() { if info.Name() == "go.mod" { moduleDirs = append(moduleDirs, relPath(filepath.Dir(path))) } return nil } name := info.Name() if name != *baseFlag && (name == "vendor" || name == "tools" || strings.HasPrefix(name, ".")) { return filepath.SkipDir } return nil }); err != nil { log.Fatal(err) } sort.Strings(moduleDirs) var buf bytes.Buffer var out io.Writer = &buf outFile := filepath.Join(*baseFlag, "scripts", *outFlag) if !*diffFlag { f, err := os.Create(outFile) if err != nil { log.Fatal(err) } defer f.Close() out = f } var data struct { Dirs []string } data.Dirs = moduleDirs if err := dockerfileTemplate.Execute(out, &data); err != nil { log.Fatal(err) } if *diffFlag { cmd := exec.Command("diff", "-c", outFile, "-") cmd.Stdin = &buf cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr if err := cmd.Run(); err != nil { log.Fatal(err) } } }