github.com/waldiirawan/apm-agent-go/v2@v2.2.2/scripts/gendockerfile.go (about)

     1  // Licensed to Elasticsearch B.V. under one or more contributor
     2  // license agreements. See the NOTICE file distributed with
     3  // this work for additional information regarding copyright
     4  // ownership. Elasticsearch B.V. licenses this file to you under
     5  // the Apache License, Version 2.0 (the "License"); you may
     6  // not use this file except in compliance with the License.
     7  // You may obtain a copy of the License at
     8  //
     9  //     http://www.apache.org/licenses/LICENSE-2.0
    10  //
    11  // Unless required by applicable law or agreed to in writing,
    12  // software distributed under the License is distributed on an
    13  // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    14  // KIND, either express or implied.  See the License for the
    15  // specific language governing permissions and limitations
    16  // under the License.
    17  
    18  //go:build ignore
    19  // +build ignore
    20  
    21  package main
    22  
    23  import (
    24  	"bytes"
    25  	"flag"
    26  	"io"
    27  	"log"
    28  	"os"
    29  	"os/exec"
    30  	"path"
    31  	"path/filepath"
    32  	"sort"
    33  	"strings"
    34  	"text/template"
    35  )
    36  
    37  var (
    38  	baseFlag = flag.String("base", ".", "base directory of the repo, relative to the working directory")
    39  	outFlag  = flag.String("o", "Dockerfile-testing", "output file, relative to this directory")
    40  	diffFlag = flag.Bool("d", false, "diff file against output file instead of writing")
    41  )
    42  
    43  func relPath(p string) string {
    44  	if *baseFlag == "." {
    45  		return "./" + p
    46  	}
    47  	rel, err := filepath.Rel(*baseFlag, p)
    48  	if err != nil {
    49  		panic(err)
    50  	}
    51  	return rel
    52  }
    53  
    54  var dockerfileTemplateFuncs = template.FuncMap{
    55  	"join": path.Join,
    56  }
    57  
    58  // This generates a Dockerfile that copies all of the go.mod and go.sum
    59  // files found and then runs "go mod download" for each module, before
    60  // copying across the rest of the source code.
    61  var dockerfileTemplate = template.Must(template.New("Dockerfile").Funcs(dockerfileTemplateFuncs).Parse(`
    62  # Code generated by gendockerfile. DO NOT EDIT.
    63  FROM golang:latest
    64  ENV GO111MODULE=on
    65  {{range .Dirs}}
    66  COPY {{join . "go.mod"}} {{join . "go.sum"}} {{join "/go/src/github.com/waldiirawan/apm-agent-go" .}}/{{end}}
    67  
    68  {{range .Dirs}}RUN cd {{join "/go/src/github.com/waldiirawan/apm-agent-go" .}} && go mod download
    69  {{end}}
    70  WORKDIR /go/src/github.com/waldiirawan/apm-agent-go
    71  ADD . /go/src/github.com/waldiirawan/apm-agent-go
    72  `[1:]))
    73  
    74  func main() {
    75  	flag.Parse()
    76  
    77  	// Locate all go.mod files.
    78  	var moduleDirs []string
    79  	if err := filepath.Walk(*baseFlag, func(path string, info os.FileInfo, err error) error {
    80  		if err != nil {
    81  			return err
    82  		}
    83  		if !info.IsDir() {
    84  			if info.Name() == "go.mod" {
    85  				moduleDirs = append(moduleDirs, relPath(filepath.Dir(path)))
    86  			}
    87  			return nil
    88  		}
    89  		name := info.Name()
    90  		if name != *baseFlag && (name == "vendor" || strings.HasPrefix(name, ".")) {
    91  			return filepath.SkipDir
    92  		}
    93  		return nil
    94  	}); err != nil {
    95  		log.Fatal(err)
    96  	}
    97  	sort.Strings(moduleDirs)
    98  
    99  	var buf bytes.Buffer
   100  	var out io.Writer = &buf
   101  	outFile := filepath.Join(*baseFlag, "scripts", *outFlag)
   102  	if !*diffFlag {
   103  		f, err := os.Create(outFile)
   104  		if err != nil {
   105  			log.Fatal(err)
   106  		}
   107  		defer f.Close()
   108  		out = f
   109  	}
   110  
   111  	var data struct {
   112  		Dirs []string
   113  	}
   114  	data.Dirs = moduleDirs
   115  
   116  	if err := dockerfileTemplate.Execute(out, &data); err != nil {
   117  		log.Fatal(err)
   118  	}
   119  	if *diffFlag {
   120  		cmd := exec.Command("diff", "-c", outFile, "-")
   121  		cmd.Stdin = &buf
   122  		cmd.Stdout = os.Stdout
   123  		cmd.Stderr = os.Stderr
   124  		if err := cmd.Run(); err != nil {
   125  			log.Fatal(err)
   126  		}
   127  	}
   128  }