2026-08-15 09:45:05 +01:00
|
|
|
// Package packageurl builds package URLs from ecosystem-native package names.
|
|
|
|
|
package packageurl
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
|
|
"github.com/git-pkgs/purl"
|
|
|
|
|
)
|
|
|
|
|
|
2026-08-16 23:10:33 +01:00
|
|
|
// Make constructs a package URL from an ecosystem-native package name.
|
2026-08-15 09:45:05 +01:00
|
|
|
func Make(ecosystem, name, version string) *purl.PURL {
|
|
|
|
|
return purl.MakePURL(ecosystem, name, version)
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-16 23:10:33 +01:00
|
|
|
// MakeString constructs a package URL string. It returns an empty string when
|
|
|
|
|
// the package identity cannot be represented as a PURL.
|
2026-08-15 09:45:05 +01:00
|
|
|
func MakeString(ecosystem, name, version string) string {
|
2026-08-16 23:10:33 +01:00
|
|
|
return purl.MakePURLString(ecosystem, name, version)
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-16 23:28:12 +01:00
|
|
|
// WithVersionString returns a package PURL with its version replaced. It
|
|
|
|
|
// returns an empty string when packagePURL is invalid.
|
|
|
|
|
func WithVersionString(packagePURL, version string) string {
|
|
|
|
|
pkg, err := purl.Parse(packagePURL)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return ""
|
|
|
|
|
}
|
|
|
|
|
return pkg.WithVersion(version).String()
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-16 23:10:33 +01:00
|
|
|
// MakeCacheStrings returns package and version PURLs suitable for artifact
|
|
|
|
|
// cache records. Swift registry identities use an explicit generic PURL until
|
2026-08-20 09:18:05 +01:00
|
|
|
// their source repository has been resolved. The result is independent of the
|
|
|
|
|
// configured upstream so cache entries survive an upstream.swift change,
|
|
|
|
|
// matching every other ecosystem.
|
|
|
|
|
func MakeCacheStrings(ecosystem, name, version string) (packagePURL, versionPURL string) {
|
2026-08-16 23:10:33 +01:00
|
|
|
if pkg := Make(ecosystem, name, ""); pkg != nil {
|
|
|
|
|
return pkg.String(), pkg.WithVersion(version).String()
|
|
|
|
|
}
|
|
|
|
|
if purl.NormalizeEcosystem(ecosystem) != "swift" {
|
|
|
|
|
return "", ""
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
identity, ok := swiftRegistryIdentity(name)
|
|
|
|
|
if !ok {
|
|
|
|
|
return "", ""
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-20 09:18:05 +01:00
|
|
|
pkg := purl.New("generic", "swift-registry", identity, "", nil)
|
2026-08-16 23:10:33 +01:00
|
|
|
return pkg.String(), pkg.WithVersion(version).String()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func swiftRegistryIdentity(name string) (string, bool) {
|
|
|
|
|
scope, packageName, found := strings.Cut(name, "/")
|
|
|
|
|
if !found {
|
|
|
|
|
scope, packageName, found = strings.Cut(name, ".")
|
|
|
|
|
}
|
|
|
|
|
if !found || scope == "" || packageName == "" || strings.ContainsAny(packageName, "/.") {
|
|
|
|
|
return "", false
|
|
|
|
|
}
|
|
|
|
|
return strings.ToLower(scope) + "." + strings.ToLower(packageName), true
|
2026-08-15 09:45:05 +01:00
|
|
|
}
|