Masterminds/semver

GitHub: Masterminds/semver

semver 是一个 Go 语言库,用于解析、排序和约束检查语义化版本号,帮助开发者在依赖管理和发布流程中精确处理版本逻辑。

Stars: 1422 | Forks: 166

# SemVer `semver` 包提供了在 Go 中处理[语义化版本](http://semver.org)的能力。具体来说,它提供了以下功能: * 解析语义化版本 * 排序语义化版本 * 检查语义化版本是否符合一组约束条件 * 可选地处理 `v` 前缀 [![稳定性: 活跃](https://masterminds.github.io/stability/active.svg)](https://masterminds.github.io/stability/active.html) [![](https://static.pigsec.cn/wp-content/uploads/repos/cas/09/097271ca091990be630ef6043309cc48240faa054413384202036fa2efedb2d2.svg)](https://github.com/Masterminds/semver/actions) [![GoDoc](https://img.shields.io/static/v1?label=godoc&message=reference&color=blue)](https://pkg.go.dev/github.com/Masterminds/semver/v3) [![Go Report Card](https://goreportcard.com/badge/github.com/Masterminds/semver)](https://goreportcard.com/report/github.com/Masterminds/semver) ## 包版本 请注意,导入 `github.com/Masterminds/semver/v3` 以使用最新版本。 `semver` 包有三个主要版本。 * 3.x.x 是稳定且活跃的版本。此版本专注于与其他语言工具中范围处理的约束兼容性。它的 API 与 v1 版本类似。此版本的开发在 master 分支上进行。此版本的文档如下。 * 2.x 主要是为 [dep](https://github.com/golang/dep) 开发的。没有打标签的发布版本,开发由 [@sdboyer](https://github.com/sdboyer) 完成。与 v1 存在 API 破坏性变更。此版本位于 [2.x 分支](https://github.com/Masterminds/semver/tree/2.x)。 * 1.x.x 是最初的发布版本。它已不再维护。您应该改用 v3 版本。您可以在此处阅读 1.x.x 版本的文档[这里](https://github.com/Masterminds/semver/blob/release-1/README.md)。 ## 解析语义化版本 有两个函数可以解析语义化版本。`StrictNewVersion` 函数仅解析规范中规定的有效 2.0.0 版本的语义化版本。`NewVersion` 函数尝试将版本强制转换为语义化版本并进行解析。例如,如果存在前导 v 或未列出所有 3 部分的版本(例如 `v1.2`),它将尝试将其强制转换为有效的语义化版本(例如 1.2.0)。在这两种情况下,都会返回一个 `Version` 对象,该对象可以进行排序、比较,并用于约束条件中。 解析版本时,如果解析过程中出现问题,将返回错误。例如, ``` v, err := semver.NewVersion("1.2.3-beta.1+build345") ``` Version 对象提供了多种方法,可用于获取版本各部分、将其与其他版本进行比较、将其转换回字符串以及获取原始字符串。如果语义化版本被强制转换为了有效格式,获取原始字符串将会非常有用。 一些包级别的变量会影响 `NewVersion` 处理解析的方式。 - `CoerceNewVersion` 默认为 `true`。当设置为 `true` 时,它会将不合规的版本强制转换为 SemVer。例如,允许在 major、minor 或 patch 部分使用前导 0。这使得即使在不符合 SemVer 规范的情况下,也能在版本中使用 CalVer。当设置为 `false` 时,会减少强制转换的操作。 - `DetailedNewVersionErrors` 提供更详细的错误信息。它仅在 `CoerceNewVersion` 设置为 `false` 时生效。当 `DetailedNewVersionErrors` 设置为 `true` 时,它可以提供更多关于版本为何无效的见解。将 `DetailedNewVersionErrors` 设置为 `false` 在性能上会更快,但如果版本解析失败,提供的错误信息详细程度会降低。 ## 排序语义化版本 可以使用标准库中的 `sort` 包对一组版本进行排序。例如, ``` raw := []string{"1.2.3", "1.0", "1.3", "2", "0.4.2",} vs := make([]*semver.Version, len(raw)) for i, r := range raw { v, err := semver.NewVersion(r) if err != nil { t.Errorf("Error parsing version: %s", err) } vs[i] = v } sort.Sort(semver.Collection(vs)) ``` ## 检查版本约束 有两种比较版本的方法。一种是在 `Version` 实例上使用比较方法,另一种是使用 `Constraints`。这两种比较方法之间有一些重要的区别需要注意。 1. 当使用 `Compare`、`LessThan` 等函数比较两个版本时,它将遵循规范,并在比较中始终包含预发布版本。它提供的答案符合 https://semver.org/#spec-item-11 上规范中关于比较部分的规定。 2. 当使用约束检查进行检查或验证时,它将遵循另一套规则,这套规则在 npm/js 和 Rust/Cargo 等工具的范围处理中很常见。这包括在范围不包含预发布版本时,将预发布版本视为无效。如果您希望包含预发布版本,一个简单的解决方案是在您的范围中包含 `-0`。 3. 约束范围可以有一些复杂的规则,包括 ~ 和 ^ 的简写用法。有关这些内容的更多详细信息,请参阅下方的选项。 这两种检查版本的方法之间存在差异,因为 `Version` 上的比较方法遵循规范,而比较范围并不是规范的一部分。不同的包和工具各自制定了范围规则。这导致了差异。例如,npm/js 和 Cargo/Rust 遵循相似的模式,而 PHP 对 ^ 有不同的模式。此包中的比较功能遵循 npm/js 和 Cargo/Rust 的方向,因为使用它的应用程序在其版本方面也遵循了类似的模式。 检查版本是否符合版本约束是该包功能最丰富的部分之一。 ``` c, err := semver.NewConstraint(">= 1.2.3") if err != nil { // Handle constraint not being parsable. } v, err := semver.NewVersion("1.3") if err != nil { // Handle version not being parsable. } // Check if the version meets the constraints. The variable a will be true. a := c.Check(v) ``` ### 基本比较 比较包含两个元素。首先,比较字符串是一个由空格或逗号分隔的 AND 比较列表。然后这些比较通过 || (OR) 进行分隔。例如,`">= 1.2 < 3.0.0 || >= 4.2.3"` 会寻找大于等于 1.2 且小于 3.0.0,或者大于等于 4.2.3 的版本。 基本的比较操作符有: * `=`:等于(别名为无操作符) * `!=`:不等于 * `>`:大于 * `<`:小于 * `>=`:大于或等于 * `<=`:小于或等于 ### 处理预发布版本 对于不熟悉预发布版本的人来说,预发布版本用于在稳定版本或正式发布版本之前的软件发布。预发布版本的例子包括开发版、alpha 版、beta 版和发布候选版(RC)。预发布版本可能是类似于 `1.2.3-beta.1` 的版本,而稳定版本则是 `1.2.3`。在优先级顺序中,预发布版本排在其相关联的发布版本之前。在这个例子中 `1.2.3-beta.1 < 1.2.3`。 根据语义化版本规范,预发布版本在 API 方面可能与其对应的发布版本不兼容。规范指出, SemVer 在使用没有预发布比较器的约束进行比较时,会跳过预发布版本。例如,在查看发布列表时 `>=1.2.3` 会跳过预发布版本,而 `>=1.2.3-0` 则会评估并找到预发布版本。 在上面的比较示例中,之所以使用 `0` 作为预发布版本,是因为根据规范,预发布版本只能包含 ASCII 字母数字字符和连字符(以及 `.` 分隔符)。同样根据规范,排序是基于 ASCII 排序顺序进行的。在 ASCII 排序顺序中,最小的字符是 `0`(参见 [ASCII 表](http://www.asciitable.com/)) 了解 ASCII 排序顺序很重要,因为 A-Z 排在 a-z 之前。这意味着 `>=1.2.3-BETA` 会返回 `1.2.3-alpha`。您所期望的大小写敏感性在这里并不适用。这是由于规范规定了使用 ASCII 排序顺序。 从 `semver.NewConstraint()` 返回的 `Constraints` 实例具有一个 `IncludePrerelease` 属性,当设置为 true 时,在调用 `Check()` 和 `Validate()` 时将返回预发布版本。 ### 连字符范围比较 处理范围有多种方法,第一种是连字符范围。它们的形式如下: * `1.2 - 1.4.5` 等价于 `>= 1.2 <= 1.4.5` * `2.3.4 - 4.5` 等价于 `>= 2.3.4 <= 4.5` 请注意,不带空格的 `1.2-1.4.5` 的解析方式完全不同;它会被解析为带有_预发布版本_ `1.4.5` 的单一约束 `1.2.0`。 ### 比较中的通配符 `x`、`X` 和 `*` 字符可用作通配符。这适用于所有比较操作符。当在 `=` 操作符上使用时,它会回退到 patch 级别的比较(参见下文的波浪号)。例如, * `1.2.x` 等价于 `>= 1.2.0, < 1.3.0` * `>= 1.2.x` 等价于 `>= 1.2.0` * `<= 2.x` 等价于 `< 3` * `*` 等价于 `>= 0.0.0` ### 波浪号范围比较 当指定了 minor 版本时,波浪号 (`~`) 比较操作符用于 patch 级别的范围;如果缺少 minor 号,则用于 major 级别的更改。例如, * `~1.2.3` 等价于 `>= 1.2.3, < 1.3.0` * `~1` 等价于 `>= 1, < 2` * `~2.3` 等价于 `>= 2.3, < 2.4` * `~1.2.x` 等价于 `>= 1.2.0, < 1.3.0` * `~1.x` 等价于 `>= 1, < 2` ### 抑音符范围比较 一旦发生了稳定 (1.0.0) 版本发布,抑音符 (`^`) 比较操作符就用于 major 级别的更改。在 1.0.0 版本发布之前,minor 版本充当 API 稳定性级别。这在比较 API 版本时非常有用,因为 major 级别的更改会破坏 API。例如, * `^1.2.3` 等价于 `>= 1.2.3, < 2.0.0` * `^1.2.x` 等价于 `>= 1.2.0, < 2.0.0` * `^2.3` 等价于 `>= 2.3, < 3` * `^2.x` 等价于 `>= 2.0.0, < 3` * `^0.2.3` 等价于 `>=0.2.3 <0.3.0` * `^0.2` 等价于 `>=0.2.0 <0.3.0` * `^0.0.3` 等价于 `>=0.0.3 <0.0.4` * `^0.0` 等价于 `>=0.0.0 <0.1.0` * `^0` 等价于 `>=0.0.0 <1.0.0` ## 验证 除了根据约束测试版本外,还可以根据约束验证版本。当验证失败时,将返回一个包含版本为何不满足约束原因的错误切片。例如, ``` c, err := semver.NewConstraint("<= 1.2.3, >= 1.4") if err != nil { // Handle constraint not being parseable. } v, err := semver.NewVersion("1.3") if err != nil { // Handle version not being parseable. } // Validate a version against a constraint. a, msgs := c.Validate(v) // a is false for _, m := range msgs { fmt.Println(m) // Loops over the errors which would read // "1.3 is greater than 1.2.3" // "1.3 is less than 1.4" } ``` ## 贡献 如果您发现问题或想要贡献,请提交一个 [issue](https://github.com/Masterminds/semver/issues) 或[创建 pull request](https://github.com/Masterminds/semver/pulls)。 ## 安全 安全是这个项目的一个重要考量。该项目目前使用以下工具来帮助发现安全问题: * [CodeQL](https://codeql.github.com) * [gosec](https://github.com/securego/gosec) * 每日 Fuzz 测试 如果您认为自己发现了安全漏洞,可以通过 [GitHub 安全页面](https://github.com/Masterminds/semver/security)进行私密披露。
标签:EVTX分析, 日志审计