mirror of
https://gitlab.com/gitlab-org/gitlab-foss.git
synced 2025-08-10 01:31:45 +00:00
102 lines
2.8 KiB
Ruby
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
|