]> git.r.bdr.sh - rbdr/dotfiles/blob
499cd646d3e84d22eeb98c662d689afad22d0b96
[rbdr/dotfiles] /
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);