通常团队协作编程的时候,为了确保每一次的代码提交都能够保证质量,我们通常会指定一些提交前的检查和规约,比如:
- 检查代码规范是否符合要求
- 运行单元测试,检查是否全部通过
- 其他(视具体项目而定)
以上这些检查可以通过hooks(钩子)来实现。比方说:我们可以在commit操作前指定特定的钩子程序,该钩子程序就可以去运行如上这些检查,只有全部通过才能提交代码。Git提供了诸如:pre-commit、pre-push、post-update等等好几种hooks。可以通过项目中的:.git/hooks目录查看所有Git支持的hooks:
要想了解更多关于git hooks的内容,可以访问这个教程
直接通过修改对应的sample文件就可以书写你自己的钩子程序,修改完后把sample后缀去掉即可。
但是,git的钩子程序默认是shell脚本,这点对于不怎么会复杂shell程序的同学来说不是很爽。而且也没有办法跨平台。事实上,钩子程序要运行的都是一些特定的任务,而现如今Grunt毫无疑问是最最流行的任务执行器,因此,要是Git钩子程序能够和Grunt结合起来,直接可以运行Grunt任务就圆满了。
怎么办呢?很简单,通过使用Grunt GitHooks 就可以轻松实现。
首先,我们可以使用NPM来简单地安装Grunt GitHooks模块:
cd /path/to/your/project
npm i grunt-githooks --save-dev
安装完成后,只要在Gruntfile.js文件中配置好对应的钩子和要执行的任务即可:
grunt.initConfig({
githooks: {
options: {
// Task-specific options go here.
},
all: {
'pre-commit': 'test.api'
}
},
})
如上这段配置就等于配置了一个pre-commit钩子程序,并且该程序要执行test.api任务,该任务会执行所有的api测试,只有当这些测试都通过后,git进行代码提交。
最后,你只要在项目目录下,运行如下shell脚本就可以将该钩子程序应用到git中:
grunt githooks
好了,接下来你可以修改一些文件,然后尝试下git commit,git会自动运行你指定的test.api任务了。好了,就是这么简单了!
学习技术,我们更多时候要知其然,更要知其所以然。我们来看看Grunt Githooks的原理是什么吧!
其实原理也很简单,它会在你运行:grunt githooks的时候,做如下几件事情:
- 读取你gruntfile的配置
- 根据它内置的模版文件生成一段可执行的node脚本
- 该node脚本就是去执行你配置的grunt任务(test.api),并将该脚本注入到.git/hooks中
我们可以通过简单查看:.git/hooks目录下发现pre-commit.sample文件这个时候已经变成了pre-commit文件了,其内容如下所示:
#!/usr/bin/env node
// GRUNT-GITHOOKS START
var exec = require('child_process').exec;
exec('grunt test.api', {
cwd: '/Users/goddyzhao/workspace/swork/test/blog'
}, function (err, stdout, stderr) {
console.log(stdout);
var exitCode = 0;
if (err) {
console.log(stderr);
exitCode = -1;
}
process.exit(exitCode);
});
// GRUNT-GITHOOKS END#!/usr/bin/env node
这下豁然开朗了吧!上面这段就是不折不扣的node程序,第一行#!/usr/bin/env node就指明了运行上下文,然后会node的同学肯定就秒懂了这段程序。而git就是通过exit code(退出码)来判断是否hooks运行成功,所有非0的退出码都被认为是执行失败。了解了原理后,我们就不难想象其实我们可以手动去写任何语言版本的git hooks,只要目的机器上支持该脚本即可!