0

How do I create a diff of two json objects such that they are in the manual diff format which can be sent to reviewboard? I need to generate the diff from inside a python script.I think manual diffs are generated using the "diff file1 file2" command line utility. Can I generate a similar reviewboard compatible diff using difflib? Or is there another library that I need to use? Thanks!

user1427026
  • 861
  • 2
  • 16
  • 32
  • 2
    I have no idea what format reviewboard takes, but if diff'ing JSON, make sure to emit the keys in a particular well-defined order for best results (this will vary based on JSON generator, as dictionaries are technically orderless). –  Oct 26 '12 at 03:19
  • Thanks for the tip! Are there any built in diff libraries in python that you'd suggest? Would something like difflib.context_diff work? – user1427026 Oct 26 '12 at 03:25
  • Just to add reviewboard uses Myers Diff, I think they should be able to handle display my side by side json diff once I send them a prudely generated manual diff. However, I cant figure out the format I need to send them this diff in:((python equivalent of commandline diff i guess) The keys tip is useful though and since its json and not textual diff I'll keep in mind that my json diff is generated as expected! – user1427026 Oct 26 '12 at 03:32

2 Answers2

1

Use difflib:

def show_diff(seqm):
    output= []
    for opcode, a0, a1, b0, b1 in seqm.get_opcodes():
        if opcode == 'equal':
            output.append(seqm.a[a0:a1])
        elif opcode == 'insert':
            output.append("<ins>" + seqm.b[b0:b1] + "</ins>")
        elif opcode == 'delete':
            output.append("<del>" + seqm.a[a0:a1] + "</del>")
        elif opcode == 'replace':
            output.append("<del>" + seqm.a[a0:a1] + "</del>" + "<ins>" + seqm.b[b0:b1] + "</ins>" )
        else:
            raise RuntimeError, "Unexpected opcode"
    return ''.join(output)

In your situation, you compare your json files (I just used dummy text):

In [4]: sm = difflib.SequenceMatcher(None, 'hello', 'hello world')

In [6]: diff = show_diff(sm)

In [7]: diff
Out[7]: 'hello<ins> world</ins>'

Look at the documentation if you need a different output from difflib

r_31415
  • 8,752
  • 17
  • 74
  • 121
1

I just think before going through diff, you should reformat JSON object lets say on alphabetical and numeric order.

Supreet Sethi
  • 1,780
  • 14
  • 24