UNPKG

2.87 kBJavaScriptView Raw
1var fs = require('fs');
2var path = require('path');
3/*
4 options: {
5 utimes: false, // Boolean | Object, keep utimes if true
6 mode: false, // Boolean | Number, keep file mode if true
7 cover: true, // Boolean, cover if file exists
8 filter: true, // Boolean | Function, file filter
9 }
10*/
11function copydirSync(from, to, options) {
12 if (typeof options === 'function') {
13 options = {
14 filter: options
15 };
16 }
17 if(typeof options === 'undefined') options = {};
18 if(typeof options.cover === 'undefined') {
19 options.cover = true;
20 }
21 options.filter = typeof options.filter === 'function' ? options.filter : function(state, filepath, filename) {
22 return options.filter;
23 };
24 var stats = fs.lstatSync(from);
25 var statsname = stats.isDirectory() ? 'directory' :
26 stats.isFile() ? 'file' :
27 stats.isSymbolicLink() ? 'symbolicLink' :
28 '';
29 var valid = options.filter(statsname, from, path.dirname(from), path.basename(from));
30
31 if (statsname === 'directory' || statsname === 'symbolicLink') {
32 // Directory or SymbolicLink
33 if(valid) {
34 try {
35 fs.statSync(to);
36 } catch(err) {
37 if(err.code === 'ENOENT') {
38 fs.mkdirSync(to);
39 options.debug && console.log('>> ' + to);
40 } else {
41 throw err;
42 }
43 }
44 rewriteSync(to, options, stats);
45 if (statsname != 'symbolicLink')
46 listDirectorySync(from, to, options);
47 }
48 } else if(stats.isFile()) {
49 // File
50 if(valid) {
51 if(options.cover) {
52 writeFileSync(from, to, options, stats);
53 } else {
54 try {
55 fs.statSync(to);
56 } catch(err) {
57 if(err.code === 'ENOENT') {
58 writeFileSync(from, to, options, stats);
59 } else {
60 throw err;
61 }
62 }
63 }
64 }
65 } else {
66 throw new Error('stats invalid: '+ from);
67 }
68};
69
70function listDirectorySync(from, to, options) {
71 var files = fs.readdirSync(from);
72 copyFromArraySync(files, from, to, options);
73}
74
75function copyFromArraySync(files, from, to, options) {
76 if(files.length === 0) return true;
77 var f = files.shift();
78 copydirSync(path.join(from, f), path.join(to, f), options);
79 copyFromArraySync(files, from, to, options);
80}
81
82function writeFileSync(from, to, options, stats) {
83 fs.writeFileSync(to, fs.readFileSync(from, 'binary'), 'binary');
84 options.debug && console.log('>> ' + to);
85 rewriteSync(to, options, stats);
86}
87
88function rewriteSync(f, options, stats, callback) {
89 if(options.cover) {
90 var mode = options.mode === true ? stats.mode : options.mode;
91 var utimes = options.utimes === true ? {
92 atime: stats.atime,
93 mtime: stats.mtime
94 } : options.utimes;
95 mode && fs.chmodSync(f, mode);
96 utimes && fs.utimesSync(f, utimes.atime, utimes.mtime);
97 }
98 return true;
99}
100
101module.exports = copydirSync;