第
在?Swift?中编写Git?Hooks脚本的方法
目录前言用githooks自动生成提交信息为什么我使用Swift?让我们开始吧编写git钩子检索提交消息注意:检索问题编号修改提交信息设置git钩子测试结果参考资料
前言
这周,我决定完成因为工作而推迟了一周的TODO事项来改进我的Git工作流程。
为了在提交的时候尽可能多的携带上下文信息,我们让提交信息包含了正在处理的JIRA编号。这样,将来如果有人回到我们现在正在提交的源代码,输入??gitblame??,就能很容易的找出JIRA的编号。
每次提交都包含这些信息可能会有点乏味(如果你使用了类似TDD[1]之类的方法,您会提交的更加频繁),而且,尽管像Tower[2]这样的git客户端会让此变得容易一些,但是您仍然需要手动将问题编号复制粘贴到提交消息中,并且记住这样做,这是我最难以解决的问题:sweat_smile:。
出于这个原因,我开始寻求了解githooks,试图自动化这项任务。我的想法是能够从git分支获取JIRA编号(我们有一个分支命名约定,形如:story/ISSUE-1234_branch-name),然后将提交消息更改为以JIRA编号为前缀,从而生成最终结果消息:ISSUE-1234-其他原本的提交信息。
用githooks自动生成提交信息
?GitHooks[3]提供了一种在运行某些重要的git命令时触发自定义操作的方法,例如在一次commit或者push之前执行一些操作。
在本例中,我使用了commit-msg钩子,它能够在当前提交信息生效前修改此信息。钩子由一个参数调用,该参数是指向包含用户输入的提交消息的文件的路径。这意味着,为了改变提交消息,我们只需要从文件中读取、修改其内容,然后写回调用挂钩的文件。
要创建git钩子,我们需要在.git/hooks?路经下提供一个可执行脚本。我的钩子放在了.git/hooks/commit-msg路经之下。
为什么我使用Swift?
Githooks可以使用任何你熟悉的,并且在主机上安装了解释器(通过shebang来指定)的脚本语言来编写。
虽然有很多更受欢迎的选项,比如bash?、ruby等等,但我还是决定使用Swift。因为我对Swift更熟悉,因为我每天都在使用它,而且我真的非常喜欢它强大的类型语法以及低内存占用。
让我们开始吧
你可以使用任何你喜欢的IDE编写Swift脚本。但是如果你想要有适当的代码补全以及调试能力,你可以为其创建一个Xcode项目。为此,在macOS?下选择CommandLineTool创建一个新的项目。
在创建的文件顶部加上Swiftshebang,引入Foundation库。
#!/usr/bin/swift
importFoundation
这样当git执行文件时,shebang将确保使用文件作为输入数据调用/usr/bin/swift二进制文件。
编写git钩子
项目已经全部设置好,所以现在可以编写git挂钩了。让我们走完所有的步骤。
检索提交消息
要做的第一件事就是从脚本传进来的参数检索临时提交文件的路径然后读取文件内容。
letcommitMessageFile=CommandLine.arguments[1]
guardletdata=FileManager.default.contents(atPath:commitMessageFile),
letcommitMessage=String(data:data,encoding:.utf8)else{
exit(1)
}
在上面的代码片段中,我们首先拿到了提交文件的路径(git?传递给脚本),然后通过FileManagerAPI?读取了文件内容。如果因为一些原因检索失败了,我们退出(exit?)脚本同时返回状态码1,这将告诉git终止此次提交。
注意:
根据githooks文档,如果任何钩子脚本返回的状态码大于??0??,它都将终止即将要要发生的操作。这将在本文后面的部分中使用,以便在不需要做任何修改而优雅地退出。
检索问题编号
既然提交信息的字符串已经可用,接下来就需要找到当前分支并从中检索到问题编号。正如本文前面提到的,这只可能是因为团队对分支命名的严格格式,在其名称中始终包含JIRA编号(例如,story/ISSUE-1234_some-awesome-feature-work)。
为了实现这一点,我们必须检索当前的工作分支,然后用正