mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-06-12 09:24:23 +00:00
214 lines
5.0 KiB
Go
214 lines
5.0 KiB
Go
// Copyright 2020 The Kubernetes Authors.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
// A code copier launched via `go generate`.
|
|
// See k8segen/doc.go for further discussion.
|
|
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"bytes"
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"strings"
|
|
)
|
|
|
|
const (
|
|
// Splitting this so it doesn't show up in grep.
|
|
apiMachineryModule = "k8s.io" + "/" + "apimachinery"
|
|
apiMachineryVersion = "v0.17.0"
|
|
sigsK8sIo = "sigs.k8s.io"
|
|
)
|
|
|
|
var (
|
|
filesToCopy = map[string][]string{
|
|
filepath.Join("pkg", "labels"): {
|
|
"labels.go",
|
|
"selector.go",
|
|
"zz_generated.deepcopy.go",
|
|
},
|
|
filepath.Join("pkg", "selection"): {
|
|
"operator.go",
|
|
},
|
|
filepath.Join("pkg", "util", "sets"): {
|
|
"empty.go",
|
|
"string.go",
|
|
},
|
|
filepath.Join("pkg", "util", "errors"): {
|
|
"errors.go",
|
|
},
|
|
filepath.Join("pkg", "util", "validation"): {
|
|
"validation.go",
|
|
},
|
|
filepath.Join("pkg", "util", "validation", "field"): {
|
|
"errors.go",
|
|
"path.go",
|
|
},
|
|
}
|
|
)
|
|
|
|
func main() {
|
|
c := newCopier()
|
|
// c.print()
|
|
runNoOutputCommand("go", "get", c.apiMachineryModSpec())
|
|
for dir, files := range filesToCopy {
|
|
for _, n := range files {
|
|
if err := c.copyFile(dir, n); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
}
|
|
}
|
|
runNoOutputCommand(
|
|
"go", "mod", "edit", "-droprequire="+apiMachineryModule)
|
|
runNoOutputCommand("go", "mod", "tidy")
|
|
runGetOutputCommand("go", "fmt", "./...")
|
|
}
|
|
|
|
type copier struct {
|
|
goModCache string
|
|
topPackage string
|
|
srcDir string
|
|
pgmName string
|
|
}
|
|
|
|
func (c copier) apiMachineryModSpec() string {
|
|
return apiMachineryModule + "@" + apiMachineryVersion
|
|
}
|
|
|
|
func (c copier) replacementPath() string {
|
|
return filepath.Join(c.topPackage, c.subPath())
|
|
}
|
|
|
|
func (c copier) subPath() string {
|
|
return filepath.Join("internal", c.pgmName)
|
|
}
|
|
|
|
func (c copier) print() {
|
|
fmt.Printf(" apiMachineryModule: %s\n", apiMachineryModule)
|
|
fmt.Printf(" replacementPath: %s\n", c.replacementPath())
|
|
fmt.Printf(" goModCache: %s\n", c.goModCache)
|
|
fmt.Printf(" topPackage: %s\n", c.topPackage)
|
|
fmt.Printf(" subPath: %s\n", c.subPath())
|
|
fmt.Printf(" srcDir: %s\n", c.srcDir)
|
|
fmt.Printf(" apiMachineryModSpec: %s\n", c.apiMachineryModSpec())
|
|
fmt.Printf(" pgmName: %s\n", c.pgmName)
|
|
fmt.Printf(" pwd: %s\n", os.Getenv("PWD"))
|
|
}
|
|
|
|
func newCopier() copier {
|
|
tmp := copier{
|
|
pgmName: os.Getenv("GOPACKAGE"),
|
|
goModCache: runGetOutputCommand("go", "env", "GOMODCACHE"),
|
|
}
|
|
goMod := runGetOutputCommand("go", "env", "GOMOD")
|
|
topPackage := filepath.Join(goMod[:len(goMod)-len("go.mod")-1], "yaml")
|
|
k := strings.Index(topPackage, sigsK8sIo)
|
|
if k < 1 {
|
|
log.Fatalf("cannot find %s in %s", sigsK8sIo, topPackage)
|
|
}
|
|
tmp.srcDir = topPackage[:k-1]
|
|
tmp.topPackage = topPackage[k:]
|
|
return tmp
|
|
}
|
|
|
|
func (c copier) copyFile(dir, name string) error {
|
|
inFile, err := os.Open(
|
|
filepath.Join(c.goModCache, c.apiMachineryModSpec(), dir, name))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer inFile.Close()
|
|
scanner := bufio.NewScanner(inFile)
|
|
|
|
w, err := newWriter(dir, name)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer w.close()
|
|
|
|
w.write(
|
|
fmt.Sprintf(
|
|
// This particular phrasing is required.
|
|
"// Code generated by %s/generator from %s; DO NOT EDIT.",
|
|
c.pgmName, c.apiMachineryModSpec()))
|
|
w.write(
|
|
fmt.Sprintf(
|
|
"// Copied from %s\n",
|
|
filepath.Join(c.apiMachineryModSpec(), dir, name)))
|
|
|
|
for scanner.Scan() {
|
|
l := scanner.Text()
|
|
// Disallow recursive generation.
|
|
if strings.HasPrefix(l, "//go:generate") {
|
|
continue
|
|
}
|
|
// Don't want it to appear double generated.
|
|
if strings.HasPrefix(l, "// Code generated") {
|
|
continue
|
|
}
|
|
// Fix self-imports.
|
|
l = strings.Replace(l, apiMachineryModule, c.replacementPath(), 1)
|
|
// Replace klog with generic log (eschewing k8s.io entirely).
|
|
l = strings.Replace(l, "\"k8s.io/klog\"", "\"log\"", 1)
|
|
l = strings.Replace(l, "klog.V(10).Infof(", "log.Printf(", 1)
|
|
w.write(l)
|
|
}
|
|
if err := scanner.Err(); err != nil {
|
|
return err
|
|
}
|
|
w.write("")
|
|
return nil
|
|
}
|
|
|
|
type writer struct {
|
|
root string
|
|
f *os.File
|
|
}
|
|
|
|
func newWriter(toDir, name string) (*writer, error) {
|
|
if err := os.MkdirAll(toDir, 0755); err != nil {
|
|
log.Printf("unable to create directory: %s", toDir)
|
|
return nil, err
|
|
}
|
|
n := filepath.Join(toDir, name)
|
|
f, err := os.Create(n)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("unable to create `%s`; %v", n, err)
|
|
}
|
|
return &writer{root: toDir, f: f}, nil
|
|
}
|
|
|
|
func (w *writer) close() {
|
|
w.f.Close()
|
|
}
|
|
|
|
func (w *writer) write(line string) {
|
|
if _, err := w.f.WriteString(line + "\n"); err != nil {
|
|
log.Printf("Trouble writing: %s", line)
|
|
log.Fatalf("Error: %s", err)
|
|
}
|
|
}
|
|
|
|
func runNoOutputCommand(n string, args ...string) {
|
|
o := runGetOutputCommand(n, args...)
|
|
if len(o) > 0 {
|
|
log.Fatalf("unexpected output: %q", o)
|
|
}
|
|
}
|
|
|
|
func runGetOutputCommand(n string, args ...string) string {
|
|
cmd := exec.Command(n, args...)
|
|
var outBuf bytes.Buffer
|
|
cmd.Stdout = &outBuf
|
|
var errBuf bytes.Buffer
|
|
cmd.Stderr = &errBuf
|
|
if err := cmd.Run(); err != nil {
|
|
fmt.Printf("err: %q\n", errBuf.String())
|
|
log.Fatal(err)
|
|
}
|
|
return strings.TrimSpace(outBuf.String())
|
|
}
|