Last active
October 7, 2019 22:45
-
-
Save blepfo/5defe98d22cc230bf42f686cd7709e7d to your computer and use it in GitHub Desktop.
Simple utility to print difference between JSON files
This file contains hidden or 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
/* Print out differences between two JSON files | |
*/ | |
'use strict' | |
const _ = require('lodash'); | |
const path = require('path'); | |
/** | |
* Print out all differences between two objects | |
* @param a - First object | |
* @param b - Second object | |
* @param a_name - Name of first object | |
* @param b_name - Name of second object | |
* @param prefix - Used during recursive calls to keep track of subobject keys. | |
*/ | |
function diff(a, b, a_name, b_name, prefix='') { | |
// If prefix is nonempty, it is a key and needs a | |
const pref = (prefix == '') | |
? prefix | |
: `${prefix}.` | |
const a_keys = new Set(_.keys(a)); | |
const b_keys = new Set(_.keys(b)); | |
const not_in_b = [...a_keys].filter(x => !b_keys.has(x)); | |
if(not_in_b.length > 0) | |
console.log(`Keys not in ${b_name}: ${_.map(not_in_b, (key) => pref + key.toString())}`); | |
const not_in_a = [...b_keys].filter(x => !a_keys.has(x)); | |
if(not_in_a.length > 0) | |
console.log(`Keys not in ${a_name}: ${_.map(not_in_a, (key) => pref + key.toString())}`); | |
const keys_in_both = [...a_keys].filter(x => b_keys.has(x)); | |
keys_in_both.forEach((key) => { | |
// Deep equality check | |
if(!_.isEqual(a[key], b[key])) { | |
// Recursively check subobjects for differences | |
if(a[key] instanceof Object || b[key] instanceof Object) { | |
diff(a[key], b[key], a_name, b_name, `${pref}${key}`); | |
} | |
else { | |
// Case where one value is int and another is string | |
if(a[key].toString() == b[key].toString()) | |
console.log(`${pref}${key}: ${a_name}==${a[key]} is type ${typeof(a[key])}, but ${b_name}==${b[key]} is type ${typeof(b[key])}`); | |
else | |
console.log(`${pref}${key}: ${a_name}==${a[key]} != ${b_name}==${b[key]}`); | |
} | |
} | |
}); | |
} | |
if(process.argv.length < 4) { | |
throw Error("You must provide 2 JSON files to diff"); | |
} | |
const file1 = process.argv[2]; | |
const file2 = process.argv[3]; | |
let a = undefined | |
try { | |
a = require(file1); | |
} | |
catch (e) { | |
console.log(`Unable to load JSON from file ${file1}`); | |
throw e; | |
} | |
let b = undefined | |
try { | |
b = require(file2); | |
} | |
catch (e) { | |
console.log(`Unable to load JSON from file ${file2}`); | |
throw e | |
} | |
const a_name = path.basename(file1).replace('.json', ''); | |
const b_name = path.basename(file2).replace('.json', ''); | |
console.log(''); | |
diff(a, b, a_name, b_name); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment