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
19 changes: 19 additions & 0 deletions internal/core/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -245,3 +245,22 @@ func (b *BaseURLs) PURL(name, version string) string {
}
return fmt.Sprintf("pkg:%s/%s", "generic", name)
}

// BuildURLs returns a map of all non-empty URLs for a package.
// Keys are "registry", "download", "docs", and "purl".
func BuildURLs(urls URLBuilder, name, version string) map[string]string {
result := make(map[string]string)
if v := urls.Registry(name, version); v != "" {
result["registry"] = v
}
if v := urls.Download(name, version); v != "" {
result["download"] = v
}
if v := urls.Documentation(name, version); v != "" {
result["docs"] = v
}
if v := urls.PURL(name, version); v != "" {
result["purl"] = v
}
return result
}
51 changes: 51 additions & 0 deletions internal/core/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,57 @@ import (
"testing"
)

func TestBuildURLs(t *testing.T) {
urls := &BaseURLs{
RegistryFn: func(name, version string) string { return "https://example.com/" + name },
DownloadFn: func(name, version string) string { return "https://example.com/" + name + "/download" },
DocumentationFn: func(name, version string) string { return "https://docs.example.com/" + name },
PURLFn: func(name, version string) string { return "pkg:test/" + name + "@" + version },
}

got := BuildURLs(urls, "foo", "1.0.0")

expected := map[string]string{
"registry": "https://example.com/foo",
"download": "https://example.com/foo/download",
"docs": "https://docs.example.com/foo",
"purl": "pkg:test/foo@1.0.0",
}

if len(got) != len(expected) {
t.Fatalf("BuildURLs returned %d entries, want %d", len(got), len(expected))
}

for k, want := range expected {
if got[k] != want {
t.Errorf("BuildURLs[%q] = %q, want %q", k, got[k], want)
}
}
}

func TestBuildURLs_OmitsEmpty(t *testing.T) {
urls := &BaseURLs{
RegistryFn: func(name, version string) string { return "https://example.com/" + name },
// Documentation and Download are nil, so they return ""
}

got := BuildURLs(urls, "foo", "1.0.0")

if _, ok := got["docs"]; ok {
t.Error("BuildURLs should omit empty docs URL")
}
if _, ok := got["download"]; ok {
t.Error("BuildURLs should omit empty download URL")
}
if _, ok := got["registry"]; !ok {
t.Error("BuildURLs should include non-empty registry URL")
}
// PURL falls back to generic format in BaseURLs
if _, ok := got["purl"]; !ok {
t.Error("BuildURLs should include PURL fallback")
}
}

func TestDefaultClient_UserAgent(t *testing.T) {
var gotUA string
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
Expand Down
6 changes: 6 additions & 0 deletions registries.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,12 @@ func SupportedEcosystems() []string {
return core.SupportedEcosystems()
}

// BuildURLs returns a map of all non-empty URLs for a package.
// Keys are "registry", "download", "docs", and "purl".
func BuildURLs(urls URLBuilder, name, version string) map[string]string {
return core.BuildURLs(urls, name, version)
}

// DefaultURL returns the default registry URL for an ecosystem.
func DefaultURL(ecosystem string) string {
return core.DefaultURL(ecosystem)
Expand Down
19 changes: 19 additions & 0 deletions registries_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,25 @@ func TestIntegration(t *testing.T) {
}
}

func TestBuildURLs(t *testing.T) {
reg, err := registries.New("cargo", "", nil)
if err != nil {
t.Fatalf("New failed: %v", err)
}

got := registries.BuildURLs(reg.URLs(), "serde", "1.0.0")

if got["registry"] == "" {
t.Error("expected non-empty registry URL")
}
if got["docs"] == "" {
t.Error("expected non-empty docs URL")
}
if got["purl"] != "pkg:cargo/serde@1.0.0" {
t.Errorf("purl = %q, want %q", got["purl"], "pkg:cargo/serde@1.0.0")
}
}

func TestConstants(t *testing.T) {
// Verify constants are exported correctly
if registries.Runtime != "runtime" {
Expand Down