Skip to content

Commit 85743cd

Browse files
committed
minor style changes in corderresources.go
Signed-off-by: Callum Styan <[email protected]>
1 parent ed629c1 commit 85743cd

File tree

1 file changed

+39
-43
lines changed

1 file changed

+39
-43
lines changed

cmd/readmevalidation/coderresources.go

Lines changed: 39 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,14 @@ import (
1515
"gopkg.in/yaml.v3"
1616
)
1717

18-
var supportedResourceTypes = []string{"modules", "templates"}
18+
var (
19+
supportedResourceTypes = []string{"modules", "templates"}
20+
21+
// TODO: This is a holdover from the validation logic used by the Coder Modules repo. It gives us some assurance, but
22+
// realistically, we probably want to parse any Terraform code snippets, and make some deeper guarantees about how it's
23+
// structured. Just validating whether it *can* be parsed as Terraform would be a big improvement.
24+
terraformVersionRe = regexp.MustCompile("^\\s*\\bversion\\s+=")
25+
)
1926

2027
type coderResourceFrontmatter struct {
2128
Description string `yaml:"description"`
@@ -25,9 +32,8 @@ type coderResourceFrontmatter struct {
2532
Tags []string `yaml:"tags"`
2633
}
2734

28-
// coderResourceReadme represents a README describing a Terraform resource used
29-
// to help create Coder workspaces. As of 2025-04-15, this encapsulates both
30-
// Coder Modules and Coder Templates
35+
// coderResourceReadme represents a README describing a Terraform resource used to help create Coder workspaces.
36+
// As of 2025-04-15, this encapsulates both Coder Modules and Coder Templates.
3137
type coderResourceReadme struct {
3238
resourceType string
3339
filePath string
@@ -50,35 +56,33 @@ func validateCoderResourceDescription(description string) error {
5056
}
5157

5258
func validateCoderResourceIconURL(iconURL string) []error {
53-
problems := []error{}
54-
5559
if iconURL == "" {
56-
problems = append(problems, errors.New("icon URL cannot be empty"))
57-
return problems
60+
return []error{errors.New("icon URL cannot be empty")}
5861
}
5962

63+
errs := []error{}
64+
6065
isAbsoluteURL := !strings.HasPrefix(iconURL, ".") && !strings.HasPrefix(iconURL, "/")
6166
if isAbsoluteURL {
6267
if _, err := url.ParseRequestURI(iconURL); err != nil {
63-
problems = append(problems, errors.New("absolute icon URL is not correctly formatted"))
68+
errs = append(errs, errors.New("absolute icon URL is not correctly formatted"))
6469
}
6570
if strings.Contains(iconURL, "?") {
66-
problems = append(problems, errors.New("icon URLs cannot contain query parameters"))
71+
errs = append(errs, errors.New("icon URLs cannot contain query parameters"))
6772
}
68-
return problems
73+
return errs
6974
}
7075

71-
// Would normally be skittish about having relative paths like this, but it
72-
// should be safe because we have guarantees about the structure of the
73-
// repo, and where this logic will run
76+
// Would normally be skittish about having relative paths like this, but it should be safe because we have guarantees
77+
// about the structure of the repo, and where this logic will run.
7478
isPermittedRelativeURL := strings.HasPrefix(iconURL, "./") ||
7579
strings.HasPrefix(iconURL, "/") ||
7680
strings.HasPrefix(iconURL, "../../../../.icons")
7781
if !isPermittedRelativeURL {
78-
problems = append(problems, fmt.Errorf("relative icon URL %q must either be scoped to that module's directory, or the top-level /.icons directory (this can usually be done by starting the path with \"../../../.icons\")", iconURL))
82+
errs = append(errs, fmt.Errorf("relative icon URL %q must either be scoped to that module's directory, or the top-level /.icons directory (this can usually be done by starting the path with \"../../../.icons\")", iconURL))
7983
}
8084

81-
return problems
85+
return errs
8286
}
8387

8488
func validateCoderResourceTags(tags []string) error {
@@ -89,9 +93,8 @@ func validateCoderResourceTags(tags []string) error {
8993
return nil
9094
}
9195

92-
// All of these tags are used for the module/template filter controls in the
93-
// Registry site. Need to make sure they can all be placed in the browser
94-
// URL without issue
96+
// All of these tags are used for the module/template filter controls in the Registry site. Need to make sure they
97+
// can all be placed in the browser URL without issue.
9598
invalidTags := []string{}
9699
for _, t := range tags {
97100
if t != url.QueryEscape(t) {
@@ -105,16 +108,11 @@ func validateCoderResourceTags(tags []string) error {
105108
return nil
106109
}
107110

108-
// Todo: This is a holdover from the validation logic used by the Coder Modules
109-
// repo. It gives us some assurance, but realistically, we probably want to
110-
// parse any Terraform code snippets, and make some deeper guarantees about how
111-
// it's structured. Just validating whether it *can* be parsed as Terraform
112-
// would be a big improvement.
113-
var terraformVersionRe = regexp.MustCompile("^\\s*\\bversion\\s+=")
114-
115111
func validateCoderResourceReadmeBody(body string) []error {
116-
trimmed := strings.TrimSpace(body)
117112
var errs []error
113+
114+
trimmed := strings.TrimSpace(body)
115+
// TODO: this may cause unexpected behaviour since the errors slice may have a 0 length. Add a test.
118116
errs = append(errs, validateReadmeBody(trimmed)...)
119117

120118
foundParagraph := false
@@ -124,15 +122,15 @@ func validateCoderResourceReadmeBody(body string) []error {
124122
lineNum := 0
125123
isInsideCodeBlock := false
126124
isInsideTerraform := false
125+
nextLine := ""
127126

128127
lineScanner := bufio.NewScanner(strings.NewReader(trimmed))
129128
for lineScanner.Scan() {
130129
lineNum++
131-
nextLine := lineScanner.Text()
130+
nextLine = lineScanner.Text()
132131

133-
// Code assumes that invalid headers would've already been handled by
134-
// the base validation function, so we don't need to check deeper if the
135-
// first line isn't an h1
132+
// Code assumes that invalid headers would've already been handled by the base validation function, so we don't
133+
// need to check deeper if the first line isn't an h1.
136134
if lineNum == 1 {
137135
if !strings.HasPrefix(nextLine, "# ") {
138136
break
@@ -159,15 +157,13 @@ func validateCoderResourceReadmeBody(body string) []error {
159157
continue
160158
}
161159

162-
// Code assumes that we can treat this case as the end of the "h1
163-
// section" and don't need to process any further lines
160+
// Code assumes that we can treat this case as the end of the "h1 section" and don't need to process any further lines.
164161
if lineNum > 1 && strings.HasPrefix(nextLine, "#") {
165162
break
166163
}
167164

168-
// Code assumes that if we've reached this point, the only other options
169-
// are: (1) empty spaces, (2) paragraphs, (3) HTML, and (4) asset
170-
// references made via [] syntax
165+
// Code assumes that if we've reached this point, the only other options are:
166+
// (1) empty spaces, (2) paragraphs, (3) HTML, and (4) asset references made via [] syntax.
171167
trimmedLine := strings.TrimSpace(nextLine)
172168
isParagraph := trimmedLine != "" && !strings.HasPrefix(trimmedLine, "![") && !strings.HasPrefix(trimmedLine, "<")
173169
foundParagraph = foundParagraph || isParagraph
@@ -257,9 +253,9 @@ func parseCoderResourceReadmeFiles(resourceType string, rms []readme) (map[strin
257253

258254
yamlValidationErrors := []error{}
259255
for _, readme := range resources {
260-
errors := validateCoderResourceReadme(readme)
261-
if len(errors) > 0 {
262-
yamlValidationErrors = append(yamlValidationErrors, errors...)
256+
errs := validateCoderResourceReadme(readme)
257+
if len(errs) > 0 {
258+
yamlValidationErrors = append(yamlValidationErrors, errs...)
263259
}
264260
}
265261
if len(yamlValidationErrors) != 0 {
@@ -272,7 +268,7 @@ func parseCoderResourceReadmeFiles(resourceType string, rms []readme) (map[strin
272268
return resources, nil
273269
}
274270

275-
// Todo: Need to beef up this function by grabbing each image/video URL from
271+
// TODO: Need to beef up this function by grabbing each image/video URL from
276272
// the body's AST
277273
func validateCoderResourceRelativeUrls(resources map[string]coderResourceReadme) error {
278274
return nil
@@ -286,13 +282,14 @@ func aggregateCoderResourceReadmeFiles(resourceType string) ([]readme, error) {
286282

287283
var allReadmeFiles []readme
288284
var errs []error
285+
var resourceDirs []os.DirEntry
289286
for _, rf := range registryFiles {
290287
if !rf.IsDir() {
291288
continue
292289
}
293290

294291
resourceRootPath := path.Join(rootRegistryPath, rf.Name(), resourceType)
295-
resourceDirs, err := os.ReadDir(resourceRootPath)
292+
resourceDirs, err = os.ReadDir(resourceRootPath)
296293
if err != nil {
297294
if !errors.Is(err, os.ErrNotExist) {
298295
errs = append(errs, err)
@@ -345,8 +342,7 @@ func validateAllCoderResourceFilesOfType(resourceType string) error {
345342
}
346343
logger.Info(context.Background(), "Processed README files as valid Coder resources", "num_files", len(resources), "type", resourceType)
347344

348-
err = validateCoderResourceRelativeUrls(resources)
349-
if err != nil {
345+
if err = validateCoderResourceRelativeUrls(resources); err != nil {
350346
return err
351347
}
352348
logger.Info(context.Background(), "All relative URLs for READMEs are valid", "type", resourceType)

0 commit comments

Comments
 (0)