UNPKG

bia

Version:

a tool for download git repository

536 lines (503 loc) 17.9 kB
/* * @Author: hzxulin@yeah.net * @Date: 2018-11-19 18:15:59 * @Last Modified by: hzxulin@yeah.net * @Last Modified time: 2019-12-18 15:34:39 */ const path = require('path') const execa = require('execa') const ora = require('ora') const fse = require('fs-extra') const figlet = require('figlet') const colors = require('colors') const request = require('request') const BASE_CONFIG = require('../../config/base.json') /** * 获取当前时间 */ const getNowDate = () => { let _dateObj = new Date() let _year = _dateObj.getFullYear() let _month = _dateObj.getMonth() + 1 let _date = _dateObj.getDate() _month = _month < 10 ? `0${_month}` : _month _date = _date < 10 ? `0${_date}` : _date return `${_year}-${_month}-${_date}` } /** * clone远程git项目,去除.git文件 * @param {string} repo git的源地址 * @param {string} branch 分支名称 * @param {string} text 提示文案 */ const cloneGit = (repo, branch, text) => { text = text || '项目初始化中...' return new Promise((resolve, reject) => { const spinner = ora(`== ${text} ==`) const tplTemp = path.resolve(process.env.HOME, '.web-init-templates', repo.replace(/\/|:/g, '-')) spinner.start() fse.emptyDirSync(tplTemp) let cmd = `git clone ${branch ? `-b ${branch}` : ''} ${repo} ${tplTemp}` execa.shell(cmd).then(() => { fse.removeSync(path.resolve(tplTemp, '.git')) spinner.stop() resolve(tplTemp) }).catch(err => { spinner.stop() console.log(colors.red('== 初始化异常,停止进程 ==')) reject(err) }) }) } /** * 移动文件 * @param {string} file 文件名称 * @param {string} src 源路径 * @param {string} dist 目标路径 */ const moveFiles = (file, src, dist) => { return new Promise((resolve, reject) => { const srcFolder = file ? path.resolve(src, file) : src const distFolder = file ? path.resolve(dist, file) : dist try { fse.copySync(srcFolder, distFolder) resolve() } catch (err) { reject(err) } }) } /** * 渲染文件,用于pageInfo文件 * @param {object} answer 配置信息 * @param {string} src 源文件地址 * @param {string} dist 目标地址 */ const renderPageInfo = (answer, src, dist) => { return new Promise((resolve, reject) => { fse.readFile(src, 'utf-8', (_err, _data) => { if (_err) { reject(_err) } else { let _deployPC = true let _deployH5 = true let _combinePC = 'pc' let _combineH5 = 'h5' switch (+answer.platform) { case 0: { break } case 1: { _deployH5 = false _combineH5 = 'pc' break } case 2: { _deployPC = false _combinePC = 'h5' break } } let _newData = String(_data).replace(/\$\{projectId\}/, (answer.projectId && answer.projectId.length) ? `"${answer.projectId}"` : '0') .replace(/\$\{title\}/, answer.title) .replace(/\$\{startTime\}/, `${answer.startTime} 00:00:00`) .replace(/\$\{endTime\}/, `${answer.endTime} 00:00:00`) .replace(/\$\{category\}/, answer.category) .replace(/\$\{deployPC\}/, _deployPC) .replace(/\$\{deployH5\}/, _deployH5) .replace(/\$\{combinePC\}/, _combinePC) .replace(/\$\{combineH5\}/, _combineH5) try { fse.outputFileSync(dist, _newData) resolve() } catch (err) { reject(err) } } }) }) } /** * 渲染文件,用于pageInfo json文件 * @param {object} answer 配置信息 * @param {string} src 源文件地址 * @param {string} dist 目标地址 */ const renderPageInfoJson = (answer, src, dist) => { return new Promise((resolve, reject) => { fse.readFile(src, 'utf-8', (_err, _data) => { if (_err) { reject(_err) } else { let _newData = String(_data) .replace(/\$\{title\}/ig, answer.title) .replace(/\$\{startTime\}/ig, `${answer.startTime} 00:00:00`) .replace(/\$\{endTime\}/ig, `${answer.endTime} 00:00:00`) .replace(/\$\{businessId\}/ig, answer.businessId) .replace(/\$\{cateList\}/ig, answer.cateList) try { fse.removeSync(src) fse.outputFileSync(dist, _newData) resolve() } catch (err) { reject(err) } } }) }) } /** * 删除指定的文件或目录 * @param {string} dist 文件或目录 */ const removeDist = (dist) => { return new Promise((resolve, reject) => { try { fse.removeSync(dist) resolve() } catch (err) { reject(err) } }) } /** * 渲染模板 * @param {number} platform pc或者h5,或其他 * @param {*} src 源地址 * @param {*} dist 目标地址 */ const renderTpl = (platform, src, dist) => { return new Promise((resolve, reject) => { try { fse.removeSync(dist) switch (+platform) { case 1: { fse.copySync(path.resolve(src, 'pc'), path.resolve(dist, 'pc')) break } case 2: { fse.copySync(path.resolve(src, 'h5'), path.resolve(dist, 'h5')) break } case 0: default: { fse.copySync(path.resolve(src, 'pc'), path.resolve(dist, 'pc')) fse.copySync(path.resolve(src, 'h5'), path.resolve(dist, 'h5')) break } } resolve() } catch(err) { reject(err) } }) } /** * 成功打印logo * @param {function} cb 回调函数cb * @param {boolean} exitFlag 结束标志 */ const showSuccess = (cb, exitFlag) => { figlet('^ Bia >>>', (err, data) => { if (err) throw err console.log(colors.green(`\n${data}`)) if (Object.prototype.toString.call(cb) === '[object Function]') { cb() } else { console.log(colors.green('== Bia success. ==')) } if (exitFlag) process.exit() }) } /** * 查询活动计划 */ const getProjectPlan = () => { return new Promise((resolve, reject) => { request('http://pub.mail.163.com/pscpub/captain/api/project/getSimpleUnOffList.do?sign=178b95ad88feec0b9c1f04e641fe3317', (_err, _res, _body) => { if (_res.statusCode == 200) { let _result = [] try { _result = JSON.parse(_body).result } catch (e) { _result = _body.result } resolve(_result) } else { reject('Failed to get the list of plan.') } }) }) } /** * 获取页面搭建系统的cate列表 */ const getCateList = () => { return new Promise((resolve, reject) => { const cateList = BASE_CONFIG.cateList resolve(cateList) }) } /** * 渲染文件,用于floor json文件 * @param {object} answer 配置信息 * @param {string} src 源文件地址 * @param {string} dist 目标地址 */ const renderFloorListJson = (answer, src, dist) => { return new Promise((resolve, reject) => { fse.readFile(src, 'utf-8', (_err, _data) => { if (_err) { reject(_err) } else { try { let _newData = JSON.parse(String(_data)) switch (+answer.platform) { case 0: { _newData = { "pc": _newData, "h5": _newData, } break } case 1: { _newData = { "pc": _newData, } break } case 2: { _newData = { "h5": _newData, } break } } fse.removeSync(src) fse.outputFileSync(dist, JSON.stringify(_newData, null, 4)) resolve() } catch (err) { reject(err) } } }) }) } /** * 更新taro组件开发的文件信息 * @param {string} dist 目标路径 * @param {object} info */ const formatComponentFile = (dist, info) => { return new Promise((resolve, reject) => { fse.readFile(dist, 'utf-8', (_err, _data) => { if (_err) { reject(_err) } else { try { const _newData = String(_data) .replace(/\$componentName\$/ig, info.name || '') .replace(/\$componentVersion\$/ig, info.version || '') .replace(/\$componentDesc\$/ig, info.desc || '') fse.outputFileSync(dist, _newData) resolve() } catch (err) { reject(err) } } }) }) } /** * 获取目标路径下所有的文件 * @param {string} dir 目标路径 */ const getAllFiles = (dir) => { return new Promise((resolve, reject) => { try { let res = [] const findAllFiles = (subDir) => { let files = fse.readdirSync(subDir) files.forEach((item) => { let fPath = path.resolve(subDir, item) let stat = fse.statSync(fPath) if(stat.isDirectory()) { res.push({ type: 'directory', value: fPath, }) findAllFiles(fPath) } if (stat.isFile()) { res.push({ type: 'file', value: fPath, }) } }) } findAllFiles(dir) resolve(res) } catch (err) { reject(err) } }) } /** * 更新component框架下的开发src路径下的内容 * @param {object} info */ const updateComponentSrc = (info) => { return new Promise((resolve, reject) => { try { const srcFolder = path.resolve(process.cwd(), 'src/components/$componentName$') const distFolder = srcFolder.replace(/\$componentName\$/ig, info.name || '') fse.copySync(srcFolder, distFolder) removeDist(srcFolder).then(() => { return getAllFiles(path.resolve(process.cwd(), `src`)) }).then((res) => { console.log(res) return Promise.all(res.filter(item => (item.type == 'file')).map(item => { return formatComponentFile(item.value, info) })) }).then(() => { resolve() }).catch((err) => { reject(err) }) } catch (err) { reject(err) } }) } /** * 更新taro组件开发的框架 * @param {object} info */ const updateComponentFramework = (info) => { return new Promise((resolve, reject) => { return formatComponentFile(path.resolve(process.cwd(), 'package.json'), info).then(() => { return updateComponentSrc(info) }).then(() => { resolve(info) }).catch(err => { reject(err) }) }) } /** * 获取老活动框架的pageInfo */ const getOldPageInfo = () => { return new Promise((resolve, reject) => { const oriPageInfo = path.resolve(process.cwd(), 'pageInfo/pageInfo.yml') fse.readFile(oriPageInfo, 'utf-8', (_err, _data) => { if (_err) { reject(_err) } else { try { const title = String(_data).match(/title:\s*\"(.*)\"/)[1] const startTime = String(_data).match(/startTime:\s*\"(.*)\"/)[1] const endTime = String(_data).match(/endTime:\s*\"(.*)\"/)[1] resolve({ title, startTime, endTime, }) } catch (err) { reject(err) } } }) }) } /** * 输出新的pageInfo * @param {object} pageInfo 页面pageInfo */ const outputNewPageInfo = (pageInfo) => { return new Promise((resolve, reject) => { const oriPageInfo = path.resolve(process.cwd(), 'pageInfo/pageInfo.yml') const newPageInfo = path.resolve(process.cwd(), 'pageInfo/pageInfo.json') fse.readFile(newPageInfo, 'utf-8', (_err, _data) => { if (_err) { reject(_err) } else { try { const _newData = String(_data) .replace(/\$\$pageName\$\$/ig, pageInfo.title || '') .replace(/\$\$startTime\$\$/ig, pageInfo.startTime || '') .replace(/\$\$endTime\$\$/ig, pageInfo.endTime || '') fse.removeSync(oriPageInfo) fse.outputFileSync(newPageInfo, _newData) resolve() } catch (err) { reject(err) } } }) }) } /** * 输出新的package文件 */ const outputPackage = () => { return new Promise((resolve, reject) => { const oriPackage = path.resolve(process.cwd(), 'package.json') const newPackage = path.resolve(process.cwd(), 'package.temp.json') fse.readFile(oriPackage, 'utf-8', (_err, _data) => { if (_err) { reject(_err) } else { fse.readFile(newPackage, 'utf-8', (_err2, _data2) => { if (_err2) { reject(_err2) } else { let oriPackageJson = JSON.parse(String(_data)) let newPackageJson = JSON.parse(String(_data2)) const oldPackageDep = ["art-template", "art-template-loader", "autoprefixer", "babel-core", "babel-eslint", "babel-loader", "babel-plugin-add-module-exports", "babel-plugin-lodash", "babel-plugin-transform-runtime", "babel-preset-env", "babel-preset-stage-2", "chalk", "css-loader", "cssnano", "es3ify-loader", "es5-shim", "eslint", "eslint-config-standard", "eslint-friendly-formatter", "eslint-loader", "eslint-plugin-bia", "eslint-plugin-html", "eslint-plugin-import", "eslint-plugin-node", "eslint-plugin-promise", "eslint-plugin-standard", "execa", "express", "extract-text-webpack-plugin", "file-loader", "friendly-errors-webpack-plugin", "fs-extra", "html-loader", "html-string-replace-webpack-plugin", "html-webpack-inline-source-plugin", "html-webpack-plugin", "htmlhint-bia-loader", "html-modulemarket-plugin", "http-proxy-middleware", "ip", "json-server", "node-sass", "opn", "ora", "portfinder", "postcss-bialint", "postcss-import", "postcss-loader", "request", "rimraf", "sass-loader", "script-loader", "string-replace-webpack-plugin", "style-loader", "url-loader", "vconsole-webpack-plugin", "webpack", "webpack-dev-middleware", "webpack-hot-middleware", "webpack-merge", "yargs"] let tempDep = oriPackageJson.devDependencies Object.keys(tempDep).forEach((item) => { if (oldPackageDep.indexOf(item) > -1) { delete tempDep[item] } }) const resPackageJson = Object.assign({}, newPackageJson, { devDependencies: Object.assign({}, newPackageJson.devDependencies, tempDep), dependencies: Object.assign({}, newPackageJson.dependencies, oriPackageJson.dependencies), }) fse.removeSync(newPackage) fse.outputFileSync(oriPackage, JSON.stringify(resPackageJson, null, 4)) resolve() } }) } }) }) } /** * 活动框架更新 */ const updateAct = () => { return getOldPageInfo().then((pageInfo) => { return outputNewPageInfo(pageInfo) }).then(() => { return outputPackage() }) } module.exports = { getNowDate, cloneGit, moveFiles, renderPageInfo, renderPageInfoJson, removeDist, renderTpl, showSuccess, getProjectPlan, getCateList, renderFloorListJson, updateComponentFramework, updateAct, updateComponentSrc, }