easygo
Version:
198 lines (170 loc) • 4.78 kB
JavaScript
/**
* @file: file
* @author: cuihonglei(cuihonglei2xj@gmail.com)
* @Date: 2017-06-22 19:49:08
*/
;
/* eslint-disable fecs-prefer-class */
const fs = require('fs');
const path = require('path');
const fileUtil = require('./fileUtil');
const config = require('./config');
const minimatch = require('minimatch');
function values(object) {
return Object.keys(object).map(key => object[key]);
}
/**
* 执行上下文对象
*
* @constructor
* @param {string} name 组件名称
* @param {Object=} files 组件文件列表
* @param {Array=} ignore 忽略检查的文件pattern列表
*/
function Context(name, files, ignore) {
this.name = name;
this.files = files || {};
this.ingore = ignore || [];
}
/**
* 检查文件是否在忽略检查的pattern列表里面
*
* @param {string} filePath 文件路径
* @return {boolean}
*/
Context.prototype.isIgnore = function (filePath) {
if (!this.ignore.length) {
return false;
}
for (let i = 0, pattern; pattern = this.ignore[i]; i++) {
let result = minimatch(filePath, pattern);
if (result) {
return true;
}
}
return false;
};
/**
* 添加一个文件
*
* @param {Object} file 文件对象
*
* @return {this}
*/
Context.prototype.addFile = function (file) {
if (this.files[file.path]) {
throw new Error('exists file:' + file.path);
}
this.files[file.path] = file;
return this;
};
/**
* 移除一个文件
*
* @param {Object|string} file 文件对象或者路径
* @return {this}
*/
Context.prototype.removeFile = function (file) {
if (typeof file === 'string') {
delete this.files[file];
}
else {
delete this.files[file.path];
}
return this;
};
/**
* 文件是否存在
*
* @param {Object|string} file 文件对象或者路径
* @return {boolean}
*/
Context.prototype.existsFile = function (file) {
const path = typeof file === 'string' ? file : file.path;
return !!this.files[path];
};
/**
* 获取文件内容
*
* @param {Object|string} file 文件对象或者路径
* @return {Object}
*/
Context.prototype.getFile = function (file) {
const path = typeof file === 'string' ? file : file.path;
return this.files[path];
};
/**
* 获取文件列表
*
* @param {Regexp|Function=} pattern 文件过滤规则
* @return {Array.<File>}
*/
Context.prototype.getFiles = function (pattern) {
if (!pattern) {
return values(this.files);
}
// 文件过滤规则,支持function和regex
let filterFn = function () {
return true;
};
if (typeof pattern === 'function') {
filterFn = pattern;
}
else if (pattern instanceof RegExp) {
filterFn = function (file) {
return !!file.path.match(pattern);
};
}
return values(this.files).filter(filterFn);
};
/**
* 从文件中加载组件信息,返回创建的context对象
*
* @param {string} filePath 文件路径
* @return {Context} Context对象
*/
Context.load = function (filePath) {
return new Promise(resolve => {
if (!fs.existsSync(filePath)) {
throw new Error('没有找到组件目录!');
}
console.log(filePath,path.basename(filePath),'node')
const baseDir = path.dirname(filePath);
const context = new Context(path.basename(filePath));
const binaryFiles = []; // 二进制文件
const deepDepthFiles = []; // 深层次文件
// 读取目录下的文件
fileUtil.walkDir(filePath, (absolutePath, depth) => {
const relativePath = path.relative(baseDir, absolutePath);
if (depth > config.maxFileDepth) {
deepDepthFiles.push(relativePath);
return;
}
if (!fileUtil.isPlainText(absolutePath)) {
binaryFiles.push(relativePath);
return;
}
context.addFile({
path: relativePath.replace(/\\/g, '/'), // 统一使用`/`作为目录分割
content: fs.readFileSync(absolutePath, 'utf-8')
});
});
if (deepDepthFiles.length) {
throw new Error('存在深层级的文件,文件层级不能大于' + config.maxFileDepth + '级:\n'
+ deepDepthFiles.join('\n'));
}
if (binaryFiles.length) {
throw new Error('存在非文本类型的文件:\n' + binaryFiles.join('\n'));
}
resolve(context);
}, (e) => {
console.error(e);
});
};
/**
* 从zip文件中加载组件信息,返回创建的context对象
*
* @param {string} filePath 文件路径
* @return {Context} Context对象
*/
module.exports = Context;