Class: Bibliothecary::MultiParsers::CycloneDX

Inherits:
Object
  • Object
show all
Extended by:
Analyser::TryCache
Includes:
Analyser
Defined in:
lib/bibliothecary/multi_parsers/cyclonedx.rb

Defined Under Namespace

Classes: ManifestEntries

Constant Summary collapse

NoComponents =
Class.new(StandardError)

Class Method Summary collapse

Methods included from Analyser::TryCache

try_cache

Methods included from Analyser

create_analysis, create_error_analysis, included

Class Method Details

.mappingObject



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/bibliothecary/multi_parsers/cyclonedx.rb', line 74

def self.mapping
  {
    match_extension("cyclonedx.json", case_insensitive: true) => {
      kind: "lockfile",
      parser: :parse_cyclonedx_json,
      ungroupable: true,
    },
    match_extension("cdx.json", case_insensitive: true) => {
      kind: "lockfile",
      parser: :parse_cyclonedx_json,
      ungroupable: true,
    },
    match_extension("cyclonedx.xml", case_insensitive: true) => {
      kind: "lockfile",
      parser: :parse_cyclonedx_xml,
      ungroupable: true,
    },
    match_extension("cdx.xml", case_insensitive: true) => {
      kind: "lockfile",
      parser: :parse_cyclonedx_xml,
      ungroupable: true,
    },
  }
end

.parse_cyclonedx_json(file_contents, options: {}) ⇒ Object

Raises:



103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/bibliothecary/multi_parsers/cyclonedx.rb', line 103

def self.parse_cyclonedx_json(file_contents, options: {})
  manifest = try_cache(options, options[:filename]) do
    JSON.parse(file_contents)
  end

  raise NoComponents unless manifest["components"]

  manifest_entries = ManifestEntries.new(
    parse_queue: manifest["components"]
  )

  manifest_entries.parse!(options.fetch(:filename, nil)) do |component, parse_queue|
    parse_queue.concat(component["components"]) if component["components"]

    { purl: component["purl"], version: component["version"] }
  end

  ParserResult.new(dependencies: manifest_entries.entries.to_a)
end

.parse_cyclonedx_xml(file_contents, options: {}) ⇒ Object

Raises:



123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/bibliothecary/multi_parsers/cyclonedx.rb', line 123

def self.parse_cyclonedx_xml(file_contents, options: {})
  manifest = try_cache(options, options[:filename]) do
    Ox.parse(file_contents)
  end

  root = manifest
  if root.respond_to?(:bom)
    root = root.bom
  end

  raise NoComponents unless root.locate("components").first

  manifest_entries = ManifestEntries.new(
    parse_queue: root.locate("components/*")
  )

  manifest_entries.parse!(options.fetch(:filename, nil)) do |component, parse_queue|
    # #locate returns an empty array if nothing is found, so we can
    # always safely concatenate it to the parse queue.
    parse_queue.concat(component.locate("components/*"))

    purl_text = component.locate("purl").first&.text
    version = component.locate("version").first&.text

    { purl: purl_text, version: version }
  end

  ParserResult.new(dependencies: manifest_entries.entries.to_a)
end

.platform_nameObject



99
100
101
# File 'lib/bibliothecary/multi_parsers/cyclonedx.rb', line 99

def self.platform_name
  raise "CycloneDX is a multi-parser and does not have a platform name."
end