wrench
var fs = require("fs"),
_path = require("path");
exports.readdirSyncRecursive = function(baseDir) {
baseDir = baseDir.replace(/\/$/, '');
var readdirSyncRecursive = function(baseDir) {
var files = [],
curFiles,
nextDirs,
isDir = function(fname){
return fs.statSync( _path.join(baseDir, fname) ).isDirectory();
},
prependBaseDir = function(fname){
return _path.join(baseDir, fname);
};
curFiles = fs.readdirSync(baseDir);
nextDirs = curFiles.filter(isDir);
curFiles = curFiles.map(prependBaseDir);
files = files.concat( curFiles );
while (nextDirs.length) {
files = files.concat( readdirSyncRecursive( _path.join(baseDir, nextDirs.shift()) ) );
}
return files;
};
var fileList = readdirSyncRecursive(baseDir).map(function(val){
return _path.relative(baseDir, val);
});
return fileList;
};
exports.readdirRecursive = function(baseDir, fn) {
baseDir = baseDir.replace(/\/$/, '');
var waitCount = 0;
function readdirRecursive(curDir) {
var files = [],
curFiles,
nextDirs,
prependcurDir = function(fname){
return _path.join(curDir, fname);
};
waitCount++;
fs.readdir(curDir, function(e, curFiles) {
waitCount--;
curFiles = curFiles.map(prependcurDir);
curFiles.forEach(function(it) {
waitCount++;
fs.stat(it, function(e, stat) {
waitCount--;
if (e) {
fn(e);
} else {
if (stat.isDirectory()) {
readdirRecursive(it);
}
}
if (waitCount == 0) {
fn(null, null);
}
});
});
fn(null, curFiles.map(function(val) {
return _path.relative(baseDir, val);
}));
if (waitCount == 0) {
fn(null, null);
}
});
};
readdirRecursive(baseDir);
};
exports.rmdirSyncRecursive = function(path, failSilent) {
var files;
try {
files = fs.readdirSync(path);
} catch (err) {
if(failSilent) return;
throw new Error(err.message);
}
for(var i = 0; i < files.length; i++) {
var currFile = fs.lstatSync(path + "/" + files[i]);
if(currFile.isDirectory())
exports.rmdirSyncRecursive(path + "/" + files[i]);
else if(currFile.isSymbolicLink())
fs.unlinkSync(path + "/" + files[i]);
else
fs.unlinkSync(path + "/" + files[i]);
}
return fs.rmdirSync(path);
};
exports.copyDirSyncRecursive = function(sourceDir, newDirLocation, opts) {
if (!opts || !opts.preserve) {
try {
if(fs.statSync(newDirLocation).isDirectory()) exports.rmdirSyncRecursive(newDirLocation);
} catch(e) { }
}
var checkDir = fs.statSync(sourceDir);
try {
fs.mkdirSync(newDirLocation, checkDir.mode);
} catch (e) {
if (e.code !== 'EEXIST') throw e;
}
var files = fs.readdirSync(sourceDir);
for(var i = 0; i < files.length; i++) {
var currFile = fs.lstatSync(sourceDir + "/" + files[i]);
if(currFile.isDirectory()) {
exports.copyDirSyncRecursive(sourceDir + "/" + files[i], newDirLocation + "/" + files[i], opts);
} else if(currFile.isSymbolicLink()) {
var symlinkFull = fs.readlinkSync(sourceDir + "/" + files[i]);
fs.symlinkSync(symlinkFull, newDirLocation + "/" + files[i]);
} else {
var contents = fs.readFileSync(sourceDir + "/" + files[i]);
fs.writeFileSync(newDirLocation + "/" + files[i], contents);
}
}
};
exports.chmodSyncRecursive = function(sourceDir, filemode) {
var files = fs.readdirSync(sourceDir);
for(var i = 0; i < files.length; i++) {
var currFile = fs.lstatSync(sourceDir + "/" + files[i]);
if(currFile.isDirectory()) {
exports.chmodSyncRecursive(sourceDir + "/" + files[i], filemode);
} else {
fs.chmod(sourceDir + "/" + files[i], filemode);
}
}
fs.chmod(sourceDir, filemode);
};
exports.chownSyncRecursive = function(sourceDir, uid, gid) {
var files = fs.readdirSync(sourceDir);
for(var i = 0; i < files.length; i++) {
var currFile = fs.lstatSync(sourceDir + "/" + files[i]);
if(currFile.isDirectory()) {
exports.chownSyncRecursive(sourceDir + "/" + files[i], uid, gid);
} else {
fs.chownSync(sourceDir + "/" + files[i], uid, gid);
}
}
fs.chownSync(sourceDir, uid, gid);
};
exports.rmdirRecursive = function rmdirRecursive(dir, clbk){
fs.readdir(dir, function(err, files){
if (err) return clbk(err);
(function rmFile(err){
if (err) return clbk(err);
var filename = files.shift();
if (filename === null || typeof filename == 'undefined')
return fs.rmdir(dir, clbk);
var file = dir+'/'+filename;
fs.stat(file, function(err, stat){
if (err) return clbk(err);
if (stat.isDirectory())
rmdirRecursive(file, rmFile);
else
fs.unlink(file, rmFile);
});
})();
});
};
exports.copyDirRecursive = function copyDirRecursive(srcDir, newDir, clbk) {
fs.stat(newDir, function(err, newDirStat){
if (!err) return exports.rmdirRecursive(newDir, function(err){
copyDirRecursive(srcDir, newDir, clbk);
});
fs.stat(srcDir, function(err, srcDirStat){
if (err) return clbk(err);
fs.mkdir(newDir, srcDirStat.mode, function(err){
if (err) return clbk(err);
fs.readdir(srcDir, function(err, files){
if (err) return clbk(err);
(function copyFiles(err){
if (err) return clbk(err);
var filename = files.shift();
if (filename === null || typeof filename == 'undefined')
return clbk();
var file = srcDir+'/'+filename,
newFile = newDir+'/'+filename;
fs.stat(file, function(err, fileStat){
if (fileStat.isDirectory())
copyDirRecursive(file, newFile, copyFiles);
else if (fileStat.isSymbolicLink())
fs.readlink(file, function(err, link){
fs.symlink(link, newFile, copyFiles);
});
else
fs.readFile(file, function(err, data){
fs.writeFile(newFile, data, copyFiles);
});
});
})();
});
});
});
});
};
var mkdirSyncRecursive = function(path, mode) {
var self = this;
try {
fs.mkdirSync(path, mode);
} catch(err) {
if(err.code == "ENOENT") {
var slashIdx = path.lastIndexOf("/");
if(slashIdx < 0) {
slashIdx = path.lastIndexOf("\\");
}
if(slashIdx > 0) {
var parentPath = path.substring(0, slashIdx);
mkdirSyncRecursive(parentPath, mode);
mkdirSyncRecursive(path, mode);
} else {
throw err;
}
} else if(err.code == "EEXIST") {
return;
} else {
throw err;
}
}
};
exports.mkdirSyncRecursive = mkdirSyncRecursive;
exports.LineReader = function(filename, bufferSize) {
this.bufferSize = bufferSize || 8192;
this.buffer = "";
this.fd = fs.openSync(filename, "r");
this.currentPosition = 0;
};
exports.LineReader.prototype = {
getBufferAndSetCurrentPosition: function(position) {
var res = fs.readSync(this.fd, this.bufferSize, position, "ascii");
this.buffer += res[0];
if(res[1] === 0) {
this.currentPosition = -1;
} else {
this.currentPosition = position + res[1];
}
return this.currentPosition;
},
hasNextLine: function() {
while(this.buffer.indexOf('\n') === -1) {
this.getBufferAndSetCurrentPosition(this.currentPosition);
if(this.currentPosition === -1) return false;
}
if(this.buffer.indexOf("\n") > -1) return true;
return false;
},
getNextLine: function() {
var lineEnd = this.buffer.indexOf("\n"),
result = this.buffer.substring(0, lineEnd);
this.buffer = this.buffer.substring(result.length + 1, this.buffer.length);
return result;
}
};