@@ -76,15 +76,6 @@ type Proposal struct {
76
76
Contents string `json:"markdown" yaml:"-"`
77
77
}
78
78
79
- func (p * Proposal ) Validate () error {
80
- v := validator .New ()
81
- if err := v .Struct (p ); err != nil {
82
- return errors .Wrap (err , "running validation" )
83
- }
84
-
85
- return nil
86
- }
87
-
88
79
func (p * Proposal ) IsMissingMilestone () bool {
89
80
return p .LatestMilestone == ""
90
81
}
@@ -153,16 +144,75 @@ func (k *KEPHandler) Parse(in io.Reader) (*Proposal, error) {
153
144
return kep , errors .Wrap (err , "unmarshalling YAML" )
154
145
}
155
146
156
- if valErr := kep . Validate ( ); valErr != nil {
157
- k .Errors = append (k .Errors , errors . Wrap ( valErr , "validating KEP" ) )
158
- return kep , errors . Wrap ( valErr , "validating KEP" )
147
+ if err := k . validateStruct ( kep ); err != nil {
148
+ k .Errors = append (k .Errors , err )
149
+ return kep , fmt . Errorf ( "validating KEP: %w" , err )
159
150
}
160
151
161
152
kep .ID = hash (kep .OwningSIG + ":" + kep .Title )
162
153
163
154
return kep , nil
164
155
}
165
156
157
+ // validateStruct returns an error if the given Proposal has invalid fields
158
+ // as defined by struct tags, or nil if there are no invalid fields
159
+ func (k * KEPHandler ) validateStruct (p * Proposal ) error {
160
+ v := validator .New ()
161
+ return v .Struct (p )
162
+ }
163
+
164
+ // validateGroups returns errors for each invalid group (e.g. SIG) in the given
165
+ // Proposal, or nil if there are no invalid groups
166
+ func (k * KEPHandler ) validateGroups (p * Proposal ) []error {
167
+ var errs []error
168
+ validGroups := make (map [string ]bool )
169
+ for _ , g := range k .Groups {
170
+ validGroups [g ] = true
171
+ }
172
+ for _ , g := range p .ParticipatingSIGs {
173
+ if _ , ok := validGroups [g ]; ! ok {
174
+ errs = append (errs , fmt .Errorf ("invalid participating-sig: %s" , g ))
175
+ }
176
+ }
177
+ if _ , ok := validGroups [p .OwningSIG ]; ! ok {
178
+ errs = append (errs , fmt .Errorf ("invalid owning-sig: %s" , p .OwningSIG ))
179
+ }
180
+ return errs
181
+ }
182
+
183
+ // validatePRRApprovers returns errors for each invalid PRR Approver in the
184
+ // given Proposal, or nil if there are no invalid PRR Approvers
185
+ func (k * KEPHandler ) validatePRRApprovers (p * Proposal ) []error {
186
+ var errs []error
187
+ validPRRApprovers := make (map [string ]bool )
188
+ for _ , a := range k .PRRApprovers {
189
+ validPRRApprovers [a ] = true
190
+ }
191
+ for _ , a := range p .PRRApprovers {
192
+ if _ , ok := validPRRApprovers [a ]; ! ok {
193
+ errs = append (errs , fmt .Errorf ("invalid prr-approver: %s" , a ))
194
+ }
195
+ }
196
+ return errs
197
+ }
198
+
199
+ // Validate returns errors for each reason the given proposal is invalid,
200
+ // or nil if it is valid
201
+ func (k * KEPHandler ) Validate (p * Proposal ) []error {
202
+ var allErrs []error
203
+
204
+ if err := k .validateStruct (p ); err != nil {
205
+ allErrs = append (allErrs , fmt .Errorf ("struct-based validation: %w" , err ))
206
+ }
207
+ if errs := k .validateGroups (p ); errs != nil {
208
+ allErrs = append (allErrs , errs ... )
209
+ }
210
+ if errs := k .validatePRRApprovers (p ); errs != nil {
211
+ allErrs = append (allErrs , errs ... )
212
+ }
213
+ return allErrs
214
+ }
215
+
166
216
type Milestone struct {
167
217
Alpha string `json:"alpha" yaml:"alpha"`
168
218
Beta string `json:"beta" yaml:"beta"`
0 commit comments