Skip to content

Commit

Permalink
Avoid emitting YAML back-references in kpt fn output (#183)
Browse files Browse the repository at this point in the history
  • Loading branch information
dflemstr authored Aug 20, 2020
1 parent 4be34a9 commit e5e3654
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 4 deletions.
2 changes: 2 additions & 0 deletions ts/kpt-functions/src/io.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};

/**
Expand Down
68 changes: 67 additions & 1 deletion ts/kpt-functions/src/io_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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', () => {
Expand Down Expand Up @@ -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
`);
});
});
});
9 changes: 6 additions & 3 deletions ts/kpt-functions/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -403,13 +403,16 @@ export interface Result {
*/
export type Severity = 'error' | 'warn' | 'info';

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

interface JsonMap {
/** A plain old JSON object/map according to ECMA-404. */
export interface JsonMap {
[field: string]: Json;
}

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

/**
* Metadata about a specific field in a Kubernetes object.
Expand Down

0 comments on commit e5e3654

Please sign in to comment.