Updated ByteReader to allow white space and comments on the same line after --- and throw an error if anything else is detected

This commit is contained in:
brianpursley
2021-06-24 21:32:39 -04:00
parent 936ac37a2e
commit 78737f5a38
2 changed files with 94 additions and 2 deletions

View File

@@ -7,6 +7,7 @@ import (
"bytes"
"fmt"
"io"
"regexp"
"sort"
"strings"
@@ -133,6 +134,37 @@ type ByteReader struct {
var _ Reader = &ByteReader{}
// splitDocuments returns a slice of all documents contained in a YAML string. Multiple documents can be divided by the
// YAML document separator (---). It allows for white space and comments to be after the separator on the same line,
// but will return an error if anything else is on the line.
func splitDocuments(s string) ([]string, error) {
docs := make([]string, 0)
if len(s) > 0 {
// The YAML document separator is any line that starts with ---
yamlSeparatorRegexp := regexp.MustCompile(`\n---.*\n`)
// Find all separators, check them for invalid content, and append each document to docs
separatorLocations := yamlSeparatorRegexp.FindAllStringIndex(s, -1)
prev := 0
for i := range separatorLocations {
loc := separatorLocations[i]
separator := s[loc[0]:loc[1]]
// If the next non-whitespace character on the line following the separator is not a comment, return an error
trimmedContentAfterSeparator := strings.TrimSpace(separator[4:])
if len(trimmedContentAfterSeparator) > 0 && trimmedContentAfterSeparator[0] != '#' {
return nil, errors.Errorf("invalid document separator: %s", strings.TrimSpace(separator))
}
docs = append(docs, s[prev:loc[0]])
prev = loc[1]
}
docs = append(docs, s[prev:])
}
return docs, nil
}
func (r *ByteReader) Read() ([]*yaml.RNode, error) {
output := ResourceNodeSlice{}
@@ -144,8 +176,12 @@ func (r *ByteReader) Read() ([]*yaml.RNode, error) {
return nil, errors.Wrap(err)
}
// replace the ending \r\n (line ending used in windows) with \n and then separate by \n---\n
values := strings.Split(strings.ReplaceAll(input.String(), "\r\n", "\n"), "\n---\n")
// Replace the ending \r\n (line ending used in windows) with \n and then split it into multiple YAML documents
// if it contains document separators (---)
values, err := splitDocuments(strings.ReplaceAll(input.String(), "\r\n", "\n"))
if err != nil {
return nil, errors.Wrap(err)
}
index := 0
for i := range values {