]>
Commit | Line | Data |
---|---|---|
1 | (function() { | |
2 | var BINARY_EXTENSIONS, COMPRESSED_EXTENSIONS, IMAGE_EXTENSIONS, MARKDOWN_EXTENSIONS, Module, async, fs, fsPlus, isMoveTargetValid, isMoveTargetValidSync, isPathValid, lstatSyncNoException, mkdirp, path, rimraf, statSyncNoException, _, | |
3 | __slice = [].slice; | |
4 | ||
5 | fs = require('fs'); | |
6 | ||
7 | Module = require('module'); | |
8 | ||
9 | path = require('path'); | |
10 | ||
11 | _ = require('underscore-plus'); | |
12 | ||
13 | async = require('async'); | |
14 | ||
15 | mkdirp = require('mkdirp'); | |
16 | ||
17 | rimraf = require('rimraf'); | |
18 | ||
19 | fsPlus = { | |
20 | getHomeDirectory: function() { | |
21 | if (process.platform === 'win32') { | |
22 | return process.env.USERPROFILE; | |
23 | } else { | |
24 | return process.env.HOME; | |
25 | } | |
26 | }, | |
27 | absolute: function(relativePath) { | |
28 | var e, homeDir; | |
29 | if (relativePath == null) { | |
30 | return null; | |
31 | } | |
32 | homeDir = fsPlus.getHomeDirectory(); | |
33 | if (relativePath === '~') { | |
34 | relativePath = homeDir; | |
35 | } else if (relativePath.indexOf('~/') === 0) { | |
36 | relativePath = "" + homeDir + (relativePath.substring(1)); | |
37 | } | |
38 | try { | |
39 | return fs.realpathSync(relativePath); | |
40 | } catch (_error) { | |
41 | e = _error; | |
42 | return relativePath; | |
43 | } | |
44 | }, | |
45 | normalize: function(pathToNormalize) { | |
46 | var home, normalizedPath; | |
47 | if (pathToNormalize == null) { | |
48 | return null; | |
49 | } | |
50 | normalizedPath = path.normalize(pathToNormalize.toString()); | |
51 | if (home = fsPlus.getHomeDirectory()) { | |
52 | if (normalizedPath === '~') { | |
53 | normalizedPath = home; | |
54 | } else if (normalizedPath.indexOf("~" + path.sep) === 0) { | |
55 | normalizedPath = "" + home + (normalizedPath.substring(1)); | |
56 | } | |
57 | } | |
58 | return normalizedPath; | |
59 | }, | |
60 | getAppDataDirectory: function() { | |
61 | switch (process.platform) { | |
62 | case 'darwin': | |
63 | return fsPlus.absolute('~/Library/Application Support'); | |
64 | case 'linux': | |
65 | return '/var/lib'; | |
66 | case 'win32': | |
67 | return process.env.APPDATA; | |
68 | default: | |
69 | return null; | |
70 | } | |
71 | }, | |
72 | isAbsolute: function(pathToCheck) { | |
73 | if (pathToCheck == null) { | |
74 | pathToCheck = ''; | |
75 | } | |
76 | if (process.platform === 'win32') { | |
77 | if (pathToCheck[1] === ':') { | |
78 | return true; | |
79 | } | |
80 | if (pathToCheck[0] === '\\' && pathToCheck[1] === '\\') { | |
81 | return true; | |
82 | } | |
83 | } else { | |
84 | return pathToCheck[0] === '/'; | |
85 | } | |
86 | return false; | |
87 | }, | |
88 | existsSync: function(pathToCheck) { | |
89 | return isPathValid(pathToCheck) && (statSyncNoException(pathToCheck) !== false); | |
90 | }, | |
91 | isDirectorySync: function(directoryPath) { | |
92 | var stat; | |
93 | if (!isPathValid(directoryPath)) { | |
94 | return false; | |
95 | } | |
96 | if (stat = statSyncNoException(directoryPath)) { | |
97 | return stat.isDirectory(); | |
98 | } else { | |
99 | return false; | |
100 | } | |
101 | }, | |
102 | isDirectory: function(directoryPath, done) { | |
103 | if (!isPathValid(directoryPath)) { | |
104 | return done(false); | |
105 | } | |
106 | return fs.stat(directoryPath, function(error, stat) { | |
107 | if (error != null) { | |
108 | return done(false); | |
109 | } else { | |
110 | return done(stat.isDirectory()); | |
111 | } | |
112 | }); | |
113 | }, | |
114 | isFileSync: function(filePath) { | |
115 | var stat; | |
116 | if (!isPathValid(filePath)) { | |
117 | return false; | |
118 | } | |
119 | if (stat = statSyncNoException(filePath)) { | |
120 | return stat.isFile(); | |
121 | } else { | |
122 | return false; | |
123 | } | |
124 | }, | |
125 | isSymbolicLinkSync: function(symlinkPath) { | |
126 | var stat; | |
127 | if (!isPathValid(symlinkPath)) { | |
128 | return false; | |
129 | } | |
130 | if (stat = lstatSyncNoException(symlinkPath)) { | |
131 | return stat.isSymbolicLink(); | |
132 | } else { | |
133 | return false; | |
134 | } | |
135 | }, | |
136 | isSymbolicLink: function(symlinkPath, callback) { | |
137 | if (isPathValid(symlinkPath)) { | |
138 | return fs.lstat(symlinkPath, function(error, stat) { | |
139 | return typeof callback === "function" ? callback((stat != null) && stat.isSymbolicLink()) : void 0; | |
140 | }); | |
141 | } else { | |
142 | return process.nextTick(function() { | |
143 | return typeof callback === "function" ? callback(false) : void 0; | |
144 | }); | |
145 | } | |
146 | }, | |
147 | isExecutableSync: function(pathToCheck) { | |
148 | var stat; | |
149 | if (!isPathValid(pathToCheck)) { | |
150 | return false; | |
151 | } | |
152 | if (stat = statSyncNoException(pathToCheck)) { | |
153 | return (stat.mode & 0x1ff & 1) !== 0; | |
154 | } else { | |
155 | return false; | |
156 | } | |
157 | }, | |
158 | getSizeSync: function(pathToCheck) { | |
159 | var _ref; | |
160 | if (isPathValid(pathToCheck)) { | |
161 | return (_ref = statSyncNoException(pathToCheck).size) != null ? _ref : -1; | |
162 | } else { | |
163 | return -1; | |
164 | } | |
165 | }, | |
166 | listSync: function(rootPath, extensions) { | |
167 | var paths; | |
168 | if (!fsPlus.isDirectorySync(rootPath)) { | |
169 | return []; | |
170 | } | |
171 | paths = fs.readdirSync(rootPath); | |
172 | if (extensions) { | |
173 | paths = fsPlus.filterExtensions(paths, extensions); | |
174 | } | |
175 | paths = paths.sort(function(a, b) { | |
176 | return a.toLowerCase().localeCompare(b.toLowerCase()); | |
177 | }); | |
178 | paths = paths.map(function(childPath) { | |
179 | return path.join(rootPath, childPath); | |
180 | }); | |
181 | return paths; | |
182 | }, | |
183 | list: function() { | |
184 | var done, extensions, rest, rootPath; | |
185 | rootPath = arguments[0], rest = 2 <= arguments.length ? __slice.call(arguments, 1) : []; | |
186 | if (rest.length > 1) { | |
187 | extensions = rest.shift(); | |
188 | } | |
189 | done = rest.shift(); | |
190 | return fs.readdir(rootPath, function(error, paths) { | |
191 | if (error != null) { | |
192 | return done(error); | |
193 | } else { | |
194 | if (extensions) { | |
195 | paths = fsPlus.filterExtensions(paths, extensions); | |
196 | } | |
197 | paths = paths.sort(function(a, b) { | |
198 | return a.toLowerCase().localeCompare(b.toLowerCase()); | |
199 | }); | |
200 | paths = paths.map(function(childPath) { | |
201 | return path.join(rootPath, childPath); | |
202 | }); | |
203 | return done(null, paths); | |
204 | } | |
205 | }); | |
206 | }, | |
207 | filterExtensions: function(paths, extensions) { | |
208 | extensions = extensions.map(function(ext) { | |
209 | if (ext === '') { | |
210 | return ext; | |
211 | } else { | |
212 | return '.' + ext.replace(/^\./, ''); | |
213 | } | |
214 | }); | |
215 | return paths.filter(function(pathToCheck) { | |
216 | return _.include(extensions, path.extname(pathToCheck)); | |
217 | }); | |
218 | }, | |
219 | listTreeSync: function(rootPath) { | |
220 | var onPath, paths; | |
221 | paths = []; | |
222 | onPath = function(childPath) { | |
223 | paths.push(childPath); | |
224 | return true; | |
225 | }; | |
226 | fsPlus.traverseTreeSync(rootPath, onPath, onPath); | |
227 | return paths; | |
228 | }, | |
229 | move: function(source, target, callback) { | |
230 | return isMoveTargetValid(source, target, function(isMoveTargetValidErr, isTargetValid) { | |
231 | var error, targetParentPath; | |
232 | if (isMoveTargetValidErr) { | |
233 | callback(isMoveTargetValidErr); | |
234 | return; | |
235 | } | |
236 | if (!isTargetValid) { | |
237 | error = new Error("'" + target + "' already exists."); | |
238 | error.code = 'EEXIST'; | |
239 | callback(error); | |
240 | return; | |
241 | } | |
242 | targetParentPath = path.dirname(target); | |
243 | return fs.exists(targetParentPath, function(targetParentExists) { | |
244 | if (targetParentExists) { | |
245 | fs.rename(source, target, callback); | |
246 | return; | |
247 | } | |
248 | return fsPlus.makeTree(targetParentPath, function(makeTreeErr) { | |
249 | if (makeTreeErr) { | |
250 | callback(makeTreeErr); | |
251 | return; | |
252 | } | |
253 | return fs.rename(source, target, callback); | |
254 | }); | |
255 | }); | |
256 | }); | |
257 | }, | |
258 | moveSync: function(source, target) { | |
259 | var error, targetParentPath; | |
260 | if (!isMoveTargetValidSync(source, target)) { | |
261 | error = new Error("'" + target + "' already exists."); | |
262 | error.code = 'EEXIST'; | |
263 | throw error; | |
264 | } | |
265 | targetParentPath = path.dirname(target); | |
266 | if (!fs.existsSync(targetParentPath)) { | |
267 | fsPlus.makeTreeSync(targetParentPath); | |
268 | } | |
269 | return fs.renameSync(source, target); | |
270 | }, | |
271 | removeSync: function(pathToRemove) { | |
272 | return rimraf.sync(pathToRemove); | |
273 | }, | |
274 | remove: function(pathToRemove, callback) { | |
275 | return rimraf(pathToRemove, callback); | |
276 | }, | |
277 | writeFileSync: function(filePath, content, options) { | |
278 | mkdirp.sync(path.dirname(filePath)); | |
279 | return fs.writeFileSync(filePath, content, options); | |
280 | }, | |
281 | writeFile: function(filePath, content, options, callback) { | |
282 | callback = _.last(arguments); | |
283 | return mkdirp(path.dirname(filePath), function(error) { | |
284 | if (error != null) { | |
285 | return typeof callback === "function" ? callback(error) : void 0; | |
286 | } else { | |
287 | return fs.writeFile(filePath, content, options, callback); | |
288 | } | |
289 | }); | |
290 | }, | |
291 | copy: function(sourcePath, destinationPath, done) { | |
292 | return mkdirp(path.dirname(destinationPath), function(error) { | |
293 | var destinationStream, sourceStream; | |
294 | if (error != null) { | |
295 | if (typeof done === "function") { | |
296 | done(error); | |
297 | } | |
298 | return; | |
299 | } | |
300 | sourceStream = fs.createReadStream(sourcePath); | |
301 | sourceStream.on('error', function(error) { | |
302 | if (typeof done === "function") { | |
303 | done(error); | |
304 | } | |
305 | return done = null; | |
306 | }); | |
307 | destinationStream = fs.createWriteStream(destinationPath); | |
308 | destinationStream.on('error', function(error) { | |
309 | if (typeof done === "function") { | |
310 | done(error); | |
311 | } | |
312 | return done = null; | |
313 | }); | |
314 | destinationStream.on('close', function() { | |
315 | if (typeof done === "function") { | |
316 | done(); | |
317 | } | |
318 | return done = null; | |
319 | }); | |
320 | return sourceStream.pipe(destinationStream); | |
321 | }); | |
322 | }, | |
323 | copySync: function(sourcePath, destinationPath) { | |
324 | var content, destinationFilePath, source, sourceFilePath, sources, _i, _len, _results; | |
325 | sources = fs.readdirSync(sourcePath); | |
326 | mkdirp.sync(destinationPath); | |
327 | _results = []; | |
328 | for (_i = 0, _len = sources.length; _i < _len; _i++) { | |
329 | source = sources[_i]; | |
330 | sourceFilePath = path.join(sourcePath, source); | |
331 | destinationFilePath = path.join(destinationPath, source); | |
332 | if (fsPlus.isDirectorySync(sourceFilePath)) { | |
333 | _results.push(fsPlus.copySync(sourceFilePath, destinationFilePath)); | |
334 | } else { | |
335 | content = fs.readFileSync(sourceFilePath); | |
336 | _results.push(fs.writeFileSync(destinationFilePath, content)); | |
337 | } | |
338 | } | |
339 | return _results; | |
340 | }, | |
341 | makeTreeSync: function(directoryPath) { | |
342 | if (!fsPlus.isDirectorySync(directoryPath)) { | |
343 | return mkdirp.sync(directoryPath); | |
344 | } | |
345 | }, | |
346 | makeTree: function(directoryPath, callback) { | |
347 | return fsPlus.isDirectory(directoryPath, function(exists) { | |
348 | if (exists) { | |
349 | return typeof callback === "function" ? callback() : void 0; | |
350 | } | |
351 | return mkdirp(directoryPath, function(error) { | |
352 | return typeof callback === "function" ? callback(error) : void 0; | |
353 | }); | |
354 | }); | |
355 | }, | |
356 | traverseTreeSync: function(rootPath, onFile, onDirectory) { | |
357 | var traverse; | |
358 | if (onDirectory == null) { | |
359 | onDirectory = onFile; | |
360 | } | |
361 | if (!fsPlus.isDirectorySync(rootPath)) { | |
362 | return; | |
363 | } | |
364 | traverse = function(directoryPath, onFile, onDirectory) { | |
365 | var childPath, file, linkStats, stats, _i, _len, _ref; | |
366 | _ref = fs.readdirSync(directoryPath); | |
367 | for (_i = 0, _len = _ref.length; _i < _len; _i++) { | |
368 | file = _ref[_i]; | |
369 | childPath = path.join(directoryPath, file); | |
370 | stats = fs.lstatSync(childPath); | |
371 | if (stats.isSymbolicLink()) { | |
372 | if (linkStats = statSyncNoException(childPath)) { | |
373 | stats = linkStats; | |
374 | } | |
375 | } | |
376 | if (stats.isDirectory()) { | |
377 | if (onDirectory(childPath)) { | |
378 | traverse(childPath, onFile, onDirectory); | |
379 | } | |
380 | } else if (stats.isFile()) { | |
381 | onFile(childPath); | |
382 | } | |
383 | } | |
384 | return void 0; | |
385 | }; | |
386 | return traverse(rootPath, onFile, onDirectory); | |
387 | }, | |
388 | traverseTree: function(rootPath, onFile, onDirectory, onDone) { | |
389 | return fs.readdir(rootPath, function(error, files) { | |
390 | var file, queue, _i, _len, _results; | |
391 | if (error) { | |
392 | return typeof onDone === "function" ? onDone() : void 0; | |
393 | } else { | |
394 | queue = async.queue(function(childPath, callback) { | |
395 | return fs.stat(childPath, function(error, stats) { | |
396 | if (error) { | |
397 | return callback(error); | |
398 | } else if (stats.isFile()) { | |
399 | onFile(childPath); | |
400 | return callback(); | |
401 | } else if (stats.isDirectory()) { | |
402 | if (onDirectory(childPath)) { | |
403 | return fs.readdir(childPath, function(error, files) { | |
404 | var file, _i, _len; | |
405 | if (error) { | |
406 | return callback(error); | |
407 | } else { | |
408 | for (_i = 0, _len = files.length; _i < _len; _i++) { | |
409 | file = files[_i]; | |
410 | queue.unshift(path.join(childPath, file)); | |
411 | } | |
412 | return callback(); | |
413 | } | |
414 | }); | |
415 | } else { | |
416 | return callback(); | |
417 | } | |
418 | } else { | |
419 | return callback(); | |
420 | } | |
421 | }); | |
422 | }); | |
423 | queue.concurrency = 1; | |
424 | queue.drain = onDone; | |
425 | _results = []; | |
426 | for (_i = 0, _len = files.length; _i < _len; _i++) { | |
427 | file = files[_i]; | |
428 | _results.push(queue.push(path.join(rootPath, file))); | |
429 | } | |
430 | return _results; | |
431 | } | |
432 | }); | |
433 | }, | |
434 | md5ForPath: function(pathToDigest) { | |
435 | var contents; | |
436 | contents = fs.readFileSync(pathToDigest); | |
437 | return require('crypto').createHash('md5').update(contents).digest('hex'); | |
438 | }, | |
439 | resolve: function() { | |
440 | var args, candidatePath, extensions, loadPath, loadPaths, pathToResolve, resolvedPath, _i, _len, _ref; | |
441 | args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; | |
442 | if (_.isArray(_.last(args))) { | |
443 | extensions = args.pop(); | |
444 | } | |
445 | pathToResolve = (_ref = args.pop()) != null ? _ref.toString() : void 0; | |
446 | loadPaths = args; | |
447 | if (!pathToResolve) { | |
448 | return void 0; | |
449 | } | |
450 | if (fsPlus.isAbsolute(pathToResolve)) { | |
451 | if (extensions && (resolvedPath = fsPlus.resolveExtension(pathToResolve, extensions))) { | |
452 | return resolvedPath; | |
453 | } else { | |
454 | if (fsPlus.existsSync(pathToResolve)) { | |
455 | return pathToResolve; | |
456 | } | |
457 | } | |
458 | } | |
459 | for (_i = 0, _len = loadPaths.length; _i < _len; _i++) { | |
460 | loadPath = loadPaths[_i]; | |
461 | candidatePath = path.join(loadPath, pathToResolve); | |
462 | if (extensions) { | |
463 | if (resolvedPath = fsPlus.resolveExtension(candidatePath, extensions)) { | |
464 | return resolvedPath; | |
465 | } | |
466 | } else { | |
467 | if (fsPlus.existsSync(candidatePath)) { | |
468 | return fsPlus.absolute(candidatePath); | |
469 | } | |
470 | } | |
471 | } | |
472 | return void 0; | |
473 | }, | |
474 | resolveOnLoadPath: function() { | |
475 | var args, loadPaths; | |
476 | args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; | |
477 | loadPaths = Module.globalPaths.concat(module.paths); | |
478 | return fsPlus.resolve.apply(fsPlus, __slice.call(loadPaths).concat(__slice.call(args))); | |
479 | }, | |
480 | resolveExtension: function(pathToResolve, extensions) { | |
481 | var extension, pathWithExtension, _i, _len; | |
482 | for (_i = 0, _len = extensions.length; _i < _len; _i++) { | |
483 | extension = extensions[_i]; | |
484 | if (extension === "") { | |
485 | if (fsPlus.existsSync(pathToResolve)) { | |
486 | return fsPlus.absolute(pathToResolve); | |
487 | } | |
488 | } else { | |
489 | pathWithExtension = pathToResolve + "." + extension.replace(/^\./, ""); | |
490 | if (fsPlus.existsSync(pathWithExtension)) { | |
491 | return fsPlus.absolute(pathWithExtension); | |
492 | } | |
493 | } | |
494 | } | |
495 | return void 0; | |
496 | }, | |
497 | isCompressedExtension: function(ext) { | |
498 | return COMPRESSED_EXTENSIONS.hasOwnProperty(ext); | |
499 | }, | |
500 | isImageExtension: function(ext) { | |
501 | return IMAGE_EXTENSIONS.hasOwnProperty(ext); | |
502 | }, | |
503 | isPdfExtension: function(ext) { | |
504 | return ext === '.pdf'; | |
505 | }, | |
506 | isBinaryExtension: function(ext) { | |
507 | return BINARY_EXTENSIONS.hasOwnProperty(ext); | |
508 | }, | |
509 | isReadmePath: function(readmePath) { | |
510 | var base, extension; | |
511 | extension = path.extname(readmePath); | |
512 | base = path.basename(readmePath, extension).toLowerCase(); | |
513 | return base === 'readme' && (extension === '' || fsPlus.isMarkdownExtension(extension)); | |
514 | }, | |
515 | isMarkdownExtension: function(ext) { | |
516 | return MARKDOWN_EXTENSIONS.hasOwnProperty(ext); | |
517 | }, | |
518 | isCaseInsensitive: function() { | |
519 | var lowerCaseStat, upperCaseStat; | |
520 | if (fsPlus.caseInsensitiveFs == null) { | |
521 | lowerCaseStat = statSyncNoException(process.execPath.toLowerCase()); | |
522 | upperCaseStat = statSyncNoException(process.execPath.toUpperCase()); | |
523 | if (lowerCaseStat && upperCaseStat) { | |
524 | fsPlus.caseInsensitiveFs = lowerCaseStat.dev === upperCaseStat.dev && lowerCaseStat.ino === upperCaseStat.ino; | |
525 | } else { | |
526 | fsPlus.caseInsensitiveFs = false; | |
527 | } | |
528 | } | |
529 | return fsPlus.caseInsensitiveFs; | |
530 | }, | |
531 | isCaseSensitive: function() { | |
532 | return !fsPlus.isCaseInsensitive(); | |
533 | } | |
534 | }; | |
535 | ||
536 | statSyncNoException = fs.statSyncNoException, lstatSyncNoException = fs.lstatSyncNoException; | |
537 | ||
538 | if (statSyncNoException == null) { | |
539 | statSyncNoException = function() { | |
540 | var args, error; | |
541 | args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; | |
542 | try { | |
543 | return fs.statSync.apply(fs, args); | |
544 | } catch (_error) { | |
545 | error = _error; | |
546 | return false; | |
547 | } | |
548 | }; | |
549 | } | |
550 | ||
551 | if (lstatSyncNoException == null) { | |
552 | lstatSyncNoException = function() { | |
553 | var args, error; | |
554 | args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; | |
555 | try { | |
556 | return fs.lstatSync.apply(fs, args); | |
557 | } catch (_error) { | |
558 | error = _error; | |
559 | return false; | |
560 | } | |
561 | }; | |
562 | } | |
563 | ||
564 | BINARY_EXTENSIONS = { | |
565 | '.DS_Store': true, | |
566 | '.a': true, | |
567 | '.exe': true, | |
568 | '.o': true, | |
569 | '.pyc': true, | |
570 | '.pyo': true, | |
571 | '.so': true, | |
572 | '.woff': true | |
573 | }; | |
574 | ||
575 | COMPRESSED_EXTENSIONS = { | |
576 | '.bz2': true, | |
577 | '.egg': true, | |
578 | '.epub': true, | |
579 | '.gz': true, | |
580 | '.jar': true, | |
581 | '.lz': true, | |
582 | '.lzma': true, | |
583 | '.lzo': true, | |
584 | '.tar': true, | |
585 | '.tgz': true, | |
586 | '.war': true, | |
587 | '.whl': true, | |
588 | '.xpi': true, | |
589 | '.xz': true, | |
590 | '.z': true, | |
591 | '.zip': true | |
592 | }; | |
593 | ||
594 | IMAGE_EXTENSIONS = { | |
595 | '.gif': true, | |
596 | '.ico': true, | |
597 | '.jpeg': true, | |
598 | '.jpg': true, | |
599 | '.png': true, | |
600 | '.tiff': true, | |
601 | '.webp': true | |
602 | }; | |
603 | ||
604 | MARKDOWN_EXTENSIONS = { | |
605 | '.markdown': true, | |
606 | '.md': true, | |
607 | '.mdown': true, | |
608 | '.mkd': true, | |
609 | '.mkdown': true, | |
610 | '.rmd': true, | |
611 | '.ron': true | |
612 | }; | |
613 | ||
614 | isPathValid = function(pathToCheck) { | |
615 | return (pathToCheck != null) && typeof pathToCheck === 'string' && pathToCheck.length > 0; | |
616 | }; | |
617 | ||
618 | isMoveTargetValid = function(source, target, callback) { | |
619 | return fs.stat(source, function(oldErr, oldStat) { | |
620 | if (oldErr) { | |
621 | callback(oldErr); | |
622 | return; | |
623 | } | |
624 | return fs.stat(target, function(newErr, newStat) { | |
625 | if (newErr && newErr.code === 'ENOENT') { | |
626 | callback(void 0, true); | |
627 | return; | |
628 | } | |
629 | return callback(void 0, source.toLowerCase() === target.toLowerCase() && oldStat.dev === newStat.dev && oldStat.ino === newStat.ino); | |
630 | }); | |
631 | }); | |
632 | }; | |
633 | ||
634 | isMoveTargetValidSync = function(source, target) { | |
635 | var newStat, oldStat; | |
636 | oldStat = statSyncNoException(source); | |
637 | newStat = statSyncNoException(target); | |
638 | if (!(oldStat && newStat)) { | |
639 | return true; | |
640 | } | |
641 | return source.toLowerCase() === target.toLowerCase() && oldStat.dev === newStat.dev && oldStat.ino === newStat.ino; | |
642 | }; | |
643 | ||
644 | module.exports = _.extend({}, fs, fsPlus); | |
645 | ||
646 | }).call(this); |