]>
git.r.bdr.sh - rbdr/dotfiles/blob - atom/packages/ex-mode/node_modules/fs-plus/lib/fs-plus.js
2 var BINARY_EXTENSIONS
, COMPRESSED_EXTENSIONS
, IMAGE_EXTENSIONS
, MARKDOWN_EXTENSIONS
, Module
, async
, fs
, fsPlus
, isMoveTargetValid
, isMoveTargetValidSync
, isPathValid
, lstatSyncNoException
, mkdirp
, path
, rimraf
, statSyncNoException
, _
,
7 Module
= require('module');
9 path
= require('path');
11 _
= require('underscore-plus');
13 async
= require('async');
15 mkdirp
= require('mkdirp');
17 rimraf
= require('rimraf');
20 getHomeDirectory: function() {
21 if (process
.platform
=== 'win32') {
22 return process
.env
.USERPROFILE
;
24 return process
.env
.HOME
;
27 absolute: function(relativePath
) {
29 if (relativePath
== null) {
32 homeDir
= fsPlus
.getHomeDirectory();
33 if (relativePath
=== '~') {
34 relativePath
= homeDir
;
35 } else if (relativePath
.indexOf('~/') === 0) {
36 relativePath
= "" + homeDir
+ (relativePath
.substring(1));
39 return fs
.realpathSync(relativePath
);
45 normalize: function(pathToNormalize
) {
46 var home
, normalizedPath
;
47 if (pathToNormalize
== null) {
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));
58 return normalizedPath
;
60 getAppDataDirectory: function() {
61 switch (process
.platform
) {
63 return fsPlus
.absolute('~/Library/Application Support');
67 return process
.env
.APPDATA
;
72 isAbsolute: function(pathToCheck
) {
73 if (pathToCheck
== null) {
76 if (process
.platform
=== 'win32') {
77 if (pathToCheck
[1] === ':') {
80 if (pathToCheck
[0] === '\\' && pathToCheck
[1] === '\\') {
84 return pathToCheck
[0] === '/';
88 existsSync: function(pathToCheck
) {
89 return isPathValid(pathToCheck
) && (statSyncNoException(pathToCheck
) !== false);
91 isDirectorySync: function(directoryPath
) {
93 if (!isPathValid(directoryPath
)) {
96 if (stat
= statSyncNoException(directoryPath
)) {
97 return stat
.isDirectory();
102 isDirectory: function(directoryPath
, done
) {
103 if (!isPathValid(directoryPath
)) {
106 return fs
.stat(directoryPath
, function(error
, stat
) {
110 return done(stat
.isDirectory());
114 isFileSync: function(filePath
) {
116 if (!isPathValid(filePath
)) {
119 if (stat
= statSyncNoException(filePath
)) {
120 return stat
.isFile();
125 isSymbolicLinkSync: function(symlinkPath
) {
127 if (!isPathValid(symlinkPath
)) {
130 if (stat
= lstatSyncNoException(symlinkPath
)) {
131 return stat
.isSymbolicLink();
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;
142 return process
.nextTick(function() {
143 return typeof callback
=== "function" ? callback(false) : void 0;
147 isExecutableSync: function(pathToCheck
) {
149 if (!isPathValid(pathToCheck
)) {
152 if (stat
= statSyncNoException(pathToCheck
)) {
153 return (stat
.mode
& 0x1ff & 1) !== 0;
158 getSizeSync: function(pathToCheck
) {
160 if (isPathValid(pathToCheck
)) {
161 return (_ref
= statSyncNoException(pathToCheck
).size
) != null ? _ref : -1;
166 listSync: function(rootPath
, extensions
) {
168 if (!fsPlus
.isDirectorySync(rootPath
)) {
171 paths
= fs
.readdirSync(rootPath
);
173 paths
= fsPlus
.filterExtensions(paths
, extensions
);
175 paths
= paths
.sort(function(a
, b
) {
176 return a
.toLowerCase().localeCompare(b
.toLowerCase());
178 paths
= paths
.map(function(childPath
) {
179 return path
.join(rootPath
, childPath
);
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();
190 return fs
.readdir(rootPath
, function(error
, paths
) {
195 paths
= fsPlus
.filterExtensions(paths
, extensions
);
197 paths
= paths
.sort(function(a
, b
) {
198 return a
.toLowerCase().localeCompare(b
.toLowerCase());
200 paths
= paths
.map(function(childPath
) {
201 return path
.join(rootPath
, childPath
);
203 return done(null, paths
);
207 filterExtensions: function(paths
, extensions
) {
208 extensions
= extensions
.map(function(ext
) {
212 return '.' + ext
.replace(/^\./, '');
215 return paths
.filter(function(pathToCheck
) {
216 return _
.include(extensions
, path
.extname(pathToCheck
));
219 listTreeSync: function(rootPath
) {
222 onPath = function(childPath
) {
223 paths
.push(childPath
);
226 fsPlus
.traverseTreeSync(rootPath
, onPath
, onPath
);
229 move: function(source
, target
, callback
) {
230 return isMoveTargetValid(source
, target
, function(isMoveTargetValidErr
, isTargetValid
) {
231 var error
, targetParentPath
;
232 if (isMoveTargetValidErr
) {
233 callback(isMoveTargetValidErr
);
236 if (!isTargetValid
) {
237 error
= new Error("'" + target
+ "' already exists.");
238 error
.code
= 'EEXIST';
242 targetParentPath
= path
.dirname(target
);
243 return fs
.exists(targetParentPath
, function(targetParentExists
) {
244 if (targetParentExists
) {
245 fs
.rename(source
, target
, callback
);
248 return fsPlus
.makeTree(targetParentPath
, function(makeTreeErr
) {
250 callback(makeTreeErr
);
253 return fs
.rename(source
, target
, callback
);
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';
265 targetParentPath
= path
.dirname(target
);
266 if (!fs
.existsSync(targetParentPath
)) {
267 fsPlus
.makeTreeSync(targetParentPath
);
269 return fs
.renameSync(source
, target
);
271 removeSync: function(pathToRemove
) {
272 return rimraf
.sync(pathToRemove
);
274 remove: function(pathToRemove
, callback
) {
275 return rimraf(pathToRemove
, callback
);
277 writeFileSync: function(filePath
, content
, options
) {
278 mkdirp
.sync(path
.dirname(filePath
));
279 return fs
.writeFileSync(filePath
, content
, options
);
281 writeFile: function(filePath
, content
, options
, callback
) {
282 callback
= _
.last(arguments
);
283 return mkdirp(path
.dirname(filePath
), function(error
) {
285 return typeof callback
=== "function" ? callback(error
) : void 0;
287 return fs
.writeFile(filePath
, content
, options
, callback
);
291 copy: function(sourcePath
, destinationPath
, done
) {
292 return mkdirp(path
.dirname(destinationPath
), function(error
) {
293 var destinationStream
, sourceStream
;
295 if (typeof done
=== "function") {
300 sourceStream
= fs
.createReadStream(sourcePath
);
301 sourceStream
.on('error', function(error
) {
302 if (typeof done
=== "function") {
307 destinationStream
= fs
.createWriteStream(destinationPath
);
308 destinationStream
.on('error', function(error
) {
309 if (typeof done
=== "function") {
314 destinationStream
.on('close', function() {
315 if (typeof done
=== "function") {
320 return sourceStream
.pipe(destinationStream
);
323 copySync: function(sourcePath
, destinationPath
) {
324 var content
, destinationFilePath
, source
, sourceFilePath
, sources
, _i
, _len
, _results
;
325 sources
= fs
.readdirSync(sourcePath
);
326 mkdirp
.sync(destinationPath
);
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
));
335 content
= fs
.readFileSync(sourceFilePath
);
336 _results
.push(fs
.writeFileSync(destinationFilePath
, content
));
341 makeTreeSync: function(directoryPath
) {
342 if (!fsPlus
.isDirectorySync(directoryPath
)) {
343 return mkdirp
.sync(directoryPath
);
346 makeTree: function(directoryPath
, callback
) {
347 return fsPlus
.isDirectory(directoryPath
, function(exists
) {
349 return typeof callback
=== "function" ? callback() : void 0;
351 return mkdirp(directoryPath
, function(error
) {
352 return typeof callback
=== "function" ? callback(error
) : void 0;
356 traverseTreeSync: function(rootPath
, onFile
, onDirectory
) {
358 if (onDirectory
== null) {
359 onDirectory
= onFile
;
361 if (!fsPlus
.isDirectorySync(rootPath
)) {
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
++) {
369 childPath
= path
.join(directoryPath
, file
);
370 stats
= fs
.lstatSync(childPath
);
371 if (stats
.isSymbolicLink()) {
372 if (linkStats
= statSyncNoException(childPath
)) {
376 if (stats
.isDirectory()) {
377 if (onDirectory(childPath
)) {
378 traverse(childPath
, onFile
, onDirectory
);
380 } else if (stats
.isFile()) {
386 return traverse(rootPath
, onFile
, onDirectory
);
388 traverseTree: function(rootPath
, onFile
, onDirectory
, onDone
) {
389 return fs
.readdir(rootPath
, function(error
, files
) {
390 var file
, queue
, _i
, _len
, _results
;
392 return typeof onDone
=== "function" ? onDone() : void 0;
394 queue
= async
.queue(function(childPath
, callback
) {
395 return fs
.stat(childPath
, function(error
, stats
) {
397 return callback(error
);
398 } else if (stats
.isFile()) {
401 } else if (stats
.isDirectory()) {
402 if (onDirectory(childPath
)) {
403 return fs
.readdir(childPath
, function(error
, files
) {
406 return callback(error
);
408 for (_i
= 0, _len
= files
.length
; _i
< _len
; _i
++) {
410 queue
.unshift(path
.join(childPath
, file
));
423 queue
.concurrency
= 1;
424 queue
.drain
= onDone
;
426 for (_i
= 0, _len
= files
.length
; _i
< _len
; _i
++) {
428 _results
.push(queue
.push(path
.join(rootPath
, file
)));
434 md5ForPath: function(pathToDigest
) {
436 contents
= fs
.readFileSync(pathToDigest
);
437 return require('crypto').createHash('md5').update(contents
).digest('hex');
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();
445 pathToResolve
= (_ref
= args
.pop()) != null ? _ref
.toString() : void 0;
447 if (!pathToResolve
) {
450 if (fsPlus
.isAbsolute(pathToResolve
)) {
451 if (extensions
&& (resolvedPath
= fsPlus
.resolveExtension(pathToResolve
, extensions
))) {
454 if (fsPlus
.existsSync(pathToResolve
)) {
455 return pathToResolve
;
459 for (_i
= 0, _len
= loadPaths
.length
; _i
< _len
; _i
++) {
460 loadPath
= loadPaths
[_i
];
461 candidatePath
= path
.join(loadPath
, pathToResolve
);
463 if (resolvedPath
= fsPlus
.resolveExtension(candidatePath
, extensions
)) {
467 if (fsPlus
.existsSync(candidatePath
)) {
468 return fsPlus
.absolute(candidatePath
);
474 resolveOnLoadPath: function() {
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
)));
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
);
489 pathWithExtension
= pathToResolve
+ "." + extension
.replace(/^\./, "");
490 if (fsPlus
.existsSync(pathWithExtension
)) {
491 return fsPlus
.absolute(pathWithExtension
);
497 isCompressedExtension: function(ext
) {
498 return COMPRESSED_EXTENSIONS
.hasOwnProperty(ext
);
500 isImageExtension: function(ext
) {
501 return IMAGE_EXTENSIONS
.hasOwnProperty(ext
);
503 isPdfExtension: function(ext
) {
504 return ext
=== '.pdf';
506 isBinaryExtension: function(ext
) {
507 return BINARY_EXTENSIONS
.hasOwnProperty(ext
);
509 isReadmePath: function(readmePath
) {
511 extension
= path
.extname(readmePath
);
512 base
= path
.basename(readmePath
, extension
).toLowerCase();
513 return base
=== 'readme' && (extension
=== '' || fsPlus
.isMarkdownExtension(extension
));
515 isMarkdownExtension: function(ext
) {
516 return MARKDOWN_EXTENSIONS
.hasOwnProperty(ext
);
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
;
526 fsPlus
.caseInsensitiveFs
= false;
529 return fsPlus
.caseInsensitiveFs
;
531 isCaseSensitive: function() {
532 return !fsPlus
.isCaseInsensitive();
536 statSyncNoException
= fs
.statSyncNoException
, lstatSyncNoException
= fs
.lstatSyncNoException
;
538 if (statSyncNoException
== null) {
539 statSyncNoException = function() {
541 args
= 1 <= arguments
.length
? __slice
.call(arguments
, 0) : [];
543 return fs
.statSync
.apply(fs
, args
);
551 if (lstatSyncNoException
== null) {
552 lstatSyncNoException = function() {
554 args
= 1 <= arguments
.length
? __slice
.call(arguments
, 0) : [];
556 return fs
.lstatSync
.apply(fs
, args
);
564 BINARY_EXTENSIONS
= {
575 COMPRESSED_EXTENSIONS
= {
604 MARKDOWN_EXTENSIONS
= {
614 isPathValid = function(pathToCheck
) {
615 return (pathToCheck
!= null) && typeof pathToCheck
=== 'string' && pathToCheck
.length
> 0;
618 isMoveTargetValid = function(source
, target
, callback
) {
619 return fs
.stat(source
, function(oldErr
, oldStat
) {
624 return fs
.stat(target
, function(newErr
, newStat
) {
625 if (newErr
&& newErr
.code
=== 'ENOENT') {
626 callback(void 0, true);
629 return callback(void 0, source
.toLowerCase() === target
.toLowerCase() && oldStat
.dev
=== newStat
.dev
&& oldStat
.ino
=== newStat
.ino
);
634 isMoveTargetValidSync = function(source
, target
) {
635 var newStat
, oldStat
;
636 oldStat
= statSyncNoException(source
);
637 newStat
= statSyncNoException(target
);
638 if (!(oldStat
&& newStat
)) {
641 return source
.toLowerCase() === target
.toLowerCase() && oldStat
.dev
=== newStat
.dev
&& oldStat
.ino
=== newStat
.ino
;
644 module
.exports
= _
.extend({}, fs
, fsPlus
);