本文由 简悦SimpRead 转码,原文地址 medium.com
我相信你一定有过那种胃部下沉的感觉。你知道的,就是在你的R......之后,你被击中的那种感觉。
我相信你也曾有过那种胃部下沉的感觉。你知道,当你意识到你无意中要对一些灾难性的事情负责时,那种感觉就会袭来......比如你的网站在你部署到生产部门后就瘫痪了。我们都经历过这种情况。我们都是人,我们都会犯错误。尽管我们有人性,但有一个简单的方法来防止灾难:检查清单。核对表是解决我们自身不完美的一个奇妙而简单的解药。
核对表消除了模糊性,是确保你不会忘记一项任务的重要部分的好方法。航空公司的飞行员在飞行的每个阶段都使用检查表作为标准,以确保最大的安全。医生们用它们来提醒那些在紧张情况下可能被遗忘的简单的常规动作:在一项世界性的研究中发现,在重大手术中使用简单的检查表可以提高病人的存活率近40%。软件工程师也可以使用核对表--我们在程序上使用Git预提交钩子,以获得安心,提高我们的系统可靠性,增强我们对代码的生产准备的信心。
[caption id="attachment_2209 "align="aligncenter" width="500"]
手术安全检查表实例,不列颠哥伦比亚省医学杂志-2010年6月,取自Flickr,CC版权所有[/caption]
预提交的好处
预先提交钩子在Git版本控制中是相当方便的。
- 钩子只是在实际提交即将发生之前由Git启动的脚本。"它用于检查即将提交的快照......"
- 脚本可以是任何语言,只要它是a)可执行的,和b)被其运行的操作系统所支持。
- 脚本驻留在客户端版本库的'.git/hooks'文件夹下--意味着只在你的本地机器上。钩子从来不是git提交历史的一部分,因此也不在版本控制之下。
不在版本控制之下?
真的吗?是的。因为这些git钩子只存在于你的本地机器上,所以它们从不在版本控制之下。哇。自然地,这导致了一些问题。
- 我们怎样才能维护这些脚本?
- 我们如何确保团队中的每个人每次提交到各自的仓库时都会使用同一套脚本?
- 我们如何在由PHP、Python和Javascript工程师组成的多语言团队中支持多语言的git hooks?
Yelp来拯救
有一些少数解决方案针对各种语言的git预提交钩子,但近几个月,Yelp向开源社区发布了预提交项目,引起了我们的注意。
A Yelp的pre-commit是 "一个管理和维护多语言pre-commit钩子的框架"。我们对它很有好感,因为它是一个框架,易于设置,非侵入性的,而且易于扩展。
框架
这是一个简单的框架,可以围绕它建立git钩子,并支持多语言开箱。
截至本文撰写之时,Yelp的pre-commit支持这些语言。
- node.js
- python
- ruby
- pcre - "Perl兼容正则表达式"
- script - 存在于版本库内的可执行脚本
- system - 在系统层面上可用的可执行程序
对PHP的开源支持
目前还不支持PHP,所以我们在Github上开源了我们自己的专门针对PHP的预提交钩子开发,这些钩子是围绕Yelp的预提交钩子构建的。
该版本提供了以下预提交钩子。
- php-lint - 针对阶段性文件运行php -l。在发现第一个错误时退出。
- php-lint-all - 与上述类似,但只在所有文件都被提示后退出,如果发现任何错误,则报告所有文件的错误。
- php-unit - 运行适当的 PHP Unit 可执行程序
- php-cs - 运行相应的 PHP Code Sniffer 可执行文件。
阅读版本库中的 README 以了解更多的使用信息。
容易安装
我们也喜欢这个框架,因为安装过程很简单,而且依赖的东西很少。事实上,唯一的要求是你的系统有Python和Pip。
一旦这些要求得到满足,你就可以按照简易安装说明进行不同程度的使用。
可共享和易于维护的一致性。
将预提交框架集成到版本库中是相当简单的,不需要像为钩子脚本建立一个专门的文件夹那样的丑陋解决方案。
事实上,钩子本身是存储在独立的git仓库中的。通过一个配置yaml文件,pre-commit会将这些钩子从你的版本库中下载到不同的位置。这样既可以方便地分享你的pre-commit钩子,也可以重复使用已经存在的钩子,比如一些已经Yelp的预制钩子甚至我们的。
安装后要在你的版本库中使用它。
- 在你的版本库根目录下创建一个名为 .pre-commit-config.yaml 的文件。这个文件包含了pre-commit用来管理钩子的所有信息(访问安装页面了解更多信息)。
- 在版本库根目录下运行pre-commit install,初始化pre-commit。
这就是你需要在你当前的本地版本库上启用预提交的全部内容。
易于扩展
Yelp的pre-commit的钩子很容易做。总之,它需要你做的就是。
- 创建一个新的git repo
- 添加hooks.yaml到根目录,并进行适当设置
- 提交并推送到你的远程源码
下面是一个简单调用PHP本地可执行文件做语法检查的例子。
- id: php-lint
name: PHP Syntax Check (Quick)
description: Runs php -l on all staged files. Exits when it hits the first
errored file
entry: php -l
language: system
files: \.php$
在你想运行这个钩子的版本库中,在.pre-commit-config.yaml中添加一个条目。
- repo: http://source/to/your/hook/repo/url
sha: master
hooks:
- id: php-lint
pre-commit团队甚至提供了一些预建钩子,你可以使用这些钩子,包括提示(js、咖啡、scss、python)、yaml/json检查等。
缺点
在使用Yelp的pre-commit时,有一些挑战。
没有PHP
缺乏对PHP的支持是我们的一个很大的缺点,因为我们的工程团队中大部分人都在处理PHP。我们自己制作的开源PHP预提交钩子是我们的解决方法。
关于扩展的文件太少。
寥寥无几的文档让事情变得有些困难,尤其是在bash中做钩子的时候。为了弄清楚pre-commit将传递给你的脚本的参数,需要大量的试验和错误。幸好最近文档更新消除了这个问题。
总结
当正确的钩子与现有的持续集成系统一起运行时,拥有git预提交钩子是一个很好的方法,可以帮助减轻对坏代码进入生产的恐惧。一个例子是在我们的代码中进行基本的有效语法检查--即使有IDE的帮助,也会发生人为错误。这样的检查可以帮助我们避免出现糟糕的构建和发布情况。另一个例子是在每次提交前自动运行单元测试,以避免在系统中出现不良构建。
我们目前在一个工程团队中使用Yelp的预提交框架。如果这一变化被证明是有益的,它将为我们今后在其他团队中建立预提交钩子提供一个良好的基础。
一些有用的文档。
感谢
感谢Luke Kysow让我注意到这个项目,感谢Chris McGuire、George Pajari、Noel Pullen和Kimli Welsh在帮助我写这篇文章时的支持。
关于作者
Shih Oon是Hootsuite的一名运营工程师,作为Campaigns团队的一员。他是一名动漫机械人爱好者,喜欢制作比例模型机器人,同时也喜欢挑战网络技术的极限。在Twitter上关注他 @mechastorm。