deep-package-manager
Version:
DEEP Package Manager
245 lines (192 loc) • 5.5 kB
JavaScript
/**
* Created by AlexanderC on 6/1/15.
*/
/*eslint no-undefined: 0*/
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.FileWalker = undefined;
var _gracefulFs = require('graceful-fs');
var _gracefulFs2 = _interopRequireDefault(_gracefulFs);
var _fsExtra = require('fs-extra');
var _fsExtra2 = _interopRequireDefault(_fsExtra);
var _fs = require('fs');
var _fs2 = _interopRequireDefault(_fs);
var _path = require('path');
var _path2 = _interopRequireDefault(_path);
var _mkdirp = require('mkdirp');
var _mkdirp2 = _interopRequireDefault(_mkdirp);
var _ignore = require('ignore');
var _ignore2 = _interopRequireDefault(_ignore);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* File walker
*/
class FileWalker {
/**
* @param {String} type
* @param {String} ignoreFile
*/
constructor(type = FileWalker.SIMPLE, ignoreFile = null) {
this._type = type;
this._ignoreFile = ignoreFile;
}
/**
* @param {String} ignoreFile
*/
set ignoreFile(ignoreFile) {
this._ignoreFile = ignoreFile;
}
/**
* @returns {String}
*/
get ignoreFile() {
return this._ignoreFile;
}
/**
* @returns {String}
*/
get type() {
return this._type;
}
/**
* @param {String} dir
* @param {Number} mode
* @returns {FileWalker}
*/
mkdir(dir, mode = null) {
if (this._type === FileWalker.RECURSIVE) {
_mkdirp2.default.sync(dir, mode ? { mode: mode } : undefined);
} else {
_gracefulFs2.default.mkdirSync(dir, mode);
}
return this;
}
/**
* @param {Object[]} args
*/
remove(...args) {
_fsExtra2.default.removeSync(...args);
}
/**
* @param {String} source
* @param {String} destination
* @param {Function} filter
* @returns {FileWalker}
*/
copy(source, destination, filter = () => true) {
source = _path2.default.normalize(source);
destination = _path2.default.normalize(destination);
let skipDotFilter = FileWalker.skipDotsFilter(filter);
let sourceOffset = source.length;
let files = this.walk(source, skipDotFilter);
for (let i in files) {
if (!files.hasOwnProperty(i)) {
continue;
}
let file = files[i];
let relativePath = file.substring(sourceOffset);
let fileCopy = _path2.default.join(destination, relativePath);
let fileDir = _path2.default.dirname(fileCopy);
if (!_fs2.default.existsSync(fileDir)) {
this.mkdir(fileDir);
}
_fsExtra2.default.copySync(file, fileCopy);
}
return this;
}
/**
* @param {String} dir
* @param {Function} filter
* @param {Array} _readDirsCache
* @returns {Array}
*/
walk(dir, filter = () => true, _readDirsCache = []) {
let results = [];
let list = _gracefulFs2.default.readdirSync(dir);
let ignoreFilter = this._ignoreFile ? this._buildIgnoreFilter(dir) : () => true;
list = list.map(file => _path2.default.join(dir, file)).filter(ignoreFilter);
for (let i in list) {
if (!list.hasOwnProperty(i)) {
continue;
}
let file = list[i];
if (this._type === FileWalker.RECURSIVE) {
let stat = null;
try {
stat = _gracefulFs2.default.statSync(file);
} catch (error) {
// error codes:
// ELOOP - too many symbolic links encountered
// ENOENT - missing file
// EACCES - permission denied
if (['ELOOP', 'ENOENT', 'EACCES'].indexOf(error.code) !== -1) {
continue;
}
throw error;
}
if (stat.isDirectory()) {
let realDir = _gracefulFs2.default.realpathSync(file);
// avoid cyclic inheritance
if (_readDirsCache.indexOf(realDir) === -1) {
_readDirsCache.push(realDir);
results = results.concat(this.walk(file, filter, _readDirsCache));
}
} else if (filter(file)) {
results.push(file);
}
} else if (filter(file)) {
results.push(file);
}
}
return results.filter(ignoreFilter); // assure global ignores
}
/**
* @param {String} dir
* @returns {Function}
* @private
*/
_buildIgnoreFilter(dir) {
let ignoreFile = _path2.default.join(dir, this._ignoreFile);
if (_gracefulFs2.default.existsSync(ignoreFile)) {
return (0, _ignore2.default)({}).add(_gracefulFs2.default.readFileSync(ignoreFile).toString()).createFilter();
}
return () => true;
}
/**
* @param {Function|null} originalFilter
* @param {String|*} extensions
* @returns {Function}
*/
static matchExtensionsFilter(originalFilter = null, ...extensions) {
let extensionsPlain = extensions.join('|');
let regex = new RegExp(`\\.(${extensionsPlain})$`, 'i');
return file => {
return regex.test(file) && (!originalFilter || originalFilter(file));
};
}
/**
* @param {Function|null} originalFilter
* @returns {Function}
*/
static skipDotsFilter(originalFilter = null) {
return file => {
let basename = _path2.default.basename(file);
return basename !== '.' && basename !== '..' && (!originalFilter || originalFilter(file));
};
}
/**
* @returns {String}
*/
static get RECURSIVE() {
return 'recursive';
}
/**
* @returns {String}
*/
static get SIMPLE() {
return 'simple';
}
}
exports.FileWalker = FileWalker;