From fa3e829eb6ecd75be5f4d52ead63f230602be3c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20=C3=96hrn?= Date: Mon, 31 May 2021 08:00:26 +0200 Subject: [PATCH 1/6] Sink: Force JSON encoding for .json files --- kyaml/kio/byteio_writer.go | 35 +++++++++++++++++++++++++-------- kyaml/kio/byteio_writer_test.go | 30 ++++++++++++++++++++++++++-- 2 files changed, 55 insertions(+), 10 deletions(-) diff --git a/kyaml/kio/byteio_writer.go b/kyaml/kio/byteio_writer.go index 84097f1086..dc58e82380 100644 --- a/kyaml/kio/byteio_writer.go +++ b/kyaml/kio/byteio_writer.go @@ -6,7 +6,7 @@ package kio import ( "encoding/json" "io" - + "path/filepath" "sigs.k8s.io/kustomize/kyaml/errors" "sigs.k8s.io/kustomize/kyaml/kio/kioutil" "sigs.k8s.io/kustomize/kyaml/yaml" @@ -56,8 +56,23 @@ 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 != "" { + filename := filepath.Base(path) + for _, glob := range JSONMatch { + if match, _ := filepath.Match(glob, filename); match { + hasJSONPathExt[i] = true + break + } + } + } // clean resources by removing annotations set by the Reader if !w.KeepReaderAnnotations { _, err := nodes[i].Pipe(yaml.ClearAnnotation(kioutil.IndexAnnotation)) @@ -84,7 +99,7 @@ func (w ByteWriter) Write(nodes []*yaml.RNode) error { // don't wrap the elements if w.WrappingKind == "" { for i := range nodes { - if err := w.encode(encoder, nodes[i].Document()); err != nil { + if err := w.encode(encoder, hasJSONPathExt[i], nodes[i].Document()); err != nil { return err } } @@ -118,20 +133,24 @@ func (w ByteWriter) Write(nodes []*yaml.RNode) error { for i := range nodes { items.Content = append(items.Content, nodes[i].YNode()) } - err := w.encode(encoder, doc) + err := w.encode(encoder, false, doc) yaml.UndoSerializationHacksOnNodes(nodes) return err } // encode encodes the input document node to appropriate node format -func (w ByteWriter) encode(encoder *yaml.Encoder, doc *yaml.Node) error { +func (w ByteWriter) encode(encoder *yaml.Encoder, forceJSON bool, doc *yaml.Node) error { rNode := &yaml.RNode{} rNode.SetYNode(doc) - str, err := rNode.String() - if err != nil { - return errors.Wrap(err) + useJSONEncoder := forceJSON + if !forceJSON { + str, err := rNode.String() + if err != nil { + return errors.Wrap(err) + } + useJSONEncoder = json.Valid([]byte(str)) } - if json.Valid([]byte(str)) { + if useJSONEncoder { je := json.NewEncoder(w.Writer) je.SetIndent("", " ") return errors.Wrap(je.Encode(rNode)) diff --git a/kyaml/kio/byteio_writer_test.go b/kyaml/kio/byteio_writer_test.go index d038f529eb..35169a1f45 100644 --- a/kyaml/kio/byteio_writer_test.go +++ b/kyaml/kio/byteio_writer_test.go @@ -26,7 +26,7 @@ func TestByteWriter(t *testing.T) { testCases := []testCase{ // - // + // Test Case // { name: "wrap_resource_list", @@ -60,7 +60,7 @@ functionConfig: }, // - // + // Test Case // { name: "multiple_items", @@ -189,6 +189,32 @@ metadata: config.kubernetes.io/path: "a/b/a_test.yaml" `, }, + + // + // Test Case + // + { + name: "encode_valid_json", + 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" + } + } +}`, + }, + + expectedOutput: `{ + "a": "a long string that would certainly see a newline introduced by the YAML marshaller abcd123", + "metadata": { + "annotations": { + "config.kubernetes.io/path": "test.json" + } + } +}`, + }, } for i := range testCases { From 5e4fb4796e7fe706ba3eeddba5f3b18bf76b0072 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20=C3=96hrn?= Date: Tue, 1 Jun 2021 20:44:21 +0200 Subject: [PATCH 2/6] Only encoding non-wrapped single .json items as JSON --- kyaml/kio/byteio_writer.go | 56 +++++++++++----------------- kyaml/kio/byteio_writer_test.go | 65 +++++++++++++++++++++++++++++++-- 2 files changed, 84 insertions(+), 37 deletions(-) diff --git a/kyaml/kio/byteio_writer.go b/kyaml/kio/byteio_writer.go index dc58e82380..c22b2b2623 100644 --- a/kyaml/kio/byteio_writer.go +++ b/kyaml/kio/byteio_writer.go @@ -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) -} diff --git a/kyaml/kio/byteio_writer_test.go b/kyaml/kio/byteio_writer_test.go index 35169a1f45..a3f0b48767 100644 --- a/kyaml/kio/byteio_writer_test.go +++ b/kyaml/kio/byteio_writer_test.go @@ -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 { From e468d6b4d28e9262b10adee91b84053f074186ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20=C3=96hrn?= Date: Thu, 3 Jun 2021 08:29:53 +0200 Subject: [PATCH 3/6] Fixing cmd/config/internal/commands/e2e/e2e_test.go --- cmd/config/internal/commands/e2e/e2e_test.go | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/cmd/config/internal/commands/e2e/e2e_test.go b/cmd/config/internal/commands/e2e/e2e_test.go index 962134c994..c74721d791 100644 --- a/cmd/config/internal/commands/e2e/e2e_test.go +++ b/cmd/config/internal/commands/e2e/e2e_test.go @@ -87,8 +87,18 @@ metadata: expectedFiles: func(d string) map[string]string { return map[string]string{ "deployment.json": ` -{"apiVersion": "apps/v1", "kind": "Deployment", "metadata": {"name": "foo", annotations: { - a-string-value: '', a-int-value: '0', a-bool-value: 'false'}}} +{ + "apiVersion": "apps/v1", + "kind": "Deployment", + "metadata": { + "annotations": { + "a-bool-value": "false", + "a-int-value": "0", + "a-string-value": "" + }, + "name": "foo" + } +} `, } }, From 03bbb076bf2e81096adaaca9fe4a3db6d61d5f63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20=C3=96hrn?= Date: Thu, 3 Jun 2021 08:30:38 +0200 Subject: [PATCH 4/6] plugin/builtin/iampolicygenerator/go.sum tidy --- plugin/builtin/iampolicygenerator/go.sum | 1 - 1 file changed, 1 deletion(-) diff --git a/plugin/builtin/iampolicygenerator/go.sum b/plugin/builtin/iampolicygenerator/go.sum index 4e375cb8ae..4e67192558 100644 --- a/plugin/builtin/iampolicygenerator/go.sum +++ b/plugin/builtin/iampolicygenerator/go.sum @@ -126,7 +126,6 @@ github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7z github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= From 942f112ef53b4226f73a0351347006b1e5bbe125 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20=C3=96hrn?= Date: Thu, 3 Jun 2021 08:31:03 +0200 Subject: [PATCH 5/6] Fix kyaml tests --- kyaml/kio/byteio_writer_test.go | 6 +++--- kyaml/kio/filters/fmtr_test.go | 20 -------------------- kyaml/kio/filters/testyaml/testyaml.go | 23 ----------------------- 3 files changed, 3 insertions(+), 46 deletions(-) diff --git a/kyaml/kio/byteio_writer_test.go b/kyaml/kio/byteio_writer_test.go index a3f0b48767..f8e3d47bda 100644 --- a/kyaml/kio/byteio_writer_test.go +++ b/kyaml/kio/byteio_writer_test.go @@ -194,7 +194,7 @@ metadata: // Test Case // { - name: "encode_valid_json", + name: "encode_valid_json", items: []string{ `{ "a": "a long string that would certainly see a newline introduced by the YAML marshaller abcd123", @@ -220,7 +220,7 @@ metadata: // Test Case // { - name: "encode_wrapped_json_as_yaml", + name: "encode_wrapped_json_as_yaml", instance: ByteWriter{ Sort: true, WrappingKind: ResourceListKind, @@ -248,7 +248,7 @@ items: // Test Case // { - name: "encode_multi_doc_json_as_yaml", + name: "encode_multi_doc_json_as_yaml", items: []string{ `{ "a": "b", diff --git a/kyaml/kio/filters/fmtr_test.go b/kyaml/kio/filters/fmtr_test.go index 87472bbe04..cebb2da60c 100644 --- a/kyaml/kio/filters/fmtr_test.go +++ b/kyaml/kio/filters/fmtr_test.go @@ -743,26 +743,6 @@ func TestFormatFileOrDirectory_ymlExtFile(t *testing.T) { assert.Equal(t, string(testyaml.FormattedYaml1), string(b)) } -// TestFormatFileOrDirectory_skipYamlExtFileWithJson verifies that the json content is formatted -// as yaml -func TestFormatFileOrDirectory_YamlExtFileWithJson(t *testing.T) { - // write the unformatted JSON file contents - f, err := ioutil.TempFile("", "yamlfmt*.yaml") - assert.NoError(t, err) - defer os.Remove(f.Name()) - err = ioutil.WriteFile(f.Name(), testyaml.UnformattedJSON1, 0600) - assert.NoError(t, err) - - // format the file - err = FormatFileOrDirectory(f.Name()) - assert.NoError(t, err) - - // check the result is formatted as yaml - b, err := ioutil.ReadFile(f.Name()) - assert.NoError(t, err) - assert.Equal(t, string(testyaml.FormattedJSON1), string(b)) -} - // TestFormatFileOrDirectory_partialKubernetesYamlFile verifies that if a yaml file contains both // Kubernetes and non-Kubernetes documents, it will only format the Kubernetes documents func TestFormatFileOrDirectory_partialKubernetesYamlFile(t *testing.T) { diff --git a/kyaml/kio/filters/testyaml/testyaml.go b/kyaml/kio/filters/testyaml/testyaml.go index eae6692f42..c54d8d3058 100644 --- a/kyaml/kio/filters/testyaml/testyaml.go +++ b/kyaml/kio/filters/testyaml/testyaml.go @@ -68,15 +68,6 @@ metadata: selfLink: "" `) -var UnformattedJSON1 = []byte(` -{ - "spec": "a", - "status": {"conditions": [3, 1, 2]}, - "apiVersion": "example.com/v1beta1", - "kind": "MyType" -} -`) - var FormattedYaml1 = []byte(`apiVersion: example.com/v1beta1 kind: MyType spec: a @@ -97,20 +88,6 @@ status2: - 2 `) -var FormattedJSON1 = []byte(`{ - "apiVersion": "example.com/v1beta1", - "kind": "MyType", - "spec": "a", - "status": { - "conditions": [ - 3, - 1, - 2 - ] - } -} -`) - var FormattedYaml3 = []byte(`apiVersion: v1 kind: List metadata: From 3e506eae02745fb550cb65f41dcecf918456bab1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20=C3=96hrn?= Date: Fri, 4 Jun 2021 11:06:22 +0200 Subject: [PATCH 6/6] PR feedback - more tests and some cleanup --- kyaml/kio/byteio_writer.go | 49 ++++++++++++++++---------- kyaml/kio/byteio_writer_test.go | 19 ++++++++++ kyaml/kio/filters/fmtr_test.go | 40 +++++++++++++++++++++ kyaml/kio/filters/testyaml/testyaml.go | 14 ++++++++ 4 files changed, 104 insertions(+), 18 deletions(-) diff --git a/kyaml/kio/byteio_writer.go b/kyaml/kio/byteio_writer.go index c22b2b2623..a243ed9113 100644 --- a/kyaml/kio/byteio_writer.go +++ b/kyaml/kio/byteio_writer.go @@ -12,7 +12,10 @@ import ( "sigs.k8s.io/kustomize/kyaml/yaml" ) -// ByteWriter writes ResourceNodes to bytes. +// ByteWriter writes ResourceNodes to bytes. Generally YAML encoding will be used but in the special +// case of writing a single, bare yaml.RNode that has a kioutil.PathAnnotation indicating that the +// target is a JSON file JSON encoding is used. See shouldJSONEncodeSingleBareNode below for more +// information. type ByteWriter struct { // Writer is where ResourceNodes are encoded. Writer io.Writer @@ -55,22 +58,8 @@ func (w ByteWriter) Write(nodes []*yaml.RNode) error { } } - // 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 { - jsonEncodeSingleNode = true - break - } - } - } - } + // Even though we use the this value further down we must check this before removing annotations + jsonEncodeSingleBareNode := w.shouldJSONEncodeSingleBareNode(nodes) for i := range nodes { // clean resources by removing annotations set by the Reader @@ -96,7 +85,7 @@ func (w ByteWriter) Write(nodes []*yaml.RNode) error { } } - if jsonEncodeSingleNode { + if jsonEncodeSingleBareNode { encoder := json.NewEncoder(w.Writer) encoder.SetIndent("", " ") return errors.Wrap(encoder.Encode(nodes[0])) @@ -145,3 +134,27 @@ func (w ByteWriter) Write(nodes []*yaml.RNode) error { yaml.UndoSerializationHacksOnNodes(nodes) return err } + +// shouldJSONEncodeSingleBareNode determines if nodes contain a single node that should not be +// wrapped and has a JSON file extension, which in turn means that the node should be JSON encoded. +// Note 1: this must be checked before any annotations to avoid losing information about the target +// filename extension. +// Note 2: JSON encoding should only be used for single, unwrapped nodes because multiple unwrapped +// nodes cannot be represented in JSON (no multi doc support). Furthermore, the typical use +// cases for wrapping nodes would likely not include later writing the whole wrapper to a +// .json file, i.e. there is no point risking any edge case information loss e.g. comments +// disappearing, that could come from JSON encoding the whole wrapper just to ensure that +// one (or all nodes) can be read as JSON. +func (w ByteWriter) shouldJSONEncodeSingleBareNode(nodes []*yaml.RNode) bool { + 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 { + return true + } + } + } + } + return false +} \ No newline at end of file diff --git a/kyaml/kio/byteio_writer_test.go b/kyaml/kio/byteio_writer_test.go index f8e3d47bda..c284d04a89 100644 --- a/kyaml/kio/byteio_writer_test.go +++ b/kyaml/kio/byteio_writer_test.go @@ -216,6 +216,25 @@ metadata: }`, }, + // + // Test Case + // + { + name: "encode_unformatted_valid_json", + items: []string{ + `{ "a": "b", metadata: { annotations: { config.kubernetes.io/path: test.json } } }`, + }, + + expectedOutput: `{ + "a": "b", + "metadata": { + "annotations": { + "config.kubernetes.io/path": "test.json" + } + } +}`, + }, + // // Test Case // diff --git a/kyaml/kio/filters/fmtr_test.go b/kyaml/kio/filters/fmtr_test.go index cebb2da60c..e988a3ff56 100644 --- a/kyaml/kio/filters/fmtr_test.go +++ b/kyaml/kio/filters/fmtr_test.go @@ -743,6 +743,46 @@ func TestFormatFileOrDirectory_ymlExtFile(t *testing.T) { assert.Equal(t, string(testyaml.FormattedYaml1), string(b)) } +// TestFormatFileOrDirectory_YamlExtFileWithJson verifies that the JSON compatible flow style +// YAML content is formatted as such. +func TestFormatFileOrDirectory_YamlExtFileWithJson(t *testing.T) { + // write the unformatted JSON file contents + f, err := ioutil.TempFile("", "yamlfmt*.yaml") + assert.NoError(t, err) + defer os.Remove(f.Name()) + err = ioutil.WriteFile(f.Name(), testyaml.UnformattedJSON1, 0600) + assert.NoError(t, err) + + // format the file + err = FormatFileOrDirectory(f.Name()) + assert.NoError(t, err) + + // check the result is formatted as yaml + b, err := ioutil.ReadFile(f.Name()) + assert.NoError(t, err) + assert.Equal(t, string(testyaml.FormattedFlowYAML1), string(b)) +} + +// TestFormatFileOrDirectory_JsonExtFileWithNotModified verifies that a file with .json extensions +// and JSON contents won't be modified. +func TestFormatFileOrDirectory_JsonExtFileWithNotModified(t *testing.T) { + // write the unformatted JSON file contents + f, err := ioutil.TempFile("", "yamlfmt*.json") + assert.NoError(t, err) + defer os.Remove(f.Name()) + err = ioutil.WriteFile(f.Name(), testyaml.UnformattedJSON1, 0600) + assert.NoError(t, err) + + // format the file + err = FormatFileOrDirectory(f.Name()) + assert.NoError(t, err) + + // check the result is formatted as yaml + b, err := ioutil.ReadFile(f.Name()) + assert.NoError(t, err) + assert.Equal(t, string(testyaml.UnformattedJSON1), string(b)) +} + // TestFormatFileOrDirectory_partialKubernetesYamlFile verifies that if a yaml file contains both // Kubernetes and non-Kubernetes documents, it will only format the Kubernetes documents func TestFormatFileOrDirectory_partialKubernetesYamlFile(t *testing.T) { diff --git a/kyaml/kio/filters/testyaml/testyaml.go b/kyaml/kio/filters/testyaml/testyaml.go index c54d8d3058..01644b3112 100644 --- a/kyaml/kio/filters/testyaml/testyaml.go +++ b/kyaml/kio/filters/testyaml/testyaml.go @@ -68,6 +68,15 @@ metadata: selfLink: "" `) +var UnformattedJSON1 = []byte(` +{ + "spec": "a", + "status": {"conditions": [3, 1, 2]}, + "apiVersion": "example.com/v1beta1", + "kind": "MyType" +} +`) + var FormattedYaml1 = []byte(`apiVersion: example.com/v1beta1 kind: MyType spec: a @@ -88,6 +97,11 @@ status2: - 2 `) +var FormattedFlowYAML1 = []byte( + `{"apiVersion": "example.com/v1beta1", "kind": "MyType", "spec": "a", "status": {"conditions": [ + 3, 1, 2]}} +`) + var FormattedYaml3 = []byte(`apiVersion: v1 kind: List metadata: