dev
, 主分支 marster
, 当处于开发分支时,执行脚本命令 zip
自动完成 ,压缩包生成, 分支切换, 文件更新及提交graph TD
生成压缩包 --> 保存压缩包到缓存目录
保存压缩包到缓存目录 --> 切换到主分支
切换到主分支 --> 将缓存拷贝到主分支目录
将缓存拷贝到主分支目录 --> 提交
提交 --> 切回开发分支
切回开发分支 --> 删除缓存
删除缓存 --> 保存新版本信息
- root
- script
- index.js // 入口
- createZip.js // 生成压缩包
- cmmds.js // 执行git命令
- utils.js // 工具包
- version.js // 版本更新
- color.js // 信息输出
- config.json // 配置文件
/**
* 创建压缩包
*/
const fs = require('fs')
const archiver = require('archiver')
const events = {
warning(err){
console.log(`warning: ${err}`)
},
error(err){
console.log(`error: ${err}`)
}
}
/**
* 新建zip压缩包
* @param { string } entryPath 被打包文件地址
* @param { string } outPath 打包输出地址
*/
function createZip(entryPath, outPath){
const outBuff = fs.createWriteStream(outPath)
const archive = archiver('zip', {
zlib: { level: 9 }
})
Object.entries(events).map(({key, fn}) => archive[key] = fn )
archive.pipe(outBuff);
archive.directory(entryPath, false)
archive.finalize()
}
module.exports = {
createZip
}
const util = require('util')
const exec = util.promisify(require('child_process').exec);
function splitLineFeed(str){
return str.split('\n')
}
function loopPrint(str){
splitLineFeed(str).map(item => console.log(item))
}
/**
* 命令仓库
*/
class Commds{
constructor(){
this.commds = []
}
/**
* 注册命令
* 参数参考 node child_process/exec
*/
register(cmmd, options, callback){
// 调整参数
if(typeof options === 'function'){
callback = options
options = null
}
if(Array.isArray(cmmd)){
this.cmmds.concat(cmmd)
}else{
this.commds.push({ cmmd, options, callback })
}
return this
}
/**
* 按顺序调用命令
*/
run(){
return this.commds.reduce((acc, next) => acc.then(() => exec(next['cmmd'], next['options']).then(next['callback']) ), Promise.resolve() )
}
/**
* 清空命令
*/
clear(){
this.commds = []
}
/**
* 非 new 新建对象
*/
static of(){
return new Commds()
}
}
module.exports = {
splitLineFeed,
loopPrint,
Commds
}
const fs = require('fs')
const util = require('util')
const path = require('path')
const { printSuccess } = require('./color')
/**
* 拷贝文件
* @param { string } source 原文件路径
* @param { string } target 目标文件路径
*/
function copyFile(source, target){
source = path.resolve(__dirname, source)
target = path.resolve(__dirname, target)
return () => util.promisify(fs.copyFile)(source,target).then(() => printSuccess(`copy success from ${source} to ${target}`) )
}
/**
* 删除文件
* @param { string } filePath 文件路径
*/
function delFile(filePath){
return () => util.promisify(fs.unlink)(filePath)
}
/**
* 写入配置
* @param { string } path 保存路径
* @param { json } data 保存数据
*/
function updateConfig(path, data){
return util.promisify(fs.writeFile)(path, JSON.stringify(data,null, 2), {flag:'w',encoding:'utf-8',mode:'0666'}).then(() => printSuccess('save config'))
}
module.exports = {
copyFile,
delFile,
updateConfig
}
/**
* 版本更新
* @param { string } version 版本号 0.0.1
*/
function updateVersion(version, separator='.'){
const nums = String.prototype.split.apply(version, [separator])
nums.push(parseInt(nums.pop()) + 1)
return nums.join(separator)
}
module.exports = {
updateVersion
}
const chalk = require('chalk')
/**
* 彩色提示
*/
function print(msg, type='green'){
console.log('>>>', chalk[type](msg))
}
function printError(error){
print(error, 'res')
}
function printSuccess(msg){
print(msg, 'green')
}
function printWarning(warning){
print(warning, 'yellow')
}
module.exports = {
print,
printError,
printSuccess,
printWarning
}
const path = require('path')
const config = require('./config.json')
const { printError, printSuccess } = require('./color')
const { createZip } = require('./createZip')
const { zip } = config
const { Commds } = require('./cmmds')
const { updateVersion } = require('./version')
const { copyFile, delFile, updateConfig } = require('./utils')
const newVersion = updateVersion(config.varsion)
const checkoutToMarster = Commds.of().register(`git checkout ${zip.masterBranch}`, () =>printSuccess(`checkout to ${zip.masterBranch}`))
const updateMarster = Commds.of().register(`git add *`).register(`git commit -m "${newVersion}"`).register(`git push`, () => printSuccess('push success'))
const checkoutToDev = Commds.of().register(`git checkout ${zip.devBranch}`, () => printSuccess(`checkout to ${zip.devBranch}`))
const newConfig = Object.assign({}, config, { varsion: newVersion, lastTime: new Date() })
createZip(zip.entry, zip.catch)
checkoutToMarster.run()
.then(copyFile(zip.catch, zip.out)) // 将打包文件拷贝到主分支目录
.then(() => updateMarster.run()) // 提交文件
.then(() => checkoutToDev.run()) // 切回开发分支
.then(delFile(zip.catch)) // 删除打包文件
.then(() => printSuccess(`remove catch from ${zip.catch}`))
.then(() => updateConfig(path.resolve(__dirname, './config.json'), newConfig)) // 保存版本信息
.catch(printError)
{
...
"scripts":{
"zip": "node ./script"
}
}
最初的想法,希望在开发分支生成压缩包后,通过checkout [branch] [file]
合并文件,但切换分支时,因为生成了新文件,需要保存更新。所以改用将压缩包生成到项目目录外的方式。后期应该会改用临时文件的方式。当前脚本只是对 vue 打包后的文件做压缩上传, 通过 webpack hook 可以将打包压缩继承到一起。