-
Notifications
You must be signed in to change notification settings - Fork 32
/
main.go
213 lines (185 loc) · 5.82 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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
package scaffold
import (
"embed"
"fmt"
"os"
"path/filepath"
"time"
"github.com/httprunner/funplugin/fungo"
"github.com/pkg/errors"
"github.com/test-instructor/yangfan/server/global"
"go.uber.org/zap"
"github.com/test-instructor/yangfan/hrp"
"github.com/test-instructor/yangfan/hrp/internal/builtin"
"github.com/test-instructor/yangfan/hrp/internal/myexec"
"github.com/test-instructor/yangfan/hrp/internal/sdk"
"github.com/test-instructor/yangfan/hrp/internal/version"
)
type PluginType string
const (
Empty PluginType = "empty"
Ignore PluginType = "ignore"
Py PluginType = "py"
Go PluginType = "go"
)
type ProjectInfo struct {
ProjectName string `json:"project_name,omitempty" yaml:"project_name,omitempty"`
CreateTime time.Time `json:"create_time,omitempty" yaml:"create_time,omitempty"`
Version string `json:"hrp_version,omitempty" yaml:"hrp_version,omitempty"`
}
//go:embed templates/*
var templatesDir embed.FS
// CopyFile copies a file from templates dir to scaffold project
func CopyFile(templateFile, targetFile string) error {
global.GVA_LOG.Info("create file", zap.String("path", targetFile))
content, err := templatesDir.ReadFile(templateFile)
if err != nil {
return errors.Wrap(err, "template file not found")
}
err = os.WriteFile(targetFile, content, 0o644)
if err != nil {
global.GVA_LOG.Error("create file failed", zap.Error(err))
return err
}
return nil
}
func CreateScaffold(projectName string, pluginType PluginType, venv string, force bool) error {
// report event
sdk.SendEvent(sdk.EventTracking{
Category: "Scaffold",
Action: "hrp startproject",
})
global.GVA_LOG.Info("create new scaffold project", zap.String("projectName", projectName), zap.String("pluginType", string(pluginType)), zap.Bool("force", force))
// check if projectName exists
if _, err := os.Stat(projectName); err == nil {
if !force {
global.GVA_LOG.Warn("project name already exists, please specify a new one.", zap.String("projectName", projectName))
return fmt.Errorf("project name already exists")
}
global.GVA_LOG.Warn("project name already exists, remove first !!!", zap.String("projectName", projectName))
os.RemoveAll(projectName)
}
// create project folders
if err := builtin.CreateFolder(projectName); err != nil {
return err
}
if err := builtin.CreateFolder(filepath.Join(projectName, "har")); err != nil {
return err
}
if err := builtin.CreateFile(filepath.Join(projectName, "har", ".keep"), ""); err != nil {
return err
}
if err := builtin.CreateFolder(filepath.Join(projectName, "testcases")); err != nil {
return err
}
if err := builtin.CreateFolder(filepath.Join(projectName, "reports")); err != nil {
return err
}
if err := builtin.CreateFile(filepath.Join(projectName, "reports", ".keep"), ""); err != nil {
return err
}
projectInfo := &ProjectInfo{
ProjectName: filepath.Base(projectName),
CreateTime: time.Now(),
Version: version.VERSION,
}
// dump project information to file
err := builtin.Dump2JSON(projectInfo, filepath.Join(projectName, "proj.json"))
if err != nil {
return err
}
// create .gitignore
err = CopyFile("templates/gitignore", filepath.Join(projectName, ".gitignore"))
if err != nil {
return err
}
// create .env
err = CopyFile("templates/env", filepath.Join(projectName, ".env"))
if err != nil {
return err
}
// create project testcases
if pluginType == Empty {
// create empty project
err := CopyFile("templates/testcases/demo_empty_request.json",
filepath.Join(projectName, "testcases", "requests.json"))
if err != nil {
return err
}
return nil
} else if pluginType == Ignore {
// create project without funplugin
err := CopyFile("templates/testcases/demo_without_funplugin.json",
filepath.Join(projectName, "testcases", "requests.json"))
if err != nil {
return err
}
global.GVA_LOG.Info("skip creating function plugin")
return nil
}
// create project with funplugin
err = CopyFile("templates/testcases/demo_with_funplugin.json",
filepath.Join(projectName, "testcases", "demo.json"))
if err != nil {
return err
}
err = CopyFile("templates/testcases/demo_requests.json",
filepath.Join(projectName, "testcases", "requests.json"))
if err != nil {
return err
}
err = CopyFile("templates/testcases/demo_requests.yml",
filepath.Join(projectName, "testcases", "requests.yml"))
if err != nil {
return err
}
err = CopyFile("templates/testcases/demo_ref_testcase.yml",
filepath.Join(projectName, "testcases", "ref_testcase.yml"))
if err != nil {
return err
}
// create debugtalk function plugin
switch pluginType {
case Py:
return createPythonPlugin(projectName, venv)
case Go:
return createGoPlugin(projectName)
}
return nil
}
func createGoPlugin(projectName string) error {
global.GVA_LOG.Info("start to create hashicorp go plugin")
// check go sdk
if err := myexec.RunCommand("go", "version"); err != nil {
return errors.Wrap(err, "go sdk not installed")
}
// create debugtalk.go
pluginDir := filepath.Join(projectName, "plugin")
if err := builtin.CreateFolder(pluginDir); err != nil {
return err
}
err := CopyFile("templates/plugin/debugtalk.go",
filepath.Join(projectName, "plugin", hrp.PluginGoSourceFile))
if err != nil {
return errors.Wrap(err, "copy debugtalk.go failed")
}
return nil
}
func createPythonPlugin(projectName, venv string) error {
global.GVA_LOG.Info("start to create hashicorp python plugin")
// create debugtalk.py
pluginFile := filepath.Join(projectName, hrp.PluginPySourceFile)
err := CopyFile("templates/plugin/debugtalk.py", pluginFile)
if err != nil {
return errors.Wrap(err, "copy file failed")
}
packages := []string{
fmt.Sprintf("funppy==%s", fungo.Version),
fmt.Sprintf("httprunner==%s", version.HttpRunnerMinimumVersion),
}
_, err = myexec.EnsurePython3Venv(venv, packages...)
if err != nil {
return err
}
return nil
}