生态系统
SDK 把全部 19 个 OSV 生态定义为类型化常量——杜绝字符串拼错的隐患。
全部列表
| 常量 | 值 | 说明 |
|---|---|---|
EcosystemGo | Go | Go 模块路径 |
EcosystemNpm | npm | NPM 包名 |
EcosystemPyPI | PyPI | 规范化的 PyPI 名 |
EcosystemRubyGems | RubyGems | Gem 名 |
EcosystemCratesIo | crates.io | Rust crate |
EcosystemPackagist | Packagist | PHP |
EcosystemMaven | Maven | Java——name 为 groupId:artifactId |
EcosystemNuGet | NuGet | .NET |
EcosystemHex | Hex | Erlang/Elixir |
EcosystemPub | Pub | Dart |
EcosystemLinux | Linux | 仅内核 |
EcosystemDebian | Debian | 可能带 :<RELEASE> 后缀 |
EcosystemAlpine | Alpine | 需带 :v<RELEASE> 后缀 |
EcosystemRocky | Rocky | 可能带 :<RELEASE> 后缀 |
EcosystemAlmaLinux | AlmaLinux | 可能带 :<RELEASE> 后缀 |
EcosystemAndroid | Android | 组件名 |
EcosystemOSSFuzz | OSS-Fuzz | Fuzz 目标 |
EcosystemConanCenter | ConanCenter | C/C++ |
EcosystemGitHubActions | GitHub Actions | {owner}/{repo} |
按类别分组
生态 → 版本方案
一个生态不只是给注册表起名——它还隐含了版本如何排序,而这正是 range.type 需要的(见 RangeType)。正因如此,你不能用普通字符串 < 来比较版本。
命名约定与后缀
package.name 字符串并非自由格式——每个生态都有自己的形状,有些还带强制或可选的 :<release> 后缀。弄错这一点是 HasEcosystem 匹配静默失败的最常见原因。
发行版后缀属于生态字符串,而非 name
对 Alpine 而言 release 后缀(Alpine:v3.18)是必需的;对 Debian/Rocky/AlmaLinux 则是可选的。后缀挂在生态字符串上,所以精确匹配的 HasEcosystem(EcosystemAlpine) 不会匹配 Alpine:v3.18。只有在你把后缀归一化掉之后,才应与基础常量比较。
用法
// 检查单个生态
if v.Affected.HasEcosystem(osv.EcosystemPyPI) {
// ...
}
// 过滤受影响条目
pypiAffected := v.Affected.FilterByEcosystem(osv.EcosystemPyPI)
// Maven 拆分
for _, a := range v.Affected {
if a.Package != nil && a.Package.IsMaven() {
fmt.Println(a.Package.GetGroupID()) // groupId
fmt.Println(a.Package.GetArtifactID()) // artifactId
}
}消费 Ecosystem 常量的入口有两个——一个问是/否,另一个返回缩小后的切片。两者都遍历同一个 AffectedSlice:
Ecosystem 是带类型字符串,不是自由字符串
传常量如 osv.EcosystemPyPI,而非字面量 "PyPI"。常量带有 OSV 规范要求的精确大小写,于是比较区分大小写且杜绝拼写错误。
FilterByEcosystem 防的是切片 nil,不是元素级 Package
HasEcosystem 在读 .Ecosystem 前先检查 item.Package != nil(第 49 行),故条目上 null/缺失的 package 会被安全跳过。FilterByEcosystem 只防切片本身为 nil(if x == nil { return nil },第 69 行)——其谓词随后直接读 affected.Package.Ecosystem,没有逐元素 nil 检查。故某条 affected 的 package 为 null 时会 panic。实践中每条合规的 OSV affected 条目都带 package,但若你解析的是不受信任的数据,请先用 [[osv-validate]] 校验,或自行对切片做防护。
Maven name 的拆分
GetGroupID / GetArtifactID 用 strings.SplitN(name, ":", 2),故 org.apache.commons:collections4 这样的 name 会拆成 org.apache.commons(group)和 collections4(artifact)——只有第一个 : 是分隔符。两者都对 nil 安全:nil 的 Package 或不含 : 的 name 返回 "",而非 panic。它们对任意 Package 都可调用,但只有 IsMaven() 为真时才有意义。
源码:package.go