Skip to content

Instantly share code, notes, and snippets.

@blepfo
Last active October 7, 2019 22:45
Show Gist options
  • Save blepfo/5defe98d22cc230bf42f686cd7709e7d to your computer and use it in GitHub Desktop.
Save blepfo/5defe98d22cc230bf42f686cd7709e7d to your computer and use it in GitHub Desktop.
Simple utility to print difference between JSON files
/* 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