1
2
3
4
5
6
7
8
9
10
11
12
13
14 package main
15
16 import (
17 "fmt"
18 "go/ast"
19 "go/parser"
20 "go/token"
21 "os"
22 "path/filepath"
23 "strings"
24
25 "github.com/pingcap/errors"
26 "sigs.k8s.io/controller-runtime/pkg/log/zap"
27 )
28
29 var (
30 log = zap.New(zap.UseDevMode(true))
31 )
32
33 type metadata struct {
34 Type string
35 OneShotExp string
36 }
37
38 func main() {
39 implCode := boilerplate + implImport
40
41 testCode := boilerplate + testImport
42 initImpl := ""
43 scheduleImpl := ""
44 allTypes := make([]string, 0, 10)
45
46 workflowGenerator := newWorkflowCodeGenerator(nil)
47 workflowTestGenerator := newWorkflowTestCodeGenerator(nil)
48 workflowFrontendGenerator := newWorkflowFrontendCodeGenerator(nil)
49
50 scheduleGenerator := newScheduleCodeGenerator(nil)
51
52 filepath.Walk("./api/v1alpha1", func(path string, info os.FileInfo, err error) error {
53 log := log.WithValues("file", path)
54
55 if err != nil {
56 log.Error(err, "fail to walk in directory")
57 return err
58 }
59 if info.IsDir() {
60 return nil
61 }
62 if !strings.HasSuffix(info.Name(), ".go") {
63 return nil
64 }
65
66 fset := token.NewFileSet()
67 file, err := parser.ParseFile(fset, path, nil, parser.ParseComments)
68 if err != nil {
69 log.Error(err, "fail to parse file")
70 return err
71 }
72
73 cmap := ast.NewCommentMap(fset, file, file.Comments)
74
75 out:
76 for node, commentGroups := range cmap {
77 for _, commentGroup := range commentGroups {
78 var err error
79 var oneShotExp string
80 for _, comment := range commentGroup.List {
81 if strings.Contains(comment.Text, "+chaos-mesh:oneshot") {
82 oneShotExp = strings.TrimPrefix(comment.Text, "// +chaos-mesh:oneshot=")
83 log.Info("decode oneshot expression", "expression", oneShotExp)
84 }
85 }
86 for _, comment := range commentGroup.List {
87 if strings.Contains(comment.Text, "+chaos-mesh:base") {
88 log.Info("build", "pos", fset.Position(comment.Pos()))
89 baseDecl, ok := node.(*ast.GenDecl)
90 if !ok {
91 err = errors.Errorf("node is not a *ast.GenDecl")
92 log.Error(err, "fail to get type")
93 return err
94 }
95
96 if baseDecl.Tok != token.TYPE {
97 err = errors.Errorf("node.Tok is not token.TYPE")
98 log.Error(err, "fail to get type")
99 return err
100 }
101
102 baseType, ok := baseDecl.Specs[0].(*ast.TypeSpec)
103 if !ok {
104 err = errors.Errorf("node is not a *ast.TypeSpec")
105 log.Error(err, "fail to get type")
106 return err
107 }
108 if baseType.Name.Name != "Workflow" {
109 implCode += generateImpl(baseType.Name.Name, oneShotExp)
110 testCode += generateTest(baseType.Name.Name)
111 initImpl += generateInit(baseType.Name.Name)
112 workflowGenerator.AppendTypes(baseType.Name.Name)
113 workflowTestGenerator.AppendTypes(baseType.Name.Name)
114 workflowFrontendGenerator.AppendTypes(baseType.Name.Name)
115 }
116 scheduleImpl += generateScheduleRegister(baseType.Name.Name)
117 scheduleGenerator.AppendTypes(baseType.Name.Name)
118 allTypes = append(allTypes, baseType.Name.Name)
119 continue out
120 }
121 }
122 }
123 }
124
125 return nil
126 })
127
128 implCode += fmt.Sprintf(`
129 func init() {
130 %s
131 %s
132 }
133 `, initImpl, scheduleImpl)
134 file, err := os.Create("./api/v1alpha1/zz_generated.chaosmesh.go")
135 if err != nil {
136 log.Error(err, "fail to create file")
137 os.Exit(1)
138 }
139 fmt.Fprint(file, implCode)
140
141 testCode += testInit
142 file, err = os.Create("./api/v1alpha1/zz_generated.chaosmesh_test.go")
143 if err != nil {
144 log.Error(err, "fail to create file")
145 os.Exit(1)
146 }
147 fmt.Fprint(file, testCode)
148
149 file, err = os.Create("./api/v1alpha1/zz_generated.workflow.chaosmesh.go")
150 if err != nil {
151 log.Error(err, "fail to create file")
152 os.Exit(1)
153 }
154 fmt.Fprint(file, workflowGenerator.Render())
155
156 file, err = os.Create("./api/v1alpha1/zz_generated.workflow.chaosmesh_test.go")
157 if err != nil {
158 log.Error(err, "fail to create file")
159 os.Exit(1)
160 }
161 fmt.Fprint(file, workflowTestGenerator.Render())
162
163 file, err = os.Create("./ui/src/api/zz_generated.workflow.chaos-mesh.ts")
164 if err != nil {
165 log.Error(err, "fail to create file")
166 os.Exit(1)
167 }
168 fmt.Fprint(file, workflowFrontendGenerator.Render())
169
170 file, err = os.Create("./api/v1alpha1/zz_generated.schedule.chaosmesh.go")
171 if err != nil {
172 log.Error(err, "fail to create file")
173 os.Exit(1)
174 }
175 fmt.Fprint(file, scheduleGenerator.Render())
176
177 }
178