在 iOS 开发中使用 pre-commit hook-演道网

许多人写了单元测试并且运行持续集成服务器来检查 pull requests,我们还可以利用像 Danger 这样强大的工具。
如果想要在最早期阻止一些常见的错误,我们可以使用 pre-commit hook。
注:原作者的朋友 Sami Samhuri 改善了他的脚本,本文也随着更新了。另外译文调整了一下结构,增加了对 pre-commit 的简要说明。最新的脚本在这里。
pre-commit hook
有时候一些测试代码或者测试工具不应该提交到远程仓库,所以提交代码前的审查就很有必要。Git 支持很多 hooks,hooks 是一些在$GIT-DIR/hooks
目录中的脚本,由特定的事件触发执行。pre-commit hook 就是在提交之前触发,可以用来检查待提交代码是否有错误。这里可以查看到有关 git hooks 更详细的说明。
我们想要阻止的
放错位置的视图 (Misplaced Views)
你有提交过一些位置不对的视图,打算以后修复吗?
有时候 Xcode 过于热切,并且有多个显示器(视网膜vs非视网膜问题…),就很容易突然把东西放错位置。
我就做过。
用一个简单的 grep 扫描 interface builder 文件内容可以发现这些错位的视图:
- 模式:misplaced=”YES”
- 文件:*Specs.swift *.storyboard
集中测试 (Focused tests)
像 Kiwi 或者 Quick 这样的代码库可以让我们做集中测试,这可以加快开发速度,很有用。
但是它们绝对不应该被提交,否则可能无意中改变一些东西,造成其他所有测试都被禁用,还会隐藏一些严重的问题。
我们需要在测试文件中找出 fdescribe / fit / fcontext 和其他类似的东西:
- 模式:
(fdescribe|fit|fcontext|xdescribe|xit|xcontext)
- 文件:
*Specs.swift
合并起来
我们只需要确认已暂存(staged)的改变中是否包含上面的东西就好了,不要检查所有文件,因为这在开发的时候会很烦人。
幸运的是,我们可以把 git diff-index -p -M --cached HEAD
和 grep '^+'
一起使用。
最终的 pre-commit.sh 文件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
<span class=“c”>#!/usr/bin/env bash
<span class=“nb”>set</span> –eu
<span class=“nv”>failed</span><span class=“o”>=</span>0
<span class=“nv”>test_pattern</span><span class=“o”>=</span><span class=“s1”>‘b(fdescribe|fit|fcontext|xdescribe|xit|xcontext)b’</span>
<span class=“k”>if </span>git diff–index –p –M —cached HEAD — <span class=“s1”>‘*Tests.swift’</span> <span class=“s1”>‘*Specs.swift’</span> | grep <span class=“s1”>‘^+’</span> | egrep <span class=“s2”>“s2“>”</span> >/dev/null 2>&1
<span class=“k”>then</span>
<span class=“nb”>echo</span> <span class=“s2”>“COMMIT REJECTED for fdescribe/fit/fcontext/xdescribe/xit/xcontext.”</span> >&2
<span class=“nb”>echo</span> <span class=“s2”>“Remove focused and disabled tests before committing.”</span> >&2
<span class=“nb”>echo</span> <span class=“s1”>‘—-‘</span> >&2
git grep –E <span class=“s2”>“s2“>”</span> <span class=“s1”>‘*Tests.swift’</span> <span class=“s1”>‘*Specs.swift’</span> >&2
<span class=“nb”>echo</span> <span class=“s1”>‘—-‘</span> >&2
<span class=“nv”>failed</span><span class=“o”>=</span>1
<span class=“k”>fi</span>
<span class=“nv”>misplaced_pattern</span><span class=“o”>=</span><span class=“s1”>‘misplaced=”YES”‘</span>
<span class=“k”>if </span>git diff–index –p –M —cached HEAD — <span class=“s1”>‘*.xib’</span> <span class=“s1”>‘*.storyboard’</span> | grep <span class=“s1”>‘^+’</span> | egrep <span class=“s2”>“s2“>”</span> >/dev/null 2>&1
<span class=“k”>then</span>
<span class=“nb”>echo</span> <span class=“s2”>“COMMIT REJECTED for misplaced views. Correct them before committing.”</span> >&2
<span class=“nb”>echo</span> <span class=“s1”>‘—-‘</span> >&2
git grep –E <span class=“s2”>“s2“>”</span> <span class=“s1”>‘*.xib’</span> <span class=“s1”>‘*.storyboard’</span> >&2
<span class=“nb”>echo</span> <span class=“s1”>‘—-‘</span> >&2
<span class=“nv”>failed</span><span class=“o”>=</span>1
<span class=“k”>fi</span>
<span class=“nb”>exit</span> <span class=“nv”>$failed</span>
|
你也可以在这里获取最新的脚本。这个脚本在命令行和 macOS git 客户端都可以使用。
让 hook 在团队中保持同步
大多数的应用都是由团队制作的,我们就想到要在每个 git 仓库中安装钩子 (git hook)。但这并不是使用 git 的工作方式,那我们该怎么做呢?答案:使用符号链接(symlinks)。
我负责过的大多数项目都有类似于 bootstrap script 的东西,用来加载 Carthage 或者做其他一些准备工作。
下面这个简单的启动脚本 (bootstrap script) 可以让你在你的仓库里安装钩子 (git hook),使得整个团队保持同步变得简单。
1
2
3
4
5
6
|
<span class=“c”>#!/usr/bin/env bash
<span class=“c”># Usage: scripts/bootstrap
<span class=“nb”>set</span> –eu
ln –s ../../scripts/pre–commit.sh .git/hooks/pre–commit
|
- 如果有错误,它将退出shell,如果未设置任何变量,则将错误消息写入标准错误。
- 创建 git 内部预提交钩子文件(internal git pre-commit hook file)与我们的仓库中脚本之间的符号链接。
这个脚本假设 pre-commit.sh 和 bootstrap 文件都在你的仓库的 Scripts 文件夹下面。
总结
预提交钩子给我们提供了很简单的方式去阻止一些常见的错误,
- 一行代码就可以为团队中所有人配置
- 在整个团队中同步
- git 跟踪变化,PR 中可见
- 用脚本实现,如果你愿意,你可以把它作为 build phase 执行(尽管我没有)
相关阅读
在 React Web 和 原生 App 中共享代码
React Native 一周年回顾
快速部署Test-Driven Development/Debug环境
作者往期佳作
iOS – 更轻量级的 AppDelegate – 面向服务设计
使用 FlowControllers 改进iOS应用架构
Objective-C Runtime 之动态方法解析实践
作者信息
转载自演道,想查看更及时的互联网产品技术热点文章请点击http://go2live.cn