forked from evergreen-ci/evergreen
-
Notifications
You must be signed in to change notification settings - Fork 0
/
generate.go
98 lines (86 loc) · 2.66 KB
/
generate.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
package command
import (
"context"
"encoding/json"
"io/ioutil"
"os"
"path/filepath"
"github.com/evergreen-ci/evergreen/model"
"github.com/evergreen-ci/evergreen/rest/client"
"github.com/mitchellh/mapstructure"
"github.com/mongodb/grip"
"github.com/pkg/errors"
)
type generateTask struct {
// Files are a list of JSON documents.
Files []string `mapstructure:"files"`
base
}
func generateTaskFactory() Command { return &generateTask{} }
func (c *generateTask) Name() string { return "generate.tasks" }
func (c *generateTask) ParseParams(params map[string]interface{}) error {
if err := mapstructure.Decode(params, c); err != nil {
return errors.Wrapf(err, "Error decoding %s params", c.Name())
}
if len(c.Files) == 0 {
return errors.Errorf("Must provide at least 1 file to '%s'", c.Name())
}
return nil
}
func (c *generateTask) Execute(ctx context.Context, comm client.Communicator, logger client.LoggerProducer, conf *model.TaskConfig) error {
catcher := grip.NewBasicCatcher()
td := client.TaskData{ID: conf.Task.Id, Secret: conf.Task.Secret}
var jsonBytes [][]byte
for _, fn := range c.Files {
if ctx.Err() != nil {
catcher.Add(ctx.Err())
break
}
data, err := generateTaskForFile(fn, conf)
if err != nil {
catcher.Add(err)
continue
}
jsonBytes = append(jsonBytes, data)
}
if catcher.HasErrors() {
return errors.WithStack(catcher.Resolve())
}
post, err := makeJsonOfAllFiles(jsonBytes)
if err != nil {
return errors.Wrap(err, "problem parsing JSON")
}
return errors.Wrap(comm.GenerateTasks(ctx, td, post), "Problem posting task data")
}
func generateTaskForFile(fn string, conf *model.TaskConfig) ([]byte, error) {
fileLoc := filepath.Join(conf.WorkDir, fn)
if _, err := os.Stat(fileLoc); os.IsNotExist(err) {
return nil, errors.Wrapf(err, "File '%s' does not exist", fn)
}
jsonFile, err := os.Open(fileLoc)
if err != nil {
return nil, errors.Wrapf(err, "Couldn't open file '%s'", fn)
}
defer jsonFile.Close()
var data []byte
data, err = ioutil.ReadAll(jsonFile)
if err != nil {
return nil, errors.Wrapf(err, "Problem reading from file '%s'", fn)
}
return data, nil
}
// makeJsonOfAllFiles creates a single JSON document that is an array of all JSON files. This allows
// us to avoid posting multiple JSON files.
func makeJsonOfAllFiles(jsonBytes [][]byte) ([]json.RawMessage, error) {
catcher := grip.NewBasicCatcher()
post := []json.RawMessage{}
for _, j := range jsonBytes {
jsonRaw := json.RawMessage{}
if err := json.Unmarshal(j, &jsonRaw); err != nil {
catcher.Add(errors.Wrap(err, "error unmarshaling JSON for generate.tasks"))
continue
}
post = append(post, jsonRaw)
}
return post, catcher.Resolve()
}