forked from anchore/syft
-
Notifications
You must be signed in to change notification settings - Fork 0
/
url.go
110 lines (92 loc) · 2.27 KB
/
url.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package pkg
import (
"regexp"
"sort"
"strings"
"github.com/anchore/packageurl-go"
"github.com/anchore/syft/syft/linux"
)
const (
PURLQualifierArch = "arch"
PURLQualifierDistro = "distro"
PURLQualifierEpoch = "epoch"
PURLQualifierVCSURL = "vcs_url"
// PURLQualifierUpstream this qualifier is not in the pURL spec, but is used by grype to perform indirect matching based on source information
PURLQualifierUpstream = "upstream"
purlCargoPkgType = "cargo"
purlGradlePkgType = "gradle"
)
type urlIdentifier interface {
PackageURL(*linux.Release) string
}
func URL(p Package, release *linux.Release) string {
if p.Metadata != nil {
if i, ok := p.Metadata.(urlIdentifier); ok {
return i.PackageURL(release)
}
}
// the remaining cases are primarily reserved for packages without metadata struct instances
var purlType = p.Type.PackageURLType()
var name = p.Name
var namespace = ""
switch {
case purlType == "":
purlType = packageurl.TypeGeneric
case p.Type == GoModulePkg:
re := regexp.MustCompile(`(/)[^/]*$`)
fields := re.Split(p.Name, -1)
if len(fields) > 1 {
namespace = fields[0]
name = strings.TrimPrefix(p.Name, namespace+"/")
}
case p.Type == NpmPkg:
fields := strings.SplitN(p.Name, "/", 2)
if len(fields) > 1 {
namespace = fields[0]
name = fields[1]
}
}
// generate a purl from the package data
return packageurl.NewPackageURL(
purlType,
namespace,
name,
p.Version,
nil,
"",
).ToString()
}
func purlQualifiers(vars map[string]string, release *linux.Release) (q packageurl.Qualifiers) {
keys := make([]string, 0, len(vars))
for k := range vars {
keys = append(keys, k)
}
sort.Strings(keys)
for _, k := range keys {
val := vars[k]
if val == "" {
continue
}
q = append(q, packageurl.Qualifier{
Key: k,
Value: vars[k],
})
}
distroQualifiers := []string{}
if release == nil {
return q
}
if release.ID != "" {
distroQualifiers = append(distroQualifiers, release.ID)
}
if release.VersionID != "" {
distroQualifiers = append(distroQualifiers, release.VersionID)
} else if release.BuildID != "" {
distroQualifiers = append(distroQualifiers, release.BuildID)
}
q = append(q, packageurl.Qualifier{
Key: PURLQualifierDistro,
Value: strings.Join(distroQualifiers, "-"),
})
return q
}