- var fs = require('fs');
- var minimatch = require('minimatch');
- var pathUtils = require('path');
-
- module.exports = {
- detectLoop : function(entry, symlinkCache){
- if(entry && entry.symlink){
- var realPath = pathUtils.normalize(fs.realpathSync(entry.path)).toLowerCase();
- if(symlinkCache[realPath]){
- return true;
- }
- }
- return false;
- },
-
- cloneSymlinkCache : function(symlinkCache){
- return {
- dir1 : this.shallowClone(symlinkCache.dir1),
- dir2 : this.shallowClone(symlinkCache.dir2)
- }
- },
-
- shallowClone : function(obj){
- var cloned = {};
- Object.keys(obj).forEach(function(key){
- cloned[key] = obj[key];
- });
- return cloned;
- },
-
- buildEntry : function(path, name){
- var statEntry = fs.statSync(path);
- var lstatEntry = fs.lstatSync(path);
- var isSymlink = lstatEntry.isSymbolicLink();
- return {
- name : name,
- path : path,
- stat : statEntry,
- lstat : lstatEntry,
- symlink : isSymlink,
- toString : function () {
- return this.name;
- }
- };
- },
-
- /**
- * One of 'missing','file','directory'
- */
- getType : function(fileStat) {
- if (fileStat) {
- if (fileStat.isDirectory()) {
- return 'directory';
- } else {
- return 'file';
- }
- } else {
- return 'missing';
- }
- },
- /**
- * Matches fileName with pattern.
- */
- match : function(fileName, pattern){
- var patternArray = pattern.split(',');
- for(var i = 0; i<patternArray.length; i++){
- var pat = patternArray[i];
- if(minimatch(fileName, pat, { dot: true })){ //nocase
- return true;
- }
- }
- return false;
- },
-
- /**
- * Filter entries by file name. Returns true if the file is to be processed.
- */
- filterEntry : function(entry, options){
- if (entry.symlink && options.skipSymlinks){
- return false;
- }
-
- if ((entry.stat.isFile() && options.includeFilter) && (!this.match(entry.name, options.includeFilter))) {
- return false;
- }
-
- if ((options.excludeFilter) && (this.match(entry.name, options.excludeFilter))) {
- return false;
- }
-
- return true;
- },
- /**
- * Comparator for directory entries sorting.
- */
- compareEntryCaseSensitive : function (a, b, ignoreCase) {
- if (a.stat.isDirectory() && b.stat.isFile()) {
- return -1;
- } else if (a.stat.isFile() && b.stat.isDirectory()) {
- return 1;
- } else {
- // http://stackoverflow.com/questions/1179366/is-there-a-javascript-strcmp
- var str1 = a.name, str2 = b.name;
- return ( ( str1 == str2 ) ? 0 : ( ( str1 > str2 ) ? 1 : -1 ) );
- }
- },
- /**
- * Comparator for directory entries sorting.
- */
- compareEntryIgnoreCase : function (a, b, ignoreCase) {
- if (a.stat.isDirectory() && b.stat.isFile()) {
- return -1;
- } else if (a.stat.isFile() && b.stat.isDirectory()) {
- return 1;
- } else {
- // http://stackoverflow.com/questions/1179366/is-there-a-javascript-strcmp
- var str1 = a.name.toLowerCase(), str2 = b.name.toLowerCase();
- return ( ( str1 == str2 ) ? 0 : ( ( str1 > str2 ) ? 1 : -1 ) );
- }
- },
- /**
- * Compares two dates and returns true/false depending on tolerance (milliseconds).
- * Two dates are considered equal if the difference in milliseconds between them is less or equal than tolerance.
- */
- sameDate : function(date1, date2, tolerance){
- return Math.abs(date1.getTime() - date2.getTime()) <= tolerance ? true : false;
- },
- isNumeric : function(n) {
- return !isNaN(parseFloat(n)) && isFinite(n);
- }
- }