/
generate_mock_client.go
96 lines (77 loc) · 1.56 KB
/
generate_mock_client.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
package main
import (
"bytes"
"fmt"
"go/ast"
"go/format"
"go/parser"
"go/token"
"os"
"text/template"
_ "embed"
"github.com/go-task/slim-sprig/v3"
)
//go:embed mock_client.tpl
var clientTpl string
type services []service
type service struct {
Name string
}
func main() {
svcs, err := svcs()
if err != nil {
panic(err)
}
fmt.Println(svcs)
err = writeTemplate("test/client/mock_client.go", clientTpl, svcs)
if err != nil {
panic(err)
}
}
func svcs() (services, error) {
var (
result = services{}
set = token.NewFileSet()
)
f, err := parser.ParseFile(set, "metal.go", nil, parser.ParseComments)
if err != nil {
return nil, err
}
for _, decl := range f.Decls {
if gen, isGen := decl.(*ast.GenDecl); isGen {
for _, spec := range gen.Specs {
if t, isType := spec.(*ast.TypeSpec); isType {
if t.Name.String() != "Client" {
continue
}
if i, IsInterface := t.Type.(*ast.InterfaceType); IsInterface {
for _, m := range i.Methods.List {
for _, name := range m.Names {
result = append(result, service{
Name: name.Name,
})
}
}
}
}
}
}
}
return result, nil
}
func writeTemplate(dest, text string, data any) error {
t, err := template.New("").Funcs(sprig.FuncMap()).Parse(text)
if err != nil {
return err
}
var buf bytes.Buffer
if err := t.Execute(&buf, data); err != nil {
return err
}
p, err := format.Source(buf.Bytes())
if err != nil {
return err
}
fmt.Printf("writing to %s\n", dest)
return os.WriteFile(dest, p, 0755) // nolint:gosec
}