Skip to content

Commit

Permalink
Fix JSON/YAML diffs
Browse files Browse the repository at this point in the history
Fixes #13981.
  • Loading branch information
Frassle committed Jan 18, 2024
1 parent 7e9aab2 commit f5ee11e
Show file tree
Hide file tree
Showing 15 changed files with 336 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
changes:
- type: fix
scope: cli/display
description: Fix JSON/YAML value diff displays.
22 changes: 22 additions & 0 deletions pkg/backend/display/diff_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,3 +153,25 @@ func TestDiffEvents(t *testing.T) {
})
}
}

func TestJsonYamlDiff(t *testing.T) {
t.Parallel()

accept := cmdutil.IsTruthy(os.Getenv("PULUMI_ACCEPT"))

entries, err := os.ReadDir("testdata/json-yaml")
require.NoError(t, err)

//nolint:paralleltest
for _, entry := range entries {
if entry.IsDir() || filepath.Ext(entry.Name()) != ".json" {
continue
}

path := filepath.Join("testdata/json-yaml", entry.Name())
t.Run(entry.Name(), func(t *testing.T) {
t.Parallel()
testDiffEvents(t, path, accept, false)
})
}
}
13 changes: 9 additions & 4 deletions pkg/backend/display/object_diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -1201,13 +1201,16 @@ func (p *propertyPrinter) printEncodedValueDiff(old, new string) bool {
return false
}

if oldKind != newKind {
p.write("(%s => %s) ", oldKind, newKind)
} else if old != new {
// If the decoded values are the same, then print a text diff as an object diff won't show any changes.
if oldValue.DeepEquals(newValue) {
p.printTextDiff(strconv.Quote(old), strconv.Quote(new))
return true
} else {
}

if oldKind == newKind {
p.write("(%s) ", oldKind)
} else {
p.write("(%s => %s) ", oldKind, newKind)
}

diff := oldValue.Diff(newValue, resource.IsInternalPropertyKey)
Expand All @@ -1220,6 +1223,8 @@ func (p *propertyPrinter) printEncodedValueDiff(old, new string) bool {
return true
}

// decodeValue attempts to decode a string as JSON or YAML. The second return value is the kind of value that was
// decoded, either "json" or "yaml".
func (p *propertyPrinter) decodeValue(repr string) (resource.PropertyValue, string, bool) {
decode := func() (interface{}, string, bool) {
// Strip whitespace for the purposes of decoding.
Expand Down
64 changes: 64 additions & 0 deletions pkg/backend/display/testdata/json-yaml/json-text-change.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
{
"sequence": 0,
"timestamp": 1677074634,
"preludeEvent": {
"config": {}
}
}
{
"sequence": 3,
"timestamp": 1677074634,
"resourcePreEvent": {
"metadata": {
"op": "update",
"urn": "urn:pulumi:dev::pulumi-stack-output-diff::pulumi:pulumi:Stack::pulumi-stack-output-diff-dev",
"type": "pulumi:pulumi:Stack",
"old": {
"type": "pulumi:pulumi:Stack",
"urn": "urn:pulumi:dev::pulumi-stack-output-diff::pulumi:pulumi:Stack::pulumi-stack-output-diff-dev",
"id": "",
"parent": "",
"inputs": {},
"outputs": {
"vehicles": {
"taxi": "{\"color\":\"yellow\"}"
}
},
"provider": ""
},
"new": {
"type": "pulumi:pulumi:Stack",
"urn": "urn:pulumi:dev::pulumi-stack-output-diff::pulumi:pulumi:Stack::pulumi-stack-output-diff-dev",
"id": "",
"parent": "",
"inputs": {},
"outputs": {
"vehicles": {
"taxi": "{\"color\": \"yellow\" }"
}
},
"provider": ""
},
"logical": true,
"provider": ""
},
"planning": true
}
}
{
"sequence": 21,
"timestamp": 1677074635,
"summaryEvent": {
"maybeCorrupt": false,
"durationSeconds": 0,
"resourceChanges": {
"update": 1
},
"PolicyPacks": {}
}
}
{
"sequence": 22,
"timestamp": 1677074635,
"cancelEvent": {}
}
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<{%reset%}>Configuration:<{%reset%}>
<{%fg 3%}>~ pulumi:pulumi:Stack: (update)
<{%reset%}> [urn=urn:pulumi:dev::pulumi-stack-output-diff::pulumi:pulumi:Stack::pulumi-stack-output-diff-dev]
<{%reset%}><{%fg 3%}> ~ vehicles: <{%reset%}><{%fg 3%}>{
<{%reset%}><{%fg 3%}> ~ taxi: <{%reset%}><{%fg 3%}>"<{%reset%}><{%reset%}>\"{\\\"color\\\":<{%reset%}><{%reset%}>\\\"yellow\\\"<{%reset%}><{%reset%}>}\"<{%reset%}><{%fg 3%}>"<{%reset%}><{%fg 3%}> => <{%reset%}><{%fg 3%}>"<{%reset%}><{%reset%}>\"{\\\"color\\\":<{%reset%}><{%fg 2%}> <{%reset%}><{%reset%}>\\\"yellow\\\"<{%reset%}><{%fg 2%}> <{%reset%}><{%reset%}>}\"<{%reset%}><{%fg 3%}>"
<{%reset%}><{%fg 3%}> }
<{%reset%}><{%reset%}><{%fg 13%}><{%bold%}>Resources:<{%reset%}>
<{%fg 3%}>~ 1 updated<{%reset%}>

<{%fg 13%}><{%bold%}>Duration:<{%reset%}> 0s
64 changes: 64 additions & 0 deletions pkg/backend/display/testdata/json-yaml/json.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
{
"sequence": 0,
"timestamp": 1677074634,
"preludeEvent": {
"config": {}
}
}
{
"sequence": 3,
"timestamp": 1677074634,
"resourcePreEvent": {
"metadata": {
"op": "update",
"urn": "urn:pulumi:dev::pulumi-stack-output-diff::pulumi:pulumi:Stack::pulumi-stack-output-diff-dev",
"type": "pulumi:pulumi:Stack",
"old": {
"type": "pulumi:pulumi:Stack",
"urn": "urn:pulumi:dev::pulumi-stack-output-diff::pulumi:pulumi:Stack::pulumi-stack-output-diff-dev",
"id": "",
"parent": "",
"inputs": {},
"outputs": {
"vehicles": {
"taxi": "{\"color\":\"yellow\"}"
}
},
"provider": ""
},
"new": {
"type": "pulumi:pulumi:Stack",
"urn": "urn:pulumi:dev::pulumi-stack-output-diff::pulumi:pulumi:Stack::pulumi-stack-output-diff-dev",
"id": "",
"parent": "",
"inputs": {},
"outputs": {
"vehicles": {
"taxi": "{\"color\":\"red\"}"
}
},
"provider": ""
},
"logical": true,
"provider": ""
},
"planning": true
}
}
{
"sequence": 21,
"timestamp": 1677074635,
"summaryEvent": {
"maybeCorrupt": false,
"durationSeconds": 0,
"resourceChanges": {
"update": 1
},
"PolicyPacks": {}
}
}
{
"sequence": 22,
"timestamp": 1677074635,
"cancelEvent": {}
}
Empty file.
12 changes: 12 additions & 0 deletions pkg/backend/display/testdata/json-yaml/json.json.stdout.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<{%reset%}>Configuration:<{%reset%}>
<{%fg 3%}>~ pulumi:pulumi:Stack: (update)
<{%reset%}> [urn=urn:pulumi:dev::pulumi-stack-output-diff::pulumi:pulumi:Stack::pulumi-stack-output-diff-dev]
<{%reset%}><{%fg 3%}> ~ vehicles: <{%reset%}><{%fg 3%}>{
<{%reset%}><{%fg 3%}> ~ taxi: <{%reset%}><{%fg 3%}>(json) <{%reset%}><{%fg 3%}>{
<{%reset%}><{%fg 3%}> ~ color: <{%reset%}><{%fg 3%}>"<{%reset%}><{%fg 1%}>yellow<{%reset%}><{%fg 3%}>"<{%reset%}><{%fg 3%}> => <{%reset%}><{%fg 3%}>"<{%reset%}><{%fg 2%}>red<{%reset%}><{%fg 3%}>"
<{%reset%}><{%fg 3%}> }
<{%reset%}><{%fg 3%}> }
<{%reset%}><{%reset%}><{%fg 13%}><{%bold%}>Resources:<{%reset%}>
<{%fg 3%}>~ 1 updated<{%reset%}>

<{%fg 13%}><{%bold%}>Duration:<{%reset%}> 0s
64 changes: 64 additions & 0 deletions pkg/backend/display/testdata/json-yaml/yaml-text-change.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
{
"sequence": 0,
"timestamp": 1677074634,
"preludeEvent": {
"config": {}
}
}
{
"sequence": 3,
"timestamp": 1677074634,
"resourcePreEvent": {
"metadata": {
"op": "update",
"urn": "urn:pulumi:dev::pulumi-stack-output-diff::pulumi:pulumi:Stack::pulumi-stack-output-diff-dev",
"type": "pulumi:pulumi:Stack",
"old": {
"type": "pulumi:pulumi:Stack",
"urn": "urn:pulumi:dev::pulumi-stack-output-diff::pulumi:pulumi:Stack::pulumi-stack-output-diff-dev",
"id": "",
"parent": "",
"inputs": {},
"outputs": {
"vehicles": {
"taxi": "color: yellow\ntype: car"
}
},
"provider": ""
},
"new": {
"type": "pulumi:pulumi:Stack",
"urn": "urn:pulumi:dev::pulumi-stack-output-diff::pulumi:pulumi:Stack::pulumi-stack-output-diff-dev",
"id": "",
"parent": "",
"inputs": {},
"outputs": {
"vehicles": {
"taxi": "# a comment\ncolor: yellow \ntype: car"
}
},
"provider": ""
},
"logical": true,
"provider": ""
},
"planning": true
}
}
{
"sequence": 21,
"timestamp": 1677074635,
"summaryEvent": {
"maybeCorrupt": false,
"durationSeconds": 0,
"resourceChanges": {
"update": 1
},
"PolicyPacks": {}
}
}
{
"sequence": 22,
"timestamp": 1677074635,
"cancelEvent": {}
}
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<{%reset%}>Configuration:<{%reset%}>
<{%fg 3%}>~ pulumi:pulumi:Stack: (update)
<{%reset%}> [urn=urn:pulumi:dev::pulumi-stack-output-diff::pulumi:pulumi:Stack::pulumi-stack-output-diff-dev]
<{%reset%}><{%fg 3%}> ~ vehicles: <{%reset%}><{%fg 3%}>{
<{%reset%}><{%fg 3%}> ~ taxi: <{%reset%}><{%fg 3%}>"<{%reset%}><{%reset%}>\"<{%reset%}><{%reset%}>color: yellow<{%reset%}><{%reset%}>\\ntype: car\"<{%reset%}><{%fg 3%}>"<{%reset%}><{%fg 3%}> => <{%reset%}><{%fg 3%}>"<{%reset%}><{%reset%}>\"<{%reset%}><{%fg 2%}># a comment\\n<{%reset%}><{%reset%}>color: yellow<{%reset%}><{%fg 2%}> <{%reset%}><{%reset%}>\\ntype: car\"<{%reset%}><{%fg 3%}>"
<{%reset%}><{%fg 3%}> }
<{%reset%}><{%reset%}><{%fg 13%}><{%bold%}>Resources:<{%reset%}>
<{%fg 3%}>~ 1 updated<{%reset%}>

<{%fg 13%}><{%bold%}>Duration:<{%reset%}> 0s
64 changes: 64 additions & 0 deletions pkg/backend/display/testdata/json-yaml/yaml.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
{
"sequence": 0,
"timestamp": 1677074634,
"preludeEvent": {
"config": {}
}
}
{
"sequence": 3,
"timestamp": 1677074634,
"resourcePreEvent": {
"metadata": {
"op": "update",
"urn": "urn:pulumi:dev::pulumi-stack-output-diff::pulumi:pulumi:Stack::pulumi-stack-output-diff-dev",
"type": "pulumi:pulumi:Stack",
"old": {
"type": "pulumi:pulumi:Stack",
"urn": "urn:pulumi:dev::pulumi-stack-output-diff::pulumi:pulumi:Stack::pulumi-stack-output-diff-dev",
"id": "",
"parent": "",
"inputs": {},
"outputs": {
"vehicles": {
"taxi": "color: yellow\ntype: car"
}
},
"provider": ""
},
"new": {
"type": "pulumi:pulumi:Stack",
"urn": "urn:pulumi:dev::pulumi-stack-output-diff::pulumi:pulumi:Stack::pulumi-stack-output-diff-dev",
"id": "",
"parent": "",
"inputs": {},
"outputs": {
"vehicles": {
"taxi": "color: red\ntype: car"
}
},
"provider": ""
},
"logical": true,
"provider": ""
},
"planning": true
}
}
{
"sequence": 21,
"timestamp": 1677074635,
"summaryEvent": {
"maybeCorrupt": false,
"durationSeconds": 0,
"resourceChanges": {
"update": 1
},
"PolicyPacks": {}
}
}
{
"sequence": 22,
"timestamp": 1677074635,
"cancelEvent": {}
}
Empty file.
13 changes: 13 additions & 0 deletions pkg/backend/display/testdata/json-yaml/yaml.json.stdout.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<{%reset%}>Configuration:<{%reset%}>
<{%fg 3%}>~ pulumi:pulumi:Stack: (update)
<{%reset%}> [urn=urn:pulumi:dev::pulumi-stack-output-diff::pulumi:pulumi:Stack::pulumi-stack-output-diff-dev]
<{%reset%}><{%fg 3%}> ~ vehicles: <{%reset%}><{%fg 3%}>{
<{%reset%}><{%fg 3%}> ~ taxi: <{%reset%}><{%fg 3%}>(yaml) <{%reset%}><{%fg 3%}>{
<{%reset%}><{%fg 3%}> ~ color: <{%reset%}><{%fg 3%}>"<{%reset%}><{%fg 1%}>yellow<{%reset%}><{%fg 3%}>"<{%reset%}><{%fg 3%}> => <{%reset%}><{%fg 3%}>"<{%reset%}><{%fg 2%}>red<{%reset%}><{%fg 3%}>"
<{%reset%}><{%reset%}> type : <{%reset%}><{%reset%}>"car"<{%reset%}><{%reset%}>
<{%reset%}><{%fg 3%}> }
<{%reset%}><{%fg 3%}> }
<{%reset%}><{%reset%}><{%fg 13%}><{%bold%}>Resources:<{%reset%}>
<{%fg 3%}>~ 1 updated<{%reset%}>

<{%fg 13%}><{%bold%}>Duration:<{%reset%}> 0s

0 comments on commit f5ee11e

Please sign in to comment.