Skip to content

Commit 5f4c576

Browse files
authored
Merge pull request #15 from git-pkgs/use-purl-library
Replace inline PURL construction with purl library
2 parents 40cfd77 + 364549a commit 5f4c576

4 files changed

Lines changed: 32 additions & 61 deletions

File tree

internal/handler/handler.go

Lines changed: 8 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"github.com/git-pkgs/proxy/internal/database"
1414
"github.com/git-pkgs/proxy/internal/metrics"
1515
"github.com/git-pkgs/proxy/internal/storage"
16+
"github.com/git-pkgs/purl"
1617
"github.com/git-pkgs/registries/fetch"
1718
)
1819

@@ -50,8 +51,8 @@ type CacheResult struct {
5051

5152
// GetOrFetchArtifact retrieves an artifact from cache or fetches from upstream.
5253
func (p *Proxy) GetOrFetchArtifact(ctx context.Context, ecosystem, name, version, filename string) (*CacheResult, error) {
53-
pkgPURL := fmt.Sprintf("pkg:%s/%s", ecosystem, name)
54-
versionPURL := fmt.Sprintf("pkg:%s/%s@%s", ecosystem, name, version)
54+
pkgPURL := purl.MakePURLString(ecosystem, name, "")
55+
versionPURL := purl.MakePURLString(ecosystem, name, version)
5556

5657
if cached, err := p.checkCache(ctx, pkgPURL, versionPURL, filename); err != nil {
5758
return nil, err
@@ -101,8 +102,9 @@ func (p *Proxy) checkCache(ctx context.Context, pkgPURL, versionPURL, filename s
101102
_ = p.DB.RecordArtifactHit(versionPURL, filename)
102103

103104
// Extract ecosystem from pkgPURL for metrics
104-
ecosystem := extractEcosystem(pkgPURL)
105-
metrics.RecordCacheHit(ecosystem)
105+
if p, err := purl.Parse(pkgPURL); err == nil {
106+
metrics.RecordCacheHit(purl.PURLTypeToEcosystem(p.Type))
107+
}
106108

107109
return &CacheResult{
108110
Reader: reader,
@@ -251,8 +253,8 @@ func JSONError(w http.ResponseWriter, status int, message string) {
251253
// GetOrFetchArtifactFromURL retrieves an artifact from cache or fetches from a specific URL.
252254
// This is useful for registries where download URLs are determined from metadata.
253255
func (p *Proxy) GetOrFetchArtifactFromURL(ctx context.Context, ecosystem, name, version, filename, downloadURL string) (*CacheResult, error) {
254-
pkgPURL := fmt.Sprintf("pkg:%s/%s", ecosystem, name)
255-
versionPURL := fmt.Sprintf("pkg:%s/%s@%s", ecosystem, name, version)
256+
pkgPURL := purl.MakePURLString(ecosystem, name, "")
257+
versionPURL := purl.MakePURLString(ecosystem, name, version)
256258

257259
if cached, err := p.checkCache(ctx, pkgPURL, versionPURL, filename); err != nil {
258260
return nil, err
@@ -297,28 +299,3 @@ func (p *Proxy) fetchAndCacheFromURL(ctx context.Context, ecosystem, name, versi
297299
}, nil
298300
}
299301

300-
// extractEcosystem extracts the ecosystem from a package PURL.
301-
// PURL format: pkg:ecosystem/name[@version]
302-
func extractEcosystem(purl string) string {
303-
if len(purl) < 5 || !startsWith(purl, "pkg:") {
304-
return "unknown"
305-
}
306-
rest := purl[4:] // Skip "pkg:"
307-
if idx := indexOf(rest, "/"); idx != -1 {
308-
return rest[:idx]
309-
}
310-
return "unknown"
311-
}
312-
313-
func startsWith(s, prefix string) bool {
314-
return len(s) >= len(prefix) && s[:len(prefix)] == prefix
315-
}
316-
317-
func indexOf(s, substr string) int {
318-
for i := 0; i+len(substr) <= len(s); i++ {
319-
if s[i:i+len(substr)] == substr {
320-
return i
321-
}
322-
}
323-
return -1
324-
}

internal/server/api.go

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@ import (
66
"strings"
77

88
shared "github.com/git-pkgs/enrichment"
9-
"github.com/go-chi/chi/v5"
109
"github.com/git-pkgs/proxy/internal/database"
1110
"github.com/git-pkgs/proxy/internal/enrichment"
11+
"github.com/git-pkgs/purl"
12+
"github.com/go-chi/chi/v5"
1213
)
1314

1415
// APIHandler provides REST endpoints for package enrichment data.
@@ -357,24 +358,15 @@ func (h *APIHandler) HandleBulkLookup(w http.ResponseWriter, r *http.Request) {
357358
} else {
358359
// Fall back to individual lookups via registries
359360
packages := make([]struct{ Ecosystem, Name string }, 0, len(req.PURLs))
360-
purlMap := make(map[string]string) // map from "ecosystem/name" to original purl
361-
362-
for _, purl := range req.PURLs {
363-
// Parse PURL to extract ecosystem and name
364-
// Format: pkg:ecosystem/name@version
365-
if strings.HasPrefix(purl, "pkg:") {
366-
parts := strings.SplitN(purl[4:], "/", 2)
367-
if len(parts) == 2 {
368-
ecosystem := parts[0]
369-
namePart := parts[1]
370-
// Remove version if present
371-
if idx := strings.Index(namePart, "@"); idx > 0 {
372-
namePart = namePart[:idx]
373-
}
374-
packages = append(packages, struct{ Ecosystem, Name string }{ecosystem, namePart})
375-
purlMap[ecosystem+"/"+namePart] = purl
376-
}
361+
362+
for _, purlStr := range req.PURLs {
363+
p, err := purl.Parse(purlStr)
364+
if err != nil {
365+
continue
377366
}
367+
ecosystem := purl.PURLTypeToEcosystem(p.Type)
368+
name := p.FullName()
369+
packages = append(packages, struct{ Ecosystem, Name string }{ecosystem, name})
378370
}
379371

380372
results := h.enrichment.BulkEnrichPackages(r.Context(), packages)

internal/server/browse.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@ import (
99
"strings"
1010

1111
"github.com/git-pkgs/archives"
12-
"github.com/git-pkgs/proxy/internal/database"
1312
"github.com/git-pkgs/archives/diff"
13+
"github.com/git-pkgs/proxy/internal/database"
14+
"github.com/git-pkgs/purl"
1415
"github.com/go-chi/chi/v5"
1516
)
1617

@@ -49,8 +50,8 @@ func (s *Server) handleBrowseList(w http.ResponseWriter, r *http.Request) {
4950
dirPath := r.URL.Query().Get("path")
5051

5152
// Get the artifact for this version
52-
purl := fmt.Sprintf("pkg:%s/%s@%s", ecosystem, name, version)
53-
artifacts, err := s.db.GetArtifactsByVersionPURL(purl)
53+
versionPURL := purl.MakePURLString(ecosystem, name, version)
54+
artifacts, err := s.db.GetArtifactsByVersionPURL(versionPURL)
5455
if err != nil {
5556
http.Error(w, "version not found", http.StatusNotFound)
5657
return
@@ -137,8 +138,8 @@ func (s *Server) handleBrowseFile(w http.ResponseWriter, r *http.Request) {
137138
}
138139

139140
// Get the artifact for this version
140-
purl := fmt.Sprintf("pkg:%s/%s@%s", ecosystem, name, version)
141-
artifacts, err := s.db.GetArtifactsByVersionPURL(purl)
141+
versionPURL := purl.MakePURLString(ecosystem, name, version)
142+
artifacts, err := s.db.GetArtifactsByVersionPURL(versionPURL)
142143
if err != nil {
143144
http.Error(w, "version not found", http.StatusNotFound)
144145
return
@@ -345,8 +346,8 @@ func (s *Server) handleCompareDiff(w http.ResponseWriter, r *http.Request) {
345346
toVersion := chi.URLParam(r, "toVersion")
346347

347348
// Get artifacts for both versions
348-
fromPURL := fmt.Sprintf("pkg:%s/%s@%s", ecosystem, name, fromVersion)
349-
toPURL := fmt.Sprintf("pkg:%s/%s@%s", ecosystem, name, toVersion)
349+
fromPURL := purl.MakePURLString(ecosystem, name, fromVersion)
350+
toPURL := purl.MakePURLString(ecosystem, name, toVersion)
350351

351352
fromArtifacts, err := s.db.GetArtifactsByVersionPURL(fromPURL)
352353
if err != nil || len(fromArtifacts) == 0 {

internal/server/server.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,16 +44,17 @@ import (
4444
"strconv"
4545
"time"
4646

47-
"github.com/go-chi/chi/v5"
48-
"github.com/go-chi/chi/v5/middleware"
4947
"github.com/git-pkgs/proxy/internal/config"
5048
"github.com/git-pkgs/proxy/internal/database"
5149
"github.com/git-pkgs/proxy/internal/enrichment"
5250
"github.com/git-pkgs/proxy/internal/handler"
5351
"github.com/git-pkgs/proxy/internal/metrics"
5452
"github.com/git-pkgs/proxy/internal/storage"
53+
"github.com/git-pkgs/purl"
5554
"github.com/git-pkgs/registries/fetch"
5655
"github.com/git-pkgs/spdx"
56+
"github.com/go-chi/chi/v5"
57+
"github.com/go-chi/chi/v5/middleware"
5758
)
5859

5960
// Server is the main proxy server.
@@ -613,15 +614,15 @@ func (s *Server) handleVersionShow(w http.ResponseWriter, r *http.Request) {
613614
return
614615
}
615616

616-
purl := fmt.Sprintf("pkg:%s/%s@%s", ecosystem, name, version)
617-
ver, err := s.db.GetVersionByPURL(purl)
617+
versionPURL := purl.MakePURLString(ecosystem, name, version)
618+
ver, err := s.db.GetVersionByPURL(versionPURL)
618619
if err != nil || ver == nil {
619620
s.logger.Error("failed to get version", "error", err)
620621
http.Error(w, "version not found", http.StatusNotFound)
621622
return
622623
}
623624

624-
artifacts, err := s.db.GetArtifactsByVersionPURL(purl)
625+
artifacts, err := s.db.GetArtifactsByVersionPURL(versionPURL)
625626
if err != nil {
626627
s.logger.Error("failed to get artifacts", "error", err)
627628
artifacts = []database.Artifact{}

0 commit comments

Comments
 (0)