From 82f32b99c05f293c5ca990540f99f669ebf10b0a Mon Sep 17 00:00:00 2001 From: Aditya Thebe Date: Wed, 19 Jun 2024 16:16:35 +0545 Subject: [PATCH] feat: json diff --- diff/json.go | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ go.mod | 1 + go.sum | 2 ++ 3 files changed, 52 insertions(+) create mode 100644 diff/json.go diff --git a/diff/json.go b/diff/json.go new file mode 100644 index 0000000..9f13af2 --- /dev/null +++ b/diff/json.go @@ -0,0 +1,49 @@ +package diff + +import ( + "encoding/json" + "fmt" + + "github.com/hexops/gotextdiff" + "github.com/hexops/gotextdiff/myers" +) + +// JSONCompare calculates the diff (git style) between the given 2 configs. +func JSONCompare(newConf, prevConfig string) (string, error) { + // We want a nicely indented json config with each key-vals in new line + // because that gives us a better diff. A one-line json string config produces diff + // that's not very helpful. + before, err := normalizeJSON(prevConfig) + if err != nil { + return "", fmt.Errorf("failed to normalize json for previous config: %w", err) + } + + after, err := normalizeJSON(newConf) + if err != nil { + return "", fmt.Errorf("failed to normalize json for new config: %w", err) + } + + edits := myers.ComputeEdits("", before, after) + if len(edits) == 0 { + return "", nil + } + + diff := fmt.Sprint(gotextdiff.ToUnified("before", "after", before, edits)) + return diff, nil +} + +// normalizeJSON returns an indented json string. +// The keys are sorted lexicographically. +func normalizeJSON(jsonStr string) (string, error) { + var jsonStrMap map[string]any + if err := json.Unmarshal([]byte(jsonStr), &jsonStrMap); err != nil { + return "", err + } + + jsonStrIndented, err := json.MarshalIndent(jsonStrMap, "", "\t") + if err != nil { + return "", err + } + + return string(jsonStrIndented), nil +} diff --git a/go.mod b/go.mod index 4d95266..145c2b7 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ require ( github.com/google/uuid v1.5.0 github.com/hashicorp/go-getter v1.7.3 github.com/henvic/httpretty v0.1.2 + github.com/hexops/gotextdiff v1.0.3 github.com/kr/pretty v0.3.1 github.com/onsi/gomega v1.27.6 github.com/patrickmn/go-cache v2.1.0+incompatible diff --git a/go.sum b/go.sum index a7fa0ed..980de02 100644 --- a/go.sum +++ b/go.sum @@ -876,6 +876,8 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/henvic/httpretty v0.1.2 h1:EQo556sO0xeXAjP10eB+BZARMuvkdGqtfeS4Ntjvkiw= github.com/henvic/httpretty v0.1.2/go.mod h1:ViEsly7wgdugYtymX54pYp6Vv2wqZmNHayJ6q8tlKCc= +github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= +github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=