$ jdiff.py from-file to-file
Last active
August 29, 2015 14:22
-
-
Save jroelofs/8d410621a6ea168c75fe to your computer and use it in GitHub Desktop.
Diff program for JSON dictionaries
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
import sys | |
import json | |
def string_from_keypath(keypath): | |
return 'dict["' + ('"]["'.join(keypath)) + '"]' | |
class ValueChange(object): | |
def __init__(self, keypath, lhs, rhs): | |
self.keypath = keypath | |
self.lhs = lhs | |
self.rhs = rhs | |
def dump(self): | |
print "@@ ", string_from_keypath(self.keypath), " @@" | |
print "- ", self.lhs | |
print "+ ", self.rhs | |
class KeyAddition(object): | |
def __init__(self, keypath, value): | |
self.keypath = keypath | |
self.value = value | |
def dump(self): | |
print "@@ ", string_from_keypath(self.keypath), " @@" | |
print "+ ", self.value | |
class KeyDeletion(object): | |
def __init__(self, keypath, value): | |
self.keypath = keypath | |
self.value = value | |
def dump(self): | |
print "@@ ", string_from_keypath(self.keypath), " @@" | |
print "- ", self.value | |
def recursive_diff(keypath, lhs, rhs): | |
if type(lhs) != type(rhs): | |
return [ValueChange(keypath, lhs, rhs)] | |
if type(rhs) != dict: | |
if lhs != rhs: | |
return [ValueChange(keypath, lhs, rhs)] | |
else: | |
return [] | |
changes = [] | |
for key in lhs.keys(): | |
if key not in rhs.keys(): | |
changes += [KeyDeletion(keypath + [key], lhs[key])] | |
for key in rhs.keys(): | |
if key not in lhs.keys(): | |
changes += [KeyAddition(keypath + [key], rhs[key])] | |
for key in lhs.keys(): | |
if key in rhs.keys(): | |
changes += recursive_diff(keypath + [key], lhs[key], rhs[key]) | |
return changes | |
def main(): | |
lhs_filename = sys.argv[1] | |
with open(lhs_filename, "r") as lhs_file: | |
lhs_text = lhs_file.read() | |
lhs = json.loads(lhs_text) | |
rhs_filename = sys.argv[2] | |
with open(rhs_filename, "r") as rhs_file: | |
rhs_text = rhs_file.read() | |
rhs = json.loads(rhs_text) | |
changes = recursive_diff([], lhs, rhs) | |
if len(changes) == 0: | |
sys.exit(0) | |
print "--- ", sys.argv[1] | |
print "+++ ", sys.argv[2] | |
for change in changes: | |
change.dump() | |
sys.exit(-1) | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment