forked from c1ay/gnostic
/
openapi-validator.go
180 lines (162 loc) · 5.67 KB
/
openapi-validator.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
package linter
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"strings"
"google.golang.org/protobuf/proto"
)
//The Lint struct is used to parse the structured json data from the IBM linter output.
//Documentation for IBM's openapi-validator results: https://github.com/IBM/openapi-validator#validation-results
type IBMLint struct {
LinterErrors ErrorResult `json:"errors"`
LinterWarnings WarningResult `json:"warnings"`
}
type ErrorResult struct {
Parameters []EMessage `json:"parameters-ibm"`
PathsIBM []EMessage `json:"paths-ibm"`
Paths []WMessage `json:"paths"`
Schemas []EMessage `json:"schema-ibm"`
FormData []WMessage `json:"form-data"`
WalkerIBM []EMessage `json:"walker-ibm"`
}
type WarningResult struct {
OperationID []WMessage `json:"operation-ids"`
Operations []WMessage `json:"operation"`
OperationsShared []WMessage `json:"operations-shared"`
Refs []WMessage `json:"refs"`
Schemas []EMessage `json:"schema-ibm"`
PathsIBM []EMessage `json:"paths-ibm"`
WalkerIBM []EMessage `json:"walker-ibm"`
CircularIBM []WMessage `json:"circular-references-ibm"`
Responses []EMessage `json:"responses"`
ParametersIBM []EMessage `json:"parameters-ibm"`
}
type EMessage struct {
Path []string `json:"path"`
Message string `json:"message"`
Line int `json:"line"`
}
type WMessage struct {
Path string `json:"path"`
Message string `json:"message"`
Line int `json:"line"`
}
// writePb takes a Linter proto structure, marshals the data and saves it to
// the "linterResults.pb" file in the current working directory.
func writePb(v *Linter) {
bytes, err := proto.Marshal(v)
if err != nil {
panic(err)
}
err = ioutil.WriteFile("linterResults.pb", bytes, 0644)
if err != nil {
panic(err)
}
}
// addToMessages creates a new Message struct given a message type, message, path
// and line. The new struct is then returned.
func addToMessages(mtype string, message string, path []string, line int) *Message {
temp := &Message{
Type: mtype,
Message: message,
Keys: path,
Line: int32(line),
}
return temp
}
// fillMessageProtoStructureIBM is used to create a slice of messages
// from the results of IBM's openapi-validator output.
func fillMessageProtoStructureIBM(lint IBMLint) []*Message {
messages := make([]*Message, 0)
for _, v := range lint.LinterErrors.Parameters {
temp := addToMessages("Error", v.Message, v.Path, v.Line)
messages = append(messages, temp)
}
for _, v := range lint.LinterErrors.PathsIBM {
temp := addToMessages("Error", v.Message, v.Path, v.Line)
messages = append(messages, temp)
}
for _, v := range lint.LinterErrors.Paths {
temp := addToMessages("Error", v.Message, strings.Split(v.Path, "."), v.Line)
messages = append(messages, temp)
}
for _, v := range lint.LinterErrors.Schemas {
temp := addToMessages("Error", v.Message, v.Path, v.Line)
messages = append(messages, temp)
}
for _, v := range lint.LinterErrors.FormData {
temp := addToMessages("Error", v.Message, strings.Split(v.Path, "."), v.Line)
messages = append(messages, temp)
}
for _, v := range lint.LinterErrors.WalkerIBM {
temp := addToMessages("Error", v.Message, v.Path, v.Line)
messages = append(messages, temp)
}
for _, v := range lint.LinterWarnings.OperationID {
temp := addToMessages("Warning", v.Message, strings.Split(v.Path, "."), v.Line)
messages = append(messages, temp)
}
for _, v := range lint.LinterWarnings.OperationsShared {
temp := addToMessages("Warning", v.Message, strings.Split(v.Path, "."), v.Line)
messages = append(messages, temp)
}
for _, v := range lint.LinterWarnings.Refs {
temp := addToMessages("Warning", v.Message, strings.Split(v.Path, "."), v.Line)
messages = append(messages, temp)
}
for _, v := range lint.LinterWarnings.Schemas {
temp := addToMessages("Warning", v.Message, v.Path, v.Line)
messages = append(messages, temp)
}
for _, v := range lint.LinterWarnings.PathsIBM {
temp := addToMessages("Warning", v.Message, v.Path, v.Line)
messages = append(messages, temp)
}
for _, v := range lint.LinterWarnings.WalkerIBM {
temp := addToMessages("Warning", v.Message, v.Path, v.Line)
messages = append(messages, temp)
}
for _, v := range lint.LinterWarnings.CircularIBM {
temp := addToMessages("Warning", v.Message, strings.Split(v.Path, "."), v.Line)
messages = append(messages, temp)
}
for _, v := range lint.LinterWarnings.Operations {
temp := addToMessages("Warning", v.Message, strings.Split(v.Path, "."), v.Line)
messages = append(messages, temp)
}
for _, v := range lint.LinterWarnings.Responses {
temp := addToMessages("Warning", v.Message, v.Path, v.Line)
messages = append(messages, temp)
}
for _, v := range lint.LinterWarnings.ParametersIBM {
temp := addToMessages("Warning", v.Message, v.Path, v.Line)
messages = append(messages, temp)
}
return messages
}
// openAndReadJSON takes the name of the filename that contains the linter results
// from the openapi-validator and parses it into the linter struct
func openAndReadJSON(filename string) IBMLint {
jsonFile, err := os.Open(filename)
if err != nil {
fmt.Println(err)
}
defer jsonFile.Close()
byteValue, _ := ioutil.ReadAll(jsonFile)
var lint IBMLint
json.Unmarshal(byteValue, &lint)
return lint
}
// LintOpenapiValidator functions serves as a linter results translater. The function takes the filename
// which contains the json results of IBM's openapi-validator and creates a new instance of
// the linter struct using the JSON data.
func LintOpenAPIValidator(filename string) {
lint := openAndReadJSON(filename)
messages := fillMessageProtoStructureIBM(lint)
linterResult := &Linter{
Messages: messages,
}
writePb(linterResult)
}