1 |
|
2 |
|
3 |
|
4 |
|
5 | var fs = require('fs');
|
6 | var util = require('utils-extend');
|
7 | var path = require('path');
|
8 | var fileMatch = require('file-match');
|
9 |
|
10 | function checkCbAndOpts(options, callback) {
|
11 | if (util.isFunction(options)) {
|
12 | return {
|
13 | options: null,
|
14 | callback: options
|
15 | };
|
16 | } else if (util.isObject(options)) {
|
17 | return {
|
18 | options: options,
|
19 | callback: callback
|
20 | };
|
21 | } else {
|
22 | return {
|
23 | options: null,
|
24 | callback: util.noop
|
25 | };
|
26 | }
|
27 | }
|
28 |
|
29 | function getExists(filepath) {
|
30 | var exists = fs.existsSync(filepath);
|
31 |
|
32 | if (exists) {
|
33 | return filepath;
|
34 | } else {
|
35 | return getExists(path.dirname(filepath));
|
36 | }
|
37 | }
|
38 |
|
39 | util.extend(exports, fs);
|
40 |
|
41 |
|
42 |
|
43 |
|
44 |
|
45 | exports.fs = fs;
|
46 |
|
47 | exports.fileMatch = fileMatch;
|
48 |
|
49 |
|
50 |
|
51 |
|
52 |
|
53 |
|
54 |
|
55 |
|
56 |
|
57 |
|
58 |
|
59 | exports.mkdir = function(filepath, mode, callback) {
|
60 | var root = getExists(filepath);
|
61 | var children = path.relative(root, filepath);
|
62 |
|
63 | if (util.isFunction(mode)) {
|
64 | callback = mode;
|
65 | mode = null;
|
66 | }
|
67 |
|
68 | if (!util.isFunction(callback)) {
|
69 | callback = util.noop;
|
70 | }
|
71 |
|
72 | mode = mode || 511;
|
73 |
|
74 | if (!children) return callback();
|
75 |
|
76 | children = children.split(path.sep);
|
77 |
|
78 | function create(filepath) {
|
79 | if (create.count === children.length) {
|
80 | return callback();
|
81 | }
|
82 |
|
83 | filepath = path.join(filepath, children[create.count]);
|
84 |
|
85 | fs.mkdir(filepath, mode, function(err) {
|
86 | create.count++;
|
87 | create(filepath);
|
88 | });
|
89 | }
|
90 |
|
91 | create.count = 0;
|
92 | create(root);
|
93 | };
|
94 |
|
95 |
|
96 |
|
97 |
|
98 |
|
99 | exports.mkdirSync = function(filepath, mode) {
|
100 | var root = getExists(filepath);
|
101 | var children = path.relative(root, filepath);
|
102 |
|
103 | if (!children) return;
|
104 |
|
105 | children = children.split(path.sep);
|
106 |
|
107 | children.forEach(function(item) {
|
108 | root = path.join(root, item);
|
109 | fs.mkdirSync(root, mode);
|
110 | });
|
111 | };
|
112 |
|
113 |
|
114 |
|
115 |
|
116 |
|
117 |
|
118 |
|
119 |
|
120 |
|
121 |
|
122 |
|
123 |
|
124 | exports.writeFile = function(filename, data, options, callback) {
|
125 | var result = checkCbAndOpts(options, callback);
|
126 | var dirname = path.dirname(filename);
|
127 | options = result.options;
|
128 | callback = result.callback;
|
129 |
|
130 |
|
131 | exports.mkdir(dirname, function() {
|
132 | fs.writeFile(filename, data, options, callback);
|
133 | });
|
134 | };
|
135 |
|
136 |
|
137 |
|
138 |
|
139 |
|
140 | exports.writeFileSync = function(filename, data, options) {
|
141 | var dirname = path.dirname(filename);
|
142 |
|
143 | exports.mkdirSync(dirname);
|
144 | fs.writeFileSync(filename, data, options);
|
145 | };
|
146 |
|
147 |
|
148 |
|
149 |
|
150 |
|
151 |
|
152 |
|
153 | exports.copyFile = function(srcpath, destpath, options) {
|
154 | options = util.extend({
|
155 | encoding: 'utf8',
|
156 | done: util.noop
|
157 | }, options || {});
|
158 |
|
159 | if (!options.process) {
|
160 | options.encoding = null;
|
161 | }
|
162 |
|
163 | fs.readFile(srcpath, {
|
164 | encoding: options.encoding
|
165 | }, function(err, contents) {
|
166 | if (err) return options.done(err);
|
167 |
|
168 | if (options.process) {
|
169 | contents = options.process(contents);
|
170 | }
|
171 |
|
172 | exports.writeFile(destpath, contents, options, options.done);
|
173 | });
|
174 | };
|
175 |
|
176 |
|
177 |
|
178 |
|
179 |
|
180 |
|
181 |
|
182 |
|
183 | exports.copyFileSync = function(srcpath, destpath, options) {
|
184 | options = util.extend({
|
185 | encoding: 'utf8'
|
186 | }, options || {});
|
187 | var contents;
|
188 |
|
189 | if (options.process) {
|
190 | contents = fs.readFileSync(srcpath, options);
|
191 | contents = options.process(contents);
|
192 | exports.writeFileSync(destpath, contents, options);
|
193 | } else {
|
194 | contents = fs.readFileSync(srcpath);
|
195 | exports.writeFileSync(destpath, contents);
|
196 | }
|
197 | };
|
198 |
|
199 |
|
200 |
|
201 |
|
202 |
|
203 |
|
204 |
|
205 |
|
206 |
|
207 |
|
208 | exports.recurse = function(dirpath, filter, callback) {
|
209 | if (util.isFunction(filter)) {
|
210 | callback = filter;
|
211 | filter = null;
|
212 | }
|
213 | var filterCb = fileMatch(filter);
|
214 | var rootpath = dirpath;
|
215 |
|
216 | function recurse(dirpath) {
|
217 | fs.readdir(dirpath, function(err, files) {
|
218 | if (err) return callback(err);
|
219 |
|
220 | files.forEach(function(filename) {
|
221 | var filepath = path.join(dirpath, filename);
|
222 |
|
223 | fs.stat(filepath, function(err, stats) {
|
224 | var relative = path.relative(rootpath, filepath);
|
225 | var flag = filterCb(relative);
|
226 |
|
227 | if (stats.isDirectory()) {
|
228 | recurse(filepath);
|
229 | if (flag) callback(filepath);
|
230 | } else {
|
231 | if (flag) callback(filepath, filename);
|
232 | }
|
233 | });
|
234 | });
|
235 | });
|
236 | }
|
237 |
|
238 | recurse(dirpath);
|
239 | };
|
240 |
|
241 |
|
242 |
|
243 |
|
244 |
|
245 |
|
246 |
|
247 |
|
248 | exports.recurseSync = function(dirpath, filter, callback) {
|
249 | if (util.isFunction(filter)) {
|
250 | callback = filter;
|
251 | filter = null;
|
252 | }
|
253 | var filterCb = fileMatch(filter);
|
254 | var rootpath = dirpath;
|
255 |
|
256 | function recurse(dirpath) {
|
257 |
|
258 | try {
|
259 | fs.readdirSync(dirpath).forEach(function(filename) {
|
260 | var filepath = path.join(dirpath, filename);
|
261 | var stats = fs.statSync(filepath);
|
262 | var relative = path.relative(rootpath, filepath);
|
263 | var flag = filterCb(relative);
|
264 |
|
265 | if (stats.isDirectory()) {
|
266 | recurse(filepath);
|
267 | if (flag) callback(filepath);
|
268 | } else {
|
269 | if (flag) callback(filepath, filename);
|
270 | }
|
271 | });
|
272 | } catch(e) {
|
273 | fs.chmodSync(dirpath, 511);
|
274 | recurse(dirpath);
|
275 | }
|
276 | }
|
277 |
|
278 | recurse(dirpath);
|
279 | };
|
280 |
|
281 |
|
282 |
|
283 |
|
284 |
|
285 |
|
286 |
|
287 | exports.rmdirSync = function(dirpath) {
|
288 | exports.recurseSync(dirpath, function(filepath, filename) {
|
289 |
|
290 | if (filename) {
|
291 | fs.unlinkSync(filepath);
|
292 | } else {
|
293 | fs.rmdirSync(filepath);
|
294 | }
|
295 | });
|
296 |
|
297 | fs.rmdirSync(dirpath);
|
298 | };
|
299 |
|
300 |
|
301 |
|
302 |
|
303 |
|
304 |
|
305 |
|
306 |
|
307 |
|
308 |
|
309 |
|
310 |
|
311 | exports.copySync = function(dirpath, destpath, options) {
|
312 | options = util.extend({
|
313 | encoding: 'utf8',
|
314 | filter: null,
|
315 | noProcess: ''
|
316 | }, options || {});
|
317 | var files = [];
|
318 | var folders = [];
|
319 |
|
320 | exports.recurseSync(dirpath, options.filter, function(filepath, filename) {
|
321 | if (!filename) return;
|
322 | files.push(filepath);
|
323 | folders.push(path.dirname(filepath));
|
324 | });
|
325 |
|
326 | var length = files.length;
|
327 | var noProcessCb = fileMatch(options.noProcess);
|
328 |
|
329 |
|
330 | exports.mkdirSync(destpath);
|
331 |
|
332 | folders.forEach(function(item, index) {
|
333 | var isCreate = true;
|
334 | var relative, newpath;
|
335 |
|
336 | while(index++ < length) {
|
337 | if (folders[index] === item) {
|
338 | isCreate = false;
|
339 | break;
|
340 | }
|
341 | }
|
342 |
|
343 | if (isCreate) {
|
344 | relative = path.relative(dirpath, item);
|
345 | if (relative) {
|
346 | newpath = path.join(destpath, relative);
|
347 | exports.mkdirSync(newpath);
|
348 | }
|
349 | }
|
350 | });
|
351 |
|
352 | function copy(oldpath, newpath, options) {
|
353 | var result;
|
354 | if (options.process) {
|
355 | var encoding = {
|
356 | encoding: options.encoding
|
357 | };
|
358 | result = fs.readFileSync(oldpath, encoding);
|
359 | result = options.process(result, oldpath);
|
360 |
|
361 | if (util.isObject(result) && result.filepath) {
|
362 | fs.writeFileSync(result.filepath, result.contents, encoding);
|
363 | } else {
|
364 | fs.writeFileSync(newpath, result, encoding);
|
365 | }
|
366 | } else {
|
367 | result = fs.readFileSync(oldpath);
|
368 | fs.writeFileSync(newpath, result);
|
369 | }
|
370 | }
|
371 |
|
372 | // Copy file
|
373 | files.forEach(function(item) {
|
374 | var relative = path.relative(dirpath, item);
|
375 | var newpath = path.join(destpath, relative);
|
376 |
|
377 | if (options.process) {
|
378 | if (noProcessCb(relative)) {
|
379 | copy(item, newpath, {});
|
380 | } else {
|
381 | copy(item, newpath, options);
|
382 | }
|
383 | } else {
|
384 | copy(item, newpath, {});
|
385 | }
|
386 | });
|
387 | }; |
\ | No newline at end of file |