当前位置: 首页 >  技术宝典 >  awk 处理 Git 提交信息生成 Release Note

awk 处理 Git 提交信息生成 Release Note

导读:发布软件时通常都会写 Release Note,但每次从头手打也有点累,可以考虑从 Git 的提交历史中自动生成。.Git 提交信息一般是三段式结构,段落之间使用空行隔开:.<subject>.// 空行.<body>.// 空行.<trailers>.subject 和 bod

发布软件时通常都会写 Release Note,但每次从头手打也有点累,可以考虑从 Git 的提交历史中自动生成。

Git 提交信息一般是三段式结构,段落之间使用空行隔开:

<subject>
// 空行
<body>
// 空行
<trailers>

subjectbody 自不必多说,trailers 中一般是一条条键 – 值对构成的信息,键和值由冒号 : 分隔。比如 Git 的 Commiter: 就可以视为一条 trailer,Gerrit 代码审查通过后,也会在 Git 提交消息中添加 Reviewed-by:Tested-by: 之类的 trailer

现假设提交信息中的 trailers 包含 TypeIssue 字段,分别表示类别(NewFeature, BugFix 之类)和 BUG 编号(GitHub 上的 issue 编号或者内部系统的 BUG 编号):

Fixed a crash

- blahblah
- blahblahblah

Type: BugFix
Issue: issue-120

就可以结合 git logawk 生成 Rlease Note:

git log --format='%(trailers:key=Type,valueonly,separator=%x20)%x1c%s [%(trailers:key=Issue,valueonly,separator=,)]' $FROM..HEAD | awk -F "\034" '
    {
        gsub(/\[\]$/, "", $2);
        if (length($1) == 0) $1="MISC";
        if (!($1 in item_count)) item_count[$1]=0;
        items[$1, item_count[$1]]=$2;
        item_count[$1]++;
    }
    END {
        for (k in item_count) {
            print k;
            k2=k;
            gsub(/./, "-", k2);
            print k2
            for (i=0; i<item_count[k]; i++) print "* "items[k, i];
            print ""
        }
    }'

输出:

BugFix
------
* Fixed a typo
* Fixed a crash [issue-120]

NewFeature
----------
* Added some magic

选择使用 awk 处理 git log 的输出是因为 linux 跟 macOS 都带这个软件,不需要额外安装依赖。
Git 2.22.0 及以上版本才支持按键值筛选 trailers

在 Windows 系统上,可能没有办法直接运行 .sh 文件。但是如果安装了 Windows 版本的 Git,则会带一个 Git Bash(也带了 awk!),这样就可以在 Git Bash 中运行 .sh 文件,也可以创建一个 .cmd 文件包装一下:

@ECHO off
SETLOCAL

CALL :FIND-PATH GITEXE_PATH git.exe
IF "%GITEXE_PATH%"=="" (
    ECHO git.exe is not found on your system
    EXIT /B 2
)

CALL :GET-DIR-NAME GITEXE_DIR "%GITEXE_PATH%"
CALL :GET-DIR-NAME GITEXE_DIR "%GITEXE_DIR:~0,-1%"

@"%GITEXE_DIR%bin\bash.exe" release-note.sh %*

:FIND-PATH
SET "%~1=%~f$PATH:2"
EXIT /B

:GET-DIR-NAME
SET "%~1=%~dp2"
EXIT /B

上面的脚本只能把 release note 生成出来,如果可以直接添加到 changelog.md 就好了,可以把脚本做如下改动。

一,添加版本信息。添加一个变量 PROJ_VER 表示当前项目版本,以 maven 项目为例:

PROJ_VER=`./mvnw help:evaluate -Dexpression='project.version' -q -DforceStdout|tail -n 1`

然后将这个变量暴露给 awk,在 awk 命令后面添加 -v PROJ_VER PROJ_VER 即可。

二,将版本和日期打印出来。在 awk 程序中添加 BEGIN 块:

BEGIN {
  "date +%Y-%m-%d"|getline date;
  if (PROJ_VER == "") print "# "date;
  else print "# "PROJ_VER" "date;
}

三,在 change.md 头部追加生成的内容:

# 生成临时文件
tempf=`mktemp $TEMP/changelog.md.XXXX`
touch changelog.md

# 将生成的内容与原 changelog.md 中的内容合并,保存到临时文件中,然后用临时文件替换当前文件即可
... | cat - changelog.md > $tempf && mv $tempf changelog.md

这样一顿操作下来,生成的 changelog.md 如下:

# 1.2.3 2023-03-31
BugFix
------
* Fixed a typo
* Fixed a crash [issue-120]

NewFeature
----------
* Added some magic

内容
  • 三维模型轻量化在移动应用场景的如何发挥作用
    三维模型轻量化在移动应用场景的如
    2023-12-01
    在移动应用场景中,三维模型的重量对于应用的性能、流畅度和用户体验都有很大的影响。而三维模型轻量化技术可以通过减少模型数据
  • 旋转网格超采样(Rotated Grid Supersampling)
    旋转网格超采样(Rotated
    2023-12-06
    旋转网格超采样(Rotated Grid Supersampling).这是对文章 4-Rook Antialiasin
  • gitlab ci 集成 eslint/prettier/tsc 做代码审查,并使用 eslint 输出作为显示代码质量
    gitlab ci 集成 esl
    2023-12-09
    前言.想自动化一下公司里代码的部分审查,最初想用 reviewdog 的,但是公司的域名基本都在 VPN 中访问的,gi
  • 什么是软件供应链?
    什么是软件供应链?
    2023-12-05
    1 软件供应链定义.需方和供方基于供应关系,开展并完成软件采购、开发、交付、获取、运维和废止等供应活动而形成的网链结构。
  • 在idea/webstorm等terminal运行命令报错:Command rejected by the operating system没有权限【已解决】
    在idea/webstorm等t
    2023-12-10
    在idea/webstorm等编译器terminal窗口运行命令报错:Command rejected by the o
  • 实时光线追踪(3)Ray Casting
    实时光线追踪(3)Ray Cas
    2023-12-01
    目录.硬件光追(Hardware Ray Tracing).加速结构(Acceleration Structure,AS