gliviu/dir-compare

Comparing files gives confusing result

rrthomas opened this issue · 4 comments

If the arguments to compareSync are two files, then the result of comparison is a little odd: it seems they are treated as if they were each contained in a directory, so the files are only considered the same if their names are the same.

But compareSync applied to two directories compares their contents; it should do the same for files.

I came across this issue because I have some code that normally compares directories, but in some cases it may only compare single files, and I had to special case this and not use dir-compare for the single files.

Thanks for dir-compare! A very handy piece of code.

The current behavior is exactly as you specified. Initially dir-compare was intended to work with directories. Later I added for convenience the ability to specify files as arguments but failed to make it right as you suggested.

I will think about it. It will definitely need to bump a major version as it breaks compatibility.

Meanwhile you can use custom-name-comparators to overcome this inconvenience.

var dircompare = require('./build/src/index.js');

var options = {
    compareSize: true,
    compareContent: false,
    compareNameHandler: customNameCompare,
    compareFiles: true // Change this to 'false' to go back to old behavior
};

var path1 = '/.../test.js';
var path2 = '/.../test2.js';

function customNameCompare(name1, name2, options) {
    if(options.compareFiles){
        return 0  // ignore differences in file names
    }
    return ((name1 === name2) ? 0 : ((name1 > name2) ? 1 : -1))  // default name comparator
}

var res = dircompare.compareSync(path1, path2, options);

Thanks very much for the quick response and workaround! I look forward to an eventual new release.

Issue fixed in v4.0.0.

Lets consider these directories as example.

d1
  a1.txt (size=1)
  a2.txt (size=1)
d2
  a1.txt (size=2)
  a2.txt (size=2)

Following table shows the difference from v3.x to v4.0.0 when calling compare() or compareSync(). In this example the comparison is done by size (Options.compareSize=true) so d1/a1==d1/a2 and d2/a1==d2/a2.

compare() v3.x v4.0.0 Notes
compare('d1/a1.txt', 'd1/a2.txt') a1.txt != a2.txt a1.txt == a2.txt v3 shows !=
because file names
are different
compare('d1/a1.txt', 'd1/a1.txt') a1.txt == a1.txt a1.txt == a1.txt
compare('d1/a1.txt', 'd2/a1.txt') a1.txt != a1.txt a1.txt != a1.txt
compare('d1/a1.txt', 'd2/a2.txt') a1.txt != a2.txt a1.txt != a2.txt
compare('d1', 'd2/a2.txt') d1/a1.txt != missing
d1/a2.txt != d2/a2.txt
d1 != d2/a2.txt v3 compares d2/a2.txt
against the content of d1.
v4 will return false immediatly
without traveling the contents of d1.

Thanks very much for this; I was able to simplify my code exactly as I hoped.