node脚本实现自动git操作

416 阅读2分钟

因工作需要经常会有一个项目的git目录下多套代码的打包需求,因此做一个简易的自动拉取多套代码、分支切换、安装依赖且打包的node脚本,留个笔记

主要借助的就是node中的readline模块进行命令行询问互动以及dhild_process模块来执行cmd

首先初始化一下readline

const readline = require('readline')

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
})

API文档留个链接:nodejs.org/dist/latest…

先初始化三个变量用于保存询问结果,包括仓库地址、分支名称及是否需要打包

let gitURL = ''
let branchname = ''
let needPack = 'n'

随后编写询问代码,大概就是先记录项目统一的仓库前置路径,然后询问是否需要指定分支,最后询问是否打包

rl.question('Please input path > ', url => {
  if (url) {
    gitURL = url
    rl.question('Input branchname or use default branch > ', name => {
      name && (branchname = name)
      rl.question('Do you want to pack them? (y/n) > ', answer => {
        answer && (needPack = answer)
        rl.close()
        ;['project1', 'project2', 'project3'].forEach(projectName => {
          resolveProject(projectName)
        })
      })
    })
  } else {
    rl.close()
  }
})

代码中的project1、project2等是具体的代码仓库名称

接下来编写resolveProject函数,主要就是下载依赖及打包

const { exec } = require("child_process")

function resolveProject(projectName) {
  console.log(`Start cloning ${projectName}...`)
  let cmd = `git clone ${gitURL}/${projectName}.git`
  if (branchname) cmd += ` && git checkout ${branchname}`
  exec(cmd, {}, (err, stdout, stderr) => {
    console.log(err || stderr || stdout)
    if (!err) {
      console.log(`Finish cloning ${projectName}`)
      if (needPack === 'y') {
        console.log(`Start downloading and packing for ${projectName}...`)
        exec(`cd ${projectName} && npm i && npm run build`, (err, stdout, stderr) => {
          console.log(err || stderr || stdout)
          if (!err) {
            console.log(`Finish packing ${projectName}`)
          }
        })
      }
    }
  })
}

到这里主要功能就可以实现了,顺便记录下cmd的 & 与 && 的区别

  • & 无论前一条指令是否成功,都会执行下一条
  • && 只有前一条成功后才会执行下一条

为了优化下体验,最好加个执行等待中的效果,例如进度条

let n = 0
console.log('')
setInterval(() => {
  if (n < 100) n++
  console.log('\u001b[1A[' + '#'.repeat(n) + '-'.repeat(100 - n) + ']')
}, 100)

复制以上代码用node执行即可模拟一个进度条,大概原理是移动光标重写上一次的打印,实现同行刷新

\u001b[ 是 ANSI 转义序列默认的开头,1A 代表向上移动1行光标

至于如何控制进度条可以自行发挥了,顺便贴一个类似的加载中旋转的效果

let strArr = ['-', '\\ ', '| ', '/ ']
let index = -1
console.log('')
setInterval(() => {
  index = index >= 3 ? 0 : index + 1
  console.log("\u001b[1A" + strArr[index])
}, 100)

以上代码用node执行可以模拟一个小横线旋转的效果