Skip to content

Commit e5e3654

Browse files
authored
Avoid emitting YAML back-references in kpt fn output (#183)
1 parent 4be34a9 commit e5e3654

File tree

3 files changed

+75
-4
lines changed

3 files changed

+75
-4
lines changed

ts/kpt-functions/src/io.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ const YAML_STYLE: DumpOptions = {
3838
skipInvalid: true,
3939
// unset lineWidth from default of 80 to avoid reformatting
4040
lineWidth: -1,
41+
// avoid refs because many YAML parsers in the k8s ecosystem don't support them
42+
noRefs: true,
4143
};
4244

4345
/**

ts/kpt-functions/src/io_test.ts

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@
1515
*/
1616

1717
import { FileFormat, parse, stringify } from './io';
18-
import { Configs, KubernetesObject } from './types';
18+
import { Configs, JsonArray, KubernetesObject } from './types';
19+
import { kubernetesObjectResult } from './result';
1920

2021
describe('read', () => {
2122
describe('in YAML format', () => {
@@ -686,3 +687,68 @@ results:
686687
});
687688
});
688689
});
690+
691+
describe('roundtrip', () => {
692+
describe('using YAML', () => {
693+
it('should not insert YAML references', () => {
694+
interface Baz {
695+
baz: number;
696+
}
697+
698+
interface Foo extends KubernetesObject {
699+
spec: {
700+
array: Baz[];
701+
};
702+
}
703+
704+
const input =
705+
'items: [{apiVersion: v1, kind: Foo, metadata: {name: bar}, spec: {array: [{baz: 1}]}}]';
706+
const configs = parse(input, FileFormat.YAML);
707+
708+
const foo = configs.getAll()[0] as Foo;
709+
configs.addResults(
710+
kubernetesObjectResult('something is wrong', foo, {
711+
path: 'spec.array',
712+
// Note: we re-use objects from the input to trigger YAML refs to normally be created
713+
currentValue: (foo.spec.array as unknown) as JsonArray,
714+
suggestedValue: (foo.spec.array.concat([
715+
{ baz: 3 },
716+
]) as unknown) as JsonArray,
717+
})
718+
);
719+
720+
const stringified = stringify(configs, FileFormat.YAML);
721+
722+
// We want to verify that there are no back-references like &ref and *ref in the output
723+
expect(stringified).toEqual(`apiVersion: v1
724+
kind: ResourceList
725+
metadata:
726+
name: output
727+
items:
728+
- apiVersion: v1
729+
kind: Foo
730+
metadata:
731+
name: bar
732+
spec:
733+
array:
734+
- baz: 1
735+
results:
736+
- message: something is wrong
737+
severity: error
738+
resourceRef:
739+
apiVersion: v1
740+
kind: Foo
741+
namespace: ''
742+
name: bar
743+
file: {}
744+
field:
745+
path: spec.array
746+
currentValue:
747+
- baz: 1
748+
suggestedValue:
749+
- baz: 1
750+
- baz: 3
751+
`);
752+
});
753+
});
754+
});

ts/kpt-functions/src/types.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -403,13 +403,16 @@ export interface Result {
403403
*/
404404
export type Severity = 'error' | 'warn' | 'info';
405405

406-
interface JsonArray extends Array<Json> {}
406+
/** A plain old JSON array according to ECMA-404. */
407+
export interface JsonArray extends Array<Json> {}
407408

408-
interface JsonMap {
409+
/** A plain old JSON object/map according to ECMA-404. */
410+
export interface JsonMap {
409411
[field: string]: Json;
410412
}
411413

412-
type Json = null | boolean | number | string | JsonArray | JsonMap;
414+
/** Any plain old JSON value according to ECMA-404. */
415+
export type Json = null | boolean | number | string | JsonArray | JsonMap;
413416

414417
/**
415418
* Metadata about a specific field in a Kubernetes object.

0 commit comments

Comments
 (0)