k1LoW / runn

runn is a package/tool for running operations following a scenario.
https://runn.run
MIT License
417 stars 30 forks source link

Add jq path syntax support for excluding comparison targets in diff()/compare() functions. #936

Closed h6ah4i closed 3 months ago

h6ah4i commented 3 months ago

Hi. This is an enhancement of the diff() and compare() built-in functions. The current ignoreKeys option can only filter out the root field(s) of an object, but it does not help in these situations:

The jq tool has powerful features that can be used in these situations. Luckily, there is a pure-Go implementation of jq called gojq, and runn is normalizing two values by JSON marshaling before comparison, so I can easily integrate gojq into the diff() and compare() functions 😉

Mechanism

For instance, if you specify ".foo", ".bar" for ignorePaths, it will be transformed into the jq query delpaths([(try path(.foo)), (try path(.bar))]) and applied before comparing the two values.

❯ echo '{"foo":1,"bar":2, "baz":3}' | jq 'delpaths([(try path(.foo)), (try path(.bar))])'
{
  "baz": 3
}

Examples

diff(vars.a, vars.b, "foo") --- supports specifying by key for backward compatibility
diff(vars.a, vars.b, ".foo")
diff(vars.a, vars.b, ".foo.bar")
diff(vars.a, vars.b, ".[].foo")
diff(vars.a, vars.b, ".[1].foo")
diff(vars.a, vars.b, ".. | .foo?")

jq References

k1LoW commented 3 months ago

Hi @h6ah4i. Looks great!

k1LoW commented 3 months ago

@k2tzumi I'd like you to have a look too, if you like 👍

h6ah4i commented 3 months ago

I have just updated my code to utilize the gojq#Compile() function. Here is the microbenchmarking result and we can see some improvements as expected 👍

Microbenchmark result

goos: darwin
goarch: amd64
pkg: github.com/k1LoW/runn/builtin
cpu: Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
BenchmarkTestCompareWithIgnoreKeys_Baseline
BenchmarkTestCompareWithIgnoreKeys_Baseline-16                  5036        671463 ns/op      231211 B/op       5713 allocs/op
BenchmarkTestCompareWithIgnoreKeys_JqQuery
BenchmarkTestCompareWithIgnoreKeys_JqQuery-16                   3589        905717 ns/op      505892 B/op       9459 allocs/op
BenchmarkTestCompareWithIgnoreKeys_JqQueryCompiled
BenchmarkTestCompareWithIgnoreKeys_JqQueryCompiled-16           4705        787820 ns/op      422435 B/op       7181 allocs/op
k1LoW commented 3 months ago

GREAT!

h6ah4i commented 3 months ago

@k2tzumi @k1LoW Hi. I have updated my code to use the cmp.FilterPath() function to preserve the current diff output as much as possible. Can you take a look at it? Thanks.

k1LoW commented 3 months ago

Wow!!!!!! GREAT WORK!!!!!!!!

k1LoW commented 3 months ago

@h6ah4i Sorry, can you resolve the conflict?

h6ah4i commented 3 months ago

@k1LoW Hi, I've just resolved the conflict!

k1LoW commented 3 months ago

@h6ah4i Thank you!!!!!!!!