cyclonedx-cocoapods 1.3.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5b02ca712eff5c74b3c7a4e3c59ab7a402a87cf2f3053be388f64a702ca0d3a1
4
- data.tar.gz: ca6e3d81e4b255dfcd43add1017e1b5dc939274544b6bade803da0246c544ebc
3
+ metadata.gz: 4b3c1577d54844759e40218fb3b0876014aa8a2eac1a8ea2be2512cab13d79f9
4
+ data.tar.gz: dd99bd2aa09a1d6ecd956fdd3118a064df6662026b6816ee86f9a2f553347068
5
5
  SHA512:
6
- metadata.gz: 74af3ed1ceded419670e4e4cc2b69a955730f963ef92510159505809a02681ae39347c91a24ac99d988f142f987465998fdd4bf4629e799d0dc33e01f96fbb9a
7
- data.tar.gz: b1ce5ceae85c7b3ff993109203a53f9f7fa61397f8d58f6b18220ee2ed5e866ab1bc210b6ac48b375de3ec49e6928abe2245413fac56b437403317fb1c2ba783
6
+ metadata.gz: 5e82c25c27de0fbede464d04a06b9b7f06c3fc79550041835395c6fe5aa32a0f1c4bba1d391b988ff6d39107f696960f064730de43ef8c0f0e8000d576cd1010
7
+ data.tar.gz: '048fa99979dd4e606b4952412dad3675bad2ebe3e45eccd8513089f18908d5594213031cb85130434f002d7a8edbafbb67818e602c648b49137768e8085c445b'
data/CHANGELOG.md CHANGED
@@ -4,6 +4,15 @@ All notable changes to this project will be documented in this file.
4
4
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5
5
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [1.4.0]
8
+
9
+ ### Added
10
+ - Added `evidence` element to the component output to indicate that we are doing manifest analysis to generate the bom. ([Issue #69](https://github.com/CycloneDX/cyclonedx-cocoapods/issues/69)) [@macblazer](https://github.com/macblazer).
11
+
12
+ ### Fixed
13
+ - Added top level dependencies when the metadata/component is specified (by using the `--name`, `--version`, and `--type` parameters). ([PR #70](https://github.com/CycloneDX/cyclonedx-cocoapods/pull/70)) [@fnxpt](https://github.com/fnxpt)
14
+ - Properly concatenate paths to Podfile and Podfile.lock (with unit tests!). ([Issue #71](https://github.com/CycloneDX/cyclonedx-cocoapods/issues/71)) [@macblazer](https://github.com/macblazer).
15
+
7
16
  ## [1.3.0]
8
17
 
9
18
  ### Added
@@ -104,10 +104,28 @@ module CycloneDX
104
104
  end
105
105
  end
106
106
 
107
- def add_to_bom(xml, trim_strings_length = 0)
107
+ # Add evidence of the purl identity.
108
+ # See https://github.com/CycloneDX/guides/blob/main/SBOM/en/0x60-Evidence.md for more info
109
+ def xml_add_evidence(xml, manifest_path)
110
+ xml.evidence do
111
+ xml.identity do
112
+ xml.field 'purl'
113
+ xml.confidence '0.6'
114
+ xml.methods_ do
115
+ xml.method_ do
116
+ xml.technique 'manifest-analysis'
117
+ xml.confidence '0.6'
118
+ xml.value manifest_path
119
+ end
120
+ end
121
+ end
122
+ end
123
+ end
124
+
125
+ def add_to_bom(xml, manifest_path, trim_strings_length = 0)
108
126
  xml.component(type: 'library', 'bom-ref': purl) do
109
127
  xml_add_author(xml, trim_strings_length)
110
- xml.name name
128
+ xml.name_ name
111
129
  xml.version version.to_s
112
130
  xml.description { xml.cdata description } unless description.nil?
113
131
  unless checksum.nil?
@@ -126,6 +144,8 @@ module CycloneDX
126
144
  xml.purl purl.slice(0, trim_strings_length)
127
145
  end
128
146
  xml_add_homepage(xml)
147
+
148
+ xml_add_evidence(xml, manifest_path)
129
149
  end
130
150
  end
131
151
 
@@ -133,7 +153,7 @@ module CycloneDX
133
153
  def add_to_bom(xml)
134
154
  xml.license do
135
155
  xml.id identifier if identifier_type == :id
136
- xml.name identifier if identifier_type == :name
156
+ xml.name_ identifier if identifier_type == :name
137
157
  xml.text_ text unless text.nil?
138
158
  xml.url url unless url.nil?
139
159
  end
@@ -143,21 +163,23 @@ module CycloneDX
143
163
 
144
164
  class Component
145
165
  def add_to_bom(xml)
146
- xml.component(type: type) do
166
+ xml.component(type: type, 'bom-ref': bomref) do
147
167
  xml.group group unless group.nil?
148
- xml.name name
168
+ xml.name_ name
149
169
  xml.version version
150
170
  end
151
171
  end
152
172
  end
153
173
 
174
+ # Turns the internal model data into an XML bom.
154
175
  class BOMBuilder
155
176
  NAMESPACE = 'http://cyclonedx.org/schema/bom/1.5'
156
177
 
157
- attr_reader :component, :pods, :dependencies
178
+ attr_reader :component, :pods, :manifest_path, :dependencies
158
179
 
159
- def initialize(pods:, component: nil, dependencies: nil)
180
+ def initialize(pods:, manifest_path:, component: nil, dependencies: nil)
160
181
  @pods = pods.sort_by(&:purl)
182
+ @manifest_path = manifest_path
161
183
  @component = component
162
184
  @dependencies = dependencies&.sort
163
185
  end
@@ -184,17 +206,17 @@ module CycloneDX
184
206
  xml.bom(xmlns: NAMESPACE, version: version.to_i.to_s, serialNumber: "urn:uuid:#{SecureRandom.uuid}") do
185
207
  bom_metadata(xml)
186
208
 
187
- bom_components(xml, pods, trim_strings_length)
209
+ bom_components(xml, pods, manifest_path, trim_strings_length)
188
210
 
189
211
  bom_dependencies(xml, dependencies)
190
212
  end
191
213
  end.to_xml
192
214
  end
193
215
 
194
- def bom_components(xml, pods, trim_strings_length)
216
+ def bom_components(xml, pods, manifest_path, trim_strings_length)
195
217
  xml.components do
196
218
  pods.each do |pod|
197
- pod.add_to_bom(xml, trim_strings_length)
219
+ pod.add_to_bom(xml, manifest_path, trim_strings_length)
198
220
  end
199
221
  end
200
222
  end
@@ -223,7 +245,7 @@ module CycloneDX
223
245
  xml.tools do
224
246
  xml.tool do
225
247
  xml.vendor 'CycloneDX'
226
- xml.name 'cyclonedx-cocoapods'
248
+ xml.name_ 'cyclonedx-cocoapods'
227
249
  xml.version VERSION
228
250
  end
229
251
  end
@@ -39,9 +39,9 @@ module CycloneDX
39
39
  setup_logger(verbose: options[:verbose])
40
40
  @logger.debug "Running cyclonedx-cocoapods with options: #{options}"
41
41
 
42
- pods, dependencies = analyze(options)
42
+ component, pods, manifest_path, dependencies = analyze(options)
43
43
 
44
- build_and_write_bom(options, pods, dependencies)
44
+ build_and_write_bom(options, component, pods, manifest_path, dependencies)
45
45
  rescue StandardError => e
46
46
  @logger.error ([e.message] + e.backtrace).join($INPUT_RECORD_SEPARATOR)
47
47
  exit 1
@@ -136,11 +136,26 @@ module CycloneDX
136
136
  pods, dependencies = analyzer.parse_pods(podfile, lockfile)
137
137
  analyzer.populate_pods_with_additional_info(pods)
138
138
 
139
- [pods, dependencies]
139
+ component = component_from_options(options)
140
+
141
+ unless component.nil?
142
+ # add top level pods to main component
143
+ top_deps = analyzer.top_level_deps(podfile, lockfile)
144
+ dependencies[component.bomref] = top_deps
145
+ end
146
+
147
+ manifest_path = lockfile.defined_in_file
148
+ if manifest_path.absolute?
149
+ # Use the folder that we are building in, then the path to the manifest file
150
+ manifest_path = Pathname.pwd.basename + manifest_path.relative_path_from(Pathname.pwd)
151
+ end
152
+
153
+ [component, pods, manifest_path, dependencies]
140
154
  end
141
155
 
142
- def build_and_write_bom(options, pods, dependencies)
143
- builder = BOMBuilder.new(pods: pods, component: component_from_options(options), dependencies: dependencies)
156
+ def build_and_write_bom(options, component, pods, manifest_path, dependencies)
157
+ builder = BOMBuilder.new(pods: pods, manifest_path: manifest_path,
158
+ component: component, dependencies: dependencies)
144
159
  bom = builder.bom(version: options[:bom_version] || 1,
145
160
  trim_strings_length: options[:trim_strings_length] || 0)
146
161
  write_bom_to_file(bom: bom, options: options)
@@ -24,7 +24,7 @@ module CycloneDX
24
24
  class Component
25
25
  VALID_COMPONENT_TYPES = %w[application framework library container operating-system device firmware file].freeze
26
26
 
27
- attr_reader :group, :name, :version, :type
27
+ attr_reader :group, :name, :version, :type, :bomref
28
28
 
29
29
  def initialize(name:, version:, type:, group: nil)
30
30
  raise ArgumentError, 'Group, if specified, must be non empty' if !group.nil? && group.to_s.strip.empty?
@@ -39,6 +39,11 @@ module CycloneDX
39
39
  @name = name
40
40
  @version = version
41
41
  @type = type
42
+ @bomref = "#{name}@#{version}"
43
+
44
+ return if group.nil?
45
+
46
+ @bomref = "#{group}/#{@bomref}"
42
47
  end
43
48
  end
44
49
  end
@@ -74,6 +74,11 @@ module CycloneDX
74
74
  pods
75
75
  end
76
76
 
77
+ def top_level_deps(podfile, lockfile)
78
+ pods_used = top_level_pods(podfile)
79
+ dependencies_for_pod(pods_used, podfile, lockfile)
80
+ end
81
+
77
82
  private
78
83
 
79
84
  def load_plugins(podfile_path)
@@ -137,6 +142,8 @@ module CycloneDX
137
142
  end
138
143
 
139
144
  def initialize_cocoapods_config(project_dir)
145
+ # First, reset the ::Pod::Config instance in case we need to use this analyzer on multiple pods
146
+ ::Pod::Config.instance = nil
140
147
  ::Pod::Config.instance.installation_root = project_dir
141
148
  end
142
149
 
@@ -204,15 +211,19 @@ module CycloneDX
204
211
  [result, dependencies_hash]
205
212
  end
206
213
 
207
- def create_list_of_included_pods(podfile, lockfile)
208
- pods_cache = simple_hash_of_lockfile_pods(lockfile)
209
-
214
+ def top_level_pods(podfile)
210
215
  included_targets = podfile.target_definition_list.select { |target| include_target_named(target.label) }
211
216
  included_target_names = included_targets.map(&:label)
212
217
  @logger.debug "Including all pods for targets: #{included_target_names}"
213
218
 
214
219
  top_level_deps = included_targets.map(&:dependencies).flatten.uniq
215
- pods_used = top_level_deps.map(&:name).uniq
220
+ top_level_deps.map(&:name).uniq
221
+ end
222
+
223
+ def create_list_of_included_pods(podfile, lockfile)
224
+ pods_cache = simple_hash_of_lockfile_pods(lockfile)
225
+
226
+ pods_used = top_level_pods(podfile)
216
227
  pods_used, dependencies = append_all_pod_dependencies(pods_used, pods_cache)
217
228
 
218
229
  [pods_used.sort, dependencies]
@@ -21,6 +21,6 @@
21
21
 
22
22
  module CycloneDX
23
23
  module CocoaPods
24
- VERSION = '1.3.0'
24
+ VERSION = '1.4.0'
25
25
  end
26
26
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cyclonedx-cocoapods
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - José González
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2024-02-08 00:00:00.000000000 Z
12
+ date: 2024-10-15 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: cocoapods
@@ -140,7 +140,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
140
140
  - !ruby/object:Gem::Version
141
141
  version: '0'
142
142
  requirements: []
143
- rubygems_version: 3.5.4
143
+ rubygems_version: 3.5.16
144
144
  signing_key:
145
145
  specification_version: 4
146
146
  summary: CycloneDX software bill-of-material (SBOM) generation utility