This is an automated email from the ASF dual-hosted git repository.

sebb pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/whimsy.git


The following commit(s) were added to refs/heads/master by this push:
     new b8627d18 Initial stab at comparing JSON files
b8627d18 is described below

commit b8627d18d4f30b353b46cc8583312828ab287d9d
Author: Sebb <s...@apache.org>
AuthorDate: Sun Feb 25 15:27:44 2024 +0000

    Initial stab at comparing JSON files
---
 lib/whimsy/asf/json-utils.rb | 69 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 69 insertions(+)

diff --git a/lib/whimsy/asf/json-utils.rb b/lib/whimsy/asf/json-utils.rb
new file mode 100644
index 00000000..f07a730e
--- /dev/null
+++ b/lib/whimsy/asf/json-utils.rb
@@ -0,0 +1,69 @@
+# JSON utilities
+
+# This addon must be required before use
+
+require 'json'
+
+module ASFJSON
+  # Compare JSON files
+  # bc = breadcrumb
+  # yield the changes for subsequent processing:
+  # bc, type (Dropped, Scalar, Array, Added), key, args (scalar or array)
+  def self.cmphash(h1, h2, bc=nil, &block)
+    bc ||= ['root']
+    h1.each do |k, v1|
+      v2 = h2[k]
+      if v2.nil?
+        yield [bc, 'Dropped', k, v1]
+      elsif v1 != v2
+        case v1.class.to_s
+        when 'String', 'Integer'
+          yield [bc, 'Scalar', k, [v1, v2]]
+        when 'Array'
+          yield [bc, 'Array', k, [v1, v2]]
+        when 'Hash'
+          self.cmphash v1, v2, [bc,k].flatten, &block
+        else
+          raise ArgumentError.new "#{bc.join('.')} #{k} Unexpected class 
#{v1.class}"
+        end
+      end
+    end
+    # Now deal with items not in old (other items have been compared?)
+    h2.each do |k,v2|
+      v1 = h1[k]
+      if v1.nil?
+        yield [bc, 'Added', k, v2]
+      end
+    end
+  end
+
+  # Sample method to process differences
+  def self.compare_json(old_json, new_json, out=$stdout)
+    cmphash old_json, new_json do |bc, type, key, args|
+      bcj = bc.join('.')
+      case type
+      when 'Scalar'
+        v1, v2 = args
+        out.puts [bcj, key, v1, '=>', v2].inspect
+      when 'Array'
+        v1, v2 = args
+        out.puts  [bcj, 'Dropped', v1-v2, 'Added', v2-v1].inspect
+      when 'Dropped'
+        out.puts  [bcj, 'Dropped', key, args].inspect
+      when 'Added'
+        out.puts  [bcj, 'Added', key, args].inspect
+      else
+        raise ArgumentError.new "Unexpected type: #{type} in #{bc} #{key}"
+      end
+    end
+  end
+
+end
+
+if __FILE__ == $0
+  old_file = ARGV.shift or raise ArgumentError.new "Old file!"
+  new_file = ARGV.shift or raise ArgumentError.new "New file!"
+  old_json = JSON.parse(File.read(old_file))
+  new_json = JSON.parse(File.read(new_file))
+  ASFJSON.compare_json(old_json, new_json)
+end

Reply via email to