golang根据语义化版本规则比较Go模块版本变更类型插件库modversemver的使用
Golang根据语义化版本规则比较Go模块版本变更类型插件库modver/mver的使用
Modver是一个帮助你在Go模块中遵循语义化版本规则的工具。它可以读取和比较同一模块的两个不同版本,并报告变更类型(主版本号、次版本号或补丁版本号)。
安装和使用
命令行界面
安装modver命令:
go install github.com/bobg/modver/v2/cmd/modver@latest
使用示例(假设当前目录是Git仓库根目录):
$ modver -git .git HEAD~1 HEAD
其中:
-git .git
指定Git仓库路径(也可以是URL)HEAD~1
和HEAD
指定要比较的两个Git修订版本(可以是标签或提交哈希)
GitHub Action
在.github/workflows
目录下创建Yaml文件,内容如下:
name: Tests
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: 1.19
- name: Modver
if: ${{ github.event_name == 'pull_request' }}
uses: bobg/modver@v2.5.0
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
pull_request_url: https://github.com/${{ github.repository }}/pull/${{ github.event.number }}
注意:
fetch-depth: 0
确保克隆完整历史记录- 将
main
改为你的默认分支名 - 若非GitHub.com,需修改
pull_request_url
中的主机名
Go库
添加到项目中:
go get github.com/bobg/modver/v2@latest
使用示例代码:
package main
import (
"fmt"
"github.com/bobg/modver/v2"
)
func main() {
// 比较两个目录中的模块版本
result, err := modver.CompareDirs("/path/to/old", "/path/to/new")
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
// 输出变更类型
switch result {
case modver.Major:
fmt.Println("需要主版本号变更")
case modver.Minor:
fmt.Println("需要次版本号变更")
case modver.Patch:
fmt.Println("需要补丁版本号变更")
case modver.None:
fmt.Println("无需版本变更")
}
}
语义化版本规则
- 主版本号变更:公共API的不兼容变更(如类型删除/重命名、函数参数/返回值变更)
- 次版本号变更:公共API的新增功能(如新入口点、现有结构的新字段)
- 补丁版本变更:其他不影响API的变更
Modver返回的是最小所需的变更类型。实际可能需要更大的变更,但可以保证:
- 返回Major时,次版本变更不够
- 返回Minor时,补丁版本变更不够
完整示例Demo
package main
import (
"fmt"
"github.com/bobg/modver/v2"
"os"
)
func main() {
if len(os.Args) != 3 {
fmt.Println("Usage: go run main.go <old-dir> <new-dir>")
os.Exit(1)
}
oldDir := os.Args[1]
newDir := os.Args[2]
// 比较两个目录中的模块版本
result, err := modver.CompareDirs(oldDir, newDir)
if err != nil {
fmt.Printf("比较失败: %v\n", err)
os.Exit(1)
}
// 输出结果
fmt.Printf("比较 %s 和 %s 的结果:\n", oldDir, newDir)
switch result {
case modver.Major:
fmt.Println("变更类型: MAJOR (主版本号变更)")
case modver.Minor:
fmt.Println("变更类型: MINOR (次版本号变更)")
case modver.Patch:
fmt.Println("变更类型: PATCH (补丁版本变更)")
case modver.None:
fmt.Println("变更类型: NONE (无需版本变更)")
default:
fmt.Println("未知变更类型")
}
}
使用方式:
go run main.go /path/to/v1.0.0 /path/to/v1.1.0
更多关于golang根据语义化版本规则比较Go模块版本变更类型插件库modversemver的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于golang根据语义化版本规则比较Go模块版本变更类型插件库modversemver的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
使用modversemver比较Go模块版本变更类型
modversemver是一个用于分析Go模块版本变更类型的库,它基于语义化版本(SemVer)规则来判断版本变更属于哪种类型(主版本、次版本或修订版本)。
安装
go get github.com/icholy/modversemver
基本用法
比较两个版本
package main
import (
"fmt"
"github.com/icholy/modversemver"
)
func main() {
// 比较两个版本
change, err := modversemver.Compare("v1.2.3", "v1.2.4")
if err != nil {
panic(err)
}
fmt.Printf("Change type: %s\n", change.Type) // "patch"
fmt.Printf("Is breaking: %v\n", change.Breaking) // false
}
版本变更类型
modversemver会返回以下变更类型:
major
- 主版本变更 (v1.0.0 → v2.0.0)minor
- 次版本变更 (v1.0.0 → v1.1.0)patch
- 修订版本变更 (v1.0.0 → v1.0.1)
高级用法
检查是否包含破坏性变更
func isBreakingChange(oldVer, newVer string) bool {
change, err := modversemver.Compare(oldVer, newVer)
if err != nil {
return false
}
return change.Breaking
}
func main() {
fmt.Println(isBreakingChange("v1.2.3", "v2.0.0")) // true
fmt.Println(isBreakingChange("v1.2.3", "v1.3.0")) // false
}
分析模块版本历史
func analyzeModuleHistory(versions []string) {
if len(versions) < 2 {
return
}
for i := 1; i < len(versions); i++ {
change, err := modversemver.Compare(versions[i-1], versions[i])
if err != nil {
fmt.Printf("Error comparing %s → %s: %v\n", versions[i-1], versions[i], err)
continue
}
fmt.Printf("%s → %s: %s change (breaking: %v)\n",
versions[i-1], versions[i], change.Type, change.Breaking)
}
}
func main() {
versions := []string{"v1.0.0", "v1.0.1", "v1.1.0", "v2.0.0"}
analyzeModuleHistory(versions)
}
处理Go模块的特殊情况
Go模块在主版本变更时会在模块路径中包含版本号(如/v2
),modversemver也能正确处理这种情况:
func main() {
// 处理带版本号的模块路径
change, err := modversemver.Compare(
"github.com/user/module/v1.2.3",
"github.com/user/module/v2.0.0")
if err != nil {
panic(err)
}
fmt.Println(change.Type) // "major"
}
错误处理
modversemver会返回以下可能的错误:
- 版本格式无效
- 版本号缺失
- 比较的版本不属于同一模块
func safeCompare(v1, v2 string) (modversemver.Change, error) {
change, err := modversemver.Compare(v1, v2)
if err != nil {
switch err {
case modversemver.ErrInvalidVersion:
fmt.Println("Invalid version format")
case modversemver.ErrMissingVersion:
fmt.Println("Missing version number")
case modversemver.ErrDifferentModules:
fmt.Println("Comparing versions from different modules")
default:
fmt.Println("Unknown error:", err)
}
return modversemver.Change{}, err
}
return change, nil
}
modversemver是一个轻量级但功能强大的工具,特别适合在CI/CD流程中自动检查版本变更是否符合语义化版本规范,或在发布工具中自动确定下一个版本号。