如何在Git Hooks中运行Grunt任务

通常团队协作编程的时候,为了确保每一次的代码提交都能够保证质量,我们通常会指定一些提交前的检查和规约,比如:

  • 检查代码规范是否符合要求
  • 运行单元测试,检查是否全部通过
  • 其他(视具体项目而定)

以上这些检查可以通过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的时候,做如下几件事情:

  1. 读取你gruntfile的配置
  2. 根据它内置的模版文件生成一段可执行的node脚本
  3. 该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,只要目的机器上支持该脚本即可!

推荐阅读更多精彩内容