-
Notifications
You must be signed in to change notification settings - Fork 2.2k
/
main.go
132 lines (116 loc) · 2.62 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
// See /plugin/doc.go for an explanation.
package main
import (
"bufio"
"fmt"
"log"
"os"
"path/filepath"
"strings"
"sigs.k8s.io/kustomize/v3/pkg/pgmconfig"
"sigs.k8s.io/kustomize/v3/pkg/plugins"
)
func main() {
root := inputFileRoot()
file, err := os.Open(root + ".go")
if err != nil {
log.Fatal(err)
}
defer file.Close()
scanner := bufio.NewScanner(file)
readToPackageMain(scanner, file.Name())
w := NewWriter(root)
defer w.close()
// This particular phrasing is required.
w.write(
fmt.Sprintf(
"// Code generated by pluginator on %s; DO NOT EDIT.",
root))
w.write("package builtin")
for scanner.Scan() {
l := scanner.Text()
if strings.HasPrefix(l, "//go:generate") {
continue
}
if l == "var "+plugins.PluginSymbol+" plugin" {
w.write("func New" + root + "Plugin() *" + root + "Plugin {")
w.write(" return &" + root + "Plugin{}")
w.write("}")
continue
}
w.write(l)
}
if err := scanner.Err(); err != nil {
log.Fatal(err)
}
}
func inputFileRoot() string {
n := os.Getenv("GOFILE")
if !strings.HasSuffix(n, ".go") {
log.Fatalf("expecting .go suffix on %s", n)
}
return n[:len(n)-len(".go")]
}
func readToPackageMain(s *bufio.Scanner, f string) {
gotMain := false
for !gotMain && s.Scan() {
gotMain = strings.HasPrefix(s.Text(), "package main")
}
if !gotMain {
log.Fatalf("%s missing package main", f)
}
}
type writer struct {
root string
f *os.File
}
func NewWriter(r string) *writer {
n := makeOutputFileName(r)
f, err := os.Create(n)
if err != nil {
log.Fatalf("unable to create `%s`; %v", n, err)
}
return &writer{root: r, f: f}
}
func makeOutputFileName(root string) string {
return filepath.Join(
os.Getenv("GOPATH"),
"src",
pgmconfig.DomainName,
pgmconfig.ProgramName,
pgmconfig.PluginRoot,
"builtin",
root+".go")
}
func (w *writer) close() {
fmt.Println("Generated " + w.root)
w.f.Close()
}
func (w *writer) write(line string) {
_, err := w.f.WriteString(w.filter(line) + "\n")
if err != nil {
log.Printf("Trouble writing: %s", line)
log.Fatal(err)
}
}
func (w *writer) filter(in string) string {
if ok, newer := w.replace(in, "type plugin struct"); ok {
return newer
}
if ok, newer := w.replace(in, "*plugin)"); ok {
return newer
}
return in
}
// replace 'plugin' with 'FooPlugin' in context
// sensitive manner.
func (w *writer) replace(in, target string) (bool, string) {
if !strings.Contains(in, target) {
return false, ""
}
newer := strings.Replace(
target, "plugin", w.root+"Plugin", 1)
return true, strings.Replace(in, target, newer, 1)
}