summaryrefslogtreecommitdiff
path: root/node_modules/dir-compare/src/compareAsync.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/dir-compare/src/compareAsync.js')
-rw-r--r--node_modules/dir-compare/src/compareAsync.js141
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