1
1
package main
2
2
3
3
import (
4
- "bufio"
5
- "context"
6
4
"errors"
7
5
"net/url"
8
6
"os"
@@ -89,7 +87,7 @@ func validateCoderResourceIconURL(iconURL string) []error {
89
87
return []error {xerrors .New ("icon URL cannot be empty" )}
90
88
}
91
89
92
- errs := []error {}
90
+ var errs []error
93
91
94
92
// If the URL does not have a relative path.
95
93
if ! strings .HasPrefix (iconURL , "." ) && ! strings .HasPrefix (iconURL , "/" ) {
@@ -120,7 +118,7 @@ func validateCoderResourceTags(tags []string) error {
120
118
121
119
// All of these tags are used for the module/template filter controls in the Registry site. Need to make sure they
122
120
// can all be placed in the browser URL without issue.
123
- invalidTags := []string {}
121
+ var invalidTags []string
124
122
for _ , t := range tags {
125
123
if t != url .QueryEscape (t ) {
126
124
invalidTags = append (invalidTags , t )
@@ -133,108 +131,27 @@ func validateCoderResourceTags(tags []string) error {
133
131
return nil
134
132
}
135
133
136
- func validateCoderResourceReadmeBody (body string ) []error {
137
- var errs []error
138
-
139
- trimmed := strings .TrimSpace (body )
140
- // TODO: this may cause unexpected behavior since the errors slice may have a 0 length. Add a test.
141
- errs = append (errs , validateReadmeBody (trimmed )... )
142
-
143
- foundParagraph := false
144
- terraformCodeBlockCount := 0
145
- foundTerraformVersionRef := false
146
-
147
- lineNum := 0
148
- isInsideCodeBlock := false
149
- isInsideTerraform := false
150
-
151
- lineScanner := bufio .NewScanner (strings .NewReader (trimmed ))
152
- for lineScanner .Scan () {
153
- lineNum ++
154
- nextLine := lineScanner .Text ()
155
-
156
- // Code assumes that invalid headers would've already been handled by the base validation function, so we don't
157
- // need to check deeper if the first line isn't an h1.
158
- if lineNum == 1 {
159
- if ! strings .HasPrefix (nextLine , "# " ) {
160
- break
161
- }
162
- continue
163
- }
164
-
165
- if strings .HasPrefix (nextLine , "```" ) {
166
- isInsideCodeBlock = ! isInsideCodeBlock
167
- isInsideTerraform = isInsideCodeBlock && strings .HasPrefix (nextLine , "```tf" )
168
- if isInsideTerraform {
169
- terraformCodeBlockCount ++
170
- }
171
- if strings .HasPrefix (nextLine , "```hcl" ) {
172
- errs = append (errs , xerrors .New ("all .hcl language references must be converted to .tf" ))
173
- }
174
- continue
175
- }
176
-
177
- if isInsideCodeBlock {
178
- if isInsideTerraform {
179
- foundTerraformVersionRef = foundTerraformVersionRef || terraformVersionRe .MatchString (nextLine )
180
- }
181
- continue
182
- }
183
-
184
- // Code assumes that we can treat this case as the end of the "h1 section" and don't need to process any further lines.
185
- if lineNum > 1 && strings .HasPrefix (nextLine , "#" ) {
186
- break
187
- }
188
-
189
- // Code assumes that if we've reached this point, the only other options are:
190
- // (1) empty spaces, (2) paragraphs, (3) HTML, and (4) asset references made via [] syntax.
191
- trimmedLine := strings .TrimSpace (nextLine )
192
- isParagraph := trimmedLine != "" && ! strings .HasPrefix (trimmedLine , "![" ) && ! strings .HasPrefix (trimmedLine , "<" )
193
- foundParagraph = foundParagraph || isParagraph
194
- }
195
-
196
- if terraformCodeBlockCount == 0 {
197
- errs = append (errs , xerrors .New ("did not find Terraform code block within h1 section" ))
198
- } else {
199
- if terraformCodeBlockCount > 1 {
200
- errs = append (errs , xerrors .New ("cannot have more than one Terraform code block in h1 section" ))
201
- }
202
- if ! foundTerraformVersionRef {
203
- errs = append (errs , xerrors .New ("did not find Terraform code block that specifies 'version' field" ))
204
- }
205
- }
206
- if ! foundParagraph {
207
- errs = append (errs , xerrors .New ("did not find paragraph within h1 section" ))
208
- }
209
- if isInsideCodeBlock {
210
- errs = append (errs , xerrors .New ("code blocks inside h1 section do not all terminate before end of file" ))
134
+ func validateCoderResourceFrontmatter (resourceType string , filePath string , fm coderResourceFrontmatter ) []error {
135
+ if ! slices .Contains (supportedResourceTypes , resourceType ) {
136
+ return []error {xerrors .Errorf ("cannot process unknown resource type %q" , resourceType )}
211
137
}
212
138
213
- return errs
214
- }
215
-
216
- func validateCoderResourceReadme (rm coderResourceReadme ) []error {
217
139
var errs []error
218
-
219
- for _ , err := range validateCoderResourceReadmeBody (rm .body ) {
220
- errs = append (errs , addFilePathToError (rm .filePath , err ))
221
- }
222
-
223
- if err := validateCoderResourceDisplayName (rm .frontmatter .DisplayName ); err != nil {
224
- errs = append (errs , addFilePathToError (rm .filePath , err ))
140
+ if err := validateCoderResourceDisplayName (fm .DisplayName ); err != nil {
141
+ errs = append (errs , addFilePathToError (filePath , err ))
225
142
}
226
- if err := validateCoderResourceDescription (rm . frontmatter .Description ); err != nil {
227
- errs = append (errs , addFilePathToError (rm . filePath , err ))
143
+ if err := validateCoderResourceDescription (fm .Description ); err != nil {
144
+ errs = append (errs , addFilePathToError (filePath , err ))
228
145
}
229
- if err := validateCoderResourceTags (rm . frontmatter .Tags ); err != nil {
230
- errs = append (errs , addFilePathToError (rm . filePath , err ))
146
+ if err := validateCoderResourceTags (fm .Tags ); err != nil {
147
+ errs = append (errs , addFilePathToError (filePath , err ))
231
148
}
232
149
233
- for _ , err := range validateCoderResourceIconURL (rm . frontmatter .IconURL ) {
234
- errs = append (errs , addFilePathToError (rm . filePath , err ))
150
+ for _ , err := range validateCoderResourceIconURL (fm .IconURL ) {
151
+ errs = append (errs , addFilePathToError (filePath , err ))
235
152
}
236
- for _ , err := range validateSupportedOperatingSystems (rm . frontmatter .OperatingSystems ) {
237
- errs = append (errs , addFilePathToError (rm . filePath , err ))
153
+ for _ , err := range validateSupportedOperatingSystems (fm .OperatingSystems ) {
154
+ errs = append (errs , addFilePathToError (filePath , err ))
238
155
}
239
156
240
157
return errs
@@ -248,7 +165,7 @@ func parseCoderResourceReadme(resourceType string, rm readme) (coderResourceRead
248
165
249
166
keyErrs := validateFrontmatterYamlKeys (fm , supportedCoderResourceStructKeys )
250
167
if len (keyErrs ) != 0 {
251
- remapped := []error {}
168
+ var remapped []error
252
169
for _ , e := range keyErrs {
253
170
remapped = append (remapped , addFilePathToError (rm .filePath , e ))
254
171
}
@@ -268,7 +185,11 @@ func parseCoderResourceReadme(resourceType string, rm readme) (coderResourceRead
268
185
}, nil
269
186
}
270
187
271
- func parseCoderResourceReadmeFiles (resourceType string , rms []readme ) (map [string ]coderResourceReadme , error ) {
188
+ func parseCoderResourceReadmeFiles (resourceType string , rms []readme ) ([]coderResourceReadme , error ) {
189
+ if ! slices .Contains (supportedResourceTypes , resourceType ) {
190
+ return nil , xerrors .Errorf ("cannot process unknown resource type %q" , resourceType )
191
+ }
192
+
272
193
resources := map [string ]coderResourceReadme {}
273
194
var yamlParsingErrs []error
274
195
for _ , rm := range rms {
@@ -287,30 +208,27 @@ func parseCoderResourceReadmeFiles(resourceType string, rms []readme) (map[strin
287
208
}
288
209
}
289
210
290
- yamlValidationErrors := []error {}
291
- for _ , readme := range resources {
292
- errs := validateCoderResourceReadme (readme )
293
- if len (errs ) > 0 {
294
- yamlValidationErrors = append (yamlValidationErrors , errs ... )
295
- }
211
+ var serialized []coderResourceReadme
212
+ for _ , r := range resources {
213
+ serialized = append (serialized , r )
296
214
}
297
- if len (yamlValidationErrors ) != 0 {
298
- return nil , validationPhaseError {
299
- phase : validationPhaseReadme ,
300
- errors : yamlValidationErrors ,
301
- }
302
- }
303
-
304
- return resources , nil
215
+ slices .SortFunc (serialized , func (r1 coderResourceReadme , r2 coderResourceReadme ) int {
216
+ return strings .Compare (r1 .filePath , r2 .filePath )
217
+ })
218
+ return serialized , nil
305
219
}
306
220
307
221
// Todo: Need to beef up this function by grabbing each image/video URL from
308
222
// the body's AST.
309
- func validateCoderResourceRelativeURLs (_ map [ string ]coderResourceReadme ) error {
223
+ func validateCoderResourceRelativeURLs (_ [ ]coderResourceReadme ) error {
310
224
return nil
311
225
}
312
226
313
227
func aggregateCoderResourceReadmeFiles (resourceType string ) ([]readme , error ) {
228
+ if ! slices .Contains (supportedResourceTypes , resourceType ) {
229
+ return nil , xerrors .Errorf ("cannot process unknown resource type %q" , resourceType )
230
+ }
231
+
314
232
registryFiles , err := os .ReadDir (rootRegistryPath )
315
233
if err != nil {
316
234
return nil , err
@@ -359,27 +277,3 @@ func aggregateCoderResourceReadmeFiles(resourceType string) ([]readme, error) {
359
277
}
360
278
return allReadmeFiles , nil
361
279
}
362
-
363
- func validateAllCoderResourceFilesOfType (resourceType string ) error {
364
- if ! slices .Contains (supportedResourceTypes , resourceType ) {
365
- return xerrors .Errorf ("resource type %q is not part of supported list [%s]" , resourceType , strings .Join (supportedResourceTypes , ", " ))
366
- }
367
-
368
- allReadmeFiles , err := aggregateCoderResourceReadmeFiles (resourceType )
369
- if err != nil {
370
- return err
371
- }
372
-
373
- logger .Info (context .Background (), "processing README files" , "num_files" , len (allReadmeFiles ))
374
- resources , err := parseCoderResourceReadmeFiles (resourceType , allReadmeFiles )
375
- if err != nil {
376
- return err
377
- }
378
- logger .Info (context .Background (), "processed README files as valid Coder resources" , "num_files" , len (resources ), "type" , resourceType )
379
-
380
- if err := validateCoderResourceRelativeURLs (resources ); err != nil {
381
- return err
382
- }
383
- logger .Info (context .Background (), "all relative URLs for READMEs are valid" , "type" , resourceType )
384
- return nil
385
- }
0 commit comments