cyclonedx-cocoapods 1.0.0 → 1.1.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 +4 -4
- data/CHANGELOG.md +4 -0
- data/README.md +23 -11
- data/lib/cyclonedx/cocoapods/cli_runner.rb +34 -109
- data/lib/cyclonedx/cocoapods/podfile_analyzer.rb +182 -0
- data/lib/cyclonedx/cocoapods/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a3c7ebcac0eb8ea04cf5b1aed4da3bdbe1cadc2acb33e1bc4ebec9f52ac9bad9
|
4
|
+
data.tar.gz: bdc83e96c9b4750bf2135a85b30d384ae2096e4c0591d3db2f65434506f4c220
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 94cdbbcb32c6d83dad78c383536dc484f08a040f5104318a3c2355b070fb915474e25027188bcaa8dfffc4222772525e4e051dfc8a1d673a08a31cd51f4d3cc2
|
7
|
+
data.tar.gz: 1c0da4d2d356eb06207f889605e3c65ea0594821b7de130ebe5ce3d182917f87415fdc615d727f54f540b5a3c9c2b58d915117627b7b71c7a115045e799bc0c4
|
data/CHANGELOG.md
CHANGED
@@ -4,6 +4,10 @@ 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.1.0]
|
8
|
+
|
9
|
+
- Can now eliminate Podfile targets that include "test" in their name ([Issue #43](https://github.com/CycloneDX/cyclonedx-cocoapods/issues/43)) [@macblazer](https://github.com/macblazer).
|
10
|
+
|
7
11
|
## [1.0.0]
|
8
12
|
|
9
13
|
### Added
|
data/README.md
CHANGED
@@ -9,7 +9,7 @@
|
|
9
9
|
|
10
10
|
# CycloneDX CocoaPods (Objective-C/Swift)
|
11
11
|
|
12
|
-
The CycloneDX CocoaPods Gem creates a valid CycloneDX software bill-of-material document from all project dependencies. CycloneDX is a lightweight BoM specification that is easily created, human readable, and simple to parse.
|
12
|
+
The CycloneDX CocoaPods Gem creates a valid CycloneDX software bill-of-material document from all [CocoaPods](https://cocoapods.org/) project dependencies. CycloneDX is a lightweight BoM specification that is easily created, human readable, and simple to parse.
|
13
13
|
|
14
14
|
## Installation
|
15
15
|
|
@@ -36,18 +36,30 @@ Building from source requires Ruby 2.4.0 or newer.
|
|
36
36
|
You can use the [CycloneDX CLI](https://github.com/CycloneDX/cyclonedx-cli#convert-command) to convert between multiple BOM formats or specification versions.
|
37
37
|
|
38
38
|
## Usage
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
-t, --type type (Optional) Type of the component for which the BOM is generated (one of application|framework|library|container|operating-system|device|firmware|file)
|
39
|
+
```
|
40
|
+
Generates a BOM with the given parameters. BOM component metadata is only generated if the component's name, version, and type are provided using the --name, --version, and --type parameters.
|
41
|
+
[version <version_number>]
|
42
|
+
|
43
|
+
USAGE
|
44
|
+
cyclonedx-cocoapods [options]
|
45
|
+
|
46
|
+
OPTIONS
|
47
|
+
--[no-]verbose Show verbose debugging output
|
49
48
|
-h, --help Show help message
|
50
49
|
|
50
|
+
BOM Generation
|
51
|
+
-p, --path path Path to CocoaPods project directory (default: current directory)
|
52
|
+
-o, --output bom_file_path Path to output the bom.xml file to (default: "bom.xml")
|
53
|
+
-b, --bom-version bom_version Version of the generated BOM (default: "1")
|
54
|
+
-x, --exclude-test-targets Eliminate Podfile targets whose name contains the word "test"
|
55
|
+
|
56
|
+
Component Metadata
|
57
|
+
-n, --name name (If specified version and type are also required) Name of the component for which the BOM is generated
|
58
|
+
-v, --version version Version of the component for which the BOM is generated
|
59
|
+
-t, --type type Type of the component for which the BOM is generated (one of application|framework|library|container|operating-system|device|firmware|file)
|
60
|
+
-g, --group group Group of the component for which the BOM is generated
|
61
|
+
```
|
62
|
+
|
51
63
|
**Output:** BoM file at specified location, `./bom.xml` if not specified
|
52
64
|
|
53
65
|
### Example
|
@@ -18,19 +18,15 @@
|
|
18
18
|
# Copyright (c) OWASP Foundation. All Rights Reserved.
|
19
19
|
#
|
20
20
|
|
21
|
-
require 'optparse'
|
22
21
|
require 'logger'
|
23
|
-
require '
|
22
|
+
require 'optparse'
|
24
23
|
|
25
|
-
require_relative 'component'
|
26
|
-
require_relative 'pod'
|
27
|
-
require_relative 'pod_attributes'
|
28
|
-
require_relative 'source'
|
29
24
|
require_relative 'bom_builder'
|
25
|
+
require_relative 'component'
|
26
|
+
require_relative 'podfile_analyzer'
|
30
27
|
|
31
28
|
module CycloneDX
|
32
29
|
module CocoaPods
|
33
|
-
class PodfileParsingError < StandardError; end
|
34
30
|
class BOMOutputError < StandardError; end
|
35
31
|
|
36
32
|
class CLIRunner
|
@@ -41,10 +37,10 @@ module CycloneDX
|
|
41
37
|
setup_logger(verbose: options[:verbose])
|
42
38
|
@logger.debug "Running cyclonedx-cocoapods with options: #{options}"
|
43
39
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
populate_pods_with_additional_info(pods)
|
40
|
+
analyzer = PodfileAnalyzer.new(logger: @logger, exclude_test_targets: options[:exclude_test_targets])
|
41
|
+
podfile, lockfile = analyzer.ensure_podfile_and_lock_are_present(options)
|
42
|
+
pods = analyzer.parse_pods(podfile, lockfile)
|
43
|
+
analyzer.populate_pods_with_additional_info(pods)
|
48
44
|
|
49
45
|
bom = BOMBuilder.new(component: component_from_options(options), pods: pods).bom(version: options[:bom_version] || 1)
|
50
46
|
write_bom_to_file(bom: bom, options: options)
|
@@ -57,34 +53,48 @@ module CycloneDX
|
|
57
53
|
|
58
54
|
private
|
59
55
|
|
56
|
+
|
60
57
|
def parseOptions
|
61
58
|
parsedOptions = {}
|
62
59
|
component_types = Component::VALID_COMPONENT_TYPES
|
63
60
|
OptionParser.new do |options|
|
64
61
|
options.banner = <<~BANNER
|
65
|
-
|
66
|
-
|
62
|
+
Generates a BOM with the given parameters. BOM component metadata is only generated if the component's name, version, and type are provided using the --name, --version, and --type parameters.
|
63
|
+
[version #{CycloneDX::CocoaPods::VERSION}]
|
64
|
+
|
65
|
+
USAGE
|
66
|
+
cyclonedx-cocoapods [options]
|
67
|
+
|
68
|
+
OPTIONS
|
67
69
|
BANNER
|
68
70
|
|
69
|
-
options.on('--[no-]verbose', '
|
71
|
+
options.on('--[no-]verbose', 'Show verbose debugging output') do |v|
|
70
72
|
parsedOptions[:verbose] = v
|
71
73
|
end
|
72
|
-
options.on('-
|
74
|
+
options.on('-h', '--help', 'Show help message') do
|
75
|
+
puts options
|
76
|
+
exit
|
77
|
+
end
|
78
|
+
|
79
|
+
options.separator("\n BOM Generation")
|
80
|
+
options.on('-p', '--path path', 'Path to CocoaPods project directory (default: current directory)') do |path|
|
73
81
|
parsedOptions[:path] = path
|
74
82
|
end
|
75
|
-
options.on('-o', '--output bom_file_path', '
|
83
|
+
options.on('-o', '--output bom_file_path', 'Path to output the bom.xml file to (default: "bom.xml")') do |bom_file_path|
|
76
84
|
parsedOptions[:bom_file_path] = bom_file_path
|
77
85
|
end
|
78
|
-
options.on('-b', '--bom-version bom_version', Integer, '
|
86
|
+
options.on('-b', '--bom-version bom_version', Integer, 'Version of the generated BOM (default: "1")') do |version|
|
79
87
|
parsedOptions[:bom_version] = version
|
80
88
|
end
|
81
|
-
options.on('-
|
82
|
-
parsedOptions[:
|
89
|
+
options.on('-x', '--exclude-test-targets', 'Eliminate Podfile targets whose name contains the word "test"') do |exclude|
|
90
|
+
parsedOptions[:exclude_test_targets] = exclude
|
83
91
|
end
|
84
|
-
|
92
|
+
|
93
|
+
options.separator("\n Component Metadata\n")
|
94
|
+
options.on('-n', '--name name', '(If specified version and type are also required) Name of the component for which the BOM is generated') do |name|
|
85
95
|
parsedOptions[:name] = name
|
86
96
|
end
|
87
|
-
options.on('-v', '--version version', '
|
97
|
+
options.on('-v', '--version version', 'Version of the component for which the BOM is generated') do |version|
|
88
98
|
begin
|
89
99
|
Gem::Version.new(version)
|
90
100
|
parsedOptions[:version] = version
|
@@ -92,13 +102,12 @@ module CycloneDX
|
|
92
102
|
raise OptionParser::InvalidArgument, e.message
|
93
103
|
end
|
94
104
|
end
|
95
|
-
options.on('-t', '--type type', "
|
105
|
+
options.on('-t', '--type type', "Type of the component for which the BOM is generated (one of #{component_types.join('|')})") do |type|
|
96
106
|
raise OptionParser::InvalidArgument, "Invalid value for component's type (#{type}). It must be one of #{component_types.join('|')}" unless component_types.include?(type)
|
97
107
|
parsedOptions[:type] = type
|
98
108
|
end
|
99
|
-
options.
|
100
|
-
|
101
|
-
exit
|
109
|
+
options.on('-g', '--group group', 'Group of the component for which the BOM is generated') do |group|
|
110
|
+
parsedOptions[:group] = group
|
102
111
|
end
|
103
112
|
end.parse!
|
104
113
|
|
@@ -118,90 +127,6 @@ module CycloneDX
|
|
118
127
|
end
|
119
128
|
|
120
129
|
|
121
|
-
def ensure_podfile_and_lock_are_present(options)
|
122
|
-
project_dir = Pathname.new(options[:path] || Dir.pwd)
|
123
|
-
raise PodfileParsingError, "#{options[:path]} is not a valid directory." unless File.directory?(project_dir)
|
124
|
-
options[:podfile_path] = project_dir + 'Podfile'
|
125
|
-
raise PodfileParsingError, "Missing Podfile in #{project_dir}. Please use the --path option if not running from the CocoaPods project directory." unless File.exist?(options[:podfile_path])
|
126
|
-
options[:podfile_lock_path] = project_dir + 'Podfile.lock'
|
127
|
-
raise PodfileParsingError, "Missing Podfile.lock, please run 'pod install' before generating BOM" unless File.exist?(options[:podfile_lock_path])
|
128
|
-
|
129
|
-
initialize_cocoapods_config(project_dir)
|
130
|
-
|
131
|
-
lockfile = ::Pod::Lockfile.from_file(options[:podfile_lock_path])
|
132
|
-
verify_synced_sandbox(lockfile)
|
133
|
-
|
134
|
-
return ::Pod::Podfile.from_file(options[:podfile_path]), lockfile
|
135
|
-
end
|
136
|
-
|
137
|
-
|
138
|
-
def initialize_cocoapods_config(project_dir)
|
139
|
-
::Pod::Config.instance.installation_root = project_dir
|
140
|
-
end
|
141
|
-
|
142
|
-
|
143
|
-
def verify_synced_sandbox(lockfile)
|
144
|
-
manifestFile = ::Pod::Config.instance.sandbox.manifest
|
145
|
-
raise PodfileParsingError, "Missing Manifest.lock, please run 'pod install' before generating BOM" if manifestFile.nil?
|
146
|
-
raise PodfileParsingError, "The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation." unless lockfile == manifestFile
|
147
|
-
end
|
148
|
-
|
149
|
-
|
150
|
-
def cocoapods_repository_source(podfile, lockfile, pod_name)
|
151
|
-
@source_manager ||= create_source_manager(podfile)
|
152
|
-
return Source::CocoaPodsRepository.searchable_source(url: lockfile.spec_repo(pod_name), source_manager: @source_manager)
|
153
|
-
end
|
154
|
-
|
155
|
-
|
156
|
-
def git_source(lockfile, pod_name)
|
157
|
-
checkout_options = lockfile.checkout_options_for_pod_named(pod_name)
|
158
|
-
url = checkout_options[:git]
|
159
|
-
[:tag, :branch, :commit].each do |type|
|
160
|
-
return Source::GitRepository.new(url: url, type: type, label: checkout_options[type]) if checkout_options[type]
|
161
|
-
end
|
162
|
-
return Source::GitRepository.new(url: url)
|
163
|
-
end
|
164
|
-
|
165
|
-
|
166
|
-
def source_for_pod(podfile, lockfile, pod_name)
|
167
|
-
root_name = pod_name.split('/').first
|
168
|
-
return cocoapods_repository_source(podfile, lockfile, root_name) unless lockfile.spec_repo(root_name).nil?
|
169
|
-
return git_source(lockfile, root_name) unless lockfile.checkout_options_for_pod_named(root_name).nil?
|
170
|
-
return Source::LocalPod.new(path: lockfile.to_hash['EXTERNAL SOURCES'][root_name][:path]) if lockfile.to_hash['EXTERNAL SOURCES'][root_name][:path]
|
171
|
-
return Source::Podspec.new(url: lockfile.to_hash['EXTERNAL SOURCES'][root_name][:podspec]) if lockfile.to_hash['EXTERNAL SOURCES'][root_name][:podspec]
|
172
|
-
return nil
|
173
|
-
end
|
174
|
-
|
175
|
-
|
176
|
-
def parse_pods(podfile, lockfile)
|
177
|
-
@logger.debug "Parsing pods from #{podfile.defined_in_file}"
|
178
|
-
return lockfile.pod_names.map do |name|
|
179
|
-
Pod.new(name: name, version: lockfile.version(name), source: source_for_pod(podfile, lockfile, name), checksum: lockfile.checksum(name))
|
180
|
-
end
|
181
|
-
end
|
182
|
-
|
183
|
-
|
184
|
-
def create_source_manager(podfile)
|
185
|
-
sourceManager = ::Pod::Source::Manager.new(::Pod::Config::instance.repos_dir)
|
186
|
-
@logger.debug "Parsing sources from #{podfile.defined_in_file}"
|
187
|
-
podfile.sources.each do |source|
|
188
|
-
@logger.debug "Ensuring #{source} is available for searches"
|
189
|
-
sourceManager.find_or_create_source_with_url(source)
|
190
|
-
end
|
191
|
-
@logger.debug "Source manager successfully created with all needed sources"
|
192
|
-
return sourceManager
|
193
|
-
end
|
194
|
-
|
195
|
-
|
196
|
-
def populate_pods_with_additional_info(pods)
|
197
|
-
pods.each do |pod|
|
198
|
-
@logger.debug "Completing information for #{pod.name}"
|
199
|
-
pod.complete_information_from_source
|
200
|
-
end
|
201
|
-
return pods
|
202
|
-
end
|
203
|
-
|
204
|
-
|
205
130
|
def write_bom_to_file(bom:, options:)
|
206
131
|
bom_file_path = Pathname.new(options[:bom_file_path] || './bom.xml').expand_path
|
207
132
|
bom_dir = bom_file_path.dirname
|
@@ -0,0 +1,182 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
#
|
3
|
+
# This file is part of CycloneDX CocoaPods
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the “License”);
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an “AS IS” BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
#
|
17
|
+
# SPDX-License-Identifier: Apache-2.0
|
18
|
+
# Copyright (c) OWASP Foundation. All Rights Reserved.
|
19
|
+
#
|
20
|
+
|
21
|
+
require 'cocoapods'
|
22
|
+
require 'logger'
|
23
|
+
|
24
|
+
require_relative 'pod'
|
25
|
+
require_relative 'pod_attributes'
|
26
|
+
require_relative 'source'
|
27
|
+
|
28
|
+
module CycloneDX
|
29
|
+
module CocoaPods
|
30
|
+
class PodfileParsingError < StandardError; end
|
31
|
+
|
32
|
+
class PodfileAnalyzer
|
33
|
+
def initialize(logger:, exclude_test_targets: false)
|
34
|
+
@logger = logger
|
35
|
+
@exclude_test_targets = exclude_test_targets
|
36
|
+
end
|
37
|
+
|
38
|
+
def ensure_podfile_and_lock_are_present(options)
|
39
|
+
project_dir = Pathname.new(options[:path] || Dir.pwd)
|
40
|
+
raise PodfileParsingError, "#{options[:path]} is not a valid directory." unless File.directory?(project_dir)
|
41
|
+
options[:podfile_path] = project_dir + 'Podfile'
|
42
|
+
raise PodfileParsingError, "Missing Podfile in #{project_dir}. Please use the --path option if not running from the CocoaPods project directory." unless File.exist?(options[:podfile_path])
|
43
|
+
options[:podfile_lock_path] = project_dir + 'Podfile.lock'
|
44
|
+
raise PodfileParsingError, "Missing Podfile.lock, please run 'pod install' before generating BOM" unless File.exist?(options[:podfile_lock_path])
|
45
|
+
|
46
|
+
initialize_cocoapods_config(project_dir)
|
47
|
+
|
48
|
+
lockfile = ::Pod::Lockfile.from_file(options[:podfile_lock_path])
|
49
|
+
verify_synced_sandbox(lockfile)
|
50
|
+
|
51
|
+
return ::Pod::Podfile.from_file(options[:podfile_path]), lockfile
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
def parse_pods(podfile, lockfile)
|
56
|
+
@logger.debug "Parsing pods from #{podfile.defined_in_file}"
|
57
|
+
included_pods = create_list_of_included_pods(podfile, lockfile)
|
58
|
+
return lockfile.pod_names.select { |name| included_pods.include?(name) }.map do |name|
|
59
|
+
Pod.new(name: name, version: lockfile.version(name), source: source_for_pod(podfile, lockfile, name), checksum: lockfile.checksum(name))
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
def populate_pods_with_additional_info(pods)
|
65
|
+
pods.each do |pod|
|
66
|
+
@logger.debug "Completing information for #{pod.name}"
|
67
|
+
pod.complete_information_from_source
|
68
|
+
end
|
69
|
+
return pods
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
|
76
|
+
def initialize_cocoapods_config(project_dir)
|
77
|
+
::Pod::Config.instance.installation_root = project_dir
|
78
|
+
end
|
79
|
+
|
80
|
+
|
81
|
+
def verify_synced_sandbox(lockfile)
|
82
|
+
manifestFile = ::Pod::Config.instance.sandbox.manifest
|
83
|
+
raise PodfileParsingError, "Missing Manifest.lock, please run 'pod install' before generating BOM" if manifestFile.nil?
|
84
|
+
raise PodfileParsingError, "The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation." unless lockfile == manifestFile
|
85
|
+
end
|
86
|
+
|
87
|
+
def simple_hash_of_lockfile_pods(lockfile)
|
88
|
+
pods_hash = { }
|
89
|
+
|
90
|
+
pods_used = lockfile.internal_data['PODS']
|
91
|
+
pods_used.each { |pod|
|
92
|
+
if pod.is_a?(String)
|
93
|
+
# Pods stored as String have no dependencies
|
94
|
+
pod_name = pod.split.first
|
95
|
+
pods_hash[pod_name] = []
|
96
|
+
else
|
97
|
+
# Pods stored as a hash have pod name and dependencies.
|
98
|
+
pod.each { |pod, dependencies|
|
99
|
+
pod_name = pod.split.first
|
100
|
+
pods_hash[pod_name] = dependencies.map { |d| d.split.first }
|
101
|
+
}
|
102
|
+
end
|
103
|
+
}
|
104
|
+
pods_hash
|
105
|
+
end
|
106
|
+
|
107
|
+
def append_all_pod_dependencies(pods_used, pods_cache)
|
108
|
+
result = pods_used
|
109
|
+
original_number = 0
|
110
|
+
# Loop adding pod dependencies until we are not adding any more dependencies to the result
|
111
|
+
# This brings in all the transitive dependencies of every top level pod.
|
112
|
+
# Note this also handles the edge case of having a Podfile with no pods used.
|
113
|
+
while result.length != original_number
|
114
|
+
original_number = result.length
|
115
|
+
pods_used.each { |pod_name|
|
116
|
+
result.push(*pods_cache[pod_name]) unless pods_cache[pod_name].empty?
|
117
|
+
}
|
118
|
+
result = result.uniq
|
119
|
+
pods_used = result
|
120
|
+
end
|
121
|
+
result
|
122
|
+
end
|
123
|
+
|
124
|
+
def create_list_of_included_pods(podfile, lockfile)
|
125
|
+
pods_cache = simple_hash_of_lockfile_pods(lockfile)
|
126
|
+
|
127
|
+
includedTargets = podfile.target_definition_list.select{ |target| include_target_named(target.label) }
|
128
|
+
includedTargetNames = includedTargets.map { |target| target.label }
|
129
|
+
@logger.debug "Including all pods for targets: #{includedTargetNames}"
|
130
|
+
|
131
|
+
topLevelDeps = includedTargets.map(&:dependencies).flatten.uniq
|
132
|
+
pods_used = topLevelDeps.map(&:name).uniq
|
133
|
+
pods_used = append_all_pod_dependencies(pods_used, pods_cache)
|
134
|
+
|
135
|
+
return pods_used.sort
|
136
|
+
end
|
137
|
+
|
138
|
+
|
139
|
+
def include_target_named(targetname)
|
140
|
+
!@exclude_test_targets || !targetname.downcase.include?('test')
|
141
|
+
end
|
142
|
+
|
143
|
+
|
144
|
+
def cocoapods_repository_source(podfile, lockfile, pod_name)
|
145
|
+
@source_manager ||= create_source_manager(podfile)
|
146
|
+
return Source::CocoaPodsRepository.searchable_source(url: lockfile.spec_repo(pod_name), source_manager: @source_manager)
|
147
|
+
end
|
148
|
+
|
149
|
+
|
150
|
+
def git_source(lockfile, pod_name)
|
151
|
+
checkout_options = lockfile.checkout_options_for_pod_named(pod_name)
|
152
|
+
url = checkout_options[:git]
|
153
|
+
[:tag, :branch, :commit].each do |type|
|
154
|
+
return Source::GitRepository.new(url: url, type: type, label: checkout_options[type]) if checkout_options[type]
|
155
|
+
end
|
156
|
+
return Source::GitRepository.new(url: url)
|
157
|
+
end
|
158
|
+
|
159
|
+
|
160
|
+
def source_for_pod(podfile, lockfile, pod_name)
|
161
|
+
root_name = pod_name.split('/').first
|
162
|
+
return cocoapods_repository_source(podfile, lockfile, root_name) unless lockfile.spec_repo(root_name).nil?
|
163
|
+
return git_source(lockfile, root_name) unless lockfile.checkout_options_for_pod_named(root_name).nil?
|
164
|
+
return Source::LocalPod.new(path: lockfile.to_hash['EXTERNAL SOURCES'][root_name][:path]) if lockfile.to_hash['EXTERNAL SOURCES'][root_name][:path]
|
165
|
+
return Source::Podspec.new(url: lockfile.to_hash['EXTERNAL SOURCES'][root_name][:podspec]) if lockfile.to_hash['EXTERNAL SOURCES'][root_name][:podspec]
|
166
|
+
return nil
|
167
|
+
end
|
168
|
+
|
169
|
+
|
170
|
+
def create_source_manager(podfile)
|
171
|
+
sourceManager = ::Pod::Source::Manager.new(::Pod::Config::instance.repos_dir)
|
172
|
+
@logger.debug "Parsing sources from #{podfile.defined_in_file}"
|
173
|
+
podfile.sources.each do |source|
|
174
|
+
@logger.debug "Ensuring #{source} is available for searches"
|
175
|
+
sourceManager.find_or_create_source_with_url(source)
|
176
|
+
end
|
177
|
+
@logger.debug "Source manager successfully created with all needed sources"
|
178
|
+
return sourceManager
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cyclonedx-cocoapods
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- José González
|
8
|
+
- Kyle Hammond
|
8
9
|
autorequire:
|
9
10
|
bindir: exe
|
10
11
|
cert_chain: []
|
11
|
-
date: 2022-
|
12
|
+
date: 2022-09-13 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: cocoapods
|
@@ -85,6 +86,7 @@ description: CycloneDX is a lightweight software bill-of-material (SBOM) specifi
|
|
85
86
|
This Gem generates CycloneDX BOMs from CocoaPods projects.
|
86
87
|
email:
|
87
88
|
- jose.gonzalez@openinput.com
|
89
|
+
- kyle.hammond@jamf.com
|
88
90
|
executables:
|
89
91
|
- cyclonedx-cocoapods
|
90
92
|
extensions: []
|
@@ -101,6 +103,7 @@ files:
|
|
101
103
|
- lib/cyclonedx/cocoapods/license.rb
|
102
104
|
- lib/cyclonedx/cocoapods/pod.rb
|
103
105
|
- lib/cyclonedx/cocoapods/pod_attributes.rb
|
106
|
+
- lib/cyclonedx/cocoapods/podfile_analyzer.rb
|
104
107
|
- lib/cyclonedx/cocoapods/source.rb
|
105
108
|
- lib/cyclonedx/cocoapods/spdx-licenses.json
|
106
109
|
- lib/cyclonedx/cocoapods/version.rb
|