Only encoding non-wrapped single .json items as JSON

This commit is contained in:
Mattias Öhrn
2021-06-01 20:44:21 +02:00
parent fa3e829eb6
commit 5e4fb4796e
2 changed files with 84 additions and 37 deletions

View File

@@ -12,7 +12,7 @@ import (
"sigs.k8s.io/kustomize/kyaml/yaml"
)
// Writer writes ResourceNodes to bytes.
// ByteWriter writes ResourceNodes to bytes.
type ByteWriter struct {
// Writer is where ResourceNodes are encoded.
Writer io.Writer
@@ -55,24 +55,24 @@ func (w ByteWriter) Write(nodes []*yaml.RNode) error {
}
}
encoder := yaml.NewEncoder(w.Writer)
// keep
hasJSONPathExt := make([]bool, len(nodes))
defer encoder.Close()
for i := range nodes {
// Check if the output file is a JSON file so we can force JSON encoding in that case.
// YAML flow style encoding may not be compatible because of newlines introduced by the
// YAML marshaller in long double quoted string values. These newlines are insignificant
// when interpreted as YAML but invalid when interpreted as JSON.
if path, _, _ := kioutil.GetFileAnnotations(nodes[i]); path != "" {
// Check if the output is a single JSON file so we can force JSON encoding in that case.
// YAML flow style encoding may not be compatible because of unquoted strings and newlines
// introduced by the YAML marshaller in long string values. These newlines are insignificant
// when interpreted as YAML but invalid when interpreted as JSON.
jsonEncodeSingleNode := false
if w.WrappingKind == "" && len(nodes) == 1 {
if path, _, _ := kioutil.GetFileAnnotations(nodes[0]); path != "" {
filename := filepath.Base(path)
for _, glob := range JSONMatch {
if match, _ := filepath.Match(glob, filename); match {
hasJSONPathExt[i] = true
jsonEncodeSingleNode = true
break
}
}
}
}
for i := range nodes {
// clean resources by removing annotations set by the Reader
if !w.KeepReaderAnnotations {
_, err := nodes[i].Pipe(yaml.ClearAnnotation(kioutil.IndexAnnotation))
@@ -96,10 +96,18 @@ func (w ByteWriter) Write(nodes []*yaml.RNode) error {
}
}
if jsonEncodeSingleNode {
encoder := json.NewEncoder(w.Writer)
encoder.SetIndent("", " ")
return errors.Wrap(encoder.Encode(nodes[0]))
}
encoder := yaml.NewEncoder(w.Writer)
defer encoder.Close()
// don't wrap the elements
if w.WrappingKind == "" {
for i := range nodes {
if err := w.encode(encoder, hasJSONPathExt[i], nodes[i].Document()); err != nil {
if err := encoder.Encode(nodes[i].Document()); err != nil {
return err
}
}
@@ -133,27 +141,7 @@ func (w ByteWriter) Write(nodes []*yaml.RNode) error {
for i := range nodes {
items.Content = append(items.Content, nodes[i].YNode())
}
err := w.encode(encoder, false, doc)
err := encoder.Encode(doc)
yaml.UndoSerializationHacksOnNodes(nodes)
return err
}
// encode encodes the input document node to appropriate node format
func (w ByteWriter) encode(encoder *yaml.Encoder, forceJSON bool, doc *yaml.Node) error {
rNode := &yaml.RNode{}
rNode.SetYNode(doc)
useJSONEncoder := forceJSON
if !forceJSON {
str, err := rNode.String()
if err != nil {
return errors.Wrap(err)
}
useJSONEncoder = json.Valid([]byte(str))
}
if useJSONEncoder {
je := json.NewEncoder(w.Writer)
je.SetIndent("", " ")
return errors.Wrap(je.Encode(rNode))
}
return encoder.Encode(doc)
}

View File

@@ -198,9 +198,9 @@ metadata:
items: []string{
`{
"a": "a long string that would certainly see a newline introduced by the YAML marshaller abcd123",
"metadata": {
"annotations": {
"config.kubernetes.io/path": "test.json"
metadata: {
annotations: {
config.kubernetes.io/path: test.json
}
}
}`,
@@ -215,6 +215,65 @@ metadata:
}
}`,
},
//
// Test Case
//
{
name: "encode_wrapped_json_as_yaml",
instance: ByteWriter{
Sort: true,
WrappingKind: ResourceListKind,
WrappingAPIVersion: ResourceListAPIVersion,
},
items: []string{
`{
"a": "b",
"metadata": {
"annotations": {
"config.kubernetes.io/path": "test.json"
}
}
}`,
},
expectedOutput: `apiVersion: config.kubernetes.io/v1alpha1
kind: ResourceList
items:
- {"a": "b", "metadata": {"annotations": {"config.kubernetes.io/path": "test.json"}}}
`,
},
//
// Test Case
//
{
name: "encode_multi_doc_json_as_yaml",
items: []string{
`{
"a": "b",
"metadata": {
"annotations": {
"config.kubernetes.io/path": "test-1.json"
}
}
}`,
`{
"c": "d",
"metadata": {
"annotations": {
"config.kubernetes.io/path": "test-2.json"
}
}
}`,
},
expectedOutput: `
{"a": "b", "metadata": {"annotations": {"config.kubernetes.io/path": "test-1.json"}}}
---
{"c": "d", "metadata": {"annotations": {"config.kubernetes.io/path": "test-2.json"}}}
`,
},
}
for i := range testCases {