versions

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 13, 2026 License: MIT Imports: 13 Imported by: 0

README

Versions - Go语言版本号解析计算SDK

Go Tests Go Report Card GoDoc

Versions Logo

专业的 Go 语言版本号解析计算SDK - 轻松解析、比较、排序软件版本号

versions 是一个专为 Go 开发者设计的版本号解析计算SDK,专注于处理语义化版本号的解析、比较、排序和查询。它不是一个版本管理系统,而是一个帮助开发者处理版本号字符串的工具库。无论是依赖管理、API兼容性检查还是软件更新逻辑,都能高效完成版本号的计算需求。


📋 目录


✨ 特性

🔄 全面的版本号支持 支持标准语义化版本格式(如 1.2.3)和多种变体(如 v1.2.31.2.3-beta 等)
🧩 灵活的版本号解析 自动识别前缀、版本号和后缀,处理各种版本号格式
📊 版本号比较 基于标准语义化版本规则进行版本号比较,支持前缀和后缀处理
📦 版本号分组和排序 按主版本号、次版本号分组,并提供多种排序方式
🔍 版本号范围查询 支持查询指定版本号范围内的所有版本,带有灵活的包含/排除边界选项
📋 版本号可视化 提供文本方式展示版本号之间的层次关系,直观查看版本号组织结构
📁 文件支持 直接从文件中读取和处理版本号
🚀 无外部依赖 核心功能无需额外依赖,轻量快速

📦 安装

使用 go get 命令安装:

go get -u github.com/scagogogo/versions-skills

🚀 快速开始

以下是一个简单的示例,展示如何使用 versions 库解析和比较版本号:

package main

import (
    "fmt"
    "github.com/scagogogo/versions-skills"
)

func main() {
    // 创建版本对象
    v1 := versions.NewVersion("1.2.3")
    v2 := versions.NewVersion("v1.3.0")
    
    // 比较版本大小
    if v1.CompareTo(v2) < 0 {
        fmt.Printf("%s 小于 %s\n", v1.Raw, v2.Raw)
    }
    
    // 查看版本组成部分
    fmt.Printf("版本号数字: %v\n", v1.VersionNumbers)
    fmt.Printf("前缀: %s\n", v2.Prefix)  // 输出: "v"
    
    // 排序版本号
    versionList := []*versions.Version{
        versions.NewVersion("2.0.0"),
        versions.NewVersion("1.0.0"),
        versions.NewVersion("1.10.0"),
    }
    sortedVersions := versions.SortVersionSlice(versionList)
    for _, v := range sortedVersions {
        fmt.Println(v.Raw)  // 输出: 1.0.0, 1.10.0, 2.0.0
    }
}
查看输出结果
1.2.3 小于 v1.3.0
版本号数字: [1 2 3]
前缀: v
1.0.0
1.10.0
2.0.0

📚 详细文档

数据类型和常量
类型 描述
Version 表示一个版本号,包含原始字符串、版本号数字、前缀、后缀和发布时间
VersionNumbers 整数切片,表示版本号中的数字部分
VersionPrefix 字符串,表示版本号数字部分之前的前缀
VersionSuffix 字符串,表示版本号数字部分之后的后缀
ContainsPolicy 用于控制版本查询时的包含策略(包含、不包含)
VersionGroup 版本组,包含相同主版本号的一组版本
SortedVersionGroups 有序的版本组集合,便于范围查询
主要函数
版本解析与创建
// 创建版本对象
version := versions.NewVersion("1.2.3")

// 带错误检查的版本创建
version, err := versions.NewVersionE("1.2.3")
if err != nil {
    log.Fatal(err)
}
从文件读取版本
// 读取版本号对象
versions, err := versions.ReadVersionsFromFile("path/to/versions.txt")
if err != nil {
    log.Fatal(err)
}

// 读取版本号字符串
versionStrings, err := versions.ReadVersionsStringFromFile("path/to/versions.txt")
if err != nil {
    log.Fatal(err)
}
版本分组与排序
// 版本分组
groupedVersions := versions.Group(versionList)

// 字符串版本排序
sortedStrings := versions.SortVersionStringSlice(versionStrings)

// 版本对象排序
sortedVersions := versions.SortVersionSlice(versionList)
版本范围查询
// 创建有序版本组
sortedGroups := versions.NewSortedVersionGroups(versionList)

// 定义查询范围和包含策略
startVersion := versions.NewVersion("1.0.0")
endVersion := versions.NewVersion("2.0.0")
startTuple := tuple.New2[*versions.Version, versions.ContainsPolicy](
    startVersion, versions.ContainsPolicyYes) // 包含起始版本
endTuple := tuple.New2[*versions.Version, versions.ContainsPolicy](
    endVersion, versions.ContainsPolicyNo)   // 不包含结束版本

// 执行范围查询
rangeResult := sortedGroups.QueryRange(startTuple, endTuple)
版本可视化
// 可视化所有版本(每组显示最多5个版本)
versions.VisualizeVersions(versionList, os.Stdout, 5)

// 可视化版本组层次结构
versions.VisualizeVersionGroups(versionList, os.Stdout)

可视化输出示例:

版本总数: 15
版本组数: 3

┌─ 版本组: 1.0 (3个版本)
├── 1.0.0 (发布时间: 2020-01-01)
├── 1.0.1 (发布时间: 2020-02-01)
└── 1.0.2 (发布时间: 2020-03-01)

┌─ 版本组: 2.0 (4个版本)
├── 2.0.0 (发布时间: 2021-01-01)
├── 2.0.1 (发布时间: 2021-02-01)
├── 2.0.2 (发布时间: 2021-03-01)
└── ...还有1个版本未显示

🧩 完整API文档

核心类型与功能详解

Version 类型
结构定义
type Version struct {
    // 原始版本号字符串
    Raw string
    
    // 版本发布时间
    PublicTime time.Time
    
    // 版本号数字部分,例如 1.2.3 中的 [1,2,3]
    VersionNumbers VersionNumbers
    
    // 版本号前缀,例如 v1.2.3 中的 "v"
    Prefix VersionPrefix
    
    // 版本号后缀,例如 1.2.3-beta 中的 "-beta"
    Suffix VersionSuffix
}
NewVersion - 创建版本号对象
func NewVersion(versionString string) *Version

参数:

  • versionString string: 版本号字符串,如 "1.2.3", "v1.0.0-beta" 等

返回值:

  • *Version: 解析后的版本对象

处理逻辑:

  1. 自动识别版本号前缀(如 "v")
  2. 解析版本号数字部分(如 "1.2.3" 中的 [1,2,3])
  3. 提取版本号后缀(如 "-beta", "-rc1" 等)
  4. 创建完整的版本对象

特性:

  • 支持任意数量的版本号段(如 "1.2.3.4.5")
  • 自动处理前导零(如 "1.02.003" 被解析为 [1,2,3])
  • 不会因解析错误而抛出异常,解析失败时会返回空版本号

示例:

version := versions.NewVersion("v1.2.3-rc1")
fmt.Printf("前缀: %s, 版本号: %v, 后缀: %s\n", 
    version.Prefix, version.VersionNumbers, version.Suffix)
// 输出: 前缀: v, 版本号: [1 2 3], 后缀: -rc1

// 处理非标准版本号
custom := versions.NewVersion("release-1.0-final")
fmt.Printf("前缀: %s, 版本号: %v, 后缀: %s\n", 
    custom.Prefix, custom.VersionNumbers, custom.Suffix)
// 输出: 前缀: release-, 版本号: [1 0], 后缀: -final
NewVersionE - 创建版本号对象(带错误返回)
func NewVersionE(versionString string) (*Version, error)

参数:

  • versionString string: 版本号字符串

返回值:

  • *Version: 解析后的版本对象
  • error: 解析过程中可能发生的错误,如:
    • 无法识别的版本号格式
    • 版本号中不包含数字部分
    • 版本号数字部分解析失败

错误处理:

  • 当版本号字符串为空时,返回 ErrEmptyVersionString 错误
  • 当版本号中没有找到数字时,返回 ErrNoVersionNumbersFound 错误
  • 当无法识别版本号格式时,返回 ErrInvalidVersionFormat 错误

示例:

version, err := versions.NewVersionE("v1.2.3-rc1")
if err != nil {
    log.Fatalf("版本号解析失败: %v", err)
}

// 错误处理示例
version, err = versions.NewVersionE("")
if err != nil {
    fmt.Printf("空版本号错误: %v\n", err) 
    // 输出: 空版本号错误: empty version string
}

version, err = versions.NewVersionE("no-numbers")
if err != nil {
    fmt.Printf("无数字版本号错误: %v\n", err)
    // 输出: 无数字版本号错误: no version numbers found
}
IsValid - 检查版本号是否有效
func (v *Version) IsValid() bool

返回值:

  • bool: 版本号是否有效,必须至少包含一个版本数字

验证标准:

  • 版本号对象不能为 nil
  • VersionNumbers 字段必须至少包含一个数字
  • Raw 字段不能为空字符串

使用场景:

  • 过滤无效的版本号对象
  • 验证用户输入的版本号是否有效
  • 在批量处理版本号前进行有效性检查

示例:

version := versions.NewVersion("v1.2.3")
if version.IsValid() {
    fmt.Println("版本号有效") // 会执行这行
}

emptyVersion := versions.NewVersion("")
if !emptyVersion.IsValid() {
    fmt.Println("空版本号无效") // 会执行这行
}

invalidVersion := versions.NewVersion("no-numbers")
if !invalidVersion.IsValid() {
    fmt.Println("无数字版本号无效") // 会执行这行
}
CompareTo - 比较两个版本号
func (v *Version) CompareTo(other *Version) int

参数:

  • other *Version: 要比较的另一个版本对象

返回值:

  • int:
    • 小于0: 当前版本小于 other 版本
    • 等于0: 两个版本相等
    • 大于0: 当前版本大于 other 版本

比较规则:

  1. 首先比较版本号数字部分,按位比较,长度不同时短的版本号在缺失位置视为0
  2. 如果版本号数字部分相同,则比较前缀
  3. 如果前缀也相同,则比较后缀
  4. 如果前缀和后缀都相同,则比较发布时间
  5. 如果以上都相同,则认为两个版本相等

兼容性说明:

  • 能正确处理数字部分不同长度的版本号比较(如 "1.0" 和 "1.0.0")
  • 前缀比较区分大小写(如 "v1.0" 和 "V1.0" 被视为不同)
  • 后缀比较遵循预发布版本规则(如 "-alpha" < "-beta" < "-rc" < 正式版)

示例:

v1 := versions.NewVersion("1.2.3")
v2 := versions.NewVersion("1.3.0")
result := v1.CompareTo(v2)
if result < 0 {
    fmt.Printf("%s 小于 %s\n", v1.Raw, v2.Raw) // 会执行这行
}

// 比较相同数字部分但有不同前后缀的版本
v3 := versions.NewVersion("v1.0.0")
v4 := versions.NewVersion("1.0.0-beta")
if v4.CompareTo(v3) < 0 {
    fmt.Println("预发布版本小于正式版本") // 会执行这行
}

// 比较发布时间
v5 := versions.NewVersion("1.0.0")
v6 := versions.NewVersion("1.0.0")
v5.PublicTime = time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC)
v6.PublicTime = time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC)
if v5.CompareTo(v6) < 0 {
    fmt.Println("早期发布的版本小于晚期发布的版本") // 会执行这行
}
String - 获取版本号字符串表示
func (v *Version) String() string

返回值:

  • string: 版本号的字符串表示,通常等同于原始版本号

行为说明:

  • 如果 Raw 字段不为空,则直接返回 Raw 字段
  • 如果 Raw 字段为空,则根据版本号各组成部分拼接成字符串返回
  • 返回的字符串格式为:前缀 + 版本号数字(以点分隔) + 后缀

使用场景:

  • 在日志或输出中显示版本号
  • 将版本对象转换回字符串用于存储或传输
  • 在比较后选择特定版本时获取其字符串表示

示例:

version := versions.NewVersion("v1.2.3")
fmt.Println(version.String()) // 输出: v1.2.3

// 使用String()方法在日志中显示版本信息
log.Printf("当前使用的版本: %s", version)

// 通过比较后选择最大版本并显示
v1 := versions.NewVersion("1.0.0")
v2 := versions.NewVersion("2.0.0")
var latestVersion *versions.Version
if v1.CompareTo(v2) > 0 {
    latestVersion = v1
} else {
    latestVersion = v2
}
fmt.Printf("最新版本: %s\n", latestVersion) // 输出: 最新版本: 2.0.0
VersionNumbers 类型
结构定义与方法
// VersionNumbers 是整数切片,表示版本号的数字部分
type VersionNumbers []int

// 获取主版本号
func (v VersionNumbers) MajorVersion() int

// 获取次版本号
func (v VersionNumbers) MinorVersion() int

// 获取修订版本号
func (v VersionNumbers) PatchVersion() int

// 比较两个版本号数字部分
func (v VersionNumbers) CompareTo(other VersionNumbers) int

详细方法说明:

MajorVersion(): 获取主版本号(第一个数字)

  • 返回值: int - 版本号的第一个数字
  • 行为: 如果版本号为空,返回0;否则返回第一个数字
  • 用途: 用于识别不兼容API变更的主版本

MinorVersion(): 获取次版本号(第二个数字)

  • 返回值: int - 版本号的第二个数字
  • 行为: 如果版本号不足两段,返回0;否则返回第二个数字
  • 用途: 用于识别向后兼容的功能性变更

PatchVersion(): 获取修订版本号(第三个数字)

  • 返回值: int - 版本号的第三个数字
  • 行为: 如果版本号不足三段,返回0;否则返回第三个数字
  • 用途: 用于识别向后兼容的问题修复

CompareTo(other VersionNumbers): 比较两个版本号数字部分

  • 参数: other VersionNumbers - 要比较的另一个版本号数字
  • 返回值: int - 小于0表示当前版本小,等于0表示相等,大于0表示当前版本大
  • 比较规则:
    1. 从左到右逐位比较,高位优先
    2. 对于长度不同的版本号,缺失部分视为0(如1.0和1.0.0被视为相等)
    3. 数字大的版本号大(如1.2.0大于1.1.9)

高级用法:

  • 可以处理任意长度的版本号(不限于语义化版本的三段式)
  • 支持零值安全比较(空的VersionNumbers被视为[0])
  • 可直接访问底层切片获取特定位置的版本号数字

示例:

version := versions.NewVersion("1.2.3")
major := version.VersionNumbers.MajorVersion() // 返回 1
minor := version.VersionNumbers.MinorVersion() // 返回 2
patch := version.VersionNumbers.PatchVersion() // 返回 3

// 比较版本号数字部分
v1Numbers := versions.NewVersion("1.2.0").VersionNumbers
v2Numbers := versions.NewVersion("1.2.3").VersionNumbers
if v1Numbers.CompareTo(v2Numbers) < 0 {
    fmt.Println("1.2.0 的数字部分小于 1.2.3") // 会执行这行
}

// 处理超过三段的版本号
longVersion := versions.NewVersion("1.2.3.4.5")
fmt.Printf("第5段版本号: %d\n", longVersion.VersionNumbers[4]) // 输出: 第5段版本号: 5

// 根据版本号数字部分生成分支名
version := versions.NewVersion("2.5.1")
branchName := fmt.Sprintf("release/%d.%d.x", 
    version.VersionNumbers.MajorVersion(),
    version.VersionNumbers.MinorVersion())
fmt.Println(branchName) // 输出: release/2.5.x
VersionPrefix 类型
结构定义与方法
// VersionPrefix 是字符串,表示版本号前缀
type VersionPrefix string

// 检查前缀是否为空
func (v VersionPrefix) IsEmpty() bool

// 比较两个前缀
func (v VersionPrefix) CompareTo(other VersionPrefix) int

详细方法说明:

IsEmpty(): 检查前缀是否为空

  • 返回值: bool - 前缀是否为空字符串
  • 行为: 当前缀为空字符串时返回true,否则返回false
  • 用途: 判断版本号是否有前缀,通常用于决定是否需要特殊处理

CompareTo(other VersionPrefix): 比较两个前缀

  • 参数: other VersionPrefix - 要比较的另一个前缀
  • 返回值: int - 小于0表示当前前缀字典序小,等于0表示相等,大于0表示当前前缀字典序大
  • 比较规则:
    1. 使用字符串字典序比较
    2. 区分大小写(如"v"和"V"被视为不同)
    3. 空前缀小于任何非空前缀

常见前缀类型:

  • v - 常见的版本号前缀,如 "v1.2.3"
  • version- - 一些项目使用的冗长前缀
  • release- - 表示发布版本的前缀
  • Ver - 带大写字母的变体

使用场景:

  • 识别版本号的类型或来源
  • 保持与特定工具或生态系统的兼容性
  • 在显示时维持一致的格式

示例:

version := versions.NewVersion("v1.2.3")
if !version.Prefix.IsEmpty() {
    fmt.Printf("版本前缀: %s\n", version.Prefix) // 输出: 版本前缀: v
}

// 比较前缀
v1 := versions.NewVersion("v1.0.0")
v2 := versions.NewVersion("release-1.0.0")
if v1.Prefix.CompareTo(v2.Prefix) < 0 {
    fmt.Println("v 前缀字典序小于 release- 前缀") // 不会执行,因为 "v" 字典序大于 "release-"
} else {
    fmt.Println("release- 前缀字典序小于 v 前缀") // 会执行这行
}

// 去除前缀获取纯版本号
version := versions.NewVersion("v2.0.1")
pureVersionStr := strings.TrimPrefix(version.Raw, string(version.Prefix))
fmt.Println(pureVersionStr) // 输出: 2.0.1
VersionSuffix 类型
结构定义与方法
// VersionSuffix 是字符串,表示版本号后缀
type VersionSuffix string

// 检查后缀是否为空
func (v VersionSuffix) IsEmpty() bool

// 比较两个后缀
func (v VersionSuffix) CompareTo(other VersionSuffix) int

详细方法说明:

IsEmpty(): 检查后缀是否为空

  • 返回值: bool - 后缀是否为空字符串
  • 行为: 当后缀为空字符串时返回true,否则返回false
  • 用途: 判断是否为预发布版本,通常正式版本没有后缀

CompareTo(other VersionSuffix): 比较两个后缀

  • 参数: other VersionSuffix - 要比较的另一个后缀
  • 返回值: int - 小于0表示当前后缀优先级低,等于0表示相等,大于0表示当前后缀优先级高
  • 比较规则:
    1. 空后缀大于任何非空后缀(正式版大于预发布版)
    2. 基于预发布版本通用优先级规则
    3. 对于相同类型的后缀,进一步按字符串比较

常见后缀类型和优先级(从低到高):

  1. -dev, -alpha, -a - 开发预览版/测试版
  2. -beta, -b - 测试版
  3. -milestone, -m - 里程碑版本
  4. -rc, -pre - 发布候选版
  5. 无后缀 - 正式发布版

使用场景:

  • 标识预发布版本
  • 确定版本稳定性和发布阶段
  • 控制客户端更新策略(可能排除某些后缀类型)

示例:

version := versions.NewVersion("1.2.3-beta")
if !version.Suffix.IsEmpty() {
    fmt.Printf("版本后缀: %s\n", version.Suffix) // 输出: 版本后缀: -beta
}

// 比较后缀优先级
v1 := versions.NewVersion("1.0.0-alpha")
v2 := versions.NewVersion("1.0.0-beta")
v3 := versions.NewVersion("1.0.0-rc1")
v4 := versions.NewVersion("1.0.0")

// 优先级: alpha < beta < rc < 正式版
if v1.Suffix.CompareTo(v2.Suffix) < 0 {
    fmt.Println("alpha 后缀优先级低于 beta 后缀") // 会执行这行
}
if v2.Suffix.CompareTo(v3.Suffix) < 0 {
    fmt.Println("beta 后缀优先级低于 rc 后缀") // 会执行这行
}
if v3.Suffix.CompareTo(v4.Suffix) < 0 {
    fmt.Println("rc 后缀优先级低于无后缀(正式版)") // 会执行这行
}

// 确定版本是否为预发布版本
if !version.Suffix.IsEmpty() {
    fmt.Println("这是预发布版本,不推荐用于生产环境")
}
ContainsPolicy 类型
定义与常量
// ContainsPolicy 用于控制版本范围查询时是否包含边界版本
type ContainsPolicy int

const (
    // 未指定包含策略
    ContainsPolicyNone ContainsPolicy = iota
    
    // 包含边界版本
    ContainsPolicyYes
    
    // 不包含边界版本
    ContainsPolicyNo
)

详细说明:

ContainsPolicy 是一个枚举类型,用于在版本范围查询中指定是否包含边界版本。

常量值:

ContainsPolicyNone (0):

  • 含义: 未指定包含策略,通常使用默认策略
  • 默认行为: 在大多数上下文中等同于 ContainsPolicyYes
  • 使用场景: 当不关心边界包含性或希望使用系统默认行为时

ContainsPolicyYes (1):

  • 含义: 包含边界版本
  • 符号表示: 对应数学符号中的闭区间 [, ]
  • 使用场景: 当查询需要包含指定的起始或结束版本时

ContainsPolicyNo (2):

  • 含义: 不包含边界版本
  • 符号表示: 对应数学符号中的开区间 (, )
  • 使用场景: 当查询需要排除指定的起始或结束版本时

行为举例:

  • [1.0.0, 2.0.0]: 包含1.0.0和2.0.0及其间的所有版本
  • (1.0.0, 2.0.0): 不包含1.0.0和2.0.0,只包含其间的版本
  • [1.0.0, 2.0.0): 包含1.0.0但不包含2.0.0
  • (1.0.0, 2.0.0]: 不包含1.0.0但包含2.0.0

在实际代码中的应用:

  • 与版本范围查询函数配合使用
  • 用于构建版本兼容性条件
  • 实现依赖规范中定义的版本范围

示例:

// 创建版本
v1 := versions.NewVersion("1.0.0")
v2 := versions.NewVersion("2.0.0")

// 创建版本范围查询条件
startWithInclude := tuple.New2[*versions.Version, versions.ContainsPolicy](
    v1, versions.ContainsPolicyYes) // 包含起始版本,相当于 [1.0.0
endWithExclude := tuple.New2[*versions.Version, versions.ContainsPolicy](
    v2, versions.ContainsPolicyNo)  // 不包含结束版本,相当于 2.0.0)

// 使用版本组执行范围查询(模拟 [1.0.0, 2.0.0) 范围)
result := sortedGroups.QueryRange(startWithInclude, endWithExclude)

// 在日志中显示查询范围
fmt.Printf("查询版本范围: %s%s, %s%s\n",
    inclusionSymbol(startWithInclude.V2), startWithInclude.V1.Raw,
    endWithExclude.V1.Raw, exclusionSymbol(endWithExclude.V2))
// 输出: 查询版本范围: [1.0.0, 2.0.0)

// 辅助函数示例
func inclusionSymbol(policy versions.ContainsPolicy) string {
    if policy == versions.ContainsPolicyNo {
        return "("
    }
    return "["
}

func exclusionSymbol(policy versions.ContainsPolicy) string {
    if policy == versions.ContainsPolicyNo {
        return ")"
    }
    return "]"
}
VersionGroup 类型
结构定义与方法
// VersionGroup 表示具有相同主版本号的一组版本
type VersionGroup struct {
    // ...内部字段
}

// 创建新的版本组
func NewVersionGroup(id string) *VersionGroup

// 添加版本到组中
func (g *VersionGroup) Add(version *Version)

// 检查组是否包含某个版本
func (g *VersionGroup) Contains(version *Version) bool

// 获取组ID
func (g *VersionGroup) ID() string

// 获取组中的所有版本
func (g *VersionGroup) Versions() []*Version

// 获取组中版本的数量
func (g *VersionGroup) Count() int

// 按版本号排序组内的版本
func (g *VersionGroup) SortVersions() []*Version

// 查询范围内的版本
func (g *VersionGroup) QueryRangeVersions(start, end *Version) []*Version

详细方法说明:

NewVersionGroup(id string): 创建新的版本组

  • 参数: id string - 组的标识符,通常是主版本号
  • 返回值: *VersionGroup - 新创建的版本组对象
  • 行为: 初始化一个空的版本组,带有指定的ID
  • 用途: 手动创建版本组,用于后续添加版本

Add(version *Version): 添加版本到组中

  • 参数: version *Version - 要添加的版本对象
  • 行为: 将版本添加到组中,如果版本已存在则不重复添加
  • 注意: 不会验证版本的主版本号是否与组ID匹配
  • 用途: 向版本组添加新版本

Contains(version *Version) bool: 检查组是否包含某个版本

  • 参数: version *Version - 要检查的版本对象
  • 返回值: bool - 组中是否包含该版本
  • 比较方式: 使用版本的 Raw 字符串进行比较
  • 用途: 确定特定版本是否已在组中

ID() string: 获取组ID

  • 返回值: string - 组的标识符
  • 行为: 返回创建组时指定的ID
  • 用途: 识别版本组,通常等同于主版本号

Versions() []*Version: 获取组中的所有版本

  • 返回值: []*Version - 组中所有版本的切片
  • 行为: 返回版本组内部存储的所有版本对象
  • 注意: 返回的切片不保证有特定顺序
  • 用途: 获取组内所有版本进行遍历或处理

Count() int: 获取组中版本的数量

  • 返回值: int - 组中版本的数量
  • 行为: 返回组中包含的版本对象数量
  • 用途: 快速获取组大小,无需遍历版本

SortVersions() []*Version: 按版本号排序组内的版本

  • 返回值: []*Version - 排序后的版本对象切片
  • 排序规则: 使用 Version.CompareTo 方法比较,按版本号从小到大排序
  • 用途: 获取组内按序排列的版本列表

QueryRangeVersions(start, end *Version) []*Version: 查询范围内的版本

  • 参数:
    • start *Version - 范围起始版本
    • end *Version - 范围结束版本
  • 返回值: []*Version - 符合范围条件的版本对象切片
  • 行为: 返回组内版本号在 start 和 end 之间的所有版本(包含 start 和 end)
  • 注意: 返回的结果已按版本号排序
  • 用途: 获取特定版本范围内的所有版本

版本组常见使用场景:

  • 按主版本号对版本进行分组管理
  • 在UI中展示按主版本组织的版本列表
  • 对特定主版本内的版本执行范围查询
  • 获取特定主版本的最新版本或稳定版本

示例:

// 创建版本组
group := versions.NewVersionGroup("1")

// 添加版本
group.Add(versions.NewVersion("1.0.0"))
group.Add(versions.NewVersion("1.1.0"))
group.Add(versions.NewVersion("1.2.0"))

// 获取组内所有版本
allVersions := group.Versions()
fmt.Printf("版本组 %s 包含 %d 个版本\n", group.ID(), group.Count())
// 输出: 版本组 1 包含 3 个版本

// 排序组内版本
sortedVersions := group.SortVersions()
fmt.Println("排序后的版本:")
for i, v := range sortedVersions {
    fmt.Printf("%d. %s\n", i+1, v.Raw)
}
// 输出:
// 排序后的版本:
// 1. 1.0.0
// 2. 1.1.0
// 3. 1.2.0

// 检查版本是否在组中
v := versions.NewVersion("1.1.0")
if group.Contains(v) {
    fmt.Printf("版本组 %s 包含版本 %s\n", group.ID(), v.Raw)
    // 输出: 版本组 1 包含版本 1.1.0
}

// 范围查询
start := versions.NewVersion("1.0.5")
end := versions.NewVersion("1.1.5")
rangeVersions := group.QueryRangeVersions(start, end)
fmt.Printf("范围 %s 到 %s 内的版本数: %d\n", start.Raw, end.Raw, len(rangeVersions))
// 输出: 范围 1.0.5 到 1.1.5 内的版本数: 1 (只有1.1.0在这个范围内)

// 获取组内最新版本
latestVersion := group.SortVersions()[group.Count()-1]
fmt.Printf("版本组 %s 中的最新版本: %s\n", group.ID(), latestVersion.Raw)
// 输出: 版本组 1 中的最新版本: 1.2.0
SortedVersionGroups 类型
结构定义与方法
// SortedVersionGroups 表示一组有序的版本组
type SortedVersionGroups struct {
    // ...内部字段
}

// 创建新的有序版本组
func NewSortedVersionGroups(versions []*Version) *SortedVersionGroups

// 获取所有版本组ID
func (s *SortedVersionGroups) GroupIDs() []string

// 查询指定范围内的版本
func (s *SortedVersionGroups) QueryRange(
    start *tuple.Tuple2[*Version, ContainsPolicy],
    end *tuple.Tuple2[*Version, ContainsPolicy],
) []*Version

详细方法说明:

NewSortedVersionGroups(versions []*Version): 创建新的有序版本组

  • 参数: versions []*Version - 版本对象切片
  • 返回值: *SortedVersionGroups - 有序版本组对象
  • 行为:
    1. 将版本按主版本号分组创建 VersionGroup
    2. 对各组内版本进行排序
    3. 将版本组按组ID排序
  • 用途: 构建用于高效查询和遍历的有序版本结构

GroupIDs() []string: 获取所有版本组ID

  • 返回值: []string - 所有版本组ID的切片
  • 行为: 返回已排序的版本组ID列表(通常是主版本号)
  • 顺序: 按字符串顺序排序,数字ID会考虑数值大小
  • 用途:
    • 获取所有可用的主版本号
    • 在UI中创建版本选择器
    • 按主版本顺序遍历版本

QueryRange(...) []*Version: 查询指定范围内的版本

  • 参数:
    • start *tuple.Tuple2[*Version, ContainsPolicy] - 起始版本及其包含策略
    • end *tuple.Tuple2[*Version, ContainsPolicy] - 结束版本及其包含策略
  • 返回值: []*Version - 符合范围条件的版本对象切片
  • 行为:
    1. 确定范围覆盖的版本组
    2. 在每个相关组内执行范围查询
    3. 合并结果并按版本顺序排序
  • 特点:
    • 支持跨版本组的范围查询
    • 考虑包含策略确定边界处理
    • 结果按版本顺序排序
  • 用途:
    • 实现版本选择器中的范围过滤
    • 查找指定范围内的兼容版本
    • 获取特定范围内的版本更新

使用场景:

  • 在前端UI中展示分层的版本选择器
  • 实现符合语义化版本规范的版本范围查询
  • 处理大量版本时提供高效的版本过滤和分组显示

性能特点:

  • 初始化时完成分组和排序,查询操作高效
  • 范围查询利用排序特性,具有对数级时间复杂度
  • 适合处理大规模版本集合,并支持频繁的查询操作

示例:

// 创建测试版本列表
versionList := []*versions.Version{
    versions.NewVersion("1.0.0"),
    versions.NewVersion("1.1.0"),
    versions.NewVersion("2.0.0"),
    versions.NewVersion("2.1.0"),
    versions.NewVersion("3.0.0"),
}

// 创建有序版本组
sortedGroups := versions.NewSortedVersionGroups(versionList)

// 获取所有组ID
groupIDs := sortedGroups.GroupIDs()
fmt.Printf("共有 %d 个版本组: %v\n", len(groupIDs), groupIDs)
// 输出: 共有 3 个版本组: [1 2 3]

// 执行范围查询:获取1.0.0(包含)到2.0.0(不包含)之间的所有版本
startVersion := versions.NewVersion("1.0.0")
endVersion := versions.NewVersion("2.0.0")

// 创建包含策略元组
startTuple := tuple.New2[*versions.Version, versions.ContainsPolicy](
    startVersion, versions.ContainsPolicyYes) // 包含起始版本
endTuple := tuple.New2[*versions.Version, versions.ContainsPolicy](
    endVersion, versions.ContainsPolicyNo)    // 不包含结束版本
    
// 执行查询
result := sortedGroups.QueryRange(startTuple, endTuple)
fmt.Printf("查询结果包含 %d 个版本\n", len(result))
// 输出: 查询结果包含 2 个版本 (1.0.0, 1.1.0)

// 打印查询结果
for i, v := range result {
    fmt.Printf("%d. %s\n", i+1, v.Raw)
}
// 输出:
// 1. 1.0.0
// 2. 1.1.0

// 另一个范围查询示例:获取所有大于等于2.0.0的版本
laterVersionQuery := sortedGroups.QueryRange(
    tuple.New2[*versions.Version, versions.ContainsPolicy](
        versions.NewVersion("2.0.0"), 
        versions.ContainsPolicyYes),
    tuple.New2[*versions.Version, versions.ContainsPolicy](
        nil, versions.ContainsPolicyNone), // nil表示不设上限
)
fmt.Printf("2.0.0及以后的版本共有 %d 个\n", len(laterVersionQuery))
// 输出: 2.0.0及以后的版本共有 3 个 (2.0.0, 2.1.0, 3.0.0)
文件操作函数
从文件读取版本号
// 读取文件中的版本号字符串
func ReadVersionsStringFromFile(filepath string) ([]string, error)

// 读取并解析文件中的版本号
func ReadVersionsFromFile(filepath string) ([]*Version, error)

详细函数说明:

ReadVersionsStringFromFile(filepath string): 读取文件中的版本号字符串

  • 参数: filepath string - 文件路径
  • 返回值:
    • []string - 版本号字符串切片
    • error - 读取过程中可能发生的错误
  • 行为:
    1. 打开并读取指定文件
    2. 按行分割文件内容
    3. 去除每行首尾空白字符
    4. 过滤空行和注释行(以#开头)
    5. 返回有效的版本号字符串行
  • 错误处理:
    • 文件不存在:返回 os.ErrNotExist
    • 权限问题:返回相应的文件系统错误
    • 读取失败:返回 io.EOF 或其他I/O错误
  • 用途: 读取版本列表文件,获取原始版本号字符串

ReadVersionsFromFile(filepath string): 读取并解析文件中的版本号

  • 参数: filepath string - 文件路径
  • 返回值:
    • []*Version - 版本对象切片
    • error - 读取或解析过程中可能发生的错误
  • 行为:
    1. 调用 ReadVersionsStringFromFile 获取版本号字符串
    2. 对每个字符串调用 NewVersion 创建版本对象
    3. 返回创建的版本对象切片
  • 错误处理:
    • 继承 ReadVersionsStringFromFile 的所有错误
    • 不会因版本解析失败而返回错误(使用 NewVersion 而非 NewVersionE)
  • 用途: 一次性读取并解析版本列表文件

文件格式要求:

  • 每行一个版本号
  • 支持空行(会被忽略)
  • 支持注释行(以#开头,会被忽略)
  • 行首尾的空白字符会被自动移除

性能考虑:

  • 对于大文件,考虑使用缓冲读取
  • 如需处理无效版本,应在读取后手动过滤
  • 读取后可考虑缓存结果,避免频繁IO操作

示例:

// 从文件读取版本号字符串
versionStrings, err := versions.ReadVersionsStringFromFile("versions.txt")
if err != nil {
    log.Fatalf("读取版本号失败: %v", err)
}
fmt.Printf("共读取 %d 个版本号字符串\n", len(versionStrings))

// 从文件读取并解析版本号
versionObjects, err := versions.ReadVersionsFromFile("versions.txt")
if err != nil {
    log.Fatalf("解析版本号失败: %v", err)
}
fmt.Printf("共解析 %d 个版本号对象\n", len(versionObjects))

// 版本号文件示例 (versions.txt):
// # 稳定版本
// 1.0.0
// 1.0.1
// 1.0.2
// 
// # 预发布版本
// 1.1.0-alpha
// 1.1.0-beta
// 1.1.0-rc1

// 高级应用:读取并分组版本
versionObjects, err := versions.ReadVersionsFromFile("versions.txt")
if err != nil {
    log.Fatalf("读取版本号失败: %v", err)
}
sortedGroups := versions.NewSortedVersionGroups(versionObjects)
fmt.Printf("共读取 %d 个版本,分为 %d 个版本组\n", 
    len(versionObjects), len(sortedGroups.GroupIDs()))

// 过滤无效版本
validVersions := make([]*versions.Version, 0)
for _, v := range versionObjects {
    if v.IsValid() {
        validVersions = append(validVersions, v)
    } else {
        fmt.Printf("忽略无效版本: %s\n", v.Raw)
    }
}
fmt.Printf("有效版本数: %d\n", len(validVersions))
排序函数
版本排序函数
// 对版本字符串切片进行排序
func SortVersionStringSlice(versionStringSlice []string) []string

// 对版本对象切片进行排序
func SortVersionSlice(versions []*Version) []*Version

详细函数说明:

SortVersionStringSlice(versionStringSlice []string): 对版本字符串切片进行排序

  • 参数: versionStringSlice []string - 要排序的版本号字符串切片
  • 返回值: []string - 排序后的版本号字符串切片
  • 行为:
    1. 将字符串转换为版本对象
    2. 对版本对象进行排序
    3. 将排序后的版本对象转回字符串
  • 排序规则: 基于 Version.CompareTo 方法比较
  • 处理无效版本:
    • 无效或无法解析的版本会出现在结果中
    • 无效版本之间的顺序取决于其原始字符串
  • 用途: 直接对版本号字符串进行排序,无需手动创建版本对象

SortVersionSlice(versions []*Version): 对版本对象切片进行排序

  • 参数: versions []*Version - 要排序的版本对象切片
  • 返回值: []*Version - 排序后的版本对象切片
  • 行为: 对输入的版本对象切片进行原地排序
  • 排序规则: 基于 Version.CompareTo 方法比较
  • 处理无效版本:
    • 无效版本会被保留在结果中
    • 排序时将无效版本视为最小值
  • 用途: 对已创建的版本对象集合进行排序

排序算法特点:

  • 稳定排序:相等的版本保持原始顺序
  • 时间复杂度:O(n log n),其中n为版本数量
  • 空间复杂度:SortVersionStringSlice需要O(n)额外空间,SortVersionSlice为O(1)

注意事项:

  • 两个函数都不会修改原始输入切片,而是返回新的排序结果
  • 排序时会考虑版本的所有组成部分(前缀、数字、后缀)
  • 大多数情况下,排序结果符合语义化版本规范的预期顺序

示例:

// 排序版本号字符串
unsortedStrings := []string{
    "2.0.0", 
    "1.0.0", 
    "1.10.0", 
    "1.2.0",
    "v1.5.0",
    "1.5.0-beta",
}
sortedStrings := versions.SortVersionStringSlice(unsortedStrings)
fmt.Println("排序后的版本号字符串:")
for i, v := range sortedStrings {
    fmt.Printf("%d. %s\n", i+1, v)
}
// 输出:
// 排序后的版本号字符串:
// 1. 1.0.0
// 2. 1.2.0
// 3. 1.5.0-beta
// 4. v1.5.0
// 5. 1.10.0
// 6. 2.0.0

// 排序版本对象
unsortedVersions := []*versions.Version{
    versions.NewVersion("2.0.0"),
    versions.NewVersion("1.0.0"),
    versions.NewVersion("1.10.0"),
    versions.NewVersion("1.2.0-alpha"),
}
sortedVersions := versions.SortVersionSlice(unsortedVersions)
fmt.Println("排序后的版本对象:")
for i, v := range sortedVersions {
    fmt.Printf("%d. %s\n", i+1, v.Raw)
}
// 输出:
// 排序后的版本对象:
// 1. 1.0.0
// 2. 1.2.0-alpha
// 3. 1.10.0
// 4. 2.0.0

// 自定义排序:按发布时间倒序
// 注:需配合自定义排序函数使用
type ByReleaseTimeDesc []*versions.Version
func (v ByReleaseTimeDesc) Len() int           { return len(v) }
func (v ByReleaseTimeDesc) Swap(i, j int)      { v[i], v[j] = v[j], v[i] }
func (v ByReleaseTimeDesc) Less(i, j int) bool { return v[j].PublicTime.Before(v[i].PublicTime) }

// 设置发布时间并排序
for i, v := range unsortedVersions {
    // 模拟不同的发布时间,每个版本间隔1个月
    v.PublicTime = time.Now().AddDate(0, -i, 0)
}
sort.Sort(ByReleaseTimeDesc(unsortedVersions))
fmt.Println("按发布时间倒序排序:")
for i, v := range unsortedVersions {
    fmt.Printf("%d. %s (发布于: %s)\n", i+1, v.Raw, v.PublicTime.Format("2006-01-02"))
}
分组函数
版本分组函数
// 将版本列表按主版本号分组
func Group(versions []*Version) map[string]*VersionGroup

详细函数说明:

Group(versions []*Version): 将版本列表按主版本号分组

  • 参数: versions []*Version - 要分组的版本对象列表
  • 返回值: map[string]*VersionGroup - 以组ID为键的版本组映射
  • 行为:
    1. 遍历版本对象列表
    2. 对每个版本提取其主版本号(VersionNumbers[0])作为组ID
    3. 按组ID创建或更新 VersionGroup
    4. 将版本添加到对应的组中
  • 分组标准:
    • 默认按主版本号(第一个数字)分组
    • 无效版本或无主版本号的版本使用"0"作为组ID
  • 返回格式:
    • 键:字符串形式的组ID,通常是主版本号(如"1", "2")
    • 值:包含对应主版本号所有版本的 VersionGroup 对象
  • 用途:
    • 按主版本号组织版本
    • 创建层次化版本选择界面
    • 辅助版本号可视化

常见分组用例:

  • 按语义化版本的主版本号分组,快速区分不兼容版本
  • UI中显示分级版本选择器,方便用户选择合适版本
  • 对大量版本进行结构化管理,提高版本浏览和选择效率

性能特点:

  • 时间复杂度:O(n),其中n为版本数量
  • 空间复杂度:O(n),需要存储所有版本的组织结构
  • 适合处理任意规模的版本集合,性能随版本数量线性增长

示例:

// 创建版本列表
versionList := []*versions.Version{
    versions.NewVersion("1.0.0"),
    versions.NewVersion("1.1.0"),
    versions.NewVersion("1.2.0"),
    versions.NewVersion("2.0.0"),
    versions.NewVersion("2.1.0"),
    versions.NewVersion("3.0.0-beta"),
}

// 按主版本号分组
groupMap := versions.Group(versionList)

// 打印分组结果
fmt.Printf("共有 %d 个版本组\n", len(groupMap))
// 输出: 共有 3 个版本组

// 遍历分组结果
for groupID, group := range groupMap {
    fmt.Printf("\n版本组 %s 包含 %d 个版本:\n", groupID, group.Count())
    // 对组内版本排序
    sortedVersions := group.SortVersions()
    for i, v := range sortedVersions {
        fmt.Printf("  %d. %s\n", i+1, v.Raw)
    }
}
// 输出:
// 版本组 1 包含 3 个版本:
//   1. 1.0.0
//   2. 1.1.0
//   3. 1.2.0
//
// 版本组 2 包含 2 个版本:
//   1. 2.0.0
//   2. 2.1.0
//
// 版本组 3 包含 1 个版本:
//   1. 3.0.0-beta

// 获取特定组内的最新版本
group1 := groupMap["1"]
if group1 != nil && group1.Count() > 0 {
    sortedGroup1 := group1.SortVersions()
    latestVersion := sortedGroup1[len(sortedGroup1)-1]
    fmt.Printf("\n版本组 1 中的最新版本: %s\n", latestVersion.Raw)
    // 输出: 版本组 1 中的最新版本: 1.2.0
}

// 高级应用:创建版本选择器数据
type VersionOption struct {
    Label    string
    Value    string
    Children []VersionOption
}

versionSelector := make([]VersionOption, 0, len(groupMap))
for groupID, group := range groupMap {
    children := make([]VersionOption, 0, group.Count())
    for _, v := range group.SortVersions() {
        children = append(children, VersionOption{
            Label: v.Raw,
            Value: v.Raw,
        })
    }
    versionSelector = append(versionSelector, VersionOption{
        Label:    fmt.Sprintf("版本 %s.x", groupID),
        Value:    groupID,
        Children: children,
    })
}
可视化函数
版本可视化函数
// 以文本树形式可视化版本结构
func VisualizeVersions(versions []*Version, w io.Writer, maxItemsPerGroup int)

// 以文本树形式可视化版本组层次结构
func VisualizeVersionGroups(versions []*Version, w io.Writer)

详细函数说明:

VisualizeVersions(versions []*Version, w io.Writer, maxItemsPerGroup int): 以文本树形式可视化版本结构

  • 参数:
    • versions []*Version - 要可视化的版本对象列表
    • w io.Writer - 输出写入目标
    • maxItemsPerGroup int - 每组最多显示的版本数量,0表示不限制
  • 行为:
    1. 按主版本号对版本进行分组
    2. 为每个版本组创建树形结构
    3. 对组内版本排序并输出有限数量
    4. 如超过限制,显示剩余版本数
  • 输出格式:
    • 显示总版本数和版本组数
    • 每个版本组以树形结构展示
    • 可选显示版本的发布时间
  • 用途:
    • 在终端或日志中展示版本组织结构
    • 提供版本分布的直观视图
    • 方便调试和检查版本管理逻辑

VisualizeVersionGroups(versions []*Version, w io.Writer): 以文本树形式可视化版本组层次结构

  • 参数:
    • versions []*Version - 要可视化的版本对象列表
    • w io.Writer - 输出写入目标
  • 行为:
    1. 创建版本组层次结构
    2. 以树形结构输出版本组信息
    3. 对每个组显示组ID和版本数量
  • 输出格式:
    • 不显示具体版本,只展示组级别信息
    • 每组显示ID和包含的版本数量
  • 用途:
    • 获取版本分组的概览
    • 查看不同主版本的分布情况
    • 为大型版本集合提供简化视图

视觉效果增强:

  • 使用Unicode字符创建树形结构(如 "├──", "└──")
  • 缩进和连接线提高可读性
  • 可选颜色高亮(输出到终端时)

应用场景:

  • 版本库管理和维护
  • 发布日志和版本跟踪
  • 在CLI工具中展示版本信息
  • 调试版本比较和排序逻辑

示例:

// 准备版本列表
versionList := []*versions.Version{
    versions.NewVersion("1.0.0"),
    versions.NewVersion("1.0.1"),
    versions.NewVersion("1.1.0"),
    versions.NewVersion("2.0.0"),
    versions.NewVersion("2.0.1"),
    versions.NewVersion("2.1.0"),
    versions.NewVersion("3.0.0-alpha"),
    versions.NewVersion("3.0.0-beta"),
}

// 设置发布时间(示例)
currentTime := time.Now()
for i, v := range versionList {
    // 模拟不同发布时间,每个版本间隔1个月
    v.PublicTime = currentTime.AddDate(0, -i, 0)
}

// 可视化完整版本结构,每组显示最多2个版本
fmt.Println("完整版本可视化 (每组最多2个版本):")
versions.VisualizeVersions(versionList, os.Stdout, 2)
// 输出示例:
// 版本总数: 8
// 版本组数: 3
//
// ┌─ 版本组: 1 (3个版本)
// ├── 1.0.0 (发布时间: 2023-05-15)
// ├── 1.0.1 (发布时间: 2023-04-15)
// └── ...还有1个版本未显示
//
// ┌─ 版本组: 2 (3个版本)
// ├── 2.0.0 (发布时间: 2023-02-15)
// ├── 2.0.1 (发布时间: 2023-01-15)
// └── ...还有1个版本未显示
//
// ┌─ 版本组: 3 (2个版本)
// ├── 3.0.0-alpha (发布时间: 2022-12-15)
// └── 3.0.0-beta (发布时间: 2022-11-15)

// 仅可视化版本组结构
fmt.Println("\n版本组结构可视化:")
versions.VisualizeVersionGroups(versionList, os.Stdout)
// 输出示例:
// 版本总数: 8
// 版本组数: 3
//
// ┌─ 版本组: 1 (3个版本)
// ├─ 版本组: 2 (3个版本)
// └─ 版本组: 3 (2个版本)

// 可视化特定版本范围
fmt.Println("\n筛选后的版本可视化:")
// 获取1.x和2.x系列的所有版本
filteredVersions := make([]*versions.Version, 0)
for _, v := range versionList {
    major := v.VersionNumbers.MajorVersion()
    if major == 1 || major == 2 {
        filteredVersions = append(filteredVersions, v)
    }
}
versions.VisualizeVersions(filteredVersions, os.Stdout, 0) // 0表示显示所有版本

🔍 使用示例

示例 描述
📚 基本版本解析 如何解析和比较不同格式的版本号
📂 从文件读取版本 如何从文件中读取版本信息
🔢 版本排序 如何对版本号进行排序
📦 版本分组 如何对版本进行分组管理
🔍 版本范围查询 如何查询特定版本范围
📊 版本可视化 如何可视化版本结构
版本树示例
版本树可视化示例

⚠️ 注意事项

  • ⚠️ 确保传入的文件路径正确,且文件格式符合要求
  • ⚠️ 版本号的解析和比较依赖于正确的格式,非标准格式可能会导致解析错误
  • ⚠️ 时间比较依赖于 PublicTime 被正确设置
  • ⚠️ 对于非标准格式的版本号可能需要额外的处理

📈 性能

  • 版本解析: O(n),其中 n 是版本号字符串的长度
  • 版本比较: O(m),其中 m 是版本号中数字部分的最大长度
  • 版本排序: O(n log n),其中 n 是版本列表的长度
  • 范围查询: O(log n),基于有序版本组的二分查找

🤖 Claude Code Skills

本项目同时是一个 Claude Code Skills 仓库,提供版本号处理的专业技能。安装后,您可以在 Claude Code 中通过斜杠命令调用这些技能。

安装方式
# 添加 marketplace
claude marketplace add versions https://github.com/scagogogo/versions-skills

# 安装插件
claude plugin install versions@versions
可用 Skills
Skill 命令 用途
版本号解析 /version-parsing 解析、验证版本字符串
版本号比较 /version-comparison 比较两个版本号大小
版本号排序 /version-sorting 对版本号列表排序
版本号分组 /version-grouping 按主版本号分组管理
版本范围查询 /version-range-query 查询指定范围内的版本
版本号可视化 /version-visualization 以树形结构展示版本层次
版本号文件操作 /version-file-operations 从文件读取版本号列表
使用示例

在 Claude Code 中输入:

/version-parsing v1.2.3-beta1

Claude 将基于此 Skill 提供专业的版本号解析指导,包括正确的 Go 代码示例和 API 用法。


📄 许可证

本项目采用 MIT 许可证 - 详见 LICENSE 文件

Copyright © 2023-2025 scagogogo

Documentation

Index

Constants

View Source
const (
	// DefaultVersionDelimiter 默认的版本数字分隔符
	//
	// 这是用于连接版本号数字部分的标准分隔符。即使原始版本使用了其它分隔符(如"/"),
	// 解析完毕后也会被统一为这个标准分隔符(即".")。
	DefaultVersionDelimiter = "."
)

Variables

View Source
var (
	// ErrVersionInvalid 表示版本号格式无效的错误
	//
	// 当尝试解析不符合要求的版本号字符串时返回此错误
	ErrVersionInvalid = errors.New("version invalid")

	// ErrEmptyConstraint 表示约束表达式为空的错误
	ErrEmptyConstraint = errors.New("empty constraint expression")

	// ErrMissingVersionInConstraint 表示约束表达式中缺少版本号的错误
	ErrMissingVersionInConstraint = errors.New("missing version in constraint")

	// ErrInvalidVersionInConstraint 表示约束表达式中版本号无效的错误
	ErrInvalidVersionInConstraint = errors.New("invalid version in constraint")
)

Functions

func ContainsVersion

func ContainsVersion(versions []*Version, target *Version) bool

ContainsVersion 判断版本列表中是否包含指定版本

根据 Raw 字段判断版本是否相同。

参数:

  • versions: 版本对象列表
  • target: 目标版本对象

返回:

  • bool: 如果列表中包含目标版本则返回 true

使用示例:

list := versions.NewVersions("1.0.0", "1.1.0", "2.0.0")
v := versions.NewVersion("1.1.0")
fmt.Println(versions.ContainsVersion(list, v)) // true

func Count

func Count(versions []*Version, predicate func(*Version) bool) int

Count 统计版本列表中满足谓词的版本数量

func Group

func Group(versions []*Version) map[string]*VersionGroup

Group 对版本号进行分组

该函数将版本对象数组按照其数字部分(主版本号)进行分组,为每个不同的主版本号创建一个版本组。 分组的依据是版本号的数字部分生成的组ID,如 "1.2.3" 和 "1.2.4" 会被分到同一组 "1.2"。

分组可用于: 1. 对特定主版本系列进行管理和查询 2. 分析版本演进路径 3. 查找某主版本下的最新/最旧版本

参数:

  • versions: 需要分组的版本对象数组

返回:

  • map[string]*VersionGroup: 分组结果,键为版本组ID,值为对应的版本组对象

使用示例:

allVersions := versions.NewVersions("1.0.0", "1.1.0", "1.2.0", "2.0.0", "2.1.0")
groups := versions.Group(allVersions)

// 遍历所有版本组
for groupID, group := range groups {
    fmt.Printf("版本组 %s 包含 %d 个版本\n", groupID, len(group.Versions))

    // 获取组内最新版本
    latestVersion := group.GetLatestVersion()
    fmt.Printf("组内最新版本: %s\n", latestVersion.Raw)
}

func GroupByMajor

func GroupByMajor(versions []*Version) map[int][]*Version

GroupByMajor 按主版本号分组

返回按主版本号分组的映射,键为主版本号,值为对应的版本组。

参数:

  • versions: 版本对象列表

返回:

  • map[int][]*Version: 按主版本号分组的结果

使用示例:

list := versions.NewVersions("1.0.0", "1.1.0", "2.0.0", "2.1.0")
groups := versions.GroupByMajor(list)
for major, vs := range groups {
    fmt.Printf("Major %d: %d versions\n", major, len(vs))
}

func GroupByMinor

func GroupByMinor(versions []*Version) map[string][]*Version

GroupByMinor 按次版本号分组

返回按"主版本号.次版本号"分组的映射。

参数:

  • versions: 版本对象列表

返回:

  • map[string][]*Version: 按主.次版本号分组的结果,键如 "1.2"

使用示例:

list := versions.NewVersions("1.0.0", "1.0.1", "1.1.0", "2.0.0")
groups := versions.GroupByMinor(list)
for key, vs := range groups {
    fmt.Printf("Minor %s: %d versions\n", key, len(vs))
}

func IndexOf

func IndexOf(versions []*Version, target *Version) int

IndexOf 查找版本在列表中的位置

根据 Raw 字段匹配,返回第一次出现的索引。如果未找到则返回 -1。

参数:

  • versions: 版本对象列表
  • target: 目标版本对象

返回:

  • int: 版本在列表中的索引,未找到返回 -1

使用示例:

list := versions.NewVersions("1.0.0", "1.1.0", "2.0.0")
idx := versions.IndexOf(list, versions.NewVersion("1.1.0"))
fmt.Println(idx) // 1

func Partition

func Partition(versions []*Version, predicate func(*Version) bool) ([]*Version, []*Version)

Partition 根据谓词将版本列表分为两组

返回两个切片:第一个包含满足谓词的版本,第二个包含不满足谓词的版本。 保持原始顺序。

参数:

  • versions: 版本对象列表
  • predicate: 分区谓词函数

返回:

  • []*Version: 满足谓词的版本列表
  • []*Version: 不满足谓词的版本列表

func ReadVersionsStringFromFile

func ReadVersionsStringFromFile(filepath string) ([]string, error)

ReadVersionsStringFromFile 从文件中读取版本号字符串

该函数从指定的文件中读取版本号列表,每行一个版本号,并返回字符串数组。 与 ReadVersionsFromFile 不同,此函数不会将版本号解析为Version对象, 而是保留原始字符串形式,适用于不需要解析和比较的场景。

参数:

  • filepath: 包含版本号列表的文件路径

返回:

  • []string: 读取的版本号字符串数组
  • error: 如果文件读取失败则返回相应错误

使用示例:

// 从版本列表文件中读取版本字符串
versionStrings, err := versions.ReadVersionsStringFromFile("./versions.txt")
if err != nil {
    log.Fatalf("读取版本文件失败: %v", err)
}

// 使用版本字符串
for _, vStr := range versionStrings {
    fmt.Printf("发现版本: %s\n", vStr)
}

func SortVersionGroupSlice

func SortVersionGroupSlice(groupSlice []*VersionGroup)

SortVersionGroupSlice 对版本组切片进行排序

该函数直接对传入的版本组切片进行原地排序,排序依据是版本组之间的比较规则。

参数:

  • groupSlice: 待排序的版本组切片,排序操作直接修改该切片

使用示例:

groups := []*VersionGroup{group1, group2, group3}
SortVersionGroupSlice(groups)
// 现在 groups 已按版本组规则排序

func SortVersionStringSlice

func SortVersionStringSlice(versionStringSlice []string) []string

SortVersionStringSlice 对字符串形式的版本数组进行排序

该函数接收一个字符串形式的版本号数组,将其解析为 Version 对象进行排序, 然后将排序结果转换回字符串数组返回。排序遵循版本号的自然排序规则。

参数:

  • versionStringSlice: 待排序的版本号字符串数组

返回:

  • []string: 排序后的版本号字符串数组

使用示例:

versions := []string{"1.2.0", "1.0.0", "1.10.0", "2.0.0"}
sorted := versions.SortVersionStringSlice(versions)
// 结果: ["1.0.0", "1.2.0", "1.10.0", "2.0.0"]

func VisualizeVersionGroups

func VisualizeVersionGroups(versions []*Version, w io.Writer)

VisualizeVersionGroups 可视化版本组之间的关系

此函数将版本组集合转换为可视化的树状文本表示,展示其层次关系。 适合用于查看大型版本库的版本组织结构。

参数:

  • versions: 要可视化的版本集合
  • w: 输出写入的目标

示例:

versions := ReadVersionsFromFile("versions.txt")
VisualizeVersionGroups(versions, os.Stdout)

func VisualizeVersions

func VisualizeVersions(versions []*Version, w io.Writer, maxItems int)

VisualizeVersions 可视化版本号之间的关系和结构

此函数将版本号集合转换为可视化的文本表示,展示其层次关系和排序情况。 主要用于调试、展示或理解版本数据结构。

参数:

  • versions: 要可视化的版本集合
  • w: 输出写入的目标
  • maxItems: 每个版本组最多显示的版本数量,0表示不限制

示例:

versions := ReadVersionsFromFile("versions.txt")
VisualizeVersions(versions, os.Stdout, 5)

func WriteVersionsToFile

func WriteVersionsToFile(versions []*Version, filepath string) error

WriteVersionsToFile 将版本列表写入文件

每个版本号占一行,写入版本号数字部分拼接而成的字符串。 该函数会先对版本进行排序,确保输出有序。

参数:

  • versions: 要写入的版本对象列表
  • filepath: 输出文件路径

返回:

  • error: 如果文件写入失败则返回错误

使用示例:

versions := versions.NewVersions("2.0.0", "1.0.0", "1.1.0")
err := versions.WriteVersionsToFile(versions, "./output.txt")

Types

type Constraint

type Constraint struct {
	// Operator 约束操作符
	Operator ConstraintOperator

	// Version 约束目标版本
	Version *Version
}

Constraint 表示一个版本约束条件

Constraint 用于判断某个版本是否满足指定的约束条件, 如 ">=1.0.0", "^1.2.3", "~1.2.3", "1.x" 等。

使用示例:

c, err := versions.ParseConstraint(">=1.0.0")
if err != nil {
    log.Fatal(err)
}
v := versions.NewVersion("1.5.0")
if c.Match(v) {
    fmt.Println("1.5.0 satisfies >=1.0.0")
}

func NegateConstraint

func NegateConstraint(c *Constraint) *Constraint

NegateConstraint 返回约束条件的否定形式

例如 >=1.0.0 的否定为 <1.0.0,=1.0.0 的否定为 !=1.0.0。

参数:

  • c: 要否定的约束条件

返回:

  • *Constraint: 否定后的约束条件

使用示例:

c, _ := versions.ParseConstraint(">=1.0.0")
neg := versions.NegateConstraint(c)
fmt.Println(neg.String()) // "<1.0.0"

func ParseConstraint

func ParseConstraint(expr string) (*Constraint, error)

ParseConstraint 解析单个版本约束表达式

支持的操作符: =, !=, >, >=, <, <=, ^, ~ 支持的通配符: x, X, * (如 1.x, 1.2.*)

参数:

  • expr: 约束表达式,如 ">=1.0.0", "^1.2.3", "~1.2"

返回:

  • *Constraint: 解析后的约束对象
  • error: 如果表达式格式错误则返回错误

func (*Constraint) Match

func (c *Constraint) Match(v *Version) bool

Match 判断版本是否满足约束条件

参数:

  • v: 要检查的版本对象

返回:

  • bool: 如果版本满足约束则返回 true

func (*Constraint) String

func (c *Constraint) String() string

String 返回约束条件的字符串表示

将约束条件序列化为可解析的字符串格式,如 ">=1.0.0"、"^1.2.3"、"~1.2"。 对于通配符约束(1.x),返回原始版本字符串形式。

返回:

  • string: 约束条件的字符串表示

使用示例:

c, _ := versions.ParseConstraint(">=1.0.0")
fmt.Println(c.String()) // 输出: ">=1.0.0"

type ConstraintOperator

type ConstraintOperator string

ConstraintOperator 约束操作符类型

const (
	// ConstraintEqual 等于 (=)
	ConstraintEqual ConstraintOperator = "="

	// ConstraintNotEqual 不等于 (!=)
	ConstraintNotEqual ConstraintOperator = "!="

	// ConstraintGreaterThan 大于 (>)
	ConstraintGreaterThan ConstraintOperator = ">"

	// ConstraintGreaterThanOrEqual 大于等于 (>=)
	ConstraintGreaterThanOrEqual ConstraintOperator = ">="

	// ConstraintLessThan 小于 (<)
	ConstraintLessThan ConstraintOperator = "<"

	// ConstraintLessThanOrEqual 小于等于 (<=)
	ConstraintLessThanOrEqual ConstraintOperator = "<="

	// ConstraintCaret 兼容版本 (^) — 兼容左起第一个非零版本号
	ConstraintCaret ConstraintOperator = "^"

	// ConstraintTilde 近似版本 (~) — 兼容到次版本号
	ConstraintTilde ConstraintOperator = "~"

	// ConstraintWildcard 通配符 (x/X/*) — 匹配任意子版本
	ConstraintWildcard ConstraintOperator = "x"
)

type ConstraintSet

type ConstraintSet struct {
	Constraints []Constraint
}

ConstraintSet 表示一组 AND 组合的约束条件

多个约束条件之间是 AND 关系,所有条件都必须满足。 例如 ">=1.0.0,<2.0.0" 表示版本必须同时满足 >=1.0.0 和 <2.0.0。

func ParseConstraintSet

func ParseConstraintSet(expr string) (*ConstraintSet, error)

ParseConstraintSet 解析逗号分隔的 AND 组合约束

支持格式: ">=1.0.0,<2.0.0", "^1.2.3", "~1.2"

参数:

  • expr: 逗号分隔的约束表达式

返回:

  • *ConstraintSet: 解析后的约束集合
  • error: 如果任何子表达式格式错误则返回错误

func (*ConstraintSet) Len

func (cs *ConstraintSet) Len() int

Len 返回约束集合中约束条件的数量

func (*ConstraintSet) Match

func (cs *ConstraintSet) Match(v *Version) bool

Match 判断版本是否满足所有约束(AND 逻辑)

参数:

  • v: 要检查的版本对象

返回:

  • bool: 如果版本满足所有约束则返回 true

func (*ConstraintSet) Satisfies

func (cs *ConstraintSet) Satisfies(v *Version) bool

Satisfies 判断版本是否满足约束集合

这是 Match(v) 的语义化别名,使调用方式更自然: cs.Satisfies(v) 等价于 cs.Match(v),与 Version.Satisfies(constraint) 对称。

参数:

  • v: 要检查的版本对象

返回:

  • bool: 如果版本满足所有约束则返回 true

func (*ConstraintSet) String

func (cs *ConstraintSet) String() string

String 返回约束集合的字符串表示

将约束集合序列化为逗号分隔的字符串格式,如 ">=1.0.0,<2.0.0"。

返回:

  • string: 约束集合的字符串表示

使用示例:

cs, _ := versions.ParseConstraintSet(">=1.0.0,<2.0.0")
fmt.Println(cs.String()) // 输出: ">=1.0.0,<2.0.0"

type ConstraintUnion

type ConstraintUnion struct {
	// Sets AND 约束集合列表,之间是 OR 关系
	Sets []*ConstraintSet
}

ConstraintUnion 表示一组 OR 组合的约束集合

每个 ConstraintSet 内部是 AND 逻辑,多个 ConstraintSet 之间是 OR 逻辑。 例如 ">=1.0.0,<2.0.0 || >=3.0.0" 表示版本必须满足 (>=1.0.0 AND <2.0.0) OR (>=3.0.0)。

func ParseConstraintUnion

func ParseConstraintUnion(expr string) (*ConstraintUnion, error)

ParseConstraintUnion 解析包含 OR 逻辑的约束表达式

支持格式: ">=1.0.0,<2.0.0 || >=3.0.0",其中逗号分隔为 AND,|| 分隔为 OR。 也支持不包含 || 的简单表达式,此时等价于 ParseConstraintSet。

参数:

  • expr: 约束表达式

返回:

  • *ConstraintUnion: 解析后的约束联合
  • error: 如果表达式格式错误则返回错误

func (*ConstraintUnion) Match

func (cu *ConstraintUnion) Match(v *Version) bool

Match 判断版本是否满足约束联合(OR 逻辑)

只要版本满足任意一个 ConstraintSet 即返回 true。

参数:

  • v: 要检查的版本对象

返回:

  • bool: 如果版本满足任意约束集则返回 true

func (*ConstraintUnion) Satisfies

func (cu *ConstraintUnion) Satisfies(v *Version) bool

Satisfies 判断版本是否满足约束联合

这是 Match(v) 的语义化别名,与 Version.Satisfies() 对称。

参数:

  • v: 要检查的版本对象

返回:

  • bool: 如果版本满足任意约束集则返回 true

func (*ConstraintUnion) String

func (cu *ConstraintUnion) String() string

String 返回约束联合的字符串表示

将约束联合序列化为 || 分隔的字符串格式。

返回:

  • string: 约束联合的字符串表示

type ContainsPolicy

type ContainsPolicy int

ContainsPolicy 用于控制版本查询时的包含/排除策略

该类型定义了在版本过滤或查询操作中,是否应包含或排除特定版本的策略选项。 它作为枚举类型使用,提供了三种可能的状态:未指定、包含和排除。

使用示例:

// 使用包含策略进行版本过滤
filter := &VersionFilter{
    Contains: "beta",
    ContainsPolicy: ContainsPolicyYes,
}

// 使用排除策略进行版本过滤
filter := &VersionFilter{
    Contains: "snapshot",
    ContainsPolicy: ContainsPolicyNo,
}
const (
	// ContainsPolicyNone 表示未指定包含策略
	//
	// 当设置为此值时,版本查询不会基于包含条件进行过滤
	ContainsPolicyNone ContainsPolicy = iota

	// ContainsPolicyYes 表示包含匹配的版本
	//
	// 当设置为此值时,只有包含指定字符串的版本才会被包含在结果中
	ContainsPolicyYes

	// ContainsPolicyNo 表示排除匹配的版本
	//
	// 当设置为此值时,包含指定字符串的版本将被排除在结果之外
	ContainsPolicyNo
)

func (ContainsPolicy) String

func (p ContainsPolicy) String() string

String 返回包含策略的可读名称

实现 fmt.Stringer 接口。

返回:

  • string: 策略名称,如 "none"、"yes"、"no"

type ParserOption

type ParserOption struct {
	// Delimiters 版本号数字部分的分隔符集合
	// 默认值: "." (仅点号)
	// 常见扩展: ".-_" (支持 RPM/Debian 的连字符和 Python 的下划线)
	Delimiters string
}

ParserOption 配置版本号解析器的行为

ParserOption 允许调用者自定义解析器支持的数字分隔符, 以适应不同语言生态系统的版本号格式差异。

使用示例:

// 支持 underscore 分隔(Python/RPM 生态)
v := versions.NewVersionWithOption("1_2_3",
    versions.ParserOption{Delimiters: ".-_"})

func DefaultParserOption

func DefaultParserOption() ParserOption

DefaultParserOption 返回默认的解析器选项

type SortedVersionGroups

type SortedVersionGroups struct {
	// contains filtered or unexported fields
}

SortedVersionGroups 表示已排序的版本组集合

SortedVersionGroups 封装了已排序的版本组切片和索引映射, 用于高效地进行版本组查询和范围检索。它通过预先排序和建立索引, 优化了版本组的查找性能。

结构特点: 1. 保持版本组的有序性,便于范围查询 2. 维护组ID到数组索引的映射,支持快速定位 3. 支持基于版本范围的高效查询

使用示例:

// 创建已排序的版本组
allVersions := versions.NewVersions("1.0.0", "1.1.0", "2.0.0", "2.1.0")
sortedGroups := versions.NewSortedVersionGroups(allVersions)

// 执行范围查询
startVer := versions.NewVersion("1.0.0")
endVer := versions.NewVersion("2.0.0")
startTuple := tuple.NewTuple2(startVer, versions.ContainsPolicyYes)
endTuple := tuple.NewTuple2(endVer, versions.ContainsPolicyYes)

rangeResult := sortedGroups.QueryRange(startTuple, endTuple)

func NewSortedVersionGroups

func NewSortedVersionGroups(versions []*Version) *SortedVersionGroups

NewSortedVersionGroups 为版本号创建有序的分组

该方法接收一个版本对象数组,将其分组并排序,返回一个包含已排序版本组的SortedVersionGroups对象。 处理流程: 1. 首先将版本按照其数字部分分组 2. 然后对所有分组进行排序 3. 最后构建组ID到索引的映射,用于快速查找

参数:

  • versions: 需要分组和排序的版本对象数组

返回:

  • *SortedVersionGroups: 包含已排序版本组的对象

使用示例:

// 创建版本对象数组
allVersions := versions.NewVersions("1.0.0", "1.1.0", "1.2.0", "2.0.0", "2.1.0")

// 创建已排序的版本组
sortedGroups := versions.NewSortedVersionGroups(allVersions)

func (*SortedVersionGroups) At

func (x *SortedVersionGroups) At(index int) *VersionGroup

At 根据索引获取版本组

返回排序后指定位置的版本组。如果索引越界则返回 nil。

参数:

  • index: 从 0 开始的索引位置

返回:

  • *VersionGroup: 对应的版本组,越界则返回 nil

func (*SortedVersionGroups) Contains

func (x *SortedVersionGroups) Contains(groupID string) bool

Contains 检查是否包含指定组 ID 的版本组

参数:

  • groupID: 版本组 ID

返回:

  • bool: 如果存在则返回 true

func (*SortedVersionGroups) Get

func (x *SortedVersionGroups) Get(groupID string) *VersionGroup

Get 根据组 ID 获取版本组

如果组 ID 不存在则返回 nil。

参数:

  • groupID: 版本组 ID,如 "1.2"

返回:

  • *VersionGroup: 对应的版本组,不存在则返回 nil

func (*SortedVersionGroups) GroupIDs

func (x *SortedVersionGroups) GroupIDs() []string

GroupIDs 返回所有版本组的ID列表

该方法返回按顺序排列的版本组ID列表。 返回的ID列表与内部的版本组切片顺序一致,确保保持排序状态。

返回:

  • []string: 含有所有版本组ID的字符串切片

使用示例:

sortedGroups := versions.NewSortedVersionGroups(allVersions)
groupIDs := sortedGroups.GroupIDs()
for _, id := range groupIDs {
    fmt.Printf("版本组: %s\n", id)
}

func (*SortedVersionGroups) Len

func (x *SortedVersionGroups) Len() int

Len 返回版本组的数量

func (*SortedVersionGroups) QueryRange

func (x *SortedVersionGroups) QueryRange(start, end *tuple.Tuple2[*Version, ContainsPolicy]) []*Version

QueryRange 在有序版本组中查询指定范围内的版本

该方法根据给定的起始和结束版本范围,返回所有符合条件的版本对象数组。 方法利用预排序的版本组结构,快速定位并收集符合范围条件的版本。

参数:

  • start: 包含起始版本和包含策略的元组
  • end: 包含结束版本和包含策略的元组

返回:

  • []*Version: 符合查询范围条件的版本对象数组

使用示例:

// 创建已排序的版本组
sortedGroups := versions.NewSortedVersionGroups(allVersions)

// 定义查询范围
startVer := versions.NewVersion("1.0.0")
endVer := versions.NewVersion("2.0.0")
startTuple := tuple.NewTuple2(startVer, versions.ContainsPolicyYes) // 包含1.0.0
endTuple := tuple.NewTuple2(endVer, versions.ContainsPolicyNo)      // 不包含2.0.0

// 执行范围查询
rangeResult := sortedGroups.QueryRange(startTuple, endTuple)
fmt.Printf("在范围内的版本数: %d\n", len(rangeResult))

func (*SortedVersionGroups) Versions

func (x *SortedVersionGroups) Versions() []*Version

Versions 返回所有版本组中的所有版本

版本按组排序,组内按版本排序。

返回:

  • []*Version: 所有版本的有序列表

type SuffixWeight

type SuffixWeight int

SuffixWeight 表示版本后缀的语义权重

SuffixWeight 用于在版本比较时为不同类型的后缀分配语义化的权重值, 使得预发布版本的排序符合实际发布顺序,而非简单的字典序。

权重规则(从低到高):

  • dev/snapshot < alpha/a < beta/b < milestone/m < rc/cr/pre < 正式版(无后缀)

使用示例:

weight := GetSuffixWeight("-alpha1")
fmt.Println(weight) // 100
const (
	// SuffixWeightUnknown 未知后缀类型
	SuffixWeightUnknown SuffixWeight = 0

	// SuffixWeightDev 开发版后缀
	SuffixWeightDev SuffixWeight = 50

	// SuffixWeightSnapshot 快照版后缀
	SuffixWeightSnapshot SuffixWeight = 60

	// SuffixWeightNightly 夜间构建版后缀
	SuffixWeightNightly SuffixWeight = 70

	// SuffixWeightAlpha Alpha版后缀
	SuffixWeightAlpha SuffixWeight = 100

	// SuffixWeightBeta Beta版后缀
	SuffixWeightBeta SuffixWeight = 200

	// SuffixWeightMilestone 里程碑版后缀
	SuffixWeightMilestone SuffixWeight = 300

	// SuffixWeightRC 候选发布版后缀
	SuffixWeightRC SuffixWeight = 400

	// SuffixWeightPre 预发布版后缀
	SuffixWeightPre SuffixWeight = 410

	// SuffixWeightCR 候选发布版(CR变体)
	SuffixWeightCR SuffixWeight = 420

	// SuffixWeightFinal Final后缀(Maven生态)
	SuffixWeightFinal SuffixWeight = 500

	// SuffixWeightRelease Release后缀
	SuffixWeightRelease SuffixWeight = 500

	// SuffixWeightGA GA后缀(Generally Available)
	SuffixWeightGA SuffixWeight = 500

	// SuffixWeightSP 服务包后缀
	SuffixWeightSP SuffixWeight = 600

	// SuffixWeightPatch 补丁版后缀
	SuffixWeightPatch SuffixWeight = 700

	// SuffixWeightPost Post发布版后缀(PEP 440)
	SuffixWeightPost SuffixWeight = 800
)

func GetSuffixWeight

func GetSuffixWeight(suffix string) SuffixWeight

GetSuffixWeight 获取后缀的语义权重

根据后缀字符串匹配预定义的权重规则,返回对应的语义权重。 如果没有匹配到任何规则,返回 SuffixWeightUnknown。

参数:

  • suffix: 版本后缀字符串,如 "-alpha1"、"-beta2"、"-rc1"

返回:

  • SuffixWeight: 后缀的语义权重值

func (SuffixWeight) String

func (w SuffixWeight) String() string

String 返回后缀权重的可读名称

实现 fmt.Stringer 接口。

返回:

  • string: 权重的可读名称,如 "dev"、"alpha"、"beta"、"rc"、"unknown" 等

type Version

type Version struct {

	// Raw 原始的版本号字符串
	Raw string `json:"raw"`

	// PublicTime 此版本的发布时间
	PublicTime time.Time `json:"public_time"`

	// VersionNumbers 版本号中的数字部分
	// 例如对于版本号 "v1.2.3-beta1",VersionNumbers 为 [1,2,3]
	VersionNumbers VersionNumbers `json:"version_numbers"`

	// Prefix 版本号数字部分之前的前缀
	// 例如对于版本号 "v1.2.3",Prefix 为 "v"
	Prefix VersionPrefix `json:"prefix"`

	// Suffix 版本号数字部分之后的后缀
	// 例如对于版本号 "1.2.3-beta1",Suffix 为 "-beta1"
	Suffix VersionSuffix `json:"suffix"`

	// Metadata semver 构建元数据
	//
	// 在 semver 规范中,构建元数据是版本号中 + 号后面的部分,如 "1.0.0+build123" 中的 "build123"。
	// 根据 semver 规范,构建元数据不参与版本比较。
	Metadata string `json:"metadata,omitempty"`
}

Version 用于表示一个版本号

Version 结构体封装了版本号的各个组成部分,包括原始字符串、发布时间、数字部分、 前缀和后缀。它支持版本号的解析、比较和分组等操作,实现了 Comparable 接口以便 进行版本排序。

一个典型的版本号格式可能为:v1.2.3-beta1,其中: - "v" 是前缀 - "1.2.3" 是数字部分 - "-beta1" 是后缀

使用示例:

// 创建一个版本对象
version := versions.NewVersion("v1.2.3-rc1")

// 检查版本是否有效
if version.IsValid() {
    fmt.Printf("版本号有效: %s\n", version.Raw)
    fmt.Printf("版本号数字部分: %v\n", version.VersionNumbers)
}

// 比较两个版本
v1 := versions.NewVersion("1.2.3")
v2 := versions.NewVersion("1.3.0")
if v1.CompareTo(v2) < 0 {
    fmt.Println("v1 比 v2 旧")
}

func Coerce

func Coerce(s string) *Version

Coerce 从任意字符串中提取版本号

Coerce 尝试在输入字符串中查找第一个符合版本号模式的子串。 如果找不到则返回一个无效的 Version 对象。

参数:

  • s: 可能包含版本号的字符串

返回:

  • *Version: 提取到的版本对象

使用示例:

v := versions.Coerce("program-1.2.3-linux-amd64")
fmt.Println(v.Raw) // "1.2.3"

v2 := versions.Coerce("download/v2.0.0-beta.tar.gz")
fmt.Println(v2.Raw) // "2.0.0-beta"

func CoerceE

func CoerceE(s string) (*Version, error)

CoerceE 从任意字符串中提取版本号,找不到则返回错误

参数:

  • s: 可能包含版本号的字符串

返回:

  • *Version: 提取到的版本对象
  • error: 如果找不到版本号则返回错误

func Difference

func Difference(a, b []*Version) []*Version

Difference 返回在 a 中但不在 b 中的版本(差集)

根据 Raw 字段判断版本是否相同。返回的版本保持 a 中的原始顺序。

参数:

  • a: 版本对象列表
  • b: 要排除的版本对象列表

返回:

  • []*Version: 差集版本列表

func Filter

func Filter(versions []*Version, predicate func(*Version) bool) []*Version

Filter 根据谓词函数过滤版本列表

返回所有满足谓词条件的版本。

参数:

  • versions: 版本对象列表
  • predicate: 过滤谓词函数,返回 true 表示保留该版本

返回:

  • []*Version: 满足条件的版本列表

func FilterByConstraint

func FilterByConstraint(versions []*Version, constraint *Constraint) []*Version

FilterByConstraint 根据约束条件过滤版本列表

返回所有满足约束条件的版本。

参数:

  • versions: 版本对象列表
  • constraint: 版本约束条件

返回:

  • []*Version: 满足约束的版本列表

func FilterByConstraintSet

func FilterByConstraintSet(versions []*Version, cs *ConstraintSet) []*Version

FilterByConstraintSet 根据约束集合过滤版本列表

返回所有满足约束集合中所有条件的版本。

func FilterByMajor

func FilterByMajor(versions []*Version, major int) []*Version

FilterByMajor 过滤指定主版本号的版本

func FilterByMinor

func FilterByMinor(versions []*Version, minor int) []*Version

FilterByMinor 过滤指定次版本号的版本

返回所有次版本号等于指定值的版本。

参数:

  • versions: 版本对象列表
  • minor: 目标次版本号

返回:

  • []*Version: 满足条件的版本列表

func FilterByPatch

func FilterByPatch(versions []*Version, patch int) []*Version

FilterByPatch 过滤指定修订版本号的版本

返回所有修订版本号等于指定值的版本。

参数:

  • versions: 版本对象列表
  • patch: 目标修订版本号

返回:

  • []*Version: 满足条件的版本列表

func FilterByPrefix

func FilterByPrefix(versions []*Version, prefix string) []*Version

FilterByPrefix 过滤指定前缀的版本

返回所有前缀等于指定值的版本。

参数:

  • versions: 版本对象列表
  • prefix: 目标前缀字符串,如 "v"

返回:

  • []*Version: 满足条件的版本列表

func FilterByPrerelease

func FilterByPrerelease(versions []*Version) []*Version

FilterByPrerelease 返回所有预发布版本

预发布版本是指带有后缀的版本。等价于 Filter(versions, Version.IsPrerelease)。

参数:

  • versions: 版本对象列表

返回:

  • []*Version: 所有预发布版本

func FilterByStable

func FilterByStable(versions []*Version) []*Version

FilterByStable 返回所有稳定版本

稳定版本是指不带任何后缀的版本。等价于 Filter(versions, Version.IsStable)。

参数:

  • versions: 版本对象列表

返回:

  • []*Version: 所有稳定版本

func FilterBySuffix

func FilterBySuffix(versions []*Version, suffix string) []*Version

FilterBySuffix 过滤指定后缀的版本

返回所有后缀字符串等于指定值的版本。

参数:

  • versions: 版本对象列表
  • suffix: 目标后缀字符串,如 "-beta"

返回:

  • []*Version: 满足条件的版本列表

func Intersection

func Intersection(a, b []*Version) []*Version

Intersection 返回同时存在于 a 和 b 中的版本(交集)

根据 Raw 字段判断版本是否相同。返回的版本保持 a 中的原始顺序。

参数:

  • a: 版本对象列表
  • b: 版本对象列表

返回:

  • []*Version: 交集版本列表

func LatestPrerelease

func LatestPrerelease(versions []*Version) *Version

LatestPrerelease 从版本列表中找到最新的预发布版本

如果不存在预发布版本则返回 nil。

func LatestStable

func LatestStable(versions []*Version) *Version

LatestStable 从版本列表中找到最新的稳定版本

稳定版本是指不带后缀的版本。如果不存在稳定版本则返回 nil。

func Max

func Max(versions []*Version) *Version

Max 从版本列表中找到最大的版本

如果列表为空则返回 nil。

func Min

func Min(versions []*Version) *Version

Min 从版本列表中找到最小的版本

如果列表为空则返回 nil。

参数:

  • versions: 版本对象列表

返回:

  • *Version: 最小的版本对象,列表为空时返回 nil

func MustParse

func MustParse(versionStr string) *Version

MustParse 解析版本号字符串,如果解析失败则 panic

这是 NewVersionE() 的 panic 变体,适用于初始化时确定版本号合法的场景, 类似于 regexp.MustCompile 的模式。在版本号来自硬编码或测试数据的场景下非常有用。

参数:

  • versionStr: 版本号字符串

返回:

  • *Version: 解析后的版本对象

func NewVersion

func NewVersion(versionStr string) *Version

NewVersion 从版本字符串创建一个新的 Version 对象

该方法解析给定的版本字符串,并返回一个填充了相应字段的 Version 对象。 即使版本字符串格式不正确,该方法也会返回一个对象,但其 IsValid() 方法可能返回 false。

参数:

  • versionStr: 要解析的版本号字符串,如 "1.2.3" 或 "v1.2.3-rc1"

返回:

  • *Version: 解析后的 Version 对象

使用示例:

version := versions.NewVersion("v1.2.3-beta1")

func NewVersionE

func NewVersionE(versionStr string) (*Version, error)

NewVersionE 从版本字符串创建一个新的 Version 对象,并返回可能的错误

与 NewVersion 不同,该方法会在版本字符串格式不正确时返回错误。

参数:

  • versionStr: 要解析的版本号字符串

返回:

  • *Version: 解析后的 Version 对象,如果解析失败则为 nil
  • error: 如果版本号无效,则返回 ErrVersionInvalid 错误

使用示例:

version, err := versions.NewVersionE("v1.2.3-beta1")
if err != nil {
    log.Fatalf("无效的版本号: %v", err)
}

func NewVersionWithOption

func NewVersionWithOption(versionStr string, option ParserOption) *Version

NewVersionWithOption 使用指定选项创建版本对象

func NewVersions

func NewVersions(versionStringSlice ...string) []*Version

NewVersions 批量创建多个 Version 对象

该方法接受多个版本字符串,并返回相应的 Version 对象数组。

参数:

  • versionStringSlice: 一个或多个版本号字符串

返回:

  • []*Version: 解析后的 Version 对象数组

使用示例:

versions := versions.NewVersions("1.0.0", "1.1.0", "2.0.0")
for _, v := range versions {
    fmt.Println(v.Raw)
}

func ReadVersionsFromFile

func ReadVersionsFromFile(filepath string) ([]*Version, error)

ReadVersionsFromFile 从文件中读取版本号并解析为Version对象

该函数从指定的文件中读取版本号列表,每行一个版本号,并将其解析为Version对象数组。 函数会自动忽略空行和进行行尾空白字符的清理。

参数:

  • filepath: 包含版本号列表的文件路径

返回:

  • []*Version: 解析后的Version对象数组
  • error: 如果文件读取失败则返回相应错误

示例文件内容:

1.1.28
1.1.29
1.1.30
1.1.31
1.1.31.sec01
1.1.31.sec04
1.1.31.sec06

使用示例:

// 从版本列表文件中读取版本
versions, err := versions.ReadVersionsFromFile("./versions.txt")
if err != nil {
    log.Fatalf("读取版本文件失败: %v", err)
}

// 打印解析的版本数
fmt.Printf("共读取 %d 个版本\n", len(versions))

// 对版本进行排序
sortedVersions := versions.SortVersionSlice(versions)

func ReadVersionsFromReader

func ReadVersionsFromReader(reader io.Reader) ([]*Version, error)

ReadVersionsFromReader 从 io.Reader 读取版本号并解析

该函数从任意的 io.Reader 中读取版本号列表,每行一个版本号, 并将其解析为 Version 对象数组。适用于从网络连接、字符串缓冲区等读取版本。

参数:

  • reader: 实现 io.Reader 接口的读取器

返回:

  • []*Version: 解析后的 Version 对象数组
  • error: 如果读取失败则返回错误

使用示例:

data := strings.NewReader("1.0.0\n1.1.0\n2.0.0\n")
versions, err := versions.ReadVersionsFromReader(data)

func SortVersionSlice

func SortVersionSlice(versions []*Version) []*Version

SortVersionSlice 对版本号对象数组进行排序

该函数实现了版本号的分组排序算法: 1. 首先将版本号按照主版本号分组 2. 对版本组进行排序 3. 在每个组内对版本号进行排序 4. 最后将所有组中的版本号按顺序合并

参数:

  • versions: 待排序的版本号对象数组

返回:

  • []*Version: 排序后的版本号对象数组

使用示例:

versions := versions.NewVersions("1.2.0", "1.0.0", "1.10.0", "2.0.0")
sorted := versions.SortVersionSlice(versions)
for _, v := range sorted {
    fmt.Println(v.Raw)
}

func Union

func Union(a, b []*Version) []*Version

Union 返回 a 和 b 中所有唯一版本的并集

根据 Raw 字段去重,保持 a 中元素的原始顺序,b 中不重复的元素追加到末尾。

参数:

  • a: 版本对象列表
  • b: 版本对象列表

返回:

  • []*Version: 并集版本列表

func Unique

func Unique(versions []*Version) []*Version

Unique 去除版本列表中的重复版本

根据 Raw 字段去重,保留第一次出现的版本。

func (*Version) BuildGroupID

func (x *Version) BuildGroupID() string

BuildGroupID 构造版本所属的组的ID

该方法根据版本号的数字部分生成一个组ID,用于将相似版本分组。

返回:

  • string: 表示版本组的ID字符串

使用示例:

version := versions.NewVersion("1.2.3")
groupID := version.BuildGroupID()
fmt.Printf("版本组ID: %s\n", groupID)

func (*Version) BumpMajor

func (x *Version) BumpMajor() *Version

BumpMajor 返回一个主版本号递增的新版本对象

例如 1.2.3 → 2.0.0,后缀被清除。

func (*Version) BumpMinor

func (x *Version) BumpMinor() *Version

BumpMinor 返回一个次版本号递增的新版本对象

例如 1.2.3 → 1.3.0,后缀被清除。

func (*Version) BumpPatch

func (x *Version) BumpPatch() *Version

BumpPatch 返回一个修订版本号递增的新版本对象

例如 1.2.3 → 1.2.4,后缀被清除。

func (*Version) Canonical

func (x *Version) Canonical() string

Canonical 返回版本的规范字符串表示

规范格式为:[前缀]主版本号.次版本号.修订版本号[-后缀][+元数据] 始终输出三段版本号,不足的补零。

返回:

  • string: 规范化的版本字符串

使用示例:

v := versions.NewVersion("1.2")
fmt.Println(v.Canonical()) // "1.2.0"

v2 := versions.NewVersion("v1.2.3-beta+build.1")
fmt.Println(v2.Canonical()) // "v1.2.3-beta+build.1"

func (*Version) Clone

func (x *Version) Clone() *Version

Clone 创建版本的深拷贝

返回一个与原版本完全相同的新 Version 对象,修改拷贝不会影响原版本。 对于不可变的 Version 对象,Clone 主要用于与 With* 方法配合使用。

返回:

  • *Version: 版本的深拷贝

使用示例:

v1 := versions.NewVersion("1.2.3")
v2 := v1.Clone()
v2.Raw = "modified"
fmt.Println(v1.Raw) // 仍然是 "1.2.3"

func (*Version) CompareTo

func (x *Version) CompareTo(target *Version) int

CompareTo 比较两个版本号

该方法按以下顺序比较两个版本号: 1. 首先比较主版本号数字部分 2. 其次比较发布时间 3. 然后比较后缀 4. 最后比较原始版本号字符串

参数:

  • target: 要比较的目标版本对象

返回:

  • int: 如果当前版本小于目标版本,返回-1;如果相等,返回0;如果大于,返回1

使用示例:

v1 := versions.NewVersion("1.0.0")
v2 := versions.NewVersion("1.1.0")

switch v1.CompareTo(v2) {
case -1:
    fmt.Println("v1 < v2")
case 0:
    fmt.Println("v1 = v2")
case 1:
    fmt.Println("v1 > v2")
}

func (*Version) Core

func (x *Version) Core() *Version

Core 返回版本的核心部分(去除后缀)

返回一个新 Version 对象,只保留前缀和版本号数字部分,去除所有后缀。 这是获取版本"纯净"数字部分的快捷方式。

返回:

  • *Version: 去除后缀后的核心版本对象

使用示例:

v := versions.NewVersion("1.2.3-beta1")
core := v.Core()
fmt.Println(core.RawString()) // 输出: "1.2.3"

func (*Version) Diff

func (x *Version) Diff(target *Version) *VersionDiff

Diff 计算两个版本之间的差异

返回一个 VersionDiff 结构体,包含各版本号段的差异。 如果目标版本为 nil,返回 nil。

参数:

  • target: 目标版本

返回:

  • *VersionDiff: 版本差异对象

使用示例:

v1 := versions.NewVersion("1.2.3")
v2 := versions.NewVersion("2.0.0")
d := v1.Diff(v2)
fmt.Printf("major diff: %d\n", d.Major) // 1

func (*Version) Equals

func (x *Version) Equals(target *Version) bool

Equals 判断当前版本是否与目标版本相等

等价于 CompareTo(target) == 0,但语义更清晰。

func (*Version) Format

func (x *Version) Format(template string) string

Format 按照模板格式化版本号

支持的占位符:

  • %M 主版本号
  • %m 次版本号
  • %p 修订版本号
  • %P 前缀
  • %s 后缀
  • %r 原始字符串
  • %c 规范字符串
  • %% 百分号

参数:

  • template: 格式化模板字符串

返回:

  • string: 格式化后的字符串

使用示例:

v := versions.NewVersion("v1.2.3-beta")
fmt.Println(v.Format("version %M.%m.%p"))       // "version 1.2.3"
fmt.Println(v.Format("prefix=%P major=%M"))      // "prefix=v major=1"

func (*Version) Hash

func (x *Version) Hash() string

Hash 返回版本的哈希键值

返回原始版本字符串,可用于 map 的键。

返回:

  • string: 可用作哈希键的字符串

func (*Version) Increment

func (x *Version) Increment(segment int) *Version

Increment 按位置递增版本号数字段

与 BumpMajor/BumpMinor/BumpPatch 不同,Increment 可以递增任意位置的版本号段, 并且将更高位置的段重置为零。

参数:

  • segment: 版本号段的位置索引(0=主版本号,1=次版本号,2=修订版本号,...)

返回:

  • *Version: 递增后的新版本对象

使用示例:

v := versions.NewVersion("1.2.3.4")
newV := v.Increment(2)  // 递增修订版本号
fmt.Println(newV.Raw)   // "1.2.4.0"

func (*Version) IsAlpha

func (x *Version) IsAlpha() bool

IsAlpha 判断版本是否为 Alpha 版

func (*Version) IsBeta

func (x *Version) IsBeta() bool

IsBeta 判断版本是否为 Beta 版

func (*Version) IsBetween

func (x *Version) IsBetween(low, high *Version) bool

IsBetween 判断当前版本是否在两个版本之间(包含边界)

如果 low <= x <= high 则返回 true。 如果 low 或 high 为 nil,则忽略对应的边界检查。

func (*Version) IsDev

func (x *Version) IsDev() bool

IsDev 判断版本是否为开发版

开发版是指后缀包含 dev 标识的版本,如 "1.0.0-dev1"。

func (*Version) IsFinal

func (x *Version) IsFinal() bool

IsFinal 判断版本是否为 Final 版本

Final 版本是指后缀包含 final 标识的版本(Maven 生态常见),如 "1.0.0-final"。 注意:Final 后缀与无后缀的正式版语义相同,但 IsFinal 专用于检测显式的 final 后缀。

func (*Version) IsGA

func (x *Version) IsGA() bool

IsGA 判断版本是否为 GA(Generally Available)版本

GA 版本是指后缀包含 ga 标识的版本,如 "1.0.0-ga"。

func (*Version) IsMilestone

func (x *Version) IsMilestone() bool

IsMilestone 判断版本是否为里程碑版

里程碑版是指后缀包含 milestone/m 标识的版本,如 "1.0.0-m1"、"1.0.0-milestone1"。

func (*Version) IsNewerThan

func (x *Version) IsNewerThan(target *Version) bool

IsNewerThan 判断当前版本是否比目标版本更新

等价于 CompareTo(target) > 0,但语义更清晰。

func (*Version) IsNightly

func (x *Version) IsNightly() bool

IsNightly 判断版本是否为夜间构建版

夜间构建版是指后缀包含 nightly 标识的版本,如 "1.0.0-nightly"。

func (*Version) IsOlderThan

func (x *Version) IsOlderThan(target *Version) bool

IsOlderThan 判断当前版本是否比目标版本更旧

等价于 CompareTo(target) < 0,但语义更清晰。

func (*Version) IsPost

func (x *Version) IsPost() bool

IsPost 判断版本是否为 Post 发布版

Post 发布版是指后缀包含 post 标识的版本(PEP 440 规范),如 "1.0.0-post1"。

func (*Version) IsPre

func (x *Version) IsPre() bool

IsPre 判断版本是否为预发布版(pre 标识)

预发布版是指后缀包含 pre 标识的版本,如 "1.0.0-pre1"。 注意:这是显式的 pre 后缀,与 IsPrerelease()(判断是否有任何后缀)不同。

func (*Version) IsPrerelease

func (x *Version) IsPrerelease() bool

IsPrerelease 判断版本是否为预发布版本

预发布版本是指带有后缀(如 -alpha, -beta, -rc, -SNAPSHOT 等)的版本。 正式版本(无后缀)返回 false。

返回:

  • bool: 如果是预发布版本则返回 true

使用示例:

v := versions.NewVersion("1.0.0-beta")
if v.IsPrerelease() {
    fmt.Println("这是预发布版本")
}

func (*Version) IsRC

func (x *Version) IsRC() bool

IsRC 判断版本是否为候选发布版(RC)

func (*Version) IsRelease

func (x *Version) IsRelease() bool

IsRelease 判断版本是否带有 release 后缀

带 release 后缀的版本如 "1.0.0-release"。 注意:这与 IsStable()(无后缀)不同,IsRelease 检测的是显式的 "-release" 后缀。

func (*Version) IsSP

func (x *Version) IsSP() bool

IsSP 判断版本是否为服务包版本

服务包版本是指后缀包含 sp 标识的版本,如 "1.0.0-sp1"。

func (*Version) IsSemver

func (x *Version) IsSemver() bool

IsSemver 判断版本字符串是否符合 SemVer 2.0.0 规范

严格的 semver 格式要求:主版本号.次版本号.修订版本号, 可选的预发布标识(以 - 分隔)和构建元数据(以 + 分隔)。 不允许前导零(如 01.02.03)。

返回:

  • bool: 如果符合 semver 规范则返回 true

使用示例:

v := versions.NewVersion("1.2.3")
fmt.Println(v.IsSemver()) // true

v2 := versions.NewVersion("1.2.3-alpha.1+build.123")
fmt.Println(v2.IsSemver()) // true

v3 := versions.NewVersion("1.2")
fmt.Println(v3.IsSemver()) // false(不够3段)

func (*Version) IsSnapshot

func (x *Version) IsSnapshot() bool

IsSnapshot 判断版本是否为快照版

func (*Version) IsStable

func (x *Version) IsStable() bool

IsStable 判断版本是否为正式稳定版本

正式稳定版本是指不带任何后缀的版本,如 "1.0.0"。

返回:

  • bool: 如果是正式稳定版本则返回 true

func (*Version) IsValid

func (v *Version) IsValid() bool

IsValid 检查版本号是否有效

判断依据是版本号中是否包含数字部分。只有当解析到了版本号数字时才认为是有效的版本号。

返回:

  • bool: 如果版本号有效则返回 true,否则返回 false

使用示例:

version := versions.NewVersion("not-a-version")
if !version.IsValid() {
    fmt.Println("无效的版本号")
}

func (*Version) IsZero

func (x *Version) IsZero() bool

IsZero 判断版本是否为零值

零值版本是未初始化的 Version{} 结构体,其所有字段都是默认值。 与 IsValid()(检查是否有版本号数字)不同,IsZero 检查是否完全没有被设置。

返回:

  • bool: 如果是零值则返回 true

func (*Version) Major

func (x *Version) Major() int

Major 返回主版本号

如果版本号数字部分为空则返回 0。

func (Version) MarshalJSON

func (x Version) MarshalJSON() ([]byte, error)

MarshalJSON 实现 json.Marshaler 接口

将版本序列化为 JSON 字符串(双引号包裹的原始版本字符串), 而非默认的结构体 JSON。这使得版本在 JSON 上下文中表现为简单字符串。

返回:

  • []byte: JSON 编码的版本字符串
  • error: 始终为 nil

func (Version) MarshalText

func (x Version) MarshalText() ([]byte, error)

MarshalText 实现 encoding.TextMarshaler 接口

将版本序列化为原始版本字符串的字节切片。 这使得 Version 可以被 encoding/json、toml、yaml 等序列化格式自动处理。

返回:

  • []byte: 原始版本字符串的字节切片
  • error: 始终为 nil

func (*Version) Matches

func (x *Version) Matches(expr string) (bool, error)

Matches 判断版本是否满足约束表达式字符串

该方法是 ParseConstraintSet + Match 的便捷组合, 适用于需要从字符串快速判断版本是否满足约束的场景。

参数:

  • expr: 约束表达式字符串,如 ">=1.0.0"

返回:

  • bool: 如果版本满足约束则返回 true
  • error: 如果约束表达式解析失败则返回错误

使用示例:

v := versions.NewVersion("1.5.0")
ok, err := v.Matches(">=1.0.0,<2.0.0")
if ok {
    fmt.Println("版本在范围内")
}

func (*Version) Minor

func (x *Version) Minor() int

Minor 返回次版本号

如果版本号数字部分少于2位则返回 0。

func (*Version) Patch

func (x *Version) Patch() int

Patch 返回修订版本号

如果版本号数字部分少于3位则返回 0。

func (*Version) PreReleaseType

func (x *Version) PreReleaseType() string

PreReleaseType 返回预发布版本的类型标识

返回后缀的语义权重类型名称字符串,如 "alpha"、"beta"、"rc" 等。 如果不是预发布版本则返回空字符串。

返回:

  • string: 预发布类型名称

使用示例:

v := versions.NewVersion("1.0.0-beta2")
fmt.Println(v.PreReleaseType()) // "beta"

s := versions.NewVersion("1.0.0")
fmt.Println(s.PreReleaseType()) // ""

func (*Version) RawString

func (x *Version) RawString() string

RawString 返回版本的原始字符串表示

与 String()(返回 JSON 格式)不同,RawString() 返回解析前的原始版本字符串, 如 "v1.2.3-beta1"。这是获取版本字符串最直接的方式。

返回:

  • string: 原始版本字符串

使用示例:

v := versions.NewVersion("v1.2.3-beta1")
fmt.Println(v.RawString()) // 输出: v1.2.3-beta1

func (*Version) Satisfies

func (x *Version) Satisfies(constraint *Constraint) bool

Satisfies 判断版本是否满足给定的约束条件

这是 Constraint.Match(v) 的反向调用方式,语义更自然: v.Satisfies(constraint) 等价于 constraint.Match(v)。

参数:

  • constraint: 版本约束条件

返回:

  • bool: 如果版本满足约束则返回 true

使用示例:

c, _ := versions.ParseConstraint(">=1.0.0")
v := versions.NewVersion("1.5.0")
if v.Satisfies(c) {
    fmt.Println("版本满足约束")
}

func (*Version) Scan

func (x *Version) Scan(src interface{}) error

Scan 实现 sql.Scanner 接口

从数据库扫描版本值。支持 string 和 []byte 类型。

参数:

  • src: 数据库值

返回:

  • error: 如果值类型不支持或版本无效则返回错误

func (*Version) Segments

func (x *Version) Segments() []int

Segments 返回版本号数字段的整数数组

等价于直接访问 VersionNumbers,但返回 []int 类型, 便于与不使用 VersionNumbers 类型的代码交互。

返回:

  • []int: 版本号数字段数组

使用示例:

v := versions.NewVersion("1.2.3.4")
segments := v.Segments()
// segments == []int{1, 2, 3, 4}

func (*Version) Segments64

func (x *Version) Segments64() []int64

Segments64 返回版本号数字段的 int64 数组

与 Segments() 相同,但返回 int64 类型, 适用于需要大数值范围的场景。

返回:

  • []int64: 版本号数字段 int64 数组

func (*Version) String

func (x *Version) String() string

String 返回版本的JSON字符串表示

该方法将Version对象序列化为JSON字符串,便于打印和调试。

返回:

  • string: 版本的JSON字符串表示

使用示例:

version := versions.NewVersion("1.2.3")
fmt.Println(version.String()) // 输出JSON格式的版本信息

func (*Version) SubVersion

func (x *Version) SubVersion() int

SubVersion 返回后缀中的子版本号

例如 "-beta2" 返回 2,"-rc1" 返回 1。如果后缀中没有数字则返回 0。 该方法将内部使用的 extractSubVersion 函数暴露为公开 API。

返回:

  • int: 后缀中的子版本号数字

使用示例:

v := versions.NewVersion("1.0.0-beta2")
fmt.Println(v.SubVersion()) // 输出: 2

func (*Version) SuffixWeight

func (x *Version) SuffixWeight() SuffixWeight

SuffixWeight 返回版本后缀的语义权重

等价于 GetSuffixWeight(string(x.Suffix)),但作为方法调用更方便。

返回:

  • SuffixWeight: 后缀的语义权重值

使用示例:

v := versions.NewVersion("1.0.0-beta")
w := v.SuffixWeight()
fmt.Println(w == versions.SuffixWeightBeta) // true

func (*Version) UnmarshalJSON

func (x *Version) UnmarshalJSON(data []byte) error

UnmarshalJSON 实现 json.Unmarshaler 接口

从 JSON 字符串反序列化版本对象。

参数:

  • data: JSON 编码的版本字符串

返回:

  • error: 如果版本无效则返回错误

func (*Version) UnmarshalText

func (x *Version) UnmarshalText(text []byte) error

UnmarshalText 实现 encoding.TextUnmarshaler 接口

从字节切片反序列化版本对象。解析给定的版本字符串, 如果版本无效则返回 ErrVersionInvalid。

参数:

  • text: 版本字符串的字节切片

返回:

  • error: 如果版本无效则返回 ErrVersionInvalid

func (*Version) Validate

func (x *Version) Validate() error

Validate 严格校验版本号格式

与 IsValid()(仅检查是否有版本号数字)不同,Validate 执行更严格的校验: 1. 版本号数字部分不能为空 2. 每个版本号数字必须 >= 0

返回:

  • error: 如果版本号不符合严格格式要求则返回错误

func (*Version) ValidateSemver

func (x *Version) ValidateSemver() error

ValidateSemver 按照 SemVer 2.0.0 规范严格校验版本号

与 Validate()(仅做基本校验)不同,ValidateSemver 要求: 1. 必须是三段版本号(major.minor.patch) 2. 每段数字不允许前导零 3. 预发布标识和构建元数据必须符合规范字符集

返回:

  • error: 如果不符合 semver 规范则返回错误

使用示例:

v := versions.NewVersion("1.2.3")
if err := v.ValidateSemver(); err != nil {
    fmt.Println("不符合 semver 规范:", err)
}

func (Version) Value

func (x Version) Value() (driver.Value, error)

Value 实现 driver.Valuer 接口

返回版本字符串用于数据库存储。

返回:

  • driver.Value: 版本原始字符串
  • error: 始终为 nil

func (*Version) WithMajor

func (x *Version) WithMajor(major int) *Version

WithMajor 返回一个修改主版本号的新版本对象

原版本对象不变,返回一个新对象,其主版本号被替换为指定值。 后缀和前缀保持不变。

参数:

  • major: 新的主版本号

返回:

  • *Version: 修改主版本号后的新版本对象

func (*Version) WithMetadata

func (x *Version) WithMetadata(metadata string) *Version

WithMetadata 返回一个修改构建元数据的新版本对象

原版本对象不变,返回一个新对象,其 Metadata 字段被替换为指定值。

参数:

  • metadata: 新的构建元数据字符串,如 "build123"

返回:

  • *Version: 修改元数据后的新版本对象

使用示例:

v := versions.NewVersion("1.2.3")
newV := v.WithMetadata("build.123")
fmt.Println(newV.Metadata) // "build.123"

func (*Version) WithMinor

func (x *Version) WithMinor(minor int) *Version

WithMinor 返回一个修改次版本号的新版本对象

原版本对象不变,返回一个新对象,其次版本号被替换为指定值。 前缀和后缀保持不变。

参数:

  • minor: 新的次版本号

返回:

  • *Version: 修改次版本号后的新版本对象

func (*Version) WithNumbers

func (x *Version) WithNumbers(numbers []int) *Version

WithNumbers 返回一个修改版本号数字部分的新版本对象

原版本对象不变,返回一个新对象,其版本号数字部分被替换为指定值。 前缀和后缀保持不变。

参数:

  • numbers: 新的版本号数字部分

返回:

  • *Version: 修改版本号后的新版本对象

使用示例:

v := versions.NewVersion("1.2.3")
newV := v.WithNumbers([]int{2, 0, 0})
// newV.Raw == "2.0.0"

func (*Version) WithPatch

func (x *Version) WithPatch(patch int) *Version

WithPatch 返回一个修改修订版本号的新版本对象

原版本对象不变,返回一个新对象,其修订版本号被替换为指定值。 前缀和后缀保持不变。

参数:

  • patch: 新的修订版本号

返回:

  • *Version: 修改修订版本号后的新版本对象

func (*Version) WithPrefix

func (x *Version) WithPrefix(prefix string) *Version

WithPrefix 返回一个修改前缀的新版本对象

原版本对象不变,返回一个新对象,其前缀被替换为指定值。

参数:

  • prefix: 新的前缀字符串

返回:

  • *Version: 修改前缀后的新版本对象

使用示例:

v := versions.NewVersion("1.2.3")
newV := v.WithPrefix("v")
// newV.Raw == "v1.2.3"

func (*Version) WithPublicTime

func (x *Version) WithPublicTime(t time.Time) *Version

WithPublicTime 返回一个修改发布时间的新版本对象

原版本对象不变,返回一个新对象,其发布时间被替换为指定值。

参数:

  • t: 新的发布时间

返回:

  • *Version: 修改发布时间后的新版本对象

func (*Version) WithSuffix

func (x *Version) WithSuffix(suffix string) *Version

WithSuffix 返回一个修改后缀的新版本对象

原版本对象不变,返回一个新对象,其后缀被替换为指定值。

参数:

  • suffix: 新的后缀字符串,如 "-beta1"

返回:

  • *Version: 修改后缀后的新版本对象

使用示例:

v := versions.NewVersion("1.2.3")
newV := v.WithSuffix("-rc1")
// newV.Raw == "1.2.3-rc1"

type VersionBuilder

type VersionBuilder struct {
	// contains filtered or unexported fields
}

VersionBuilder 提供流式 API 构建版本对象

VersionBuilder 允许通过方法链的方式逐步构建版本对象, 适用于需要程序化生成版本号的场景。

使用示例:

v := versions.NewVersionBuilder().
    Prefix("v").
    Major(1).
    Minor(2).
    Patch(3).
    Suffix("-beta1").
    Build()
// v.Raw == "v1.2.3-beta1"

func NewVersionBuilder

func NewVersionBuilder() *VersionBuilder

NewVersionBuilder 创建一个新的版本构建器

func (*VersionBuilder) Build

func (b *VersionBuilder) Build() *Version

Build 构建并返回版本对象

func (*VersionBuilder) Major

func (b *VersionBuilder) Major(major int) *VersionBuilder

Major 设置主版本号

func (*VersionBuilder) Metadata

func (b *VersionBuilder) Metadata(metadata string) *VersionBuilder

Metadata 设置构建元数据

func (*VersionBuilder) Minor

func (b *VersionBuilder) Minor(minor int) *VersionBuilder

Minor 设置次版本号

func (*VersionBuilder) Numbers

func (b *VersionBuilder) Numbers(numbers []int) *VersionBuilder

Numbers 设置版本号数字部分

func (*VersionBuilder) Patch

func (b *VersionBuilder) Patch(patch int) *VersionBuilder

Patch 设置修订版本号

func (*VersionBuilder) Prefix

func (b *VersionBuilder) Prefix(prefix string) *VersionBuilder

Prefix 设置版本前缀

func (*VersionBuilder) PublicTime

func (b *VersionBuilder) PublicTime(t time.Time) *VersionBuilder

PublicTime 设置版本发布时间

func (*VersionBuilder) Suffix

func (b *VersionBuilder) Suffix(suffix string) *VersionBuilder

Suffix 设置版本后缀

type VersionDiff

type VersionDiff struct {
	// Major 主版本号差值(target - source)
	Major int

	// Minor 次版本号差值(target - source)
	Minor int

	// Patch 修订版本号差值(target - source)
	Patch int

	// RawFrom 源版本原始字符串
	RawFrom string

	// RawTo 目标版本原始字符串
	RawTo string
}

VersionDiff 表示两个版本之间的差异

VersionDiff 包含各版本号段的差值,以及原始版本字符串。

func (*VersionDiff) IsDowngrade

func (d *VersionDiff) IsDowngrade() bool

IsDowngrade 判断差异是否为降级(主、次或修订版本号至少有一项减少)

func (*VersionDiff) IsMajorChange

func (d *VersionDiff) IsMajorChange() bool

IsMajorChange 判断差异是否涉及主版本号变化

func (*VersionDiff) IsMinorChange

func (d *VersionDiff) IsMinorChange() bool

IsMinorChange 判断差异是否仅涉及次版本号变化(主版本号不变)

func (*VersionDiff) IsPatchChange

func (d *VersionDiff) IsPatchChange() bool

IsPatchChange 判断差异是否仅涉及修订版本号变化(主、次版本号不变)

func (*VersionDiff) IsUpgrade

func (d *VersionDiff) IsUpgrade() bool

IsUpgrade 判断差异是否为升级(主、次或修订版本号至少有一项增加)

func (*VersionDiff) String

func (d *VersionDiff) String() string

String 返回差异的字符串表示

type VersionGroup

type VersionGroup struct {

	// GroupVersionNumbers 组的版本号中的数字部分
	// 例如对于版本号 "1.2.x",GroupVersionNumbers 为 [1,2]
	GroupVersionNumbers VersionNumbers

	// VersionMap 组中包含的所有版本,键为版本的原始字符串,值为版本对象
	VersionMap map[string]*Version
}

VersionGroup 表示一个版本组,一个版本组中可能有一个或多个版本

VersionGroup 用于管理具有相同主版本号数字部分的一组版本。它提供了版本的添加、查询、排序和范围查询等功能。 版本组是版本管理系统中的重要概念,用于将相似版本聚合在一起,便于进行版本管理和分析。

每个版本组都有一个唯一的ID,由其主版本号数字部分生成,如 "1.2"。

使用示例:

// 创建一个新的版本组
group := versions.NewVersionGroup(versions.NewVersionNumbers([]int{1, 2}))

// 添加版本到组中
v1 := versions.NewVersion("1.2.0")
v2 := versions.NewVersion("1.2.1")
group.Add(v1)
group.Add(v2)

// 获取组中的所有版本
allVersions := group.Versions()

// 获取排序后的版本
sortedVersions := group.SortVersions()

func NewVersionGroup

func NewVersionGroup(groupVersionNumbers VersionNumbers) *VersionGroup

NewVersionGroup 创建一个新的版本组

该方法根据指定的版本号数字部分创建一个新的版本组。创建时需要传递能够在包范围下唯一区分组的组ID, 这个ID选择的是版本中的数字部分。

参数:

  • groupVersionNumbers: 版本组的数字部分,如 [1,2] 表示 "1.2" 版本组

返回:

  • *VersionGroup: 新创建的版本组对象

使用示例:

// 创建表示 "1.2" 版本组的对象
group := versions.NewVersionGroup(versions.NewVersionNumbers([]int{1, 2}))

func NewVersionGroupFromVersions

func NewVersionGroupFromVersions(versions []*Version) *VersionGroup

NewVersionGroupFromVersions 从版本数组创建一个版本组

该方法基于给定的版本数组创建一个版本组。所有版本将被添加到同一个组中, 该组的数字部分取自第一个版本的数字部分。

参数:

  • versions: 要添加到组中的版本数组

返回:

  • *VersionGroup: 新创建的包含所有指定版本的版本组,如果输入为空则返回 nil

使用示例:

versions := versions.NewVersions("1.2.0", "1.2.1", "1.2.2")
group := versions.NewVersionGroupFromVersions(versions)

func SortVersionGroupMap

func SortVersionGroupMap(versionGroupMap map[string]*VersionGroup) []*VersionGroup

SortVersionGroupMap 对版本组映射进行排序

该函数将版本组映射转换为切片,并对切片中的版本组进行排序。

参数:

  • versionGroupMap: 版本组映射,键为版本组ID,值为版本组对象

返回:

  • []*VersionGroup: 排序后的版本组切片

使用示例:

groupMap := Group(versions)
sortedGroups := SortVersionGroupMap(groupMap)
for _, group := range sortedGroups {
    fmt.Printf("组: %s, 版本数: %d\n", group.GroupID, len(group.Versions))
}

func (*VersionGroup) Add

func (x *VersionGroup) Add(v *Version) bool

Add 把给定的版本添加到本版本组中

该方法将指定的版本添加到版本组中。如果版本已存在,则会被覆盖。

参数:

  • v: 要添加的版本对象

返回:

  • bool: 如果版本之前已存在于组中则返回 true,否则返回 false

使用示例:

group := versions.NewVersionGroup(versions.NewVersionNumbers([]int{1, 2}))
version := versions.NewVersion("1.2.3")
exists := group.Add(version)
if !exists {
    fmt.Println("添加了新版本")
}

func (*VersionGroup) CompareTo

func (x *VersionGroup) CompareTo(target *VersionGroup) int

CompareTo 比较两个版本组的大小

该方法通过比较版本组的数字部分来确定两个版本组的先后顺序。

参数:

  • target: 要比较的目标版本组

返回:

  • int: 如果当前版本组小于目标版本组,返回负数;如果相等,返回0;如果大于,返回正数

使用示例:

group1 := versions.NewVersionGroup(versions.NewVersionNumbers([]int{1, 2}))
group2 := versions.NewVersionGroup(versions.NewVersionNumbers([]int{1, 3}))

if group1.CompareTo(group2) < 0 {
    fmt.Println("group1 比 group2 旧")
}

func (*VersionGroup) Contains

func (x *VersionGroup) Contains(v *Version) bool

Contains 判断本版本组中是否包含给定的版本

该方法检查指定的版本是否已存在于版本组中。

参数:

  • v: 要检查的版本对象

返回:

  • bool: 如果版本存在于组中则返回 true,否则返回 false

使用示例:

group := versions.NewVersionGroup(versions.NewVersionNumbers([]int{1, 2}))
version := versions.NewVersion("1.2.3")
if !group.Contains(version) {
    group.Add(version)
}

func (*VersionGroup) Count

func (x *VersionGroup) Count() int

Count 返回版本组中的版本数量

func (*VersionGroup) Filter

func (x *VersionGroup) Filter(predicate func(*Version) bool) []*Version

Filter 根据谓词函数过滤组内版本

返回组内所有满足谓词条件的版本。

参数:

  • predicate: 过滤谓词函数

返回:

  • []*Version: 满足条件的版本列表

func (*VersionGroup) GetLatest

func (x *VersionGroup) GetLatest() *Version

GetLatest 获取版本组中最新的版本

返回按排序后最新的版本,如果组为空则返回 nil。

func (*VersionGroup) GetOldest

func (x *VersionGroup) GetOldest() *Version

GetOldest 获取版本组中最旧的版本

返回按排序后最旧的版本,如果组为空则返回 nil。

func (*VersionGroup) ID

func (x *VersionGroup) ID() string

ID 返回组的ID

该方法返回版本组的唯一标识符,由其数字部分生成。

返回:

  • string: 版本组的ID,例如 "1.2"

使用示例:

group := versions.NewVersionGroup(versions.NewVersionNumbers([]int{1, 2}))
groupID := group.ID() // 返回 "1.2"

func (*VersionGroup) LatestPrerelease

func (x *VersionGroup) LatestPrerelease() *Version

LatestPrerelease 获取版本组中最新预发布版本

返回按排序后最新的预发布版本,如果组中无预发布版本则返回 nil。

func (*VersionGroup) LatestStable

func (x *VersionGroup) LatestStable() *Version

LatestStable 获取版本组中最新稳定版本

func (*VersionGroup) PrereleaseVersions

func (x *VersionGroup) PrereleaseVersions() []*Version

PrereleaseVersions 返回版本组中所有预发布版本

func (*VersionGroup) QueryRangeVersions

func (x *VersionGroup) QueryRangeVersions(start, end *tuple.Tuple2[*Version, ContainsPolicy]) []*Version

QueryRangeVersions 获取组内指定区间内的版本

该方法根据给定的起始和结束版本范围,返回组内符合条件的版本数组。 版本的包含性由 ContainsPolicy 参数控制。

参数:

  • start: 包含起始版本和包含策略的元组
  • end: 包含结束版本和包含策略的元组

返回:

  • []*Version: 符合区间条件的版本数组

使用示例:

group := versions.NewVersionGroupFromVersions(versions.NewVersions("1.2.0", "1.2.1", "1.2.2", "1.2.3"))

// 查询 1.2.0(包含)到 1.2.2(包含)的版本
startTuple := tuple.NewTuple2(versions.NewVersion("1.2.0"), versions.ContainsPolicyYes)
endTuple := tuple.NewTuple2(versions.NewVersion("1.2.2"), versions.ContainsPolicyYes)

rangeVersions := group.QueryRangeVersions(startTuple, endTuple)
// 结果包含: ["1.2.0", "1.2.1", "1.2.2"]

func (*VersionGroup) Remove

func (x *VersionGroup) Remove(v *Version) bool

Remove 从版本组中移除指定的版本

如果版本存在于组中,则删除并返回 true;否则返回 false。

参数:

  • v: 要移除的版本对象

返回:

  • bool: 如果版本存在并被移除则返回 true

func (*VersionGroup) SortVersions

func (x *VersionGroup) SortVersions() []*Version

SortVersions 对组下的所有版本进行排序返回

该方法返回版本组中所有版本的有序数组,排序遵循版本号的自然排序规则。

返回:

  • []*Version: 排序后的版本数组

使用示例:

group := versions.NewVersionGroupFromVersions(versions.NewVersions("1.2.2", "1.2.0", "1.2.1"))
sortedVersions := group.SortVersions()
// 结果顺序: ["1.2.0", "1.2.1", "1.2.2"]

func (*VersionGroup) StableVersions

func (x *VersionGroup) StableVersions() []*Version

StableVersions 返回版本组中所有稳定版本

func (*VersionGroup) String

func (x *VersionGroup) String() string

String 返回版本组的字符串表示

实现 fmt.Stringer 接口。 格式为 "组ID (版本数)",如 "1.2 (5个版本)"。

返回:

  • string: 版本组的字符串表示

func (*VersionGroup) Versions

func (x *VersionGroup) Versions() []*Version

Versions 返回组下的所有版本

该方法返回版本组中包含的所有版本的数组,结果不保证有序。

返回:

  • []*Version: 版本组中所有版本的数组

使用示例:

group := versions.NewVersionGroupFromVersions(versions.NewVersions("1.2.0", "1.2.1"))
allVersions := group.Versions()
fmt.Printf("组中包含 %d 个版本\n", len(allVersions))

type VersionNumbers

type VersionNumbers []int

VersionNumbers 表示版本号中的数字部分

VersionNumbers 是一个整数切片类型,用于表示和操作版本号的数字部分。 例如对于版本号 "v1.2.3-beta1",其 VersionNumbers 为 [1,2,3]。 它实现了 Comparable 接口,支持版本号数字部分的比较操作。

使用示例:

// 创建一个版本号数字部分
numbers := versions.NewVersionNumbers([]int{1, 2, 3})

// 获取版本组ID
groupID := numbers.BuildGroupID() // 返回 "1.2.3"

// 比较两个版本号数字部分
other := versions.NewVersionNumbers([]int{1, 3, 0})
if numbers.CompareTo(other) < 0 {
    fmt.Println("1.2.3 比 1.3.0 旧")
}

func NewVersionNumbers

func NewVersionNumbers(versionNumbers []int) VersionNumbers

NewVersionNumbers 创建一个新的 VersionNumbers 对象

该方法将整数切片转换为 VersionNumbers 类型,便于进行版本号相关操作。

参数:

  • versionNumbers: 表示版本号的整数切片,如 [1,2,3] 表示版本号 "1.2.3"

返回:

  • VersionNumbers: 一个新的 VersionNumbers 对象

使用示例:

numbers := versions.NewVersionNumbers([]int{1, 2, 3})

func (VersionNumbers) At

func (x VersionNumbers) At(index int) int

At 返回指定索引位置的版本号数字

如果索引越界则返回 0。

参数:

  • index: 从 0 开始的索引

返回:

  • int: 对应位置的版本号数字,越界返回 0

func (VersionNumbers) BuildGroupID

func (x VersionNumbers) BuildGroupID() string

BuildGroupID 根据版本号数字部分构造版本组的ID

该方法将版本号数字部分以默认分隔符(".")连接成字符串,用于表示版本组ID。 版本组ID可用于对相同主版本号的版本进行分组和管理。

返回:

  • string: 版本组ID字符串,例如 "1.2.3"

使用示例:

numbers := versions.NewVersionNumbers([]int{1, 2, 3})
groupID := numbers.BuildGroupID() // 返回 "1.2.3"

// 可用于版本分组
versionGroups := make(map[string][]*Version)
for _, version := range allVersions {
    groupID := version.VersionNumbers.BuildGroupID()
    versionGroups[groupID] = append(versionGroups[groupID], version)
}

func (VersionNumbers) CompareTo

func (x VersionNumbers) CompareTo(target []int) int

CompareTo 比较两个版本号数字部分的大小

该方法按照版本号比较规则,从左到右逐位比较两个版本号数字部分的大小。 对于不同长度的版本号,首先比较共有部分,如果共有部分相等,则较长的版本号更大。

参数:

  • target: 要比较的目标版本号数字部分

返回:

  • int: 如果当前版本小于目标版本,返回负数;如果相等,返回0;如果大于,返回正数

使用示例:

v1 := versions.NewVersionNumbers([]int{1, 0, 0})
v2 := versions.NewVersionNumbers([]int{1, 1, 0})

result := v1.CompareTo(v2)
if result < 0 {
    fmt.Println("v1 比 v2 旧")
} else if result > 0 {
    fmt.Println("v1 比 v2 新")
} else {
    fmt.Println("v1 和 v2 相等")
}

func (VersionNumbers) Equals

func (x VersionNumbers) Equals(target VersionNumbers) bool

Equals 判断两个版本号数字部分是否相等

参数:

  • target: 目标版本号数字部分

返回:

  • bool: 如果完全相等则返回 true

func (VersionNumbers) Len

func (x VersionNumbers) Len() int

Len 返回版本号数字部分的长度

func (VersionNumbers) String

func (x VersionNumbers) String() string

String 返回版本号数字部分的字符串表示

等价于 BuildGroupID(),提供更符合 Go 惯例的 String() 方法。

返回:

  • string: 如 "1.2.3"

type VersionPrefix

type VersionPrefix string

VersionPrefix 表示版本中数字部分之前的部分

VersionPrefix 是一个字符串类型,用于表示和操作版本号的前缀部分。 在版本号格式中,前缀是位于数字部分之前的字符串,如 "v1.2.3" 中的 "v"。 前缀可以为空,表示版本号直接以数字部分开始,如 "1.2.3"。

使用示例:

// 检查前缀是否为空
prefix := versions.VersionPrefix("v")
if !prefix.IsEmpty() {
    fmt.Printf("版本前缀: %s\n", prefix)
}

// 在解析版本号时处理前缀
version := versions.NewVersion("v1.2.3")
fmt.Printf("版本 %s 的前缀是: %s\n", version.Raw, version.Prefix)
const EmptyVersionPrefix VersionPrefix = ""

EmptyVersionPrefix 表示一个空的前缀

该常量用于表示版本号没有前缀的情况,如纯数字版本号 "1.2.3"。 它也用于检查版本前缀是否为空。

func (VersionPrefix) IsEmpty

func (x VersionPrefix) IsEmpty() bool

IsEmpty 返回前缀是否为空

该方法检查版本前缀是否为空,即是否等于 EmptyVersionPrefix。

返回:

  • bool: 如果前缀为空则返回 true,否则返回 false

使用示例:

version := versions.NewVersion("1.2.3") // 没有前缀
if version.Prefix.IsEmpty() {
    fmt.Println("版本没有前缀")
}

version2 := versions.NewVersion("v1.2.3") // 有前缀
if !version2.Prefix.IsEmpty() {
    fmt.Printf("版本前缀是: %s\n", version2.Prefix)
}

func (VersionPrefix) PurePrefix

func (x VersionPrefix) PurePrefix() string

PurePrefix 返回去除分隔符后的纯净前缀

纯净前缀是去除了末尾分隔符(如 "-"、"."、"_")的前缀部分。 例如 "curl-" 的纯净前缀为 "curl","v" 的纯净前缀仍为 "v"。

返回:

  • string: 去除末尾分隔符后的前缀

func (VersionPrefix) String

func (x VersionPrefix) String() string

String 返回前缀的字符串表示

实现 fmt.Stringer 接口。

返回:

  • string: 前缀字符串,如 "v"

type VersionRange

type VersionRange struct {
	// Low 下界版本
	Low *Version

	// High 上界版本
	High *Version

	// LowInclusive 下界是否为闭区间(包含下界)
	LowInclusive bool

	// HighInclusive 上界是否为闭区间(包含上界)
	HighInclusive bool
}

VersionRange 表示一个版本范围

VersionRange 是一个包含下界和上界的版本区间,支持开区间和闭区间。 它可以用于判断版本是否落在某个范围内,以及过滤版本列表。

使用示例:

low := versions.NewVersion("1.0.0")
high := versions.NewVersion("2.0.0")
r := versions.NewVersionRange(low, high, true, true)
v := versions.NewVersion("1.5.0")
if r.Contains(v) {
    fmt.Println("1.5.0 in [1.0.0, 2.0.0]")
}

func NewClosedRange

func NewClosedRange(low, high *Version) *VersionRange

NewClosedRange 创建一个闭区间版本范围 [low, high]

使用示例:

r := versions.NewClosedRange(versions.NewVersion("1.0.0"), versions.NewVersion("2.0.0"))

func NewOpenRange

func NewOpenRange(low, high *Version) *VersionRange

NewOpenRange 创建一个开区间版本范围 (low, high)

使用示例:

r := versions.NewOpenRange(versions.NewVersion("1.0.0"), versions.NewVersion("2.0.0"))

func NewVersionRange

func NewVersionRange(low, high *Version, lowInclusive, highInclusive bool) *VersionRange

NewVersionRange 创建一个新的版本范围

参数:

  • low: 下界版本,nil 表示无下界
  • high: 上界版本,nil 表示无上界
  • lowInclusive: 下界是否为闭区间
  • highInclusive: 上界是否为闭区间

返回:

  • *VersionRange: 新的版本范围对象

使用示例:

r := versions.NewVersionRange(
    versions.NewVersion("1.0.0"),
    versions.NewVersion("2.0.0"),
    true,  // [1.0.0
    false, // 2.0.0)
)

func (*VersionRange) Contains

func (r *VersionRange) Contains(v *Version) bool

Contains 判断版本是否在当前范围内

参数:

  • v: 要检查的版本对象

返回:

  • bool: 如果版本在范围内则返回 true

使用示例:

r := versions.NewClosedRange(versions.NewVersion("1.0.0"), versions.NewVersion("2.0.0"))
v := versions.NewVersion("1.5.0")
fmt.Println(r.Contains(v)) // true

func (*VersionRange) Filter

func (r *VersionRange) Filter(versions []*Version) []*Version

Filter 过滤版本列表,只保留在范围内的版本

参数:

  • versions: 版本对象列表

返回:

  • []*Version: 范围内的版本列表

func (*VersionRange) IsEmpty

func (r *VersionRange) IsEmpty() bool

IsEmpty 判断范围是否为空(下界大于上界)

返回:

  • bool: 如果范围为空则返回 true

func (*VersionRange) String

func (r *VersionRange) String() string

String 返回版本范围的字符串表示

闭区间使用 [],开区间使用 ()。

返回:

  • string: 如 "[1.0.0, 2.0.0]"、"(1.0.0, 2.0.0)"等

type VersionSlice

type VersionSlice []*Version

VersionSlice 是 []*Version 的有序集合类型,实现了 sort.Interface

VersionSlice 提供了 Go 标准库 sort.Sort() 的直接支持, 允许使用 sort.Sort(slice) 而不是 sort.Slice() 配合闭包。

使用示例:

slice := versions.VersionSlice(versions.NewVersions("2.0.0", "1.0.0", "1.5.0"))
sort.Sort(slice)
// slice 现在按版本号排序

func (VersionSlice) Contains

func (s VersionSlice) Contains(target *Version) bool

Contains 判断切片中是否包含指定版本

根据 Raw 字段判断版本是否相同。

func (VersionSlice) Filter

func (s VersionSlice) Filter(predicate func(*Version) bool) VersionSlice

Filter 根据谓词函数过滤版本切片

返回所有满足谓词条件的版本。

func (VersionSlice) IndexOf

func (s VersionSlice) IndexOf(target *Version) int

IndexOf 查找版本在切片中的位置

如果未找到则返回 -1。

func (VersionSlice) Len

func (s VersionSlice) Len() int

Len 实现 sort.Interface

func (VersionSlice) Less

func (s VersionSlice) Less(i, j int) bool

Less 实现 sort.Interface

func (VersionSlice) Max

func (s VersionSlice) Max() *Version

Max 返回切片中最大的版本

如果切片为空则返回 nil。

func (VersionSlice) Min

func (s VersionSlice) Min() *Version

Min 返回切片中最小的版本

如果切片为空则返回 nil。

func (VersionSlice) Sort

func (s VersionSlice) Sort()

Sort 对切片进行原地排序

func (VersionSlice) Sorted

func (s VersionSlice) Sorted() VersionSlice

Sorted 返回排序后的新切片

func (VersionSlice) Swap

func (s VersionSlice) Swap(i, j int)

Swap 实现 sort.Interface

func (VersionSlice) Unique

func (s VersionSlice) Unique() VersionSlice

Unique 去除切片中的重复版本

type VersionStringParser

type VersionStringParser struct {
	// contains filtered or unexported fields
}

VersionStringParser 把版本从字符串形式解析为struct

VersionStringParser 负责将版本号字符串解析为结构化的 Version 对象。 它实现了版本号字符串的词法分析,将字符串划分为前缀、数字部分和后缀三个组成部分。

解析过程: 1. 首先识别和提取版本号的前缀部分(如 "v") 2. 然后识别和提取版本号的数字部分(如 "1.2.3") 3. 最后识别和提取版本号的后缀部分(如 "-beta1")

使用示例:

// 创建一个版本解析器
parser := versions.NewVersionStringParser("v1.2.3-beta1")

// 解析版本字符串
version := parser.Parse()

// 使用解析结果
fmt.Printf("前缀: %s\n", version.Prefix)
fmt.Printf("数字部分: %v\n", version.VersionNumbers)
fmt.Printf("后缀: %s\n", version.Suffix)

func NewVersionStringParser

func NewVersionStringParser(versionStr string) *VersionStringParser

NewVersionStringParser 创建一个版本号Parser

该方法创建一个新的版本号解析器实例。每次解析都需要重新创建新的Parser, 因为解析状态保存在Parser对象中。

参数:

  • versionStr: 要解析的版本号字符串

返回:

  • *VersionStringParser: 新创建的版本号解析器

使用示例:

parser := versions.NewVersionStringParser("v1.2.3-rc1")
version := parser.Parse()

func NewVersionStringParserWithOptions

func NewVersionStringParserWithOptions(versionStr string, option ParserOption) *VersionStringParser

NewVersionStringParserWithOptions 创建带选项的版本号解析器

func (*VersionStringParser) IsDigit

func (x *VersionStringParser) IsDigit(c rune) bool

IsDigit 判断是否是数字

该方法检查给定的字符是否为数字字符(0-9)。

参数:

  • c: 要检查的字符

返回:

  • bool: 如果是数字则返回 true,否则返回 false

func (*VersionStringParser) IsVersionNumberDelimiter

func (x *VersionStringParser) IsVersionNumberDelimiter(c rune) bool

IsVersionNumberDelimiter 判断是否是版本数字的分隔符

该方法检查给定的字符是否为版本号数字部分的分隔符(目前仅支持点号)。

参数:

  • c: 要检查的字符

返回:

  • bool: 如果是分隔符则返回 true,否则返回 false

func (*VersionStringParser) Parse

func (x *VersionStringParser) Parse() *Version

Parse 解析版本号字符串

该方法按照预定义的规则解析版本号字符串,提取前缀、数字部分和后缀, 并构造一个完整的 Version 对象返回。

返回:

  • *Version: 解析后的版本对象

使用示例:

parser := versions.NewVersionStringParser("v1.2.3-beta1")
version := parser.Parse()
fmt.Printf("版本号: %s\n", version.Raw)

type VersionSuffix

type VersionSuffix string

VersionSuffix 表示版本号的后缀,版本号中数字后面的部分

VersionSuffix 是一个字符串类型,用于表示和操作版本号的后缀部分。 在版本号格式中,后缀是位于数字部分之后的字符串,如 "1.2.3-beta1" 中的 "-beta1"。 后缀通常用于表示预发布版本、构建元数据或其他版本标识信息。

后缀可以为空,表示版本号仅包含数字部分,如 "1.2.3"。

使用示例:

// 检查后缀是否为空
suffix := versions.VersionSuffix("-beta1")
if !suffix.IsEmpty() {
    fmt.Printf("版本后缀: %s\n", suffix)
}

// 比较后缀的优先级
suffix1 := versions.VersionSuffix("-alpha")
suffix2 := versions.VersionSuffix("-beta")
if suffix1.CompareTo(suffix2) < 0 {
    fmt.Println("alpha 后缀的优先级低于 beta 后缀")
}
const EmptyVersionSuffix VersionSuffix = ""

EmptyVersionSuffix 空的后缀

该常量用于表示版本号没有后缀的情况,如纯数字版本号 "1.2.3"。 它也用于检查版本后缀是否为空。

func (VersionSuffix) CompareTo

func (x VersionSuffix) CompareTo(target VersionSuffix) int

func (VersionSuffix) IsEmpty

func (x VersionSuffix) IsEmpty() bool

IsEmpty 判断版本后缀是否为空

该方法检查版本后缀是否为空,即是否等于 EmptyVersionSuffix。

返回:

  • bool: 如果后缀为空则返回 true,否则返回 false

使用示例:

version := versions.NewVersion("1.2.3") // 没有后缀
if version.Suffix.IsEmpty() {
    fmt.Println("版本没有后缀")
}

version2 := versions.NewVersion("1.2.3-rc1") // 有后缀
if !version2.Suffix.IsEmpty() {
    fmt.Printf("版本后缀是: %s\n", version2.Suffix)
}

func (VersionSuffix) String

func (x VersionSuffix) String() string

CompareTo 比较两个版本后缀的优先级

该方法使用后缀语义权重系统比较两个版本后缀的优先级。 对于已知后缀类型(alpha、beta、rc等),按语义权重排序; 对于未知后缀,退化为字典序比较。

参数:

  • target: 要比较的目标版本后缀

返回:

  • int: 如果当前后缀优先级低于目标后缀,返回-1;如果相等,返回0;如果高于,返回1

使用示例:

suffix1 := versions.VersionSuffix("-alpha1")
suffix2 := versions.VersionSuffix("-beta1")

result := suffix1.CompareTo(suffix2)
if result < 0 {
    fmt.Println("alpha1 后缀的优先级低于 beta1 后缀")
}

String 返回后缀的字符串表示

实现 fmt.Stringer 接口。

返回:

  • string: 后缀字符串,如 "-beta1"

Directories

Path Synopsis
cmd
versions command
versions-mcp command
internal
cli
mcp

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL