Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reduce scope such as recursive function #23

Merged
merged 8 commits into from
Nov 5, 2018
121 changes: 66 additions & 55 deletions lib/fs.js
Original file line number Diff line number Diff line change
Expand Up @@ -216,22 +216,22 @@ function _readAndFilterDirSync(path, options) {
});
}

function _copyDir(src, dest, options = {}, parent = '') {
return checkParent(dest).then(() => _readAndFilterDir(src, options))
function _copyDir(src, dest, options, parent) {
return _readAndFilterDir(src, options)
.map(item => {
const childSrc = item.fullPath;
const childDest = join(dest, item.path);
const currentPath = join(parent, item.path);

if (item.isDirectory) {
return _copyDir(childSrc, childDest, options, join(parent, item.path));
return _copyDir(childSrc, childDest, options, currentPath);
}

return copyFile(childSrc, childDest, options)
.thenReturn(join(parent, item.path));
return copyFile(childSrc, childDest, options).thenReturn(currentPath);
}).reduce(reduceFiles, []);
}

function copyDir(src, dest, options, callback) {
function copyDir(src, dest, options = {}, callback) {
if (!src) throw new TypeError('src is required!');
if (!dest) throw new TypeError('dest is required!');

Expand All @@ -240,42 +240,50 @@ function copyDir(src, dest, options, callback) {
options = {};
}

return _copyDir(src, dest, options).asCallback(callback);
return checkParent(dest).then(() => _copyDir(src, dest, options, '')).asCallback(callback);
}

function _listDir(path, options = {}, parent = '') {
function _listDir(path, options, parent) {
return _readAndFilterDir(path, options).map(item => {
const currentPath = join(parent, item.path);

if (item.isDirectory) {
return _listDir(item.fullPath, options, join(parent, item.path));
return _listDir(item.fullPath, options, currentPath);
}

return join(parent, item.path);
return currentPath;
}).reduce(reduceFiles, []);
}

function listDir(path, options, callback) {
function listDir(path, options = {}, callback) {
if (!path) throw new TypeError('path is required!');

if (!callback && typeof options === 'function') {
callback = options;
options = {};
}

return _listDir(path, options).asCallback(callback);
return _listDir(path, options, '').asCallback(callback);
}

function listDirSync(path, options = {}, parent = '') {
if (!path) throw new TypeError('path is required!');

function _listDirSync(path, options, parent) {
return _readAndFilterDirSync(path, options).map(item => {
const currentPath = join(parent, item.path);

if (item.isDirectory) {
return listDirSync(item.fullPath, options, join(parent, item.path));
return _listDirSync(item.fullPath, options, currentPath);
}

return join(parent, item.path);
return currentPath;
}).reduce(reduceFiles, []);
}

function listDirSync(path, options = {}) {
if (!path) throw new TypeError('path is required!');

return _listDirSync(path, options, '');
}

function escapeEOL(str) {
return str.replace(rEOL, '\n');
}
Expand All @@ -288,15 +296,14 @@ function escapeFileContent(content) {
return escapeBOM(escapeEOL(content));
}

function readFile(path, options, callback) {
function readFile(path, options = {}, callback) {
if (!path) throw new TypeError('path is required!');

if (!callback && typeof options === 'function') {
callback = options;
options = {};
}

options = options || {};
if (!options.hasOwnProperty('encoding')) options.encoding = 'utf8';

return readFileAsync(path, options).then(content => {
Expand All @@ -322,43 +329,43 @@ function readFileSync(path, options = {}) {
return content;
}

function _emptyDir(path, options = {}, parent = '') {
function _emptyDir(path, options, parent) {
return _readAndFilterDir(path, options)
.filter(ignoreExcludeFiles(options.exclude, parent))
.map(item => {
const fullPath = item.fullPath;
const currentPath = join(parent, item.path);

if (item.isDirectory) {
return _emptyDir(fullPath, options, join(parent, item.path)).then(removed => readdirAsync(fullPath).then(files => {
return _emptyDir(fullPath, options, currentPath).tap(() => readdirAsync(fullPath).then(files => {
if (!files.length) return rmdirAsync(fullPath);
}).thenReturn(removed));
}));
}

return unlinkAsync(fullPath).thenReturn(join(parent, item.path));
return unlinkAsync(fullPath).thenReturn(currentPath);
}).reduce(reduceFiles, []);
}

function emptyDir(path, options, callback) {
function emptyDir(path, options = {}, callback) {
if (!path) throw new TypeError('path is required!');

if (!callback && typeof options === 'function') {
callback = options;
options = {};
}

return _emptyDir(path, options).asCallback(callback);
return _emptyDir(path, options, '').asCallback(callback);
}

function emptyDirSync(path, options = {}, parent = '') {
if (!path) throw new TypeError('path is required!');

function _emptyDirSync(path, options, parent) {
return _readAndFilterDirSync(path, options)
.filter(ignoreExcludeFiles(options.exclude, parent))
.map(item => {
const childPath = item.fullPath;
const currentPath = join(parent, item.path);

if (item.isDirectory) {
const removed = emptyDirSync(childPath, options, join(parent, item.path));
const removed = _emptyDirSync(childPath, options, currentPath);

if (!fs.readdirSync(childPath).length) {
rmdirSync(childPath);
Expand All @@ -368,37 +375,45 @@ function emptyDirSync(path, options = {}, parent = '') {
}

fs.unlinkSync(childPath);
return join(parent, item.path);
return currentPath;
}).reduce(reduceFiles, []);
}

function rmdir(path, callback) {
function emptyDirSync(path, options = {}) {
if (!path) throw new TypeError('path is required!');

return _emptyDirSync(path, options, '');
}

function _rmdir(path) {
return readdirAsync(path).map(item => {
const childPath = join(path, item);

return statAsync(childPath).then(stats => {
if (stats.isDirectory()) {
return rmdir(childPath);
return _rmdir(childPath);
}

return unlinkAsync(childPath);
});
}).then(() => rmdirAsync(path)).asCallback(callback);
}).then(() => rmdirAsync(path));
}

function rmdirSync(path) {
function rmdir(path, callback) {
if (!path) throw new TypeError('path is required!');

return _rmdir(path).asCallback(callback);
}

function _rmdirSync(path) {
const files = fs.readdirSync(path);

for (let i = 0, len = files.length; i < len; i++) {
const childPath = join(path, files[i]);
const stats = fs.statSync(childPath);

if (stats.isDirectory()) {
rmdirSync(childPath);
_rmdirSync(childPath);
} else {
fs.unlinkSync(childPath);
}
Expand All @@ -407,6 +422,12 @@ function rmdirSync(path) {
fs.rmdirSync(path);
}

function rmdirSync(path) {
if (!path) throw new TypeError('path is required!');

_rmdirSync(path);
}

function watch(path, options, callback) {
if (!path) throw new TypeError('path is required!');

Expand All @@ -415,34 +436,24 @@ function watch(path, options, callback) {
options = {};
}

return new Promise((resolve, reject) => {
const watcher = chokidar.watch(path, options);

watcher.on('ready', () => {
resolve(watcher);
});
const watcher = chokidar.watch(path, options);

return new Promise((resolve, reject) => {
watcher.on('ready', resolve);
watcher.on('error', reject);
}).asCallback(callback);
}).thenReturn(watcher).asCallback(callback);
}

function _findUnusedPath(path, files) {
const ext = extname(path);
const base = basename(path, ext);
const regex = new RegExp(`^${escapeRegExp(base)}(?:-(\\d+))?${escapeRegExp(ext)}$`);
let num = -1;
const regex = new RegExp(`^${escapeRegExp(base)}-(\\d+)${escapeRegExp(ext)}$`);

for (let i = 0, len = files.length; i < len; i++) {
const item = files[i];
if (!regex.test(item)) continue;
const num = files.reduce((_num, item) => {
const match = regex.exec(item);

const match = item.match(regex);
const matchNum = match[1] ? parseInt(match[1], 10) : 0;

if (matchNum > num) {
num = matchNum;
}
}
return match != null ? Math.max(parseInt(match[1], 10), _num) : _num;
}, -1);

return join(dirname(path), `${base}-${num + 1}${ext}`);
}
Expand Down Expand Up @@ -488,7 +499,7 @@ function ensureWriteStreamSync(path, options) {
['F_OK', 'R_OK', 'W_OK', 'X_OK'].forEach(key => {
Object.defineProperty(exports, key, {
enumerable: true,
value: (fs.constants || fs)[key],
value: fs.constants[key],
writable: false
});
});
Expand Down