diff --git a/ts/kpt-functions/src/io.ts b/ts/kpt-functions/src/io.ts index 6eceb8540..78bdf5dc6 100644 --- a/ts/kpt-functions/src/io.ts +++ b/ts/kpt-functions/src/io.ts @@ -38,6 +38,8 @@ const YAML_STYLE: DumpOptions = { skipInvalid: true, // unset lineWidth from default of 80 to avoid reformatting lineWidth: -1, + // avoid refs because many YAML parsers in the k8s ecosystem don't support them + noRefs: true, }; /** diff --git a/ts/kpt-functions/src/io_test.ts b/ts/kpt-functions/src/io_test.ts index f775ab985..136e95649 100644 --- a/ts/kpt-functions/src/io_test.ts +++ b/ts/kpt-functions/src/io_test.ts @@ -15,7 +15,8 @@ */ import { FileFormat, parse, stringify } from './io'; -import { Configs, KubernetesObject } from './types'; +import { Configs, JsonArray, KubernetesObject } from './types'; +import { kubernetesObjectResult } from './result'; describe('read', () => { describe('in YAML format', () => { @@ -686,3 +687,68 @@ results: }); }); }); + +describe('roundtrip', () => { + describe('using YAML', () => { + it('should not insert YAML references', () => { + interface Baz { + baz: number; + } + + interface Foo extends KubernetesObject { + spec: { + array: Baz[]; + }; + } + + const input = + 'items: [{apiVersion: v1, kind: Foo, metadata: {name: bar}, spec: {array: [{baz: 1}]}}]'; + const configs = parse(input, FileFormat.YAML); + + const foo = configs.getAll()[0] as Foo; + configs.addResults( + kubernetesObjectResult('something is wrong', foo, { + path: 'spec.array', + // Note: we re-use objects from the input to trigger YAML refs to normally be created + currentValue: (foo.spec.array as unknown) as JsonArray, + suggestedValue: (foo.spec.array.concat([ + { baz: 3 }, + ]) as unknown) as JsonArray, + }) + ); + + const stringified = stringify(configs, FileFormat.YAML); + + // We want to verify that there are no back-references like &ref and *ref in the output + expect(stringified).toEqual(`apiVersion: v1 +kind: ResourceList +metadata: + name: output +items: +- apiVersion: v1 + kind: Foo + metadata: + name: bar + spec: + array: + - baz: 1 +results: +- message: something is wrong + severity: error + resourceRef: + apiVersion: v1 + kind: Foo + namespace: '' + name: bar + file: {} + field: + path: spec.array + currentValue: + - baz: 1 + suggestedValue: + - baz: 1 + - baz: 3 +`); + }); + }); +}); diff --git a/ts/kpt-functions/src/types.ts b/ts/kpt-functions/src/types.ts index 972630ce3..5d7dc4264 100644 --- a/ts/kpt-functions/src/types.ts +++ b/ts/kpt-functions/src/types.ts @@ -403,13 +403,13 @@ export interface Result { */ export type Severity = 'error' | 'warn' | 'info'; -interface JsonArray extends Array {} +export interface JsonArray extends Array {} -interface JsonMap { +export interface JsonMap { [field: string]: Json; } -type Json = null | boolean | number | string | JsonArray | JsonMap; +export type Json = null | boolean | number | string | JsonArray | JsonMap; /** * Metadata about a specific field in a Kubernetes object.