I tried fs-extra and copy-dir to copy-folder-recursively. but I want it to
- work normally (copy-dir throws an unreasonable error)
- provide two arguments in filter: filepath and filetype (fs-extra does't tell filetype)
- have a dir-to-subdir check and a dir-to-file check
So I wrote my own:
// Node.js module for Node.js 8.6+
var path = require("path");
var fs = require("fs");
function copyDirSync(src, dest, options) {
var srcPath = path.resolve(src);
var destPath = path.resolve(dest);
if(path.relative(srcPath, destPath).charAt(0) != ".")
throw new Error("dest path must be out of src path");
var settings = Object.assign(Object.create(copyDirSync.options), options);
copyDirSync0(srcPath, destPath, settings);
function copyDirSync0(srcPath, destPath, settings) {
var files = fs.readdirSync(srcPath);
if (!fs.existsSync(destPath)) {
fs.mkdirSync(destPath);
}else if(!fs.lstatSync(destPath).isDirectory()) {
if(settings.overwrite)
throw new Error(`Cannot overwrite non-directory '${destPath}' with directory '${srcPath}'.`);
return;
}
files.forEach(function(filename) {
var childSrcPath = path.join(srcPath, filename);
var childDestPath = path.join(destPath, filename);
var type = fs.lstatSync(childSrcPath).isDirectory() ? "directory" : "file";
if(!settings.filter(childSrcPath, type))
return;
if (type == "directory") {
copyDirSync0(childSrcPath, childDestPath, settings);
} else {
fs.copyFileSync(childSrcPath, childDestPath, settings.overwrite ? 0 : fs.constants.COPYFILE_EXCL);
if(!settings.preserveFileDate)
fs.futimesSync(childDestPath, Date.now(), Date.now());
}
});
}
}
copyDirSync.options = {
overwrite: true,
preserveFileDate: true,
filter: function(filepath, type) {
return true;
}
};
And a similar function, mkdirs, which is an alternative to mkdirp:
function mkdirsSync(dest) {
var destPath = path.resolve(dest);
mkdirsSync0(destPath);
function mkdirsSync0(destPath) {
var parentPath = path.dirname(destPath);
if(parentPath == destPath)
throw new Error(`cannot mkdir ${destPath}, invalid root`);
if (!fs.existsSync(destPath)) {
mkdirsSync0(parentPath);
fs.mkdirSync(destPath);
}else if(!fs.lstatSync(destPath).isDirectory()) {
throw new Error(`cannot mkdir ${destPath}, a file already exists there`);
}
}
}