Skip to content

Commit

Permalink
Merge pull request #31 from dionysius/opt_zeroasnull
Browse files Browse the repository at this point in the history
Add option ZeroAsNull (Fixes: #30)
  • Loading branch information
sters committed Jan 26, 2023
2 parents a2ffbae + 6d590cd commit f440c3a
Show file tree
Hide file tree
Showing 5 changed files with 282 additions and 0 deletions.
4 changes: 4 additions & 0 deletions cmd/yaml-diff/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (

func main() {
ignoreEmptyFields := flag.Bool("ignore-empty-fields", false, "Ignore empty field")
ignoreZeroFields := flag.Bool("ignore-zero-fields", false, "Ignore zero field")
flag.Parse()

args := flag.Args()
Expand All @@ -36,6 +37,9 @@ func main() {
if *ignoreEmptyFields {
opts = append(opts, yamldiff.EmptyAsNull())
}
if *ignoreZeroFields {
opts = append(opts, yamldiff.ZeroAsNull())
}

fmt.Printf("--- %s\n+++ %s\n\n", file1, file2)
for _, diff := range yamldiff.Do(yamls1, yamls2, opts...) {
Expand Down
5 changes: 5 additions & 0 deletions yamldiff/diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package yamldiff

import (
"fmt"
"reflect"

"github.com/goccy/go-yaml"
)
Expand Down Expand Up @@ -312,6 +313,8 @@ func (r *runner) handlePrimitive(rawA rawType, rawB rawType, level int) *diff {
case rawA == missingKey:
if r.option.emptyAsNull && (rawB == nil || string(strB) == "{}" || string(strB) == "[]") {
result.status = DiffStatusSame
} else if r.option.zeroAsNull && (reflect.ValueOf(rawB).IsValid() && reflect.ValueOf(rawB).IsZero()) {
result.status = DiffStatusSame
} else {
result.a = nil
result.status = DiffStatus1Missing
Expand All @@ -321,6 +324,8 @@ func (r *runner) handlePrimitive(rawA rawType, rawB rawType, level int) *diff {
case rawB == missingKey:
if r.option.emptyAsNull && rawA == nil {
result.status = DiffStatusSame
} else if r.option.zeroAsNull && (reflect.ValueOf(rawA).IsValid() && reflect.ValueOf(rawA).IsZero()) {
result.status = DiffStatusSame
} else {
result.b = nil
result.status = DiffStatus2Missing
Expand Down
176 changes: 176 additions & 0 deletions yamldiff/diff_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,80 @@ func Test_performDiff(t *testing.T) {
},
},
},
"#30": {
"zero string": {
a: rawTypeMap{
yaml.MapItem{Key: "strA", Value: "foo"},
yaml.MapItem{Key: "strB", Value: ""},
yaml.MapItem{Key: "strC", Value: ""},
},
b: rawTypeMap{
yaml.MapItem{Key: "strA", Value: "foo"},
yaml.MapItem{Key: "strB", Value: ""},
},
want: &diff{
children: &diffChildren{
m: diffChildrenMap{
"strA": &diff{
status: DiffStatusSame,
a: "foo",
b: "foo",
treeLevel: 1,
},
"strB": &diff{
status: DiffStatusSame,
a: "",
b: "",
treeLevel: 1,
},
"strC": &diff{
status: DiffStatus2Missing,
a: "",
treeLevel: 1,
},
},
},
status: DiffStatusDiff,
},
},
"zero int": {
a: rawTypeMap{
yaml.MapItem{Key: "intA", Value: 5},
yaml.MapItem{Key: "intB", Value: 0},
yaml.MapItem{Key: "intC", Value: 0},
},
b: rawTypeMap{
yaml.MapItem{Key: "intA", Value: 5},
yaml.MapItem{Key: "intB", Value: 0},
},
want: &diff{
children: &diffChildren{
m: diffChildrenMap{
"intA": &diff{
status: DiffStatusSame,
a: 5,
b: 5,
treeLevel: 1,
},
"intB": &diff{
status: DiffStatusSame,
a: 0,
b: 0,
treeLevel: 1,
},
"intC": &diff{
status: DiffStatus2Missing,
a: 0,
diffCount: 1,
treeLevel: 1,
},
},
},
diffCount: 1,
status: DiffStatusDiff,
},
},
},
}
for n, tt := range tests {
tt := tt
Expand Down Expand Up @@ -612,3 +686,105 @@ func Test_performDiff_emptyAsNull(t *testing.T) {
})
}
}

func Test_performDiff_zeroAsNull(t *testing.T) {
tests := map[string]map[string]struct {
a rawType
b rawType
want *diff
}{
"#30": {
"zero string": {
a: rawTypeMap{
yaml.MapItem{Key: "strA", Value: "foo"},
yaml.MapItem{Key: "strB", Value: ""},
yaml.MapItem{Key: "strC", Value: ""},
},
b: rawTypeMap{
yaml.MapItem{Key: "strA", Value: "foo"},
yaml.MapItem{Key: "strB", Value: ""},
},
want: &diff{
children: &diffChildren{
m: diffChildrenMap{
"strA": &diff{
status: DiffStatusSame,
a: "foo",
b: "foo",
treeLevel: 1,
},
"strB": &diff{
status: DiffStatusSame,
a: "",
b: "",
treeLevel: 1,
},
"strC": &diff{
status: DiffStatusSame,
a: "",
b: missingKey,
treeLevel: 1,
},
},
},
status: DiffStatusSame,
},
},
"zero int": {
a: rawTypeMap{
yaml.MapItem{Key: "intA", Value: 5},
yaml.MapItem{Key: "intB", Value: 0},
yaml.MapItem{Key: "intC", Value: 0},
},
b: rawTypeMap{
yaml.MapItem{Key: "intA", Value: 5},
yaml.MapItem{Key: "intB", Value: 0},
},
want: &diff{
children: &diffChildren{
m: diffChildrenMap{
"intA": &diff{
status: DiffStatusSame,
a: 5,
b: 5,
treeLevel: 1,
},
"intB": &diff{
status: DiffStatusSame,
a: 0,
b: 0,
treeLevel: 1,
},
"intC": &diff{
status: DiffStatusSame,
a: 0,
b: missingKey,
treeLevel: 1,
},
},
},
status: DiffStatusSame,
},
},
},
}
for n, tt := range tests {
tt := tt
t.Run(n, func(t *testing.T) {
// t.Parallel()

for n, tc := range tt {
tc := tc
t.Run(n, func(t *testing.T) {
// t.Parallel()

got := (&runner{option: doOptions{zeroAsNull: true}}).performDiff(tc.a, tc.b, 0)

tc.want.a = tc.a
tc.want.b = tc.b
assert.Equal(t, tc.want, got)
})
}
})
}
}
7 changes: 7 additions & 0 deletions yamldiff/yaml.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ func (y *YamlDiff) Dump() string {

type doOptions struct {
emptyAsNull bool
zeroAsNull bool
}

type DoOptionFunc func(o *doOptions)
Expand All @@ -79,6 +80,12 @@ func EmptyAsNull() DoOptionFunc {
}
}

func ZeroAsNull() DoOptionFunc {
return func(o *doOptions) {
o.zeroAsNull = true
}
}

func Do(rawA RawYamlList, rawB RawYamlList, options ...DoOptionFunc) []*YamlDiff {
opts := &doOptions{}
for _, o := range options {
Expand Down
90 changes: 90 additions & 0 deletions yamldiff/yaml_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ this:
is:
the: same
empty:
---
someStr: foo
zeroStr: ""
someInt: 5
zeroInt: 0
differs: fromA
`
yamlB := `
metadata:
Expand Down Expand Up @@ -95,6 +101,10 @@ baz:
this:
is:
the: same
---
someStr: foo
someInt: 5
differs: fromB
`

yamlsA, err := Load(yamlA)
Expand All @@ -119,6 +129,7 @@ this:

confirm(resultOfNoOptions(), []DoOptionFunc{})
confirm(resultOfWithEmpty(), []DoOptionFunc{EmptyAsNull()})
confirm(resultOfWithZero(), []DoOptionFunc{ZeroAsNull()})
}

func resultOfNoOptions() string {
Expand Down Expand Up @@ -170,6 +181,13 @@ func resultOfNoOptions() string {
the: "same"
- empty:
someStr: "foo"
- zeroStr: ""
someInt: 5
- zeroInt: 0
- differs: "fromA"
+ differs: "fromB"
+ bar:
+ - "missing in a.yaml"
Expand Down Expand Up @@ -228,6 +246,78 @@ func resultOfWithEmpty() string {
the: "same"
empty:
someStr: "foo"
- zeroStr: ""
someInt: 5
- zeroInt: 0
- differs: "fromA"
+ differs: "fromB"
+ bar:
+ - "missing in a.yaml"
+ baz:
+ - "missing in a.yaml"
`
}

func resultOfWithZero() string {
return `
apiVersion: "v1"
kind: "Service"
metadata:
name: "my-service"
spec:
selector:
app: "MyApp"
ports:
-
protocol: "TCP"
- port: 80
+ port: 8080
targetPort: 9376
apiVersion: "apps/v1"
kind: "Deployment"
metadata:
name: "app-deployment"
labels:
app: "MyApp"
spec:
- replicas: 3
+ replicas: 10
selector:
matchLabels:
app: "MyApp"
template:
metadata:
labels:
app: "MyApp"
spec:
containers:
-
name: "app"
- image: "my-app:1.0.0"
+ image: "my-app:1.1.0"
ports:
-
containerPort: 9376
- foo: "missing-in-b"
this:
is:
the: "same"
- empty:
someStr: "foo"
zeroStr: ""
someInt: 5
zeroInt: 0
- differs: "fromA"
+ differs: "fromB"
+ bar:
+ - "missing in a.yaml"
Expand Down

0 comments on commit f440c3a

Please sign in to comment.