1 | const fs = require('fs');
|
2 | const pathUtils = require('path');
|
3 | const entryBuilder = require('./entry/entryBuilder');
|
4 | const entryEquality = require('./entry/entryEquality');
|
5 | const stats = require('./statistics/statisticsUpdate');
|
6 | const loopDetector = require('./symlink/loopDetector');
|
7 | const entryComparator = require('./entry/entryComparator');
|
8 | const entryType = require('./entry/entryType');
|
9 | const { getPrmissionDenieStateWhenLeftMissing, getPrmissionDenieStateWhenRightMissing, getPermissionDeniedState } = require('./permissions/permissionDeniedState');
|
10 |
|
11 |
|
12 |
|
13 | function getEntries(rootEntry, relativePath, loopDetected, options) {
|
14 | if (!rootEntry || loopDetected) {
|
15 | return [];
|
16 | }
|
17 | if (rootEntry.isDirectory) {
|
18 | if (rootEntry.isPermissionDenied) {
|
19 | return [];
|
20 | }
|
21 | const entries = fs.readdirSync(rootEntry.absolutePath);
|
22 | return entryBuilder.buildDirEntries(rootEntry, entries, relativePath, options);
|
23 | }
|
24 | return [rootEntry];
|
25 | }
|
26 |
|
27 |
|
28 |
|
29 | function compare(rootEntry1, rootEntry2, level, relativePath, options, statistics, diffSet, symlinkCache) {
|
30 | const loopDetected1 = loopDetector.detectLoop(rootEntry1, symlinkCache.dir1);
|
31 | const loopDetected2 = loopDetector.detectLoop(rootEntry2, symlinkCache.dir2);
|
32 | loopDetector.updateSymlinkCache(symlinkCache, rootEntry1, rootEntry2, loopDetected1, loopDetected2);
|
33 | const entries1 = getEntries(rootEntry1, relativePath, loopDetected1, options);
|
34 | const entries2 = getEntries(rootEntry2, relativePath, loopDetected2, options);
|
35 | let i1 = 0, i2 = 0;
|
36 | while (i1 < entries1.length || i2 < entries2.length) {
|
37 | const entry1 = entries1[i1];
|
38 | const entry2 = entries2[i2];
|
39 | let type1, type2;
|
40 |
|
41 | let cmp;
|
42 | if (i1 < entries1.length && i2 < entries2.length) {
|
43 | cmp = entryComparator.compareEntry(entry1, entry2, options);
|
44 | type1 = entryType.getType(entry1);
|
45 | type2 = entryType.getType(entry2);
|
46 | }
|
47 | else if (i1 < entries1.length) {
|
48 | type1 = entryType.getType(entry1);
|
49 | type2 = entryType.getType(undefined);
|
50 | cmp = -1;
|
51 | }
|
52 | else {
|
53 | type1 = entryType.getType(undefined);
|
54 | type2 = entryType.getType(entry2);
|
55 | cmp = 1;
|
56 | }
|
57 |
|
58 | if (cmp === 0) {
|
59 |
|
60 | let same, reason, state;
|
61 | const permissionDeniedState = getPermissionDeniedState(entry1, entry2);
|
62 | if (permissionDeniedState === "access-ok") {
|
63 | const compareEntryRes = entryEquality.isEntryEqualSync(entry1, entry2, type1, options);
|
64 | state = compareEntryRes.same ? 'equal' : 'distinct';
|
65 | same = compareEntryRes.same;
|
66 | reason = compareEntryRes.reason;
|
67 | }
|
68 | else {
|
69 | state = 'distinct';
|
70 | same = false;
|
71 | reason = "permission-denied";
|
72 | }
|
73 | options.resultBuilder(entry1, entry2, state, level, relativePath, options, statistics, diffSet, reason, permissionDeniedState);
|
74 | stats.updateStatisticsBoth(entry1, entry2, same, reason, type1, permissionDeniedState, statistics, options);
|
75 | i1++;
|
76 | i2++;
|
77 | if (!options.skipSubdirs && type1 === 'directory') {
|
78 | compare(entry1, entry2, level + 1, pathUtils.join(relativePath, entry1.name), options, statistics, diffSet, loopDetector.cloneSymlinkCache(symlinkCache));
|
79 | }
|
80 | }
|
81 | else if (cmp < 0) {
|
82 |
|
83 | const permissionDeniedState = getPrmissionDenieStateWhenRightMissing(entry1);
|
84 | options.resultBuilder(entry1, undefined, 'left', level, relativePath, options, statistics, diffSet, undefined, permissionDeniedState);
|
85 | stats.updateStatisticsLeft(entry1, type1, permissionDeniedState, statistics, options);
|
86 | i1++;
|
87 | if (type1 === 'directory' && !options.skipSubdirs) {
|
88 | compare(entry1, undefined, level + 1, pathUtils.join(relativePath, entry1.name), options, statistics, diffSet, loopDetector.cloneSymlinkCache(symlinkCache));
|
89 | }
|
90 | }
|
91 | else {
|
92 |
|
93 | let permissionDeniedState = getPrmissionDenieStateWhenLeftMissing(entry2);
|
94 | options.resultBuilder(undefined, entry2, "right", level, relativePath, options, statistics, diffSet, undefined, permissionDeniedState);
|
95 | stats.updateStatisticsRight(entry2, type2, permissionDeniedState, statistics, options);
|
96 | i2++;
|
97 | if (type2 === 'directory' && !options.skipSubdirs) {
|
98 | compare(undefined, entry2, level + 1, pathUtils.join(relativePath, entry2.name), options, statistics, diffSet, loopDetector.cloneSymlinkCache(symlinkCache));
|
99 | }
|
100 | }
|
101 | }
|
102 | }
|
103 | module.exports = compare;
|
104 |
|
\ | No newline at end of file |