Skip to content

Commit 3b23f74

Browse files
committed
remove starlark
1 parent 4a90dbf commit 3b23f74

File tree

1 file changed

+93
-188
lines changed

1 file changed

+93
-188
lines changed

cmd/src/validate.go

Lines changed: 93 additions & 188 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,34 @@ import (
1010
"net/http"
1111
"os"
1212
"strings"
13+
"text/template"
1314
"time"
1415

1516
jsoniter "github.com/json-iterator/go"
1617
"github.com/mattn/go-isatty"
17-
"github.com/sourcegraph/starlight"
18-
"github.com/sourcegraph/starlight/convert"
19-
"go.starlark.net/starlark"
2018
)
2119

22-
type validator struct{
20+
type validationSpec struct {
21+
FirstAdmin struct {
22+
Email string
23+
Username string
24+
Password string
25+
}
26+
WaitRepoCloned struct {
27+
Repo string
28+
MaxTries int
29+
SleepBetweenTriesSeconds int
30+
}
31+
SearchQuery string
32+
ExternalService struct {
33+
Kind string
34+
DisplayName string
35+
Config *json.RawMessage
36+
DeleteWhenDone bool
37+
}
38+
}
39+
40+
type validator struct {
2341
client *vdClient
2442
}
2543

@@ -43,7 +61,7 @@ or
4361

4462
var (
4563
contextFlag = flagSet.String("context", "", `Comma-separated list of key=value pairs to add to the script execution context`)
46-
docFlag = flagSet.Bool("doc", false, `Show function documentation`)
64+
docFlag = flagSet.Bool("doc", false, `Show documentation`)
4765
secretsFlag = flagSet.String("secrets", "", "Path to a file containing key=value lines. The key value pairs will be added to the script context")
4866
)
4967

@@ -93,7 +111,7 @@ or
93111
}
94112

95113
func (vd *validator) printDocumentation() {
96-
fmt.Println("TODO(uwedeportivo): write function documentation")
114+
fmt.Println("TODO(uwedeportivo): write documentation")
97115
}
98116

99117
func (vd *validator) parseKVPairs(val string, pairSep string) map[string]string {
@@ -120,33 +138,63 @@ func (vd *validator) readSecrets(path string) (map[string]string, error) {
120138
}
121139

122140
func (vd *validator) validate(script []byte, scriptContext map[string]string) error {
123-
globals := map[string]interface{}{
124-
"src_list_external_services": vd.listExternalServices,
125-
"src_add_external_service": vd.addExternalService,
126-
"src_delete_external_service": vd.deleteExternalService,
127-
"src_search_match_count": vd.searchMatchCount,
128-
"src_list_cloned_repos": vd.listClonedRepos,
129-
"src_wait_repo_cloned": vd.waitRepoCloned,
130-
"src_sleep_seconds": vd.sleepSeconds,
131-
"src_log": vd.log,
132-
"src_run_graphql": vd.runGraphQL,
133-
"src_context": scriptContext,
134-
"src_create_first_admin": vd.createFirstAdmin,
135-
"src_debug": vd.debug,
136-
}
137-
138-
vals, err := starlight.Eval(script, globals, nil)
141+
tpl, err := template.New("validate").Parse(string(script))
142+
if err != nil {
143+
return err
144+
}
145+
var ts bytes.Buffer
146+
err = tpl.Execute(&ts, scriptContext)
139147
if err != nil {
140148
return err
141149
}
142-
if passed, ok := vals["passed"].(bool); !ok || !passed {
143-
return errors.New("failed")
150+
151+
var vspec validationSpec
152+
if err := json.Unmarshal(ts.Bytes(), &vspec); err != nil {
153+
return err
154+
}
155+
156+
if vspec.FirstAdmin.Username != "" {
157+
err = vd.createFirstAdmin(&vspec)
158+
if err != nil {
159+
return err
160+
}
161+
}
162+
163+
if vspec.ExternalService.DisplayName != "" {
164+
extSvcID, err := vd.addExternalService(&vspec)
165+
if err != nil {
166+
return err
167+
}
168+
169+
defer func() {
170+
if extSvcID != "" && vspec.ExternalService.DeleteWhenDone {
171+
_ = vd.deleteExternalService(extSvcID)
172+
}
173+
}()
144174
}
145-
return nil
146-
}
147175

148-
func (vd *validator) sleepSeconds(num time.Duration) {
149-
time.Sleep(time.Second * num)
176+
if vspec.WaitRepoCloned.Repo != "" {
177+
cloned, err := vd.waitRepoCloned(vspec.WaitRepoCloned.Repo, vspec.WaitRepoCloned.SleepBetweenTriesSeconds,
178+
vspec.WaitRepoCloned.MaxTries)
179+
if err != nil {
180+
return err
181+
}
182+
if !cloned {
183+
return fmt.Errorf("repo %s didn't clone", vspec.WaitRepoCloned.Repo)
184+
}
185+
}
186+
187+
if vspec.SearchQuery != "" {
188+
matchCount, err := vd.searchMatchCount(vspec.SearchQuery)
189+
if err != nil {
190+
return err
191+
}
192+
if matchCount == 0 {
193+
return fmt.Errorf("search query %s returned no results", vspec.SearchQuery)
194+
}
195+
}
196+
197+
return nil
150198
}
151199

152200
const vdAddExternalServiceQuery = `
@@ -161,9 +209,8 @@ mutation AddExternalService($kind: ExternalServiceKind!, $displayName: String!,
161209
}
162210
}`
163211

164-
func (vd *validator) addExternalService(kind, displayName, config interface{}) (string, error) {
165-
dict := vd.convertDict(config)
166-
configJson, err := json.MarshalIndent(dict, "", " ")
212+
func (vd *validator) addExternalService(vspec *validationSpec) (string, error) {
213+
configJson, err := vspec.ExternalService.Config.MarshalJSON()
167214
if err != nil {
168215
return "", err
169216
}
@@ -174,9 +221,9 @@ func (vd *validator) addExternalService(kind, displayName, config interface{}) (
174221
}
175222

176223
err = vd.graphQL(vdAddExternalServiceQuery, map[string]interface{}{
177-
"kind": kind,
178-
"displayName": displayName,
179-
"config": string(configJson),
224+
"kind": vspec.ExternalService.Kind,
225+
"displayName": vspec.ExternalService.DisplayName,
226+
"config": string(configJson),
180227
}, &resp)
181228

182229
return resp.AddExternalService.ID, err
@@ -190,7 +237,7 @@ mutation DeleteExternalService($id: ID!) {
190237
}`
191238

192239
func (vd *validator) deleteExternalService(id string) error {
193-
var resp struct {}
240+
var resp struct{}
194241

195242
return vd.graphQL(vdDeleteExternalServiceQuery, map[string]interface{}{
196243
"id": id,
@@ -236,7 +283,7 @@ query ListRepos($cloneInProgress: Boolean!, $cloned: Boolean!, $notCloned: Boole
236283
}
237284
}`
238285

239-
func (vd *validator) listClonedReposImpl(fs []string) ([]string, error) {
286+
func (vd *validator) listClonedRepos(fs []string) ([]string, error) {
240287
var resp struct {
241288
Repositories struct {
242289
Nodes []struct {
@@ -247,9 +294,9 @@ func (vd *validator) listClonedReposImpl(fs []string) ([]string, error) {
247294

248295
err := vd.graphQL(vdListRepos, map[string]interface{}{
249296
"cloneInProgress": true,
250-
"cloned": true,
251-
"notCloned": true,
252-
"names": fs,
297+
"cloned": true,
298+
"notCloned": true,
299+
"names": fs,
253300
}, &resp)
254301

255302
names := make([]string, 0, len(resp.Repositories.Nodes))
@@ -260,16 +307,11 @@ func (vd *validator) listClonedReposImpl(fs []string) ([]string, error) {
260307
return names, err
261308
}
262309

263-
func (vd *validator) listClonedRepos(filterNames interface{}) ([]string, error) {
264-
fs := vd.convertStringList(filterNames)
265-
return vd.listClonedReposImpl(fs)
266-
}
267-
268310
func (vd *validator) waitRepoCloned(repoName string, sleepSeconds int, maxTries int) (bool, error) {
269311
nameFilter := []string{repoName}
270312

271313
for i := 0; i < maxTries; i++ {
272-
names, err := vd.listClonedReposImpl(nameFilter)
314+
names, err := vd.listClonedRepos(nameFilter)
273315
if err != nil {
274316
return false, err
275317
}
@@ -281,140 +323,6 @@ func (vd *validator) waitRepoCloned(repoName string, sleepSeconds int, maxTries
281323
return false, nil
282324
}
283325

284-
func (vd *validator) log(line string) {
285-
fmt.Println(line)
286-
}
287-
288-
func (vd *validator) runGraphQL(query string, vars interface{}) (starlark.Value, error) {
289-
resp := map[string]interface{}{}
290-
cvars := vd.convertDict(vars)
291-
292-
err := vd.graphQL(query, cvars, &resp)
293-
if err != nil {
294-
return nil, err
295-
}
296-
return vd.makeDict(resp)
297-
}
298-
299-
const vdListExternalServices = `
300-
query ExternalServices {
301-
externalServices {
302-
nodes {
303-
id
304-
displayName
305-
}
306-
}
307-
}`
308-
309-
func (vd *validator) listExternalServices() ([]map[string]string, error) {
310-
var resp struct {
311-
ExternalServices struct {
312-
Nodes []struct {
313-
DisplayName string `json:"displayName"`
314-
ID string `json:"id"`
315-
} `json:"nodes"`
316-
} `json:"externalServices"`
317-
}
318-
319-
err := vd.graphQL(vdListExternalServices, map[string]interface{}{}, &resp)
320-
if err != nil {
321-
return nil, err
322-
}
323-
324-
xs := make([]map[string]string, 0, len(resp.ExternalServices.Nodes))
325-
for _, es := range resp.ExternalServices.Nodes {
326-
xs = append(xs, map[string]string{"id": es.ID, "displayName": es.DisplayName})
327-
}
328-
329-
return xs, nil
330-
}
331-
332-
func (vd *validator) makeDict(m map[string]interface{}) (starlark.Value, error) {
333-
dict := starlark.Dict{}
334-
335-
for k, v := range m {
336-
var sv starlark.Value
337-
var err error
338-
339-
sk := starlark.String(k)
340-
if cv, ok := v.(map[string]interface{}); ok {
341-
sv, err = vd.makeDict(cv)
342-
if err != nil {
343-
return nil, err
344-
}
345-
} else {
346-
sv, err = convert.ToValue(v)
347-
if err != nil {
348-
return nil, err
349-
}
350-
}
351-
err = dict.SetKey(sk, sv)
352-
if err != nil {
353-
return nil, err
354-
}
355-
}
356-
return &dict, nil
357-
}
358-
359-
func (vd *validator) convertDict(val interface{}) map[string]interface{} {
360-
dict := val.(map[interface{}]interface{})
361-
res := make(map[string]interface{})
362-
363-
for k, v := range dict {
364-
gk := vd.fromStarLark(k).(string)
365-
gv := vd.fromStarLark(v)
366-
367-
res[gk] = gv
368-
}
369-
return res
370-
}
371-
372-
func (vd *validator) convertStringList(val interface{}) []string {
373-
list := val.([]interface{})
374-
res := make([]string, 0, len(list))
375-
376-
for _, v := range list {
377-
gv := v.(string)
378-
379-
res = append(res, gv)
380-
}
381-
return res
382-
}
383-
384-
func (vd *validator) fromStarLark(v interface{}) interface{} {
385-
switch v := v.(type) {
386-
case starlark.Bool:
387-
return bool(v)
388-
case starlark.Int:
389-
// starlark ints can be signed or unsigned
390-
if i, ok := v.Int64(); ok {
391-
return i
392-
}
393-
if i, ok := v.Uint64(); ok {
394-
return i
395-
}
396-
// buh... maybe > maxint64? Dunno
397-
panic(fmt.Errorf("can't convert starlark.Int %q to int", v))
398-
case starlark.Float:
399-
return float64(v)
400-
case starlark.String:
401-
return string(v)
402-
case *starlark.List:
403-
return convert.FromList(v)
404-
case starlark.Tuple:
405-
return convert.FromTuple(v)
406-
case *starlark.Dict:
407-
return convert.FromDict(v)
408-
case *starlark.Set:
409-
return convert.FromSet(v)
410-
default:
411-
// dunno, hope it's a custom type that the receiver knows how to deal
412-
// with. This can happen with custom-written go types that implement
413-
// starlark.Value.
414-
return v
415-
}
416-
}
417-
418326
// SiteAdminInit initializes the instance with given admin account.
419327
// It returns an authenticated client as the admin for doing e2e testing.
420328
func (vd *validator) siteAdminInit(baseURL, email, username, password string) (*vdClient, error) {
@@ -662,10 +570,11 @@ func (c *vdClient) graphQL(token, query string, variables map[string]interface{}
662570
return nil
663571
}
664572

665-
func (vd *validator) createFirstAdmin(email, username, password string) error {
666-
client, err := vd.signIn(cfg.Endpoint, email, password)
573+
func (vd *validator) createFirstAdmin(vspec *validationSpec) error {
574+
client, err := vd.signIn(cfg.Endpoint, vspec.FirstAdmin.Email, vspec.FirstAdmin.Password)
667575
if err != nil {
668-
client, err = vd.siteAdminInit(cfg.Endpoint, email, username, password)
576+
client, err = vd.siteAdminInit(cfg.Endpoint, vspec.FirstAdmin.Email, vspec.FirstAdmin.Username,
577+
vspec.FirstAdmin.Password)
669578
if err != nil {
670579
return err
671580
}
@@ -681,12 +590,8 @@ func (vd *validator) graphQL(query string, variables map[string]interface{}, tar
681590
}
682591

683592
return (&apiRequest{
684-
query: query,
685-
vars:variables,
593+
query: query,
594+
vars: variables,
686595
result: target,
687596
}).do()
688597
}
689-
690-
func (vd *validator) debug(val interface{}) {
691-
fmt.Printf("%+v\n", val)
692-
}

0 commit comments

Comments
 (0)