diff options
Diffstat (limited to 'node_modules/dir-compare/src/compareAsync.js')
-rw-r--r-- | node_modules/dir-compare/src/compareAsync.js | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/node_modules/dir-compare/src/compareAsync.js b/node_modules/dir-compare/src/compareAsync.js new file mode 100644 index 0000000..26a9d68 --- /dev/null +++ b/node_modules/dir-compare/src/compareAsync.js @@ -0,0 +1,141 @@ +var fs = require('fs') +var entryBuilder = require('./entry/entryBuilder') +var entryEquality = require('./entry/entryEquality') +var stats = require('./statistics/statisticsUpdate') +var pathUtils = require('path') +var fsPromise = require('./fs/fsPromise') +var loopDetector = require('./symlink/loopDetector') +var entryComparator = require('./entry/entryComparator') +var entryType = require('./entry/entryType') + +/** + * Returns the sorted list of entries in a directory. + */ +var getEntries = function (rootEntry, relativePath, loopDetected, options) { + if (!rootEntry || loopDetected) { + return Promise.resolve([]) + } + if (rootEntry.isDirectory) { + return fsPromise.readdir(rootEntry.absolutePath) + .then(function (entries) { + return entryBuilder.buildDirEntries(rootEntry, entries, relativePath, options) + }) + } + return Promise.resolve([rootEntry]) +} + +/** + * Compares two directories asynchronously. + */ +var compare = function (rootEntry1, rootEntry2, level, relativePath, options, statistics, diffSet, symlinkCache) { + var loopDetected1 = loopDetector.detectLoop(rootEntry1, symlinkCache.dir1) + var loopDetected2 = loopDetector.detectLoop(rootEntry2, symlinkCache.dir2) + loopDetector.updateSymlinkCache(symlinkCache, rootEntry1, rootEntry2, loopDetected1, loopDetected2) + + return Promise.all([getEntries(rootEntry1, relativePath, loopDetected1, options), getEntries(rootEntry2, relativePath, loopDetected2, options)]).then( + function (entriesResult) { + var entries1 = entriesResult[0] + var entries2 = entriesResult[1] + var i1 = 0, i2 = 0 + var comparePromises = [] + var compareFilePromises = [] + var subDiffSet + + while (i1 < entries1.length || i2 < entries2.length) { + var entry1 = entries1[i1] + var entry2 = entries2[i2] + var type1, type2 + + // compare entry name (-1, 0, 1) + var cmp + if (i1 < entries1.length && i2 < entries2.length) { + cmp = entryComparator.compareEntry(entry1, entry2, options) + type1 = entryType.getType(entry1) + type2 = entryType.getType(entry2) + } else if (i1 < entries1.length) { + type1 = entryType.getType(entry1) + type2 = entryType.getType(undefined) + cmp = -1 + } else { + type1 = entryType.getType(undefined) + type2 = entryType.getType(entry2) + cmp = 1 + } + + // process entry + if (cmp === 0) { + // Both left/right exist and have the same name and type + var compareAsyncRes = entryEquality.isEntryEqualAsync(entry1, entry2, type1, diffSet, options) + var samePromise = compareAsyncRes.samePromise + var same = compareAsyncRes.same + if (same !== undefined) { + options.resultBuilder(entry1, entry2, + same ? 'equal' : 'distinct', + level, relativePath, options, statistics, diffSet, + compareAsyncRes.reason) + stats.updateStatisticsBoth(entry1, entry2, compareAsyncRes.same, compareAsyncRes.reason, type1, statistics, options) + } else { + compareFilePromises.push(samePromise) + } + + i1++ + i2++ + if (!options.skipSubdirs && type1 === 'directory') { + if (!options.noDiffSet) { + subDiffSet = [] + diffSet.push(subDiffSet) + } + comparePromises.push(compare(entry1, entry2, level + 1, + pathUtils.join(relativePath, entry1.name), + options, statistics, subDiffSet, loopDetector.cloneSymlinkCache(symlinkCache))) + } + } else if (cmp < 0) { + // Right missing + options.resultBuilder(entry1, undefined, 'left', level, relativePath, options, statistics, diffSet) + stats.updateStatisticsLeft(entry1, type1, statistics, options) + i1++ + if (type1 === 'directory' && !options.skipSubdirs) { + if (!options.noDiffSet) { + subDiffSet = [] + diffSet.push(subDiffSet) + } + comparePromises.push(compare(entry1, undefined, + level + 1, + pathUtils.join(relativePath, entry1.name), options, statistics, subDiffSet, loopDetector.cloneSymlinkCache(symlinkCache))) + } + } else { + // Left missing + options.resultBuilder(undefined, entry2, 'right', level, relativePath, options, statistics, diffSet) + stats.updateStatisticsRight(entry2, type2, statistics, options) + i2++ + if (type2 === 'directory' && !options.skipSubdirs) { + if (!options.noDiffSet) { + subDiffSet = [] + diffSet.push(subDiffSet) + } + comparePromises.push(compare(undefined, entry2, + level + 1, + pathUtils.join(relativePath, entry2.name), options, statistics, subDiffSet, loopDetector.cloneSymlinkCache(symlinkCache))) + } + } + } + return Promise.all(comparePromises).then(function () { + return Promise.all(compareFilePromises).then(function (sameResults) { + for (var i = 0; i < sameResults.length; i++) { + var sameResult = sameResults[i] + if (sameResult.error) { + return Promise.reject(sameResult.error) + } else { + options.resultBuilder(sameResult.entry1, sameResult.entry2, + sameResult.same ? 'equal' : 'distinct', + level, relativePath, options, statistics, sameResult.diffSet, + sameResult.reason) + stats.updateStatisticsBoth(sameResult.entries1, sameResult.entries2, sameResult.same, sameResult.reason, sameResult.type1, statistics, options) + } + } + }) + }) + }) +} + +module.exports = compare |