Skip to content

Commit

Permalink
Updated ByteReader to allow white space and comments on the same line…
Browse files Browse the repository at this point in the history
… after --- and throw an error if anything else is detected
  • Loading branch information
brianpursley committed Jun 25, 2021
1 parent 936ac37 commit 78737f5
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 2 deletions.
40 changes: 38 additions & 2 deletions kyaml/kio/byteio_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"bytes"
"fmt"
"io"
"regexp"
"sort"
"strings"

Expand Down Expand Up @@ -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{}

Expand All @@ -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 {
Expand Down
56 changes: 56 additions & 0 deletions kyaml/kio/byteio_reader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,62 @@ metadata:
},
instance: ByteReader{},
},

//
//
//
{
name: "white_space_after_document_separator_should_be_ignored",
input: `
a: b
---
c: d
`,
expectedItems: []string{
`
a: b
`,
`
c: d
`,
},
instance: ByteReader{OmitReaderAnnotations: true},
},

//
//
//
{
name: "comment_after_document_separator_should_be_ignored",
input: `
a: b
--- #foo
c: d
`,
expectedItems: []string{
`
a: b
`,
`
c: d
`,
},
instance: ByteReader{OmitReaderAnnotations: true},
},

//
//
//
{
name: "anything_after_document_separator_other_than_white_space_or_comment_is_an_error",
input: `
a: b
--- foo
c: d
`,
err: "invalid document separator: --- foo",
instance: ByteReader{OmitReaderAnnotations: true},
},
}

for i := range testCases {
Expand Down

0 comments on commit 78737f5

Please sign in to comment.