Skip to content

Commit 40c63e5

Browse files
committed
MEDIUM: switch models generation to go-method-gen
Replaces the internal equal/diff code generator with the external github.com/haproxytech/go-method-gen package. The new generator produces separate per-type *_equal_generated.go and *_diff_generated.go files instead of a single *_compare.go per source file.
1 parent d7e1d8a commit 40c63e5

810 files changed

Lines changed: 34679 additions & 31966 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,6 @@
22
.idea/
33
bin/golangci-lint
44
bin/swagger
5+
bin
56
.envrc
7+
bin/go-method-gen

.gitlab-ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ generate:
6666
tags:
6767
- go
6868
before_script:
69-
- rm -rf models/*
69+
- rm -rf models/*.go
7070
- make models
7171
script:
7272
- test -z "$(git diff 2> /dev/null)" || exit "Models are not generated, issue \`make models\` and commit the result"

Makefile

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,25 @@ spec:
3333
go run cmd/specification/*.go -file specification/haproxy-spec.yaml > specification/build/haproxy_spec.yaml
3434

3535
.PHONY: models
36-
models: gentypes spec swagger-check
36+
models: gentypes spec swagger-check go-method-gen-check
3737
./bin/swagger generate model --additional-initialism=FCGI -f ${PROJECT_PATH}/specification/build/haproxy_spec.yaml -r ${PROJECT_PATH}/specification/copyright.txt -m models -t ${PROJECT_PATH}
38-
rm -rf models/server_params_prepare_for_runtime.go
39-
rm -rf models/*_compare.go
40-
rm -rf models/*_compare_test.go
38+
./bin/go-method-gen --header-file=specification/copyright.txt --scan=models --debug --overrides=models/funcs/overrides.yaml && find ./generated -name "*.go" -exec cp {} ./models \; && rm -rf generated
4139
go run cmd/struct_equal_generator/*.go -l ${PROJECT_PATH}/specification/copyright.txt ${PROJECT_PATH}/models
4240
go run cmd/struct_tags_checker/*.go ${PROJECT_PATH}/models
4341
go run cmd/kubebuilder_marker_generator/*.go ${PROJECT_PATH}/models
4442
go run cmd/server_params_runtime/*.go ${PROJECT_PATH}/models
43+
$(MAKE) gofumpt
44+
45+
.PHONY: go-method-gen-check
46+
go-method-gen-check:
47+
@GO_METHOD_GEN_BIN_NAME="go-method-gen"; \
48+
GO_METHOD_GEN_GITHUB="github.com/haproxytech/go-method-gen/cmd/go-method-gen@latest"; \
49+
if [ -f "$$GO_METHOD_GEN_BIN_NAME" ]; then \
50+
echo "$$GO_METHOD_GEN_BIN_NAME already installed"; \
51+
else \
52+
GOBIN=$(PWD)/bin go install $$GO_METHOD_GEN_GITHUB && \
53+
echo "$$GO_METHOD_GEN_BIN_NAME installed"; \
54+
fi
4555

4656
.PHONY: swagger-check
4757
swagger-check:

cmd/struct_equal_generator/embed.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,5 @@ import (
77
//go:embed header.tmpl
88
var tmplHeader string
99

10-
//go:embed generate.tmpl
11-
var tmplEqualAndDiff string
12-
1310
//go:embed test.tmpl
1411
var tmplCompareTest string

cmd/struct_equal_generator/generate.go

Lines changed: 0 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -6,49 +6,6 @@ import (
66
)
77

88
func generateEqualAndDiff(opt generateEqualAndDiffOptions) error {
9-
funcMaps := template.FuncMap{
10-
"HasPrefix": strings.HasPrefix,
11-
"TrimPrefix": strings.TrimPrefix,
12-
"Title": toTitle,
13-
"CamelCase": toCamelCase,
14-
"LowerCase": toLowerCase,
15-
"JSON": toJSON,
16-
}
17-
tmpl, err := template.New("generate.tmpl").Funcs(funcMaps).Parse(tmplEqualAndDiff)
18-
if err != nil {
19-
return err
20-
}
21-
22-
data := map[string]any{
23-
"Mode": opt.Mode,
24-
"Name": opt.Name,
25-
"Type": opt.Type,
26-
"Fields": opt.Fields,
27-
"NeedsOptions": opt.NeedsOptions,
28-
"NeedsOptionsIndex": opt.NeedsOptionsIndex,
29-
"IsBasicType": opt.IsBasicType,
30-
"IsComplex": opt.IsComplex,
31-
"IsComparable": opt.IsComparable,
32-
"IsPointer": opt.IsPointer,
33-
}
34-
35-
functions := map[string]any{
36-
"Functions": []any{
37-
map[string]any{
38-
"Name": "Equal",
39-
"Data": data,
40-
},
41-
map[string]any{
42-
"Name": "Diff",
43-
"Data": data,
44-
},
45-
},
46-
}
47-
48-
err = tmpl.Execute(opt.File, functions)
49-
if err != nil {
50-
return err
51-
}
529
return generateCompareTests(opt)
5310
}
5411

cmd/struct_equal_generator/main.go

Lines changed: 1 addition & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ func scanAllTypes(fileName string) []string {
7171
return typesInFile
7272
}
7373

74-
func generate(fileName string, args Args) (string, error) { //nolint:gocognit,maintidx
74+
func generate(fileName string, args Args) (string, error) { //nolint:gocognit
7575
fset := token.NewFileSet()
7676
var packageName string
7777

@@ -81,43 +81,19 @@ func generate(fileName string, args Args) (string, error) { //nolint:gocognit,ma
8181
}
8282
sourceOfFile = string(src)
8383

84-
// node, err := parser.ParseFile(fset, fileName, nil, parser.ParseComments)
8584
node, err := parser.ParseFile(fset, "", src, 0)
8685
if err != nil {
8786
return packageName, err
8887
}
89-
generatedFileName := strings.TrimSuffix(fileName, ".go") + "_compare.go"
9088
generatedFileNameTest := strings.TrimSuffix(fileName, ".go") + "_compare_test.go"
9189

92-
_ = os.Truncate(generatedFileName, 0)
93-
file, err := os.OpenFile(generatedFileName, os.O_CREATE|os.O_WRONLY, 0o600)
94-
if err != nil {
95-
return packageName, err
96-
}
97-
defer file.Close()
98-
9990
_ = os.Truncate(generatedFileNameTest, 0)
10091
fileTest, err := os.OpenFile(generatedFileNameTest, os.O_CREATE|os.O_WRONLY, 0o600)
10192
if err != nil {
10293
return packageName, err
10394
}
10495
defer fileTest.Close()
10596

106-
// Adding the header to the generated file
107-
tmpl, err := template.New("generate.tmpl").Parse(tmplHeader)
108-
// ParseFiles(path.Join(templatePath))
109-
if err != nil {
110-
return packageName, err
111-
}
112-
113-
err = tmpl.Execute(file, map[string]any{
114-
"Package": node.Name.String(),
115-
"License": args.License,
116-
})
117-
if err != nil {
118-
return packageName, err
119-
}
120-
12197
// Adding the header to the generated file
12298
tmpl2, err := template.New("generate.tmpl").Parse(tmplHeader)
12399
// ParseFiles(path.Join(templatePath))
@@ -176,7 +152,6 @@ func generate(fileName string, args Args) (string, error) { //nolint:gocognit,ma
176152
hasTests = true
177153
err = generateEqualAndDiff(generateEqualAndDiffOptions{
178154
PackageName: packageName,
179-
File: file,
180155
FileTest: fileTest,
181156
Name: currSpecType.Name.Name,
182157
CurrType: currSpecType,
@@ -192,7 +167,6 @@ func generate(fileName string, args Args) (string, error) { //nolint:gocognit,ma
192167
hasTests = true
193168
err = generateEqualAndDiff(generateEqualAndDiffOptions{
194169
PackageName: packageName,
195-
File: file,
196170
FileTest: fileTest,
197171
Name: currSpecType.Name.Name,
198172
NeedsOptions: false,
@@ -211,7 +185,6 @@ func generate(fileName string, args Args) (string, error) { //nolint:gocognit,ma
211185
}
212186
err = generateEqualAndDiff(generateEqualAndDiffOptions{
213187
PackageName: packageName,
214-
File: file,
215188
FileTest: fileTest,
216189
Name: currSpecType.Name.Name,
217190
Type: res.Name,
@@ -237,7 +210,6 @@ func generate(fileName string, args Args) (string, error) { //nolint:gocognit,ma
237210
}
238211
err = generateEqualAndDiff(generateEqualAndDiffOptions{
239212
PackageName: packageName,
240-
File: file,
241213
FileTest: fileTest,
242214
Name: currSpecType.Name.Name,
243215
Type: res.Name,
@@ -265,11 +237,6 @@ func generate(fileName string, args Args) (string, error) { //nolint:gocognit,ma
265237
} else {
266238
os.Remove(generatedFileNameTest)
267239
}
268-
// Format the file
269-
err = fmtFile(generatedFileName)
270-
if err != nil {
271-
return packageName, err
272-
}
273240
return packageName, nil
274241
}
275242

cmd/struct_equal_generator/misc.go

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import (
55
"os"
66
"strings"
77

8-
jsoniter "github.com/json-iterator/go"
98
"golang.org/x/text/cases"
109
"golang.org/x/text/language"
1110
)
@@ -49,15 +48,6 @@ func toTitle(s string) string {
4948
return caser.String(strings.TrimPrefix(s, "*"))
5049
}
5150

52-
func toJSON(x any) string {
53-
json := jsoniter.ConfigCompatibleWithStandardLibrary
54-
b, err := json.Marshal(x)
55-
if err != nil {
56-
panic(err)
57-
}
58-
return string(b)
59-
}
60-
6151
func toCamelCase(s string) string {
6252
caser := cases.Title(language.Und)
6353
words := strings.SplitSeq(s, "_")
@@ -71,19 +61,6 @@ func toCamelCase(s string) string {
7161
return result
7262
}
7363

74-
func toLowerCase(s string) string {
75-
caser := cases.Lower(language.Und)
76-
words := strings.SplitSeq(s, "_")
77-
sb := strings.Builder{}
78-
for word := range words {
79-
sb.WriteString(caser.String(word))
80-
}
81-
result := sb.String()
82-
result = strings.ToLower(result[:1]) + result[1:]
83-
84-
return result
85-
}
86-
8764
// isComparable checks if a given type is comparable.
8865
// It takes in the name of the type as a string and returns a boolean value.
8966
func isComparable(typeName string) bool {

cmd/struct_equal_generator/test.tmpl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,10 +112,11 @@ func Test{{$.Name}}{{.}}False(t *testing.T) {
112112
{{- if eq $.FieldCount 0 }}
113113
if len(result) == 0 {
114114
{{- else }}
115+
listDiffFields := GetListOfDiffFields(result)
115116
{{- if $.HasIndex }}
116-
if len(result) != {{$.FieldCount}} -1 {
117+
if len(result) != {{$.FieldCount}} -1 {
117118
{{- else }}
118-
if len(result) != {{$.FieldCount}} {
119+
if len(listDiffFields) != {{$.FieldCount}} {
119120
{{end -}}
120121
{{end -}}
121122
{{end -}}

cmd/struct_equal_generator/utils.tmpl

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ func equalPointers[T comparable](a, b *T) bool {
2727
return *a == *b
2828
}
2929

30-
func CheckSameNilAndLen[T any](s,t []T, opts ...Options) bool {
30+
func CheckSameNilAndLen[T any](s, t []T, opts ...Options) bool {
3131
opt := getOptions(opts...)
3232

3333
if !opt.NilSameAsEmpty {
@@ -62,7 +62,7 @@ func CheckSameNilAndLenMap[S comparable, T any](s, t map[S]T, opts ...Options) b
6262
}
6363

6464
func equalComparableSlice[T comparable](s1, s2 []T, opt Options) bool {
65-
if !opt.NilSameAsEmpty {
65+
if !opt.NilSameAsEmpty {
6666
if s1 == nil && s2 != nil {
6767
return true
6868
}
@@ -82,7 +82,7 @@ func equalComparableSlice[T comparable](s1, s2 []T, opt Options) bool {
8282
}
8383

8484
func equalComparableMap[T comparable](m1, m2 map[string]T, opt Options) bool {
85-
if !opt.NilSameAsEmpty {
85+
if !opt.NilSameAsEmpty {
8686
if m1 == nil && m2 != nil {
8787
return false
8888
}
@@ -129,10 +129,34 @@ func equalMapStringMapSting(m1, m2 map[string]map[string]string, opt Options) bo
129129
if v2, ok := m2[k1]; !ok {
130130
return false
131131
} else {
132-
if !equalComparableMap(v1, v2, opt){
132+
if !equalComparableMap(v1, v2, opt) {
133133
return false
134134
}
135135
}
136136
}
137137
return true
138138
}
139+
140+
func GetListOfDiffFields(diffs map[string][]interface{}) []string {
141+
fields := make(map[string]struct{}, len(diffs))
142+
for diff := range diffs {
143+
var sb strings.Builder
144+
for _, r := range diff {
145+
if !(unicode.IsLetter(r) || unicode.IsNumber(r)) {
146+
break
147+
}
148+
sb.WriteRune(r)
149+
}
150+
key := sb.String()
151+
if key == "Metadata" {
152+
continue
153+
}
154+
fields[key] = struct{}{}
155+
}
156+
result := make([]string, 0, len(fields))
157+
for k := range fields {
158+
result = append(result, k)
159+
}
160+
return result
161+
}
162+

go.mod

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ require (
1616
github.com/google/uuid v1.6.0
1717
github.com/haproxytech/client-native/v5 v5.1.9
1818
github.com/haproxytech/go-logger v1.1.0
19+
github.com/haproxytech/go-method-gen v0.1.2
1920
github.com/json-iterator/go v1.1.12
2021
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51
2122
github.com/mitchellh/mapstructure v1.5.0
@@ -45,14 +46,13 @@ require (
4546
github.com/go-openapi/swag/typeutils v0.26.0 // indirect
4647
github.com/go-openapi/swag/yamlutils v0.26.0 // indirect
4748
github.com/go-viper/mapstructure/v2 v2.5.0 // indirect
48-
github.com/kr/text v0.2.0 // indirect
4949
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
5050
github.com/modern-go/reflect2 v1.0.2 // indirect
5151
github.com/oklog/ulid/v2 v2.1.1 // indirect
5252
github.com/pmezard/go-difflib v1.0.0 // indirect
53-
github.com/rogpeppe/go-internal v1.14.1 // indirect
5453
go.yaml.in/yaml/v3 v3.0.4 // indirect
5554
golang.org/x/mod v0.36.0 // indirect
5655
golang.org/x/net v0.54.0 // indirect
5756
golang.org/x/sys v0.44.0 // indirect
57+
mvdan.cc/gofumpt v0.9.1 // indirect
5858
)

0 commit comments

Comments
 (0)