diff --git a/ecosystem.go b/ecosystem.go index f6733b1..6400cb4 100644 --- a/ecosystem.go +++ b/ecosystem.go @@ -36,9 +36,15 @@ var purlTypeForEcosystem = map[string]string{ // ecosystemAliases maps alternate names to canonical ecosystem names. var ecosystemAliases = map[string]string{ - "go": ecosystemGolang, - purlTypeGem: ecosystemRubyGems, - ecosystemComposer: ecosystemPackagist, + "go": ecosystemGolang, + purlTypeGem: ecosystemRubyGems, + ecosystemComposer: ecosystemPackagist, + purlTypeGitHubActions: ecosystemGitHubActions, + // OSV names that do not lowercase to the ecosystem name. + "crates.io": "cargo", + "conancenter": "conan", + "swifturl": ecosystemSwift, + "github actions": ecosystemGitHubActions, } // osvEcosystemNames maps PURL types to OSV ecosystem names. diff --git a/ecosystem_test.go b/ecosystem_test.go index 9081ad8..5947a4e 100644 --- a/ecosystem_test.go +++ b/ecosystem_test.go @@ -20,6 +20,7 @@ func TestNormalizeEcosystem(t *testing.T) { {"composer", "packagist"}, {"packagist", "packagist"}, {"cargo", "cargo"}, + {"crates.io", "cargo"}, {"unknown", "unknown"}, } @@ -32,6 +33,17 @@ func TestNormalizeEcosystem(t *testing.T) { } } +func TestNormalizeEcosystemAcceptsOSVNames(t *testing.T) { + for purlType, osv := range osvEcosystemNames { + want := NormalizeEcosystem(PURLTypeToEcosystem(purlType)) + for _, name := range []string{osv, purlType} { + if got := NormalizeEcosystem(name); got != want { + t.Errorf("NormalizeEcosystem(%q) = %q, want %q", name, got, want) + } + } + } +} + func TestEcosystemToPURLType(t *testing.T) { tests := []struct { ecosystem string @@ -217,6 +229,11 @@ func TestMakePURLString(t *testing.T) { {"freebsd default namespace", "freebsd", "py311-requests", "2.32.3_1", "pkg:bsd/freebsd/py311-requests@2.32.3_1"}, {"github-actions", "github-actions", "actions/checkout", "v4", "pkg:githubactions/actions/checkout@v4"}, {"github-actions path", "github-actions", "actions/cache/restore", "v4", "pkg:githubactions/actions/cache@v4"}, + {"githubactions path", "githubactions", "actions/cache/restore", "v4", "pkg:githubactions/actions/cache@v4"}, + {"OSV GitHub Actions", "GitHub Actions", "actions/checkout", "v4", "pkg:githubactions/actions/checkout@v4"}, + {"OSV crates.io", "crates.io", "serde", "1.0.0", "pkg:cargo/serde@1.0.0"}, + {"OSV ConanCenter", "ConanCenter", "zlib", "1.3.1", "pkg:conan/zlib@1.3.1"}, + {"OSV SwiftURL", "SwiftURL", "github.com/apple/swift-nio", "2.65.0", "pkg:swift/github.com/apple/swift-nio@2.65.0"}, {"cargo", "cargo", "serde", "1.0.0", "pkg:cargo/serde@1.0.0"}, {"generic ecosystem escaping", "cargo", "serde+derive", "1.0.0", "pkg:cargo/serde%2Bderive@1.0.0"}, {"swift source coordinate", "swift", "github.com/apple/swift-argument-parser", "1.8.2", "pkg:swift/github.com/apple/swift-argument-parser@1.8.2"}, @@ -302,18 +319,20 @@ func TestMakePURLRejectsInvalidSwiftIdentity(t *testing.T) { "apple." + strings.Repeat("a", 101), } - for _, identity := range identities { - t.Run(identity, func(t *testing.T) { - if got := MakePURL("swift", identity, "1.8.2"); got != nil { - t.Errorf("MakePURL(%q) = %q, want nil", identity, got.String()) - } - if got := MakePURLString("swift", identity, "1.8.2"); got != "" { - t.Errorf("MakePURLString(%q) = %q, want empty string", identity, got) - } - if got := BuildPURLString("swift", identity, "1.8.2", ""); got != "" { - t.Errorf("BuildPURLString(%q) = %q, want empty string", identity, got) - } - }) + for _, ecosystem := range []string{"swift", "SwiftURL"} { + for _, identity := range identities { + t.Run(ecosystem+"/"+identity, func(t *testing.T) { + if got := MakePURL(ecosystem, identity, "1.8.2"); got != nil { + t.Errorf("MakePURL(%q) = %q, want nil", identity, got.String()) + } + if got := MakePURLString(ecosystem, identity, "1.8.2"); got != "" { + t.Errorf("MakePURLString(%q) = %q, want empty string", identity, got) + } + if got := BuildPURLString(ecosystem, identity, "1.8.2", ""); got != "" { + t.Errorf("BuildPURLString(%q) = %q, want empty string", identity, got) + } + }) + } } }