Skip to content

Commit

Permalink
Merge pull request #70 from fnxpt/rootComponentdependencies
Browse files Browse the repository at this point in the history
Add root component in dependencies element
  • Loading branch information
macblazer committed Mar 22, 2024
2 parents 0e16d02 + 26dff2b commit 4d463c3
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 13 deletions.
2 changes: 1 addition & 1 deletion lib/cyclonedx/cocoapods/bom_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ def add_to_bom(xml)

class Component
def add_to_bom(xml)
xml.component(type: type) do
xml.component(type: type, 'bom-ref': bomref) do
xml.group group unless group.nil?
xml.name name
xml.version version
Expand Down
18 changes: 13 additions & 5 deletions lib/cyclonedx/cocoapods/cli_runner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ def run
setup_logger(verbose: options[:verbose])
@logger.debug "Running cyclonedx-cocoapods with options: #{options}"

pods, dependencies = analyze(options)
component, pods, dependencies = analyze(options)

build_and_write_bom(options, pods, dependencies)
build_and_write_bom(options, component, pods, dependencies)
rescue StandardError => e
@logger.error ([e.message] + e.backtrace).join($INPUT_RECORD_SEPARATOR)
exit 1
Expand Down Expand Up @@ -136,11 +136,19 @@ def analyze(options)
pods, dependencies = analyzer.parse_pods(podfile, lockfile)
analyzer.populate_pods_with_additional_info(pods)

[pods, dependencies]
component = component_from_options(options)

unless component.nil?
# add top level pods to main component
top_deps = analyzer.top_level_deps(podfile, lockfile)
dependencies[component.bomref] = top_deps
end

[component, pods, dependencies]
end

def build_and_write_bom(options, pods, dependencies)
builder = BOMBuilder.new(pods: pods, component: component_from_options(options), dependencies: dependencies)
def build_and_write_bom(options, component, pods, dependencies)
builder = BOMBuilder.new(pods: pods, component: component, dependencies: dependencies)
bom = builder.bom(version: options[:bom_version] || 1,
trim_strings_length: options[:trim_strings_length] || 0)
write_bom_to_file(bom: bom, options: options)
Expand Down
7 changes: 6 additions & 1 deletion lib/cyclonedx/cocoapods/component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ module CocoaPods
class Component
VALID_COMPONENT_TYPES = %w[application framework library container operating-system device firmware file].freeze

attr_reader :group, :name, :version, :type
attr_reader :group, :name, :version, :type, :bomref

def initialize(name:, version:, type:, group: nil)
raise ArgumentError, 'Group, if specified, must be non empty' if !group.nil? && group.to_s.strip.empty?
Expand All @@ -39,6 +39,11 @@ def initialize(name:, version:, type:, group: nil)
@name = name
@version = version
@type = type
@bomref = "#{name}@#{version}"

return if group.nil?

@bomref = "#{group}/#{@bomref}"
end
end
end
Expand Down
21 changes: 15 additions & 6 deletions lib/cyclonedx/cocoapods/podfile_analyzer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,11 @@ def populate_pods_with_additional_info(pods)
pods
end

def top_level_deps(podfile, lockfile)
pods_used = top_level_pods(podfile)
dependencies_for_pod(pods_used, podfile, lockfile)
end

private

def load_plugins(podfile_path)
Expand All @@ -100,13 +105,13 @@ def load_one_plugin(plugin_name)
def validate_options(project_dir, options)
raise PodfileParsingError, "#{options[:path]} is not a valid directory." unless File.directory?(project_dir)

options[:podfile_path] = project_dir + 'Podfile'
options[:podfile_path] = "#{project_dir}Podfile"
unless File.exist?(options[:podfile_path])
raise PodfileParsingError, "Missing Podfile in #{project_dir}. Please use the --path option if " \
'not running from the CocoaPods project directory.'
end

options[:podfile_lock_path] = project_dir + 'Podfile.lock'
options[:podfile_lock_path] = "#{project_dir}Podfile.lock"
return if File.exist?(options[:podfile_lock_path])

raise PodfileParsingError, "Missing Podfile.lock, please run 'pod install' before generating BOM"
Expand Down Expand Up @@ -204,15 +209,19 @@ def append_all_pod_dependencies(pods_used, pods_cache)
[result, dependencies_hash]
end

def create_list_of_included_pods(podfile, lockfile)
pods_cache = simple_hash_of_lockfile_pods(lockfile)

def top_level_pods(podfile)
included_targets = podfile.target_definition_list.select { |target| include_target_named(target.label) }
included_target_names = included_targets.map(&:label)
@logger.debug "Including all pods for targets: #{included_target_names}"

top_level_deps = included_targets.map(&:dependencies).flatten.uniq
pods_used = top_level_deps.map(&:name).uniq
top_level_deps.map(&:name).uniq
end

def create_list_of_included_pods(podfile, lockfile)
pods_cache = simple_hash_of_lockfile_pods(lockfile)

pods_used = top_level_pods(podfile)
pods_used, dependencies = append_all_pod_dependencies(pods_used, pods_cache)

[pods_used.sort, dependencies]
Expand Down
4 changes: 4 additions & 0 deletions spec/cyclonedx/cocoapods/bom_builder_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -248,13 +248,15 @@
it 'should generate a root component element' do
expect(xml.at('/component')).not_to be_nil
expect(xml.at('/component')['type']).to eq(component.type)
expect(xml.at('/component')['bom-ref']).not_to be_nil
end

it 'should generate proper component information' do
expect(xml.at('/component/name')).not_to be_nil
expect(xml.at('/component/name').text).to eq(component.name)
expect(xml.at('/component/version')).not_to be_nil
expect(xml.at('/component/version').text).to eq(component.version)
expect(xml.at('/component')['bom-ref']).not_to be_nil
end
end

Expand All @@ -268,6 +270,7 @@

it 'should not generate any group element' do
expect(xml.at('/component/group')).to be_nil
expect(xml.at('/component')['bom-ref']).to eq('[email protected]')
end
end

Expand All @@ -284,6 +287,7 @@
it 'should generate a proper group element' do
expect(xml.at('/component/group')).not_to be_nil
expect(xml.at('/component/group').text).to eq(component.group)
expect(xml.at('/component')['bom-ref']).to eq('application-group/[email protected]')
end
end
end
Expand Down

0 comments on commit 4d463c3

Please sign in to comment.