git代码审查以及log规范化的解决方案

林光

前言

公司前端团队百废待兴,很多流程都没有完善起来,这不最近就接到了一个小任务:规范化大家代码提交的格式以及在提交前保证代码的质量。这里的质量并没有做到单元测试覆盖率100%,集成测试全部通过,而是简单地通过语法检查,单元测试的覆盖问题在后续的项目完善中会加进来,所以今天只是讲两点:

  1. log提交格式规范化
  2. Eslint检查100%通过

寻找解决方案

之前在上一家公司做过SVN的代码提交规范化,使用python在SVN服务器上做语法检查,并且在客户端提交log的时候可以自动化的填写格式到log框里然后只需要按照给定的格式来写就行了。

但是git的思想与SVN不一样,git的每次提交都是在本地完成的,只有最后的push才会和服务器交互,所以不可能在服务器这边写脚本来检查。

大家都知道git有hooks的概念,在每个仓库中都有.git/hooks/这个目录,hooks可以在git中指定的一些重要节点上调用对应的钩子函数(文件),一想到这个就觉得应该可以使用这个。

但是后来失望了,因为本地仓库的hooks的代码不能上传到服务器上,大家都共享不了这些配置,并且这些配置在git初始化的时候都是默认的,总不能每次下载代码之后还需要手工去修改这些hooks文件吧。

所以直接使用这个本地的hooks貌似不可行,于是谷歌搜一搜,终于找到一个神器:ghooks

ghooks简单介绍

该软件包是为nodejs打造的,可以帮助我们实现本地的git hooks,支持的git hooks的所有节点,关键它有很简单的配置。其配置在package.json文件中,所以npm有的命令都可以使用

如何规范化log的提交格式

有了ghooks这个神器,那么我们知道只需要在commit-msg的阶段就可以检查提交日志的格式,不符合格式即刻驳回。那么有没有插件可以帮助我们检查代码格式呢?

万能的NPM圈中必然存在这么的,Angular代码提交指定了一套严格的流程,从而衍生出了一些插件来帮助开发者log的规范化,所以这时隆重介绍validate-commit-msg,这款插件正是针对Angular代码提交的规范做的一款检查的插件。

于是我们有了这两款神器,应该可以满足我们的要求了。开始配置:

package.json的配置

我们给出的配置是:(给出的是需要配置的一些需要改的字段)

"scripts": {
    "lint": "eslint ./ --cache --fix --ignore-pattern .gitignore",
    "precommit-msg": "echo Pre-commit checking...please wait && exit 0"
  },
  "config": {
    "validate-commit-msg": {
      "types": [
        "feat",
        "fix",
        "docs",
        "style",
        "refactor",
        "perf",
        "test",
        "chore",
        "revert"
      ],
      "warnOnFail": false,
      "maxSubjectLength": 100,
      "subjectPattern": ".+",
      "subjectPatternErrorMsg": "subject does not match subject pattern!",
      "helpMessage": ""
    },
    "ghooks": {
      "pre-commit": "npm run precommit-msg && npm run lint",
      "commit-msg": "validate-commit-msg"
    }

更加详细的可以参考:demo-for-ghooks

哈哈,貌似大功告成了~~~~

进一步优化

查看Angular给的代码提交规范,可以发现貌似很长的一大段标准,有的时候我们总是记不住格式以及那些字段的含义,那么怎么办呢?

还好git hooks提供了一个重要的节点:prepare-commit-msg,这个节点可以提供给我们在打开git log编辑器之前生成一个默认的git log模板。于是NPM中又有另外一个神器来生成这些信息:prepare-commit-msg-angular

该神器可以生成一个很标准的log模板,如下:

#⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴⎴
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch develop
# Your branch is up-to-date with 'origin/develop'.
#
# Changes to be committed:
#       modified:   package.json
#
# ------------------------ >8 ------------------------
# <type>(<scope>): <subject>
# <BLANK LINE>
# <body>
# <BLANK LINE>
# <footer>
#---
# TYPE must be one of the following:
# - feat: A new feature (will appear in CHANGELOG)
# - fix: A bug fix (will appear in CHANGELOG)
# - docs: Documentation only changes
# - style: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
# - refactor: A code change that neither fixes a bug nor adds a feature
# - perf: A code change that improves performance (will appear in CHANGELOG)
# - test: Adding missing tests
# - chore: Changes to the build process or auxiliary tools and libraries such as documentation generation
#
# SCOPE could be anything specifying place of the commit change.
# For example $location, $browser, $compile, $rootScope, ngHref, ngClick, ngView, etc...
#
# SUBJECT contains succinct description of the change:
# - use the imperative, present tense: "change" not "changed" nor "changes"
# - do not capitalize first letter
# - no dot (.) at the end
#---
# https://github.com/ajoslin/conventional-changelog/blob/master/conventions/angular.md

于是你在写日志的时候哪些字段忘记了可以参考下面的提示,如果这个你觉得太麻烦,还有一款可交互的日志填写神器:commitizen

该神器可以交互地提示你填写git log,唯一一个我在应用中觉得缺点的是:每次都是先书写完git log信息后才执行ghooks那些检查,此时如果我的Eslint或者单元测试失败的话那么你刚才写的检查就全白写了。。。。

所以最后就没有集成该插件进去。

该神器的配置可以参考:http://mp.weixin.qq.com/s?__biz=MzAwNDYwNzU2MQ&mid=401622986&idx=1&sn=470717939914b956ac372667ed23863c&scene=1&srcid=0114ZcTNyAMH8CLwTKlj6CTN#rd

完整的配置可以参考:https://github.com/linxiaowu66/demo-for-ghooks

其中prepare-commit-msg-angular和validate-commit-msg有一个地方不匹配,所以后来自己更新了一下源码,参考:https://github.com/linxiaowu66/prepare-commit-msg-angular

缺点

该方案不支持使用Git UI工具,只能使用命令行来提交代码。所以想使用Git UI工具的请忽略~~~~

参考

  1. http://codeheaven.io/simple-git-hooks-with-ghooks/
  2. https://github.com/cmalard/prepare-commit-msg-angular
  3. https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks