forked from influxdata/telegraf
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmain.go
157 lines (133 loc) · 3.69 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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
// generate_plugindata is a tool used to inject the sample configuration into all the plugins
// It extracts the sample configuration from the plugins README.md
// Then using the file plugin_name_sample_config.go as a template, and will be updated with the sample configuration
// This tool is then also used to revert these changes with the `--clean` flag
package main
import (
"bufio"
"bytes"
"flag"
"fmt"
"log" //nolint:revive
"os"
"strings"
"text/template"
"github.com/yuin/goldmark"
gast "github.com/yuin/goldmark/ast"
"github.com/yuin/goldmark/text"
)
func createSourceName(packageName string) string {
return fmt.Sprintf("%s_sample_config.go", packageName)
}
// extractPluginData reads the README.md to get the sample configuration
func extractPluginData() (string, error) {
readMe, err := os.ReadFile("README.md")
if err != nil {
return "", err
}
p := goldmark.DefaultParser()
r := text.NewReader(readMe)
root := p.Parse(r)
var currentSection string
for n := root.FirstChild(); n != nil; n = n.NextSibling() {
switch tok := n.(type) {
case *gast.Heading:
if tok.FirstChild() != nil {
currentSection = string(tok.FirstChild().Text(readMe))
}
case *gast.FencedCodeBlock:
if currentSection == "Configuration" && string(tok.Language(readMe)) == "toml" {
var config []byte
for i := 0; i < tok.Lines().Len(); i++ {
line := tok.Lines().At(i)
config = append(config, line.Value(readMe)...)
}
return string(config), nil
}
}
}
fmt.Printf("No configuration found for plugin: %s\n", os.Getenv("GOPACKAGE"))
return "", nil
}
// generatePluginData parses the main source file of the plugin as a template and updates it with the sample configuration
// The original source file is saved so that these changes can be reverted
func generatePluginData(packageName string, sampleConfig string) error {
sourceName := createSourceName(packageName)
plugin, err := os.ReadFile(sourceName)
if err != nil {
return err
}
generatedTemplate := template.Must(template.New("").Parse(string(plugin)))
f, err := os.Create(sourceName)
if err != nil {
return err
}
defer f.Close()
err = generatedTemplate.Execute(f, struct {
SampleConfig string
}{
SampleConfig: sampleConfig,
})
if err != nil {
return err
}
return nil
}
var newSampleConfigFunc = ` return ` + "`{{ .SampleConfig }}`\n"
// cleanGeneratedFiles will revert the changes made by generatePluginData
func cleanGeneratedFiles(packageName string) error {
sourceName := createSourceName(packageName)
sourcefile, err := os.Open(sourceName)
if err != nil {
return err
}
defer sourcefile.Close()
var c []byte
buf := bytes.NewBuffer(c)
scanner := bufio.NewScanner(sourcefile)
var sampleconfigSection bool
for scanner.Scan() {
if sampleconfigSection && strings.TrimSpace(scanner.Text()) == "}" {
sampleconfigSection = false
if _, err := buf.Write([]byte(newSampleConfigFunc)); err != nil {
return err
}
}
if !sampleconfigSection {
if _, err := buf.Write(scanner.Bytes()); err != nil {
return err
}
if _, err = buf.WriteString("\n"); err != nil {
return err
}
}
if !sampleconfigSection && strings.Contains(scanner.Text(), "SampleConfig() string") {
sampleconfigSection = true
}
}
err = os.WriteFile(sourceName, buf.Bytes(), 0664)
if err != nil {
return err
}
return nil
}
func main() {
clean := flag.Bool("clean", false, "Remove generated files")
flag.Parse()
goPackage := os.Getenv("GOPACKAGE")
if *clean {
err := cleanGeneratedFiles(goPackage)
if err != nil {
log.Fatal(err)
}
} else {
s, err := extractPluginData()
if err != nil {
log.Fatal(err)
}
err = generatePluginData(goPackage, s)
if err != nil {
log.Fatal(err)
}
}
}