Files
gitlab-foss/lib/gitlab/ci/reports/sbom/component.rb
2024-09-18 12:10:54 +00:00

102 lines
2.8 KiB
Ruby

# frozen_string_literal: true
module Gitlab
module Ci
module Reports
module Sbom
class Component
include Gitlab::Utils::StrongMemoize
UNKNOWN_PACKAGE = "unknown"
attr_reader :ref, :component_type, :version, :path
attr_accessor :properties, :purl, :source_package_name, :ancestors, :licenses
def initialize(ref:, type:, name:, purl:, version:, properties: nil, source_package_name: nil, licenses: [])
@ref = ref
@component_type = type
@name = name
@purl = purl
@version = version
@properties = properties
@source_package_name = source_package_name
@ancestors = []
@licenses = licenses
end
def <=>(other)
sort_by_attributes(self) <=> sort_by_attributes(other)
end
def ingestible?
supported_component_type? && supported_purl_type?
end
def purl_type
purl&.type
end
def type
component_type
end
def name
use_namespaced_name? ? [purl.namespace, purl.name].compact.join('/') : @name
end
def key
[name, version, purl&.type]
end
def reachability
reachability = properties&.data&.fetch('reachability', UNKNOWN_PACKAGE)
return UNKNOWN_PACKAGE unless supported_reachability_type?(reachability)
reachability
end
private
def supported_component_type?
::Enums::Sbom.component_types.include?(component_type.to_sym)
end
def supported_purl_type?
# the purl type is not required as per the spec: https://cyclonedx.org/docs/1.4/json/#components_items_purl
return true unless purl
# however, if the purl type is provided, it _must be valid_
::Enums::Sbom.purl_types.include?(purl.type.to_sym)
end
def supported_reachability_type?(type)
::Enums::Sbom::REACHABILITY_TYPES.include?(type)
end
def sort_by_attributes(component)
[
component.name,
purl_type_int(component),
component_type_int(component),
component.version.to_s
]
end
def component_type_int(component)
::Enums::Sbom::COMPONENT_TYPES.fetch(component.component_type.to_sym)
end
def purl_type_int(component)
::Enums::Sbom::PURL_TYPES.fetch(component.purl&.type&.to_sym, 0)
end
def use_namespaced_name?
purl.present? && Enums::Sbom.use_namespaced_name?(purl_type)
end
end
end
end
end
end