forked from peteward44/gulp-directory-sync
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
150 lines (130 loc) · 3.92 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
/*jslint node: true */
'use strict';
var through = require('through2');
var gutil = require('gulp-util');
var fs = require('fs-extra');
var crc = require('crc');
var path = require('path');
var PLUGIN_NAME = 'directory-sync';
var created = 0, removed = 0, updated = 0, same = 0;
var areTheSame = function( src, dst ) {
var s = crc.crc32(fs.readFileSync(src)).toString(16);
var d = crc.crc32(fs.readFileSync(dst)).toString(16);
return s === d;
};
var isIgnored = function( options, dir, file ) {
if ( options.ignore ) {
if ( Array.isArray( options.ignore ) ) {
return options.ignore.some( function( filter ) {
return isIgnored( { ignore: filter }, dir, file );
} );
} else {
var t = typeof options.ignore;
if ( t === 'function' ) {
return options.ignore( dir, file );
} else if ( t === 'string' ) {
return options.ignore === file;
} else {
// regular expression
var matches = options.ignore.exec( file );
return matches && matches.length > 0;
}
}
}
return false;
};
var remove = function( options, src, dst ) {
var leaves = fs.readdirSync( dst );
leaves.forEach( function( leaf ) {
if ( isIgnored( options, dst, leaf ) ) {
return;
}
var fullSrc = path.join( src, leaf );
var fullDst = path.join( dst, leaf );
if ( !fs.existsSync( fullSrc ) ) {
// exists in dst but not src - remove it
fs.removeSync( fullDst );
removed++;
} else {
var statSrc = fs.statSync( fullSrc );
var statDst = fs.statSync( fullDst );
if ( statSrc.isFile() !== statDst.isFile() || statSrc.isDirectory() !== statDst.isDirectory() ) {
fs.removeSync( fullDst ); // make sure they are the same type, else remove it
} else if ( statDst.isDirectory() ) {
remove( options, fullSrc, fullDst );
}
}
} );
};
var create = function( options, src, dst ) {
var leaves = fs.readdirSync( src );
leaves.forEach( function( leaf ) {
if ( isIgnored( options, src, leaf ) ) {
return;
}
var fullSrc = path.join( src, leaf );
var fullDst = path.join( dst, leaf );
var existsDst = fs.existsSync( fullDst );
var statSrc = fs.statSync( fullSrc );
if ( statSrc.isFile() ) {
if ( existsDst ) {
var statDst = fs.statSync( fullDst );
if ( statDst.isDirectory() ) {
// directory exists with same name as the file - remove it and copy
fs.removeSync( fullDst );
fs.copySync( fullSrc, fullDst, { force: true } );
updated++;
} else if ( statDst.isFile() ) {
// both files exist - check checksums to make sure they're the same
if ( !areTheSame( fullSrc, fullDst ) ) {
fs.copySync( fullSrc, fullDst, { force: true } );
updated++;
} else {
same++;
}
}
} else {
// exists in src but not dst - copy file over
fs.copySync( fullSrc, fullDst, { force: true } );
created++;
}
} else if ( statSrc.isDirectory() ) {
if ( !existsDst ) {
fs.mkdirsSync( fullDst );
}
create( options, fullSrc, fullDst );
}
} );
};
var dirSync = function(src, dst, options) {
options = options || {};
var func = function(callback) {
if ( !src || !dst ) {
this.emit('error', new gutil.PluginError(PLUGIN_NAME, 'Invalid parameter'));
callback();
return;
}
created = removed = updated = same = 0;
fs.ensureDirSync( dst );
if ( !options.nodelete ) {
remove( options, src, dst );
}
create( options, src, dst );
var printSummaryType = typeof options.printSummary;
if ( printSummaryType === 'boolean' && options.printSummary === true ) {
gutil.log( 'Dir Sync: ' + created + ' files created, ' + updated + ' files updated, ' + removed + ' items removed, ' + same + ' files unchanged' );
} else if ( printSummaryType === 'function' ) {
options.printSummary( { created: created, removed: removed, updated: updated, same: same } );
}
this.resume();
callback();
};
return through.obj(
function( file, enc, callback ) {
this.push( file );
callback();
},
func
);
};
module.exports = dirSync;