上一篇文章,跟大家分享了一下如何让你的mac自动同步代码。
但是在实际应用中发现会有点儿小问题,比如说:
- 如果某一个分支同步失败,会直接退出当前任务,剩下的分支要自己同步。
- 异步抓取错误,导致同步信息不好抓取。
- 使用了
fs
来将错误信息录入到提醒文件中,每次处理的都是覆盖式写入,所以会导致查看不及时,日志丢掉的问题。
本着负责到底的原则,这里跟大家再分享一个改进版。用来改进这些问题。
1. 改进点
首先我们来看下改进点:
- 使用
shell
命令来追加错误日志。 - 使用
spawnSync
代替spawn
来实现同步执行rebase
任务 - 分支同步出现问题后,使用
git rebase --abort
来退出同步,并写入错误日志。
有了改进点,明确了修改点之后,我们来继续看下如何实现这些修改点
2. 改进点实现
2.1 使用模块
之前我们使用了 fs
和 spawn
来实现这个功能。现在我们只需要使用 spawnSync
就可以
栗子:
const spawnSync = require("child_process").spawnSync;
2.2 项目目录和配置
这两项保持不变,还是之前的配置,还是之前的配方
栗子:
// 项目所在文件夹
const rootDir = '/Users/yancy/dev'
// 日志文件
const logFile = '/Users/yancy/Desktop/代码rebase出现问题-请及时查看.txt'
// 配置文件
const pullConfig = [
{
dirName: 'test', // 项目
branchList: [ // 分支列表
'test1',
'test2',
]
}
]
2.3 同步代码
遍历配置文件,并通过 spawnSync
来执行shell 和 git
命令。以此来同步代码
栗子:
pullConfig.forEach(item => {
if (item.branchList.length) {
item.branchList.forEach((branch, index) => {
let shell = getShell(item.dirName, branch)
let ls = spawnSync(shell, { shell: true }); // 需要注意
checkGit(ls.stdout.toString(), item.dirName, branch)
})
}
})
function getShell(dirName, branch) {
return `
cd ${rootDir}/${dirName};
git checkout ${branch};
git pull origin master --rebase;
`
}
注意点:
- 上次我们使用
spawn
来执行命令,返回的ls.stdout 和 ls.stderr
是一个对象,可以使用监听事件的方式来获取执行结果。 - 本次使用
spawnSync
来执行命令。返回的ls.stdout 和 ls.stderr
这两个内容本来就是一个Buffer。所以可以直接通过toString()
转换为字符串。
2.4 检查错误和后续操作
检查错误还是之前的版本。通过检查错误关键词来判断是否同步成功
栗子:
function checkGit (str, dirName, branch) {
console.log(str)
if (!(
['error', 'failed', 'git rebase --abort', 'git rebase --continue'].every(item => str.indexOf(item) === -1)
)) {
const logMsg = getErrorMsg(dirName, branch, str)
// 改进点
spawnSync(`echo '${logMsg}' >> ${logFile}`, {shell: true})
// 改进点
spawnSync(resetShell(dirName, branch, 'git rebase --abort'), {shell: true})
} else {
// 改进点
spawnSync(resetShell(dirName, branch, `git push origin ${branch} -f`), {shell: true})
}
}
说明:
-
通过
echo msg >> 日志文件
的方式来追加式的写入错误信息。>>
为向某个文件追加内容。这里意思指的是:将msg
这个信息追加到日志文件中。
-
如果查找到了错误关键词,接下来通过
git rebase --abort
来回退同步。- 这里没有了
process.exit()
所以回退之后会进行下一个分支的同步工作。
- 这里没有了
-
同步成功,使用
git push origin 分支 -f
来强制推送。(需要大家注意的是要养成及时推送代码的习惯,否则推送会出现问题)
3. crontab配置
实现修改成功后,下面我们需要使用 crontab
来定时执行同步代码的任务。
之前我们是使用 * 8 * * 1-5 node /Users/username/rebase.js
这种方式。但是这种方式如果配置不好会出现执行不成功的问题,所以本次换个方式实现。
现在我们使用 .sh
文件的形式来实现。首先创建一个 rebase.sh
文件
#! /bin/bash
source /etc/profile # 添加全局配置文件
node /Users/username/rebase.js # 使用node来执行 rebase 文件
.sh
文件写完之后,我们通过 chmod 777 rebase.sh
来修改文件权限。否则会出现不能执行的情况。
然后我们使用 crontab -e
来编写定时任务
对于 crontab
的使用方法我们在上篇文章中介绍过,本次就不再赘述了。
0 8 */1 * * ~/rebase.sh # 通过定时任务执行 rebase.sh 这个脚本文件。
注意: 测试情况下可以使用 */1 * * * * ~/rebase.sh
来节省时间
4. 完整代码演示
4.1 rebase.js
const spawnSync = require("child_process").spawnSync;
const rootDir = '/Users/yancy/dev'
const logFile = '/Users/yancy/Desktop/代码出现问题-请及时查看.txt'
const pullConfig = [
{
dirName: 'test',
branchList: [
'test1',
'test2',
]
}
]
function getShell(dirName, branch) {
return `
cd ${rootDir}/${dirName};
git checkout ${branch};
git pull origin master --rebase;
`
}
function resetShell(dirName, branch, more) {
return `
cd ${rootDir}/${dirName};
git checkout ${branch};
${more};
`
}
// 自己添加的报错信息,因为比较简单,所以没说明。
function getErrorMsg (dirName, branch, str) {
const date = new Date()
const year = date.getFullYear()
const month = date.getMonth() + 1
const day = date.getDate()
const week = date.getDay()
const hour = date.getHours()
const minute = date.getMinutes()
const second = date.getSeconds()
const time = `
${year}-${month}-${day},周${week},${hour}:${minute}:${second}
`
return `${time}项目:${dirName},分支为:${branch};
错误信息:${str}`
}
pullConfig.forEach(item => {
if (item.branchList.length) {
item.branchList.forEach((branch, index) => {
let shell = getShell(item.dirName, branch)
let ls = spawnSync(shell, { shell: true });
checkGit(ls.stdout.toString(), item.dirName, branch)
})
}
})
function checkGit (str, dirName, branch) {
console.log(str)
if (!(
['error', 'failed', 'git rebase --abort', 'git rebase --continue'].every(item => str.indexOf(item) === -1)
)) {
const logMsg = getErrorMsg(dirName, branch, str)
spawnSync(`echo '${logMsg}' >> ${logFile}`, {shell: true})
spawnSync(resetShell(dirName, branch, 'git rebase --abort'), {shell: true})
} else {
spawnSync(resetShell(dirName, branch, `git push origin ${branch} -f`), {shell: true})
}
}
function runSpawn (shell) {
spawnSync(shell, {shell: true})
}
4.2 rebase.sh
#! /bin/bash
source /etc/profile # 添加全局配置文件
node /Users/username/rebase.js # 使用node来执行 rebase 文件
4.3 crontab
0 8 */1 * * ~/rebase.sh
好了,我们本期的分享就到这里了,有兴趣的小伙伴可以尝试自己实现下。
下次再见,Bye~