-
Notifications
You must be signed in to change notification settings - Fork 6
/
dinghy.go
172 lines (149 loc) · 4.83 KB
/
dinghy.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
package cmd
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"github.com/armory-io/arm/pkg"
"github.com/armory/dinghy/pkg/cache"
"github.com/armory/dinghy/pkg/dinghyfile"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"io/ioutil"
"os"
"path/filepath"
)
// dinghyCmd represents the dinghy command
var dinghyCmd = &cobra.Command{
Use: "dinghy",
Short: "Run dinghy subcommands",
}
var renderCmd = &cobra.Command{
Use: "render [dinghyfile]",
Short: "render a dinghyfile",
Run: func(cmd *cobra.Command, args []string) {
_, err := dinghyRender(args)
if err != nil {
os.Exit(1)
}
},
}
func processRawData(rawDataPath string) map[string]interface{} {
if rawDataPath != "" {
log.Info("Reading rawdata file")
rawData, err := ioutil.ReadFile(rawDataPath)
if err != nil {
log.Error("Invalid rawdata json file path")
} else {
log.Info("Parsing rawdata json")
rawPushData := make(map[string]interface{})
err = json.Unmarshal([]byte(rawData), &rawPushData)
if err != nil {
log.Error("Invalid rawData json file")
}
return rawPushData
}
}
return nil
}
func init() {
renderCmd.Flags().String("modules", "", "local path to the dinghy modules repository")
renderCmd.Flags().String("rawdata", "", "optional rawdata json in case is needed")
renderCmd.Flags().String("output", "", "output json rendered as it will be rendered by dinghy")
dinghyCmd.AddCommand(renderCmd)
rootCmd.AddCommand(dinghyCmd)
viper.BindPFlags(renderCmd.Flags())
}
func dinghyRender(args []string) (string, error) {
log := initLog()
log.Info("Checking dinghyfile")
var file string
if len(args) > 0 {
file = args[0]
} else {
log.Error("No dinghy file was entered, please refer to documentation or execute this command with --help")
os.Exit(1)
}
downloader := pkg.LocalDownloader{}
builder := &dinghyfile.PipelineBuilder{
Downloader: downloader,
Depman: cache.NewMemoryCache(),
TemplateRepo: viper.GetString("modules"),
TemplateOrg: "templateOrg",
Logger: log.WithField("arm-cli-test", ""),
Client: nil,
EventClient: &dinghyfile.EventsTestClient{},
Parser: &dinghyfile.DinghyfileParser{},
DinghyfileName: filepath.Base(file),
Ums: []dinghyfile.Unmarshaller{&dinghyfile.DinghyJsonUnmarshaller{}},
}
//Process rawData and add it to the builder
builder.PushRaw = processRawData(viper.GetString("rawdata"))
log.Info("Parsing dinghyfile")
builder.Parser.SetBuilder(builder)
absFile, err := filepath.Abs(file)
if err != nil {
log.Errorf("Invalid path for dinghyfile: %v", err)
return "", fmt.Errorf("Invalid path for dinghyfile: %v", err)
}
repoFolder := fmt.Sprint(filepath.Dir(absFile))
fileName := fmt.Sprint(filepath.Base(absFile))
out, err := builder.Parser.Parse( "templateOrg", repoFolder, fileName, "", nil)
if err != nil {
log.Errorf("Parsing dinghyfile failed: %s", err )
return "", fmt.Errorf("Parsing dinghyfile failed: %s", err )
} else {
log.Info("Parsed dinghyfile")
if !json.Valid(out.Bytes()){
log.Info("Output:\n")
fmt.Println(out.String())
log.Error("The result is not a valid JSON Object, please fix your dinghyfile")
return "", errors.New(("The result is not a valid JSON Object, please fix your dinghyfile"))
} else {
log.Info("Parsing final dinghyfile to struct for validation")
d, err := dinghyfileStruct(builder, out)
if err != nil {
log.Errorf("Parsing to struct failed: %v", err)
return "", fmt.Errorf("Parsing to struct failed: %v", err)
}
errValidation := builder.ValidatePipelines(d, out.Bytes())
if errValidation != nil {
log.Error("Final Dinghyfile failed validations, please correct them and retry")
return "", errors.New("Final Dinghyfile failed validations, please correct them and retry")
}
//Save file if output exists
//Log output
var outIndent bytes.Buffer
json.Indent(&outIndent, out.Bytes(), "", " ")
saveOutputFile(viper.GetString("output"), outIndent)
log.Info("Output:\n")
fmt.Println(outIndent.String())
log.Info("Final dinghyfile is a valid JSON Object.")
return outIndent.String(), nil
}
}
}
func dinghyfileStruct(builder *dinghyfile.PipelineBuilder, out *bytes.Buffer) (dinghyfile.Dinghyfile, error) {
d := dinghyfile.NewDinghyfile()
parseErrs := 0
var err error
for _, ums := range builder.Ums {
log.Info("Parsing Dinghyfile to struct for validation")
if errmarshal := ums.Unmarshal(out.Bytes(), &d); errmarshal != nil {
err = errmarshal
log.Warnf("Cannot create Dinghyfile struct because of malformed syntax: %s", err.Error())
parseErrs++
continue
}
}
return d, err
}
func saveOutputFile(outputPath string, content bytes.Buffer) {
if outputPath != "" {
log.Info("Saving output file")
err := ioutil.WriteFile(outputPath, content.Bytes(), 0644)
if err != nil {
log.Error("Failed to save output file")
}
}
}