Commit dd692733 authored by Jan Provaznik's avatar Jan Provaznik

Merge branch '13084-parse-licenses-to-dl' into 'master'

Merge License info to Dependency List report

See merge request gitlab-org/gitlab-ee!15157
parents 22c25d2d 512d82dc
...@@ -78,6 +78,10 @@ module EE ...@@ -78,6 +78,10 @@ module EE
each_report(::Ci::JobArtifact::DEPENDENCY_LIST_REPORT_FILE_TYPES) do |file_type, blob| each_report(::Ci::JobArtifact::DEPENDENCY_LIST_REPORT_FILE_TYPES) do |file_type, blob|
dependency_list.parse!(blob, dependency_list_report) dependency_list.parse!(blob, dependency_list_report)
end end
each_report(::Ci::JobArtifact::LICENSE_MANAGEMENT_REPORT_FILE_TYPES) do |file_type, blob|
dependency_list.parse_licenses!(blob, dependency_list_report)
end
end end
dependency_list_report dependency_list_report
......
---
title: Merge License info to Dependency List report
merge_request: 15157
author:
type: added
...@@ -10,7 +10,7 @@ module Gitlab ...@@ -10,7 +10,7 @@ module Gitlab
end end
def parse!(json_data, report) def parse!(json_data, report)
report_data = JSON.parse!(json_data) report_data = JSON.parse(json_data)
report_data.fetch('dependency_files', []).each do |file| report_data.fetch('dependency_files', []).each do |file|
file['dependencies'].each do |dependency| file['dependencies'].each do |dependency|
report.add_dependency(formatter.format(dependency, report.add_dependency(formatter.format(dependency,
...@@ -21,6 +21,13 @@ module Gitlab ...@@ -21,6 +21,13 @@ module Gitlab
end end
end end
def parse_licenses!(json_data, report)
licenses = JSON.parse(json_data, symbolize_names: true)
licenses[:dependencies].each do |license|
report.apply_license(license)
end
end
private private
attr_reader :formatter attr_reader :formatter
......
...@@ -20,7 +20,8 @@ module Gitlab ...@@ -20,7 +20,8 @@ module Gitlab
path: file_path path: file_path
}, },
version: dependency['version'], version: dependency['version'],
vulnerabilities: collect_vulnerabilities(vulnerabilities, dependency, file_path) vulnerabilities: collect_vulnerabilities(vulnerabilities, dependency, file_path),
licenses: []
} }
end end
......
...@@ -14,6 +14,14 @@ module Gitlab ...@@ -14,6 +14,14 @@ module Gitlab
def add_dependency(dependency) def add_dependency(dependency)
dependencies << dependency dependencies << dependency
end end
def apply_license(license)
dependencies.each do |dependency|
next unless dependency[:name] == license[:dependency][:name]
dependency[:licenses] << license[:license]
end
end
end end
end end
end end
......
...@@ -5,6 +5,7 @@ FactoryBot.define do ...@@ -5,6 +5,7 @@ FactoryBot.define do
name 'nokogiri' name 'nokogiri'
packager 'Ruby (Bundler)' packager 'Ruby (Bundler)'
version '1.8.0' version '1.8.0'
licenses { [] }
location do location do
{ {
blob_path: '/some_project/path/Gemfile.lock', blob_path: '/some_project/path/Gemfile.lock',
......
...@@ -6,10 +6,9 @@ describe Gitlab::Ci::Parsers::Security::DependencyList do ...@@ -6,10 +6,9 @@ describe Gitlab::Ci::Parsers::Security::DependencyList do
let(:parser) { described_class.new(project, sha) } let(:parser) { described_class.new(project, sha) }
let(:project) { create(:project) } let(:project) { create(:project) }
let(:sha) { '4242424242424242' } let(:sha) { '4242424242424242' }
let(:report) { Gitlab::Ci::Reports::DependencyList::Report.new }
describe '#parse!' do describe '#parse!' do
let(:report) { Gitlab::Ci::Reports::DependencyList::Report.new }
before do before do
artifact.each_blob do |blob| artifact.each_blob do |blob|
parser.parse!(blob, report) parser.parse!(blob, report)
...@@ -53,4 +52,37 @@ describe Gitlab::Ci::Parsers::Security::DependencyList do ...@@ -53,4 +52,37 @@ describe Gitlab::Ci::Parsers::Security::DependencyList do
end end
end end
end end
describe '#parse_licenses!' do
let(:artifact) { create(:ee_ci_job_artifact, :license_management) }
let(:dependency_info) { build(:dependency, :with_vulnerabilities) }
before do
report.add_dependency(dependency)
artifact.each_blob do |blob|
parser.parse_licenses!(blob, report)
end
end
context 'with existing license' do
let(:dependency) { dependency_info }
it 'apply license to dependency' do
licenses = report.dependencies.last[:licenses]
expect(licenses.count).to eq(1)
expect(licenses[0][:name]).to eq('MIT')
expect(licenses[0][:url]).to eq('http://opensource.org/licenses/mit-license')
end
end
context 'without existing license' do
let(:dependency) { dependency_info.merge(name: 'irigokon') }
it 'does not apply any license if name mismatch' do
expect(report.dependencies.first[:licenses]).to be_empty
end
end
end
end end
...@@ -33,6 +33,7 @@ describe Gitlab::Ci::Parsers::Security::Formatters::DependencyList do ...@@ -33,6 +33,7 @@ describe Gitlab::Ci::Parsers::Security::Formatters::DependencyList do
expect(data[:location][:path]).to eq('rails/Gemfile.lock') expect(data[:location][:path]).to eq('rails/Gemfile.lock')
expect(data[:version]).to eq('2.2.0') expect(data[:version]).to eq('2.2.0')
expect(data[:vulnerabilities]).to be_empty expect(data[:vulnerabilities]).to be_empty
expect(data[:licenses]).to be_empty
end end
end end
......
...@@ -235,7 +235,8 @@ describe Ci::Build do ...@@ -235,7 +235,8 @@ describe Ci::Build do
end end
describe '#collect_dependency_list_reports!' do describe '#collect_dependency_list_reports!' do
let!(:artifact) { create(:ee_ci_job_artifact, :dependency_list, job: job, project: job.project) } let!(:dl_artifact) { create(:ee_ci_job_artifact, :dependency_list, job: job, project: job.project) }
let!(:lm_artifact) { create(:ee_ci_job_artifact, :license_management, job: job, project: job.project) }
let(:dependency_list_report) { Gitlab::Ci::Reports::DependencyList::Report.new } let(:dependency_list_report) { Gitlab::Ci::Reports::DependencyList::Report.new }
subject { job.collect_dependency_list_reports!(dependency_list_report) } subject { job.collect_dependency_list_reports!(dependency_list_report) }
...@@ -248,10 +249,13 @@ describe Ci::Build do ...@@ -248,10 +249,13 @@ describe Ci::Build do
it 'parses blobs and add the results to the report' do it 'parses blobs and add the results to the report' do
subject subject
blob_path = "/#{project.full_path}/blob/#{job.sha}/yarn/yarn.lock" blob_path = "/#{project.full_path}/blob/#{job.sha}/yarn/yarn.lock"
mini_portile2 = dependency_list_report.dependencies[0]
yarn = dependency_list_report.dependencies[20]
expect(dependency_list_report.dependencies.count).to eq(21) expect(dependency_list_report.dependencies.count).to eq(21)
expect(dependency_list_report.dependencies[0][:name]).to eq('mini_portile2') expect(mini_portile2[:name]).to eq('mini_portile2')
expect(dependency_list_report.dependencies[20][:location][:blob_path]).to eq(blob_path) expect(mini_portile2[:licenses][0][:name]).to eq('MIT')
expect(yarn[:location][:blob_path]).to eq(blob_path)
end end
end end
......
...@@ -23,12 +23,12 @@ describe DependencyEntity do ...@@ -23,12 +23,12 @@ describe DependencyEntity do
end end
it do it do
is_expected.to eq(dependency) is_expected.to eq(dependency.except(:licenses))
end end
end end
context 'with reporter' do context 'with reporter' do
let(:dependency_info) { build(:dependency) } let(:dependency_info) { build(:dependency).except(:licenses) }
before do before do
project.add_reporter(user) project.add_reporter(user)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment