@@ -137,8 +137,90 @@ func validateCoderModuleReadmeBody(body string) []error {
137137 var errs []error
138138
139139 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 )... )
140+ if baseErrs := validateReadmeBody (trimmed ); len (baseErrs ) != 0 {
141+ errs = append (errs , baseErrs ... )
142+ }
143+
144+ foundParagraph := false
145+ terraformCodeBlockCount := 0
146+ foundTerraformVersionRef := false
147+
148+ lineNum := 0
149+ isInsideCodeBlock := false
150+ isInsideTerraform := false
151+
152+ lineScanner := bufio .NewScanner (strings .NewReader (trimmed ))
153+ for lineScanner .Scan () {
154+ lineNum ++
155+ nextLine := lineScanner .Text ()
156+
157+ // Code assumes that invalid headers would've already been handled by the base validation function, so we don't
158+ // need to check deeper if the first line isn't an h1.
159+ if lineNum == 1 {
160+ if ! strings .HasPrefix (nextLine , "# " ) {
161+ break
162+ }
163+ continue
164+ }
165+
166+ if strings .HasPrefix (nextLine , "```" ) {
167+ isInsideCodeBlock = ! isInsideCodeBlock
168+ isInsideTerraform = isInsideCodeBlock && strings .HasPrefix (nextLine , "```tf" )
169+ if isInsideTerraform {
170+ terraformCodeBlockCount ++
171+ }
172+ if strings .HasPrefix (nextLine , "```hcl" ) {
173+ errs = append (errs , xerrors .New ("all .hcl language references must be converted to .tf" ))
174+ }
175+ continue
176+ }
177+
178+ if isInsideCodeBlock {
179+ if isInsideTerraform {
180+ foundTerraformVersionRef = foundTerraformVersionRef || terraformVersionRe .MatchString (nextLine )
181+ }
182+ continue
183+ }
184+
185+ // Code assumes that we can treat this case as the end of the "h1 section" and don't need to process any further lines.
186+ if lineNum > 1 && strings .HasPrefix (nextLine , "#" ) {
187+ break
188+ }
189+
190+ // Code assumes that if we've reached this point, the only other options are:
191+ // (1) empty spaces, (2) paragraphs, (3) HTML, and (4) asset references made via [] syntax.
192+ trimmedLine := strings .TrimSpace (nextLine )
193+ isParagraph := trimmedLine != "" && ! strings .HasPrefix (trimmedLine , "![" ) && ! strings .HasPrefix (trimmedLine , "<" )
194+ foundParagraph = foundParagraph || isParagraph
195+ }
196+
197+ if terraformCodeBlockCount == 0 {
198+ errs = append (errs , xerrors .New ("did not find Terraform code block within h1 section" ))
199+ } else {
200+ if terraformCodeBlockCount > 1 {
201+ errs = append (errs , xerrors .New ("cannot have more than one Terraform code block in h1 section" ))
202+ }
203+ if ! foundTerraformVersionRef {
204+ errs = append (errs , xerrors .New ("did not find Terraform code block that specifies 'version' field" ))
205+ }
206+ }
207+ if ! foundParagraph {
208+ errs = append (errs , xerrors .New ("did not find paragraph within h1 section" ))
209+ }
210+ if isInsideCodeBlock {
211+ errs = append (errs , xerrors .New ("code blocks inside h1 section do not all terminate before end of file" ))
212+ }
213+
214+ return errs
215+ }
216+
217+ func validateCoderTemplateReadmeBody (body string ) []error {
218+ var errs []error
219+
220+ trimmed := strings .TrimSpace (body )
221+ if baseErrs := validateReadmeBody (trimmed ); len (baseErrs ) != 0 {
222+ errs = append (errs , baseErrs ... )
223+ }
142224
143225 foundParagraph := false
144226 terraformCodeBlockCount := 0
@@ -269,10 +351,10 @@ func validateAllCoderModuleReadmes(resources []coderResourceReadme) error {
269351
270352func validateCoderTemplateReadme (rm coderResourceReadme ) []error {
271353 var errs []error
272- // for _, err := range validateCoderResourceReadmeBody (rm.body) {
273- // errs = append(errs, addFilePathToError(rm.filePath, err))
274- // }
275- if fmErrs := validateCoderResourceFrontmatter ("modules " , rm .filePath , rm .frontmatter ); len (fmErrs ) != 0 {
354+ for _ , err := range validateCoderTemplateReadmeBody (rm .body ) {
355+ errs = append (errs , addFilePathToError (rm .filePath , err ))
356+ }
357+ if fmErrs := validateCoderResourceFrontmatter ("templates " , rm .filePath , rm .frontmatter ); len (fmErrs ) != 0 {
276358 errs = append (errs , fmErrs ... )
277359 }
278360 return errs
0 commit comments