generated from tmknom/general-template
-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathinjector.go
128 lines (111 loc) · 2.44 KB
/
injector.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
package actdocs
import (
"bufio"
"bytes"
"fmt"
"io"
"os"
"strings"
)
type Injector struct {
*InjectorConfig
*IO
*YamlFile
}
func NewInjector(config *InjectorConfig, inOut *IO, yamlFile *YamlFile) *Injector {
return &Injector{
InjectorConfig: config,
IO: inOut,
YamlFile: yamlFile,
}
}
type InjectorConfig struct {
OutputFile string
DryRun bool
*GlobalConfig
}
func NewInjectorConfig(globalConfig *GlobalConfig) *InjectorConfig {
return &InjectorConfig{
GlobalConfig: globalConfig,
}
}
func (i *Injector) Run() error {
content, err := i.FormatYaml(i.GlobalConfig)
if err != nil {
return err
}
file, err := os.Open(i.OutputFile)
if err != nil {
return err
}
defer func(file *os.File) { err = file.Close() }(file)
var result string
if content != "" {
result = i.render(content, file)
} else {
result, err = i.renderWithoutOverride(file)
if err != nil {
return err
}
}
if i.DryRun {
_, err = fmt.Fprintf(i.OutWriter, result)
return err
}
return os.WriteFile(i.OutputFile, []byte(result), 0644)
}
func (i *Injector) render(content string, reader io.Reader) string {
scanner := bufio.NewScanner(reader)
before := i.scanBefore(scanner)
i.skipCurrentContent(scanner)
after := i.scanAfter(scanner)
var sb strings.Builder
sb.WriteString(before)
sb.WriteString("\n\n")
sb.WriteString(beginComment)
sb.WriteString("\n\n")
sb.WriteString(strings.TrimSpace(content))
sb.WriteString("\n\n")
sb.WriteString(endComment)
sb.WriteString("\n\n")
sb.WriteString(after)
sb.WriteString("\n")
return sb.String()
}
func (i *Injector) scanBefore(scanner *bufio.Scanner) string {
var sb strings.Builder
for scanner.Scan() {
str := scanner.Text()
if str == beginComment {
break
}
sb.WriteString(str)
sb.WriteString("\n")
}
return strings.TrimSpace(sb.String())
}
func (i *Injector) skipCurrentContent(scanner *bufio.Scanner) {
for scanner.Scan() {
if scanner.Text() == endComment {
break
}
}
}
func (i *Injector) scanAfter(scanner *bufio.Scanner) string {
var sb strings.Builder
for scanner.Scan() {
sb.WriteString(scanner.Text())
sb.WriteString("\n")
}
return strings.TrimSpace(sb.String())
}
func (i *Injector) renderWithoutOverride(reader io.Reader) (string, error) {
buf := bytes.Buffer{}
_, err := buf.ReadFrom(reader)
if err != nil {
return "", err
}
return buf.String(), nil
}
const beginComment = "<!-- actdocs start -->"
const endComment = "<!-- actdocs end -->"