UNPKG

ng-environment-setup

Version:
216 lines (199 loc) 7.38 kB
const request = require('request') const fs = require('fs') const path = require('path') const { execSync } = require('child_process') const { red, yellow, green } = require('ansi-colors') class Common { constructor() { // 项目路径 this.projectPath = process.cwd() } /** * 判断数据是否是数组 * @param {*} data * @returns {boolean} */ isArray(data) { return data instanceof Array } /** * 判断数据是否是字符串 * @param {*} str * @returns {boolean} */ isString(str) { return typeof str === 'string' } /** * 执行命令 * @param {string} command 命令字符串 * @param {function} callback 回调函数 */ execCommand(command, callback) { const stdout = execSync(command, { cwd: this.projectPath, encoding: 'utf8', stdio: 'inherit' }) console.log(green(stdout)) if (callback) { callback() } // if (error) { // console.log(red(`ERROR: ${error}`)) // } else { // if (stderr) { // stderr.on('data', (msg) => { // if (msg.includes('ERR')) { // console.log(red(msg)) // } // if (msg.includes('WARN')) { // console.log(yellow(msg)) // } // }) // } // stdout.on('data', (msg) => { // console.log(green(msg)) // }) // if (callback) { // callback() // } // } } /** * 改写文件内容 * @param {string} filePath 文件路径 * @param {RewriteFileOptions} options 改写配置 * @RewriteFileOptions {Array} replaceList 字符串替换列表,例:{ before: 'a', after: 'b', all: true } * @RewriteFileOptions {Array} matchList 根据前后字符串匹配并添加字符串列表,例:{ match: 'const a = [|]', item: 'bbb', space: 2, cover: true } * @RewriteFileOptions {Array} importList 引入模块字符串列表 例:`import a from 'a'` */ rewriteFile(filePath, options = {}) { const fileName = filePath.split('/').pop() filePath = path.join(this.projectPath, filePath) console.log(green(`${fileName} updating. . .`)) let fileString = fs.readFileSync(filePath, 'utf-8') fileString = fileString.replace(new RegExp('\r\n', 'g'), '\n') // 字符串替换 if (this.isArray(options.replaceList)) { options.replaceList.forEach(rp => { if (!fileString.includes(rp.after)) { fileString = fileString.replace(rp.all ? new RegExp(rp.before, 'g') : rp.before, rp.after) } }) } // 根据前后字符串匹配并添加字符串 if (this.isArray(options.matchList)) { options.matchList.forEach(mt => { const initString = mt.match.replace('|', '') const spaceCount = mt.space || 0 let startString = mt.match.split('|')[0] let endString = mt.match.split('|')[1] if (fileString.includes(initString)) { startString = `${startString}\n${' '.repeat(spaceCount + 2)}` endString = `\n${' '.repeat(spaceCount)}${endString}` fileString = fileString.replace(initString, `${startString}${mt.item}${endString}`) } else { startString = startString.replace('[', '\\[') endString = `\n${' '.repeat(spaceCount)}${endString.replace(']', '\\]')}` const matchStringArray = fileString.match(new RegExp(`${startString}([\\s\\S]*?)${endString}`)) const matchString = matchStringArray && matchStringArray[1] const linkString = `${mt.cover ? '' : ','}\n${' '.repeat(spaceCount + 2)}` if (!matchString.includes(mt.item)) { fileString = fileString.replace(matchString, `${mt.cover ? '' : matchString}${linkString}${mt.item}`) } } }) } // 引入模块字符串列表 if (this.isArray(options.importList)) { options.importList.forEach(ip => { if (!fileString.includes(ip)) { const lineStartIndex = fileString.lastIndexOf('import ') const lineEndIndex = fileString.indexOf('\n', lineStartIndex) const lastImportString = fileString.substring(lineStartIndex, lineEndIndex) fileString = fileString.replace(`${lastImportString}`, `${lastImportString}\n${ip}`) } }) } fs.writeFileSync(filePath, fileString, 'utf-8') console.log(green(`${fileName} update completed.`)) } /** * 生成文件 * @param {string} filePath 文件路径 * @param {string} fileString 文件内容字符串 */ generateFile(filePath, fileString) { const fileName = filePath.split('/').pop() filePath = path.join(this.projectPath, filePath) console.log(green(`${fileName} creating. . .`)) if (fs.existsSync(filePath)) { return console.log(yellow(`${fileName} already exists.`)) } fs.mkdirSync(filePath.replace(`${fileName}`, ''), { recursive: true }) fs.writeFileSync(filePath, fileString, 'utf-8') console.log(green(`${fileName} create completed.`)) } /** * 保存网络图片到本地 * @param {string} linkPath 图片链接地址 * @param {string} writePath 图片写入路径 */ downloadImage(linkPath, writePath) { const fileName = writePath.split('/').pop() writePath = path.join(this.projectPath, writePath) console.log(green(`${fileName} downloading. . .`)) fs.mkdirSync(writePath.replace(`${fileName}`, ''), { recursive: true }) const writeStream = fs.createWriteStream(writePath) const readStream = request(linkPath) readStream.pipe(writeStream) readStream.on('error', err => { console.log(red(`ERROR: ${err}`)) }) writeStream.on('finish', () => { console.log(green(`${fileName} download completed.`)) writeStream.end() }) } /** * 获取模板 * @param {string} filepath 路径名称 */ getTemplate(filepath) { return fs.readFileSync(path.join(__dirname, `./templates${filepath}`), 'utf-8') } /** * 拷贝目录 * @param {string} oldPath 旧目录路径 * @param {string} newPath 新目录路径 * @param {boolean} isMove 是否删除旧目录文件 */ copyDir(oldPath, newPath, isMove) { const fileList = fs.readdirSync(path.join(__dirname, oldPath)) fileList.forEach(filePath => { const oldFilePath = `${oldPath}/${filePath}` const newFilePath = `${newPath}/${filePath}` fs.mkdirSync(path.join(this.projectPath, newPath), { recursive: true }) if (['.html', '.scss', '.ts'].some(t => filePath.endsWith(t))) { fs.copyFileSync(path.join(__dirname, oldFilePath), path.join(this.projectPath, newFilePath)) if (isMove) { fs.unlinkSync(path.join(__dirname, oldFilePath)) if (!fs.readdirSyncpath.join(__dirname, (oldPath)).length) { fs.rmdirSync(path.join(__dirname, oldPath)) } } } else { this.copyDir(oldFilePath, newFilePath, isMove) } }) } /** * 英文字符串首字母大写 * @param {*} str 英文字符串 * @returns {string} */ getFirstLetterUpper(str) { if (this.isString(str) && str[0]) { return str[0].toUpperCase() + str.substr(1) } return '' } } module.exports = Common