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
|
# File 'lib/bundler/sbom/spdx.rb', line 11
def self.generate(gem_data, document_name)
spdx_id = SecureRandom.uuid
sbom = {
"SPDXID" => "SPDXRef-DOCUMENT",
"spdxVersion" => "SPDX-2.3",
"creationInfo" => {
"created" => Time.now.utc.strftime("%Y-%m-%dT%H:%M:%SZ"),
"creators" => ["Tool: bundle-sbom"]
},
"name" => document_name,
"dataLicense" => "CC0-1.0",
"documentNamespace" => "https://spdx.org/spdxdocs/#{document_name}-#{spdx_id}",
"packages" => []
}
if (list_version = license_list_version)
sbom["creationInfo"]["licenseListVersion"] = list_version
end
package_ids = {}
gem_data.each do |gem|
package_ids[gem[:name]] = "SPDXRef-Package-#{gem[:name]}"
end
gem_data.each do |gem|
spdx_licenses = gem[:licenses].map { |l| normalize_license_id(l) }
license_string = spdx_licenses.empty? ? "NOASSERTION" : spdx_licenses.join(" AND ")
package = {
"SPDXID" => package_ids[gem[:name]],
"name" => gem[:name],
"versionInfo" => gem[:version],
"downloadLocation" => "https://rubygems.org/gems/#{gem[:name]}/versions/#{gem[:version]}",
"filesAnalyzed" => false,
"licenseConcluded" => license_string,
"licenseDeclared" => license_string,
"copyrightText" => "NOASSERTION",
"supplier" => "NOASSERTION",
"externalRefs" => [
{
"referenceCategory" => "PACKAGE-MANAGER",
"referenceType" => "purl",
"referenceLocator" => "pkg:gem/#{gem[:name]}@#{gem[:version]}"
}
]
}
sbom["packages"] << package
end
sbom["documentDescribes"] = sbom["packages"].map { |p| p["SPDXID"] }
sbom["relationships"] = sbom["packages"].map do |p|
{
"spdxElementId" => "SPDXRef-DOCUMENT",
"relatedSpdxElement" => p["SPDXID"],
"relationshipType" => "DESCRIBES"
}
end
gem_data.each do |gem|
(gem[:dependencies] || []).each do |dep_name|
dep_id = package_ids[dep_name]
next unless dep_id
sbom["relationships"] << {
"spdxElementId" => package_ids[gem[:name]],
"relatedSpdxElement" => dep_id,
"relationshipType" => "DEPENDS_ON"
}
end
end
new(sbom)
end
|