Skip to content

Commit

Permalink
Merge pull request #4043 from phanimarupaka/PreserveIndentation
Browse files Browse the repository at this point in the history
Make seq indent configurable and add retain seq indent functionality
  • Loading branch information
k8s-ci-robot authored Jul 13, 2021
2 parents 259fcfc + 29be7fa commit 4a13725
Show file tree
Hide file tree
Showing 11 changed files with 795 additions and 14 deletions.
26 changes: 23 additions & 3 deletions kyaml/kio/byteio_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ type ByteReadWriter struct {
// the Resources, otherwise they will be cleared.
KeepReaderAnnotations bool

// PreserveSeqIndent if true adds kioutil.SeqIndentAnnotation to each resource
PreserveSeqIndent bool

// Style is a style that is set on the Resource Node Document.
Style yaml.Style

Expand All @@ -53,6 +56,7 @@ func (rw *ByteReadWriter) Read() ([]*yaml.RNode, error) {
b := &ByteReader{
Reader: rw.Reader,
OmitReaderAnnotations: rw.OmitReaderAnnotations,
PreserveSeqIndent: rw.PreserveSeqIndent,
}
val, err := b.Read()
if rw.FunctionConfig == nil {
Expand Down Expand Up @@ -109,9 +113,12 @@ type ByteReader struct {
Reader io.Reader

// OmitReaderAnnotations will configures Read to skip setting the config.kubernetes.io/index
// annotation on Resources as they are Read.
// and internal.config.kubernetes.io/seqindent annotations on Resources as they are Read.
OmitReaderAnnotations bool

// PreserveSeqIndent if true adds kioutil.SeqIndentAnnotation to each resource
PreserveSeqIndent bool

// SetAnnotations is a map of caller specified annotations to set on resources as they are read
// These are independent of the annotations controlled by OmitReaderAnnotations
SetAnnotations map[string]string
Expand Down Expand Up @@ -166,6 +173,10 @@ func splitDocuments(s string) ([]string, error) {
}

func (r *ByteReader) Read() ([]*yaml.RNode, error) {
if r.PreserveSeqIndent && r.OmitReaderAnnotations {
return nil, errors.Errorf(`"PreserveSeqIndent" option adds a reader annotation, please set "OmitReaderAnnotations" to false`)
}

output := ResourceNodeSlice{}

// by manually splitting resources -- otherwise the decoder will get the Resource
Expand All @@ -191,10 +202,11 @@ func (r *ByteReader) Read() ([]*yaml.RNode, error) {
values[i] += "\n"
}
decoder := yaml.NewDecoder(bytes.NewBufferString(values[i]))
node, err := r.decode(index, decoder)
node, err := r.decode(values[i], index, decoder)
if err == io.EOF {
continue
}

if err != nil {
return nil, errors.Wrap(err)
}
Expand Down Expand Up @@ -245,7 +257,7 @@ func (r *ByteReader) Read() ([]*yaml.RNode, error) {
return output, nil
}

func (r *ByteReader) decode(index int, decoder *yaml.Decoder) (*yaml.RNode, error) {
func (r *ByteReader) decode(originalYAML string, index int, decoder *yaml.Decoder) (*yaml.RNode, error) {
node := &yaml.Node{}
err := decoder.Decode(node)
if err == io.EOF {
Expand All @@ -268,6 +280,14 @@ func (r *ByteReader) decode(index int, decoder *yaml.Decoder) (*yaml.RNode, erro
}
if !r.OmitReaderAnnotations {
r.SetAnnotations[kioutil.IndexAnnotation] = fmt.Sprintf("%d", index)

if r.PreserveSeqIndent {
// derive and add the seqindent annotation
seqIndentStyle := yaml.DeriveSeqIndentStyle(originalYAML)
if seqIndentStyle != "" {
r.SetAnnotations[kioutil.SeqIndentAnnotation] = fmt.Sprintf("%s", seqIndentStyle)
}
}
}
var keys []string
for k := range r.SetAnnotations {
Expand Down
100 changes: 100 additions & 0 deletions kyaml/kio/byteio_reader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (

"github.com/stretchr/testify/assert"
. "sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/kio/kioutil"
)

func TestByteReader(t *testing.T) {
Expand Down Expand Up @@ -805,3 +806,102 @@ items:
})
}
}

// TestByteReader_AddSeqIndentAnnotation tests if the internal.config.kubernetes.io/seqindent
// annotation is added to resources appropriately
func TestByteReader_AddSeqIndentAnnotation(t *testing.T) {
type testCase struct {
name string
err string
input string
expectedAnnoValue string
OmitReaderAnnotations bool
}

testCases := []testCase{
{
name: "read with wide indentation",
input: `apiVersion: apps/v1
kind: Deployment
spec:
- foo
- bar
- baz
`,
expectedAnnoValue: "wide",
},
{
name: "read with compact indentation",
input: `apiVersion: apps/v1
kind: Deployment
spec:
- foo
- bar
- baz
`,
expectedAnnoValue: "compact",
},
{
name: "read with mixed indentation, wide wins",
input: `apiVersion: apps/v1
kind: Deployment
spec:
- foo
- bar
- baz
env:
- foo
- bar
`,
expectedAnnoValue: "wide",
},
{
name: "read with mixed indentation, compact wins",
input: `apiVersion: apps/v1
kind: Deployment
spec:
- foo
- bar
- baz
env:
- foo
- bar
`,
expectedAnnoValue: "compact",
},
{
name: "error if conflicting options",
input: `apiVersion: apps/v1
kind: Deployment
spec:
- foo
- bar
- baz
env:
- foo
- bar
`,
OmitReaderAnnotations: true,
err: `"PreserveSeqIndent" option adds a reader annotation, please set "OmitReaderAnnotations" to false`,
},
}

for i := range testCases {
tc := testCases[i]
t.Run(tc.name, func(t *testing.T) {
rNodes, err := (&ByteReader{
OmitReaderAnnotations: tc.OmitReaderAnnotations,
PreserveSeqIndent: true,
Reader: bytes.NewBuffer([]byte(tc.input)),
}).Read()
if tc.err != "" {
assert.Error(t, err)
assert.Equal(t, tc.err, err.Error())
return
}
assert.NoError(t, err)
actual := rNodes[0].GetAnnotations()[kioutil.SeqIndentAnnotation]
assert.Equal(t, tc.expectedAnnoValue, actual)
})
}
}
Loading

0 comments on commit 4a13725

Please sign in to comment.