迫于公司提交代码的要求越来越繁琐,需要写一堆信息。要命的是没有自动化工具,天天各种人肉手写 txt,改日期,改格式。经常会因为 txt 中漏写或者漏改日期导致 commit 被打回。烦不胜烦,忍无可忍,决定自己动手写一个自动化工具,把所有的格式化信息自动填入。
问题是什么?
我想要自动生成的是一个叫 ”测试重点” 的东西,这个文件由:头信息、提交信息组成。
其中 ”头信息“ 的格式是这样子的:
======================2020-09-19========================
### begin:2020-09-14
### end:2020-09-19
可以看到整个 “头信息” 都是可以自动生成的,只需要计算出本周开始和结束的日期即可。
“提交信息” 是这样子的:
---
### author:张三
### ISSUEID:AAA-111
### 模块:模块A
### 重点:操作xx发现xx,现象是xx,预期是xx。
结合我司的情况,其中 ISSUEID
和 模块
是可以从 commit-msg
中获取的。author
可以从 git config
中获取。唯一需要填写的就是 重点
这个条目。
那么就可以梳理出解决这个问题的思路了:
通过解析 commit-msg
和 git config
,可以得到四项中的三项,剩下的一项本来我也想着从 commit-msg
中获取,但是发现对应不上,那就只能人肉填写了。最后将生成的文件和代码一起提交就行。
选择什么工具?
一开始想到的是 IDE 插件,但是实在懒得写 UI。转念一想,Git hook 非常适合这种场景:
- 有自动切入点,不需要手动调用
- 可以无障碍获取 Git 的配置和
commit-msg
实现思路
分析一下我们的目的,可以总结一些特征点。
- 文件夹以月为单位(一个月一个文件夹)
- 文件以周为单位(一份文件记录一周的测试重点)
- 文件的主要内容可以从
commit-msg
中获取
所以我们就需要考虑以下几点:
- 文件会多次写入,需要考虑文件头,首次写入和后续写入的区别需要注意
- 需要计算一周开始和结束的日期
- 从
commit-msg
中获取信息,需要用正则来筛选 - 选用 Git hook,那么用 shell 来实现是比较方便的
- Git hook 有很多时机,经过思考认为
commit-msg
是比较合适的。
代码实现
从代码实现看看怎么落实这些思路。
通过计算日期得出文件名
year=$(date "+%Y");
sub_dir=$(date "+%Y-%m");
file_name=${project_name}_$(date "+%Y%m")$(expr $(expr $(date "+%d") + $(expr 6 - $(date "+%w")))).txt;
dir_path=test_focus/${year}/${sub_dir}
file_path=${dir_path}/${file_name}
创建文件
创建文件前先判断文件是否存在,不存在的话就创建文件并写入文件头,否则的话就什么都不做。
create_file() {
tmp_file_header_1="======================%s========================"
tmp_file_header_2="### begin:%s"
tmp_file_header_3="### end:%s"
if [ -f ${file_path} ];then
echo "File exist."
else
echo "Create file"
mkdir -p ${dir_path}
touch ${file_path}
var_begin=$(date "+%Y-%m")-$(expr $(expr $(date "+%d") - $(date "+%w")) + 1)
var_end=$(date "+%Y-%m")-$(expr $(expr $(date "+%d") + $(expr 6 - $(date "+%w"))))
file_header_1=$(printf $tmp_file_header_1 $var_end)
file_header_2=$(printf "$tmp_file_header_2" $var_begin)
file_header_3=$(printf "$tmp_file_header_3" $var_end)
echo ${file_header_1}>>${file_path}
echo ${file_header_2}>>${file_path}
echo ${file_header_3}>>${file_path}
echo "">>${file_path}
echo "">>${file_path}
fi
}
写入测试重点
可以看到代码流程:
- 先使用正则从
commit-msg
中得到ISSUEID
- 再用正则从
commit-msg
中获取到代码修改的模块
- 最后将信息按照规定的格式添加到文件中
get_issue() {
issue_str=$(echo "$1" | egrep -E '(ISSUE#([A-Za-z0-9]+-[0-9]+))' -o)
str_arry=($(echo $issue_str | awk -F# '{print $1,$2}'))
echo ${str_arry[1]}
}
get_module() {
module_str=$(echo "$1" | egrep -E '((\w+):(\w+))' -o)
str_arry=($(echo $module_str | awk -F: '{print $1,$2}'))
echo ${str_arry[1]}
}
add_content() {
issue=$(get_issue $commit_msg)
module=$(get_module $commit_msg)
author=$(git config user.name)
content_1="### author:$author"
content_2="### ISSUEID:$issue"
content_3="### 模块:$module"
content_4="### 重点:"
echo "---">>${file_path}
echo "">>${file_path}
echo ${content_1}>>${file_path}
echo ${content_2}>>${file_path}
echo ${content_3}>>${file_path}
echo ${content_4}>>${file_path}
echo "">>${file_path}
}
到这里主要实现就结束了,但是还存在一些瑕疵。
局限性
由于借助了 Git hook 的机制实现,所以存在一些瑕疵:
- 不能在提交的时候填写
重点
条目 - 在 Hook 触发的时候生成的文件,没有办法通过一次提交将文件和代码都提交,需要两次提交
也正是因为这些瑕疵,导致另一个致命的问题:
- 因为需要两次提交,意味着 Hook 会出发两次,出现套娃事件
这个问题有很多解决办法,我采用的是给 commit-msg
中添加标志,如果有这个标志 hook 就执行,否则 hook 不执行。
这样在第一次提交的时候打上标记,生成文件。
填写好重点后,第二次提交用 --amend
命令取出标记,正式提交。
但是上面的两点局限性还是存在的,没有办法避免。
最后
其实这个代码方案对于别人来说可借鉴的意义并不大,分享出来主要是聊聊思路。如果有人遇到别的问题的时候,可以从这里获得一丝丝灵感,那就是最好的。
代码
老规矩,代码在 https://gist.github.com/T-Oner/585b0d321113ac0fd6f42a39817a792f
本文由 TOner 创作,采用 知识共享署名4.0 国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
最后编辑时间为: Oct 21, 2020 at 10:40 am