Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 16 additions & 14 deletions ecosystem.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"strings"
)

const ecosystemMaven = "maven"

// purlTypeForEcosystem maps ecosystem names to PURL types.
// Most ecosystems use their name as the PURL type, but some differ.
var purlTypeForEcosystem = map[string]string{
Expand All @@ -28,7 +30,7 @@ var osvEcosystemNames = map[string]string{
"pypi": "PyPI",
"cargo": "crates.io",
"golang": "Go",
"maven": "Maven",
ecosystemMaven: "Maven",
"nuget": "NuGet",
"composer": "Packagist",
"hex": "Hex",
Expand All @@ -39,13 +41,13 @@ var osvEcosystemNames = map[string]string{

// depsdevSystemNames maps PURL types to deps.dev system names.
var depsdevSystemNames = map[string]string{
"npm": "NPM",
"gem": "RUBYGEMS",
"pypi": "PYPI",
"cargo": "CARGO",
"golang": "GO",
"maven": "MAVEN",
"nuget": "NUGET",
"npm": "NPM",
"gem": "RUBYGEMS",
"pypi": "PYPI",
"cargo": "CARGO",
"golang": "GO",
ecosystemMaven: "MAVEN",
"nuget": "NUGET",
}

// defaultNamespaces defines default namespaces for certain ecosystems.
Expand Down Expand Up @@ -128,8 +130,8 @@ func MakePURL(ecosystem, name, version string) *PURL {
switch NormalizeEcosystem(ecosystem) {
case "npm":
if strings.HasPrefix(name, "@") {
parts := strings.SplitN(name, "/", 2)
if len(parts) == 2 {
parts := strings.SplitN(name, "/", 2) //nolint:mnd
if len(parts) == 2 { //nolint:mnd
namespace = parts[0] // Keep the @ for packageurl-go
pkgName = parts[1]
}
Expand All @@ -139,22 +141,22 @@ func MakePURL(ecosystem, name, version string) *PURL {
namespace = name[:idx]
pkgName = name[idx+1:]
}
case "maven":
case ecosystemMaven:
if strings.Contains(name, ":") {
parts := strings.SplitN(name, ":", 2)
parts := strings.SplitN(name, ":", 2) //nolint:mnd
namespace = parts[0]
pkgName = parts[1]
}
case "packagist", "composer":
if strings.Contains(name, "/") {
parts := strings.SplitN(name, "/", 2)
parts := strings.SplitN(name, "/", 2) //nolint:mnd
namespace = parts[0]
pkgName = parts[1]
}
case "github-actions":
// GitHub Actions: owner/repo or owner/repo/path -> namespace=owner, name=repo (path ignored)
if strings.Contains(name, "/") {
parts := strings.SplitN(name, "/", 3)
parts := strings.SplitN(name, "/", 3) //nolint:mnd
namespace = parts[0]
pkgName = parts[1]
}
Expand Down
14 changes: 7 additions & 7 deletions makepurl.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func BuildPURLString(ecosystem, name, version, registryURL string) string {
n += 1 + len(cleanVersion) // "@" + version
}
if needsQualifier {
n += 16 + len(registryURL) // "?repository_url=" + value
n += len("?repository_url=") + len(registryURL)
}

var b strings.Builder
Expand Down Expand Up @@ -138,8 +138,8 @@ func writeComponentEscaped(b *strings.Builder, s string) {
b.WriteByte(c)
} else {
b.WriteByte('%')
b.WriteByte(hexDigit(c >> 4))
b.WriteByte(hexDigit(c & 0x0f))
b.WriteByte(hexDigit(c >> 4)) //nolint:mnd
b.WriteByte(hexDigit(c & 0x0f)) //nolint:mnd
}
}
}
Expand All @@ -163,8 +163,8 @@ func writeQualifierEscaped(b *strings.Builder, s string) {
b.WriteByte(c)
} else {
b.WriteByte('%')
b.WriteByte(hexDigit(c >> 4))
b.WriteByte(hexDigit(c & 0x0f))
b.WriteByte(hexDigit(c >> 4)) //nolint:mnd
b.WriteByte(hexDigit(c & 0x0f)) //nolint:mnd
}
}
}
Expand All @@ -175,8 +175,8 @@ func isQualifierValueSafe(c byte) bool {
}

func hexDigit(b byte) byte {
if b < 10 {
if b < 10 { //nolint:mnd
return '0' + b
}
return 'A' + b - 10
return 'A' + b - 10 //nolint:mnd
}
24 changes: 13 additions & 11 deletions registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,21 +50,23 @@ func expandTemplate(rc *RegistryConfig, namespace, name, version string) (string

// Select the appropriate template
if version != "" && rc.Components.VersionInURL {
if hasNamespace && rc.URITemplateWithVersion != "" {
switch {
case hasNamespace && rc.URITemplateWithVersion != "":
template = rc.URITemplateWithVersion
} else if !hasNamespace && rc.URITemplateWithVersionNoNS != "" {
case !hasNamespace && rc.URITemplateWithVersionNoNS != "":
template = rc.URITemplateWithVersionNoNS
} else if rc.URITemplateWithVersion != "" {
case rc.URITemplateWithVersion != "":
template = rc.URITemplateWithVersion
}
}

if template == "" {
if hasNamespace {
switch {
case hasNamespace:
template = rc.URITemplate
} else if rc.URITemplateNoNamespace != "" {
case rc.URITemplateNoNamespace != "":
template = rc.URITemplateNoNamespace
} else {
default:
template = rc.URITemplate
}
}
Expand Down Expand Up @@ -129,19 +131,19 @@ func ParseRegistryURLWithType(url, purlType string) (*PURL, error) {
if len(matches) > 1 {
namespace = matches[1]
}
if len(matches) > 2 {
if len(matches) > 2 { //nolint:mnd
name = matches[2]
}
if len(matches) > 3 {
if len(matches) > 3 { //nolint:mnd
version = matches[3]
}
} else {
// Namespace is optional: matches[1]=namespace (maybe empty), matches[2]=name
if len(matches) > 2 {
if len(matches) > 2 { //nolint:mnd
namespace = matches[1]
name = matches[2]
}
if len(matches) > 3 {
if len(matches) > 3 { //nolint:mnd
version = matches[3]
}
}
Expand All @@ -150,7 +152,7 @@ func ParseRegistryURLWithType(url, purlType string) (*PURL, error) {
if len(matches) > 1 {
name = matches[1]
}
if len(matches) > 2 {
if len(matches) > 2 { //nolint:mnd
version = matches[2]
}
}
Expand Down
7 changes: 4 additions & 3 deletions types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,14 @@ func TestTypeInfo(t *testing.T) {
for _, tt := range tests {
t.Run(tt.purlType, func(t *testing.T) {
cfg := TypeInfo(tt.purlType)
if tt.wantNil {
switch {
case tt.wantNil:
if cfg != nil {
t.Errorf("TypeInfo(%q) = %v, want nil", tt.purlType, cfg)
}
} else if cfg == nil {
case cfg == nil:
t.Errorf("TypeInfo(%q) = nil, want non-nil", tt.purlType)
} else {
default:
if cfg.Description != tt.wantDescription {
t.Errorf("Description = %q, want %q", cfg.Description, tt.wantDescription)
}
Expand Down