Git hook - 如果您使用git作为代码管理工作。

前提摘要:我们会在Rails项目中使用rubocop来校验我们代码的格式,语法等等是否正确。但有时候我们在提交时候在本地会忘记跑rubocop来校验代码是否合格,此时,如果你的项目配置了自动化CI, 那么你可能会收到一封failed的邮件通知. 这样的体验会很不好!

那么为了避免这些事情发生,git有一个很好的钩子来帮我们实线提交前的验证。<pre-commit>, 是不是听起来很不错,接下来我们来使用Ruby来完成这个git hook. 

查看所有的hooks - 在你自己项目的根目录下运行

#blog> ls .git/hooks
applypatch-msg.sample     post-update.sample        pre-push.sample           pre-receive.sample        rubocop_pre_commit_hook
commit-msg.sample         pre-applypatch.sample     pre-commit.sample         pre-rebase.sample         prepare-commit-msg.sample update.sample

接下来我们使用复制文件 cp pre-commit.smaple pre-commit, 然后使用下面的代码替换新文件内容.

#!/usr/bin/env ruby

require 'english'
require 'rubocop'

ADDED_OR_MODIFIED = /A|AM|^M/.freeze

changed_files = `git status --porcelain`.split(/\n/).
    select { |file_name_with_status|
      file_name_with_status =~ ADDED_OR_MODIFIED
    }.
    map { |file_name_with_status|
      file_name_with_status.split(' ')[1]
    }.
    select { |file_name|
      File.extname(file_name) == '.rb'
    }.join(' ')

system("bundle exec rubocop #{changed_files}") unless changed_files.empty?

exit $CHILD_STATUS.to_s[-1].to_i

以上就是整个pre-commit的脚本代码,它的实现也很简单,使用git status --porcelain得到所有改变的文件。然后使用调用系统命令帮我们运行一次rubocop. 如果没有任何错误,则会继续提交,如果失败,它则会终止提交。