Commit 8ec1f73d authored by mo khan's avatar mo khan Committed by Stan Hu

Parse path from license_scanning report

* Update usages of 'add_dependency'
* Add changelog entry
* Calculate blob_path from partial path
parent be2e94f3
......@@ -3,7 +3,9 @@
class LicenseEntity < Grape::Entity
class ComponentEntity < Grape::Entity
expose :name
expose :path, as: :blob_path
expose :blob_path do |model, options|
model.blob_path_for(options[:project])
end
end
expose :id
......
---
title: Generate a link to an artifact using the path from the license scanning report
merge_request: 43455
author:
type: fixed
......@@ -15,7 +15,7 @@ module Gitlab
json.fetch(:dependencies, []).each do |dependency|
each_license_for(dependency) do |license_hash|
license = report.add_license(id: nil, name: license_hash[:name], url: license_hash[:url])
license.add_dependency(dependency[:dependency][:name])
license.add_dependency(name: dependency[:dependency][:name])
end
end
end
......
......@@ -27,7 +27,7 @@ module Gitlab
def add_dependencies(report_hash)
report_hash[:dependencies].each do |dependency_hash|
dependency_hash[:licenses].map do |license_id|
license_for(license_id).add_dependency(dependency_hash[:name])
license_for(license_id).add_dependency(dependency_hash)
end
end
end
......
......@@ -6,11 +6,22 @@ module Gitlab
module LicenseScanning
class Dependency
attr_accessor :path
attr_reader :name
attr_reader :name, :package_manager, :version
def initialize(name, path: nil)
@name = name
@path = path
def initialize(attributes = {})
@name = attributes.fetch(:name)
@package_manager = attributes[:package_manager]
@path = attributes[:path]
@version = attributes[:version]
end
def blob_path_for(project, sha: project&.default_branch_or_master)
return if path.blank?
return path if sha.blank?
::Gitlab::Routing
.url_helpers
.project_blob_path(project, File.join(sha, path))
end
def hash
......
......@@ -54,8 +54,8 @@ module Gitlab
canonical_id.hash
end
def add_dependency(name)
@dependencies.add(::Gitlab::Ci::Reports::LicenseScanning::Dependency.new(name))
def add_dependency(attributes = {})
@dependencies.add(::Gitlab::Ci::Reports::LicenseScanning::Dependency.new(attributes))
end
def dependencies
......
......@@ -10,21 +10,21 @@ FactoryBot.define do
end
trait :report_1 do
after(:build) do |report, evaluator|
report.add_license(id: 'MIT', name: 'MIT', url: 'https://opensource.org/licenses/mit').add_dependency('Library1')
report.add_license(id: 'WTFPL', name: 'WTFPL', url: 'https://opensource.org/licenses/wtfpl').add_dependency('Library2')
report.add_license(id: 'MIT', name: 'MIT', url: 'https://opensource.org/licenses/mit').add_dependency(name: 'Library1')
report.add_license(id: 'WTFPL', name: 'WTFPL', url: 'https://opensource.org/licenses/wtfpl').add_dependency(name: 'Library2')
end
end
trait :report_2 do
after(:build) do |report, evaluator|
report.add_license(id: 'MIT', name: 'MIT', url: 'https://opensource.org/licenses/mit').add_dependency('Library1')
report.add_license(id: 'Apache-2.0', name: 'Apache 2.0', url: 'https://opensource.org/licenses/apache').add_dependency('Library3')
report.add_license(id: 'MIT', name: 'MIT', url: 'https://opensource.org/licenses/mit').add_dependency(name: 'Library1')
report.add_license(id: 'Apache-2.0', name: 'Apache 2.0', url: 'https://opensource.org/licenses/apache').add_dependency(name: 'Library3')
end
end
trait :mit do
after(:build) do |report, evaluator|
report.add_license(id: 'MIT', name: 'MIT', url: 'https://opensource.org/licenses/mit').add_dependency('rails')
report.add_license(id: 'MIT', name: 'MIT', url: 'https://opensource.org/licenses/mit').add_dependency(name: 'rails')
end
end
end
......
......@@ -122,6 +122,18 @@ RSpec.describe Gitlab::Ci::Parsers::LicenseCompliance::LicenseScanning do
expect(report.licenses[0].count).to be(2)
expect(report.licenses[0].dependencies.count).to be(2)
expect(report.licenses[0].dependencies.map(&:name)).to contain_exactly('b', 'c')
dependency_b = report.licenses[0].dependencies.find { |x| x.name == 'b' }
expect(dependency_b.name).to eql('b')
expect(dependency_b.version).to eql('0.1.0')
expect(dependency_b.path).to eql('yarn.lock')
expect(dependency_b.package_manager).to eql('yarn')
dependency_c = report.licenses[0].dependencies.find { |x| x.name == 'c' }
expect(dependency_c.name).to eql('c')
expect(dependency_c.version).to eql('1.1.0')
expect(dependency_c.path).to eql('Gemfile.lock')
expect(dependency_c.package_manager).to eql('bundler')
end
it 'parses the MIT license' do
......@@ -131,6 +143,18 @@ RSpec.describe Gitlab::Ci::Parsers::LicenseCompliance::LicenseScanning do
expect(report.licenses[1].count).to be(2)
expect(report.licenses[1].dependencies.count).to be(2)
expect(report.licenses[1].dependencies.map(&:name)).to contain_exactly('a', 'c')
dependency_a = report.licenses[1].dependencies.find { |x| x.name == 'a' }
expect(dependency_a.name).to eql('a')
expect(dependency_a.version).to eql('1.0.0')
expect(dependency_a.path).to eql('Gemfile.lock')
expect(dependency_a.package_manager).to eql('bundler')
dependency_c = report.licenses[1].dependencies.find { |x| x.name == 'c' }
expect(dependency_c.name).to eql('c')
expect(dependency_c.version).to eql('1.1.0')
expect(dependency_c.path).to eql('Gemfile.lock')
expect(dependency_c.package_manager).to eql('bundler')
end
it 'parses an unknown license' do
......@@ -140,6 +164,11 @@ RSpec.describe Gitlab::Ci::Parsers::LicenseCompliance::LicenseScanning do
expect(report.licenses[2].count).to be(1)
expect(report.licenses[2].dependencies.count).to be(1)
expect(report.licenses[2].dependencies.map(&:name)).to contain_exactly('d')
expect(report.licenses[2].dependencies[0].name).to eql('d')
expect(report.licenses[2].dependencies[0].version).to eql('1.1.1')
expect(report.licenses[2].dependencies[0].package_manager).to eql('bundler')
expect(report.licenses[2].dependencies[0].path).to eql('Gemfile.lock')
end
end
......
......@@ -61,7 +61,7 @@ RSpec.describe Gitlab::Ci::Reports::DependencyList::Report do
let(:license) { build(:ci_reports_license_scanning_report, :mit).licenses.first }
before do
license.add_dependency(name_of_dependency_with_license)
license.add_dependency(name: name_of_dependency_with_license)
report.add_dependency(dependency)
report.apply_license(license)
end
......
......@@ -7,12 +7,47 @@ RSpec.describe Gitlab::Ci::Reports::LicenseScanning::Dependency do
let(:set) { Set.new }
it 'cannot add the same dependency to a set twice' do
set.add(described_class.new('bundler'))
set.add(described_class.new('bundler'))
set.add(described_class.new(name: 'bundler'))
set.add(described_class.new(name: 'bundler'))
expect(set.count).to eq(1)
end
it { expect(described_class.new('bundler')).to eql(described_class.new('bundler')) }
it { expect(described_class.new(name: 'bundler')).to eql(described_class.new(name: 'bundler')) }
end
describe "#blob_path_for" do
let(:dependency) { described_class.new(name: 'rails', path: lockfile) }
let(:lockfile) { 'Gemfile.lock' }
context "when a project, sha and path are provided" do
subject { dependency.blob_path_for(build.project, sha: build.sha)}
let(:build) { build_stubbed(:ee_ci_build, :success, :license_scan_v2) }
specify { expect(subject).to eql("/#{build.project.namespace.path}/#{build.project.name}/-/blob/#{build.sha}/#{lockfile}") }
end
context "when a path is not available" do
subject { dependency.blob_path_for(build_stubbed(:project))}
let(:lockfile) { nil }
specify { expect(subject).to be_nil }
end
context "when a project is not provided" do
subject { dependency.blob_path_for(nil)}
specify { expect(subject).to eql(lockfile) }
end
context "when a sha is not provided" do
subject { dependency.blob_path_for(project) }
let(:project) { build_stubbed(:project) }
specify { expect(subject).to eql("/#{project.namespace.path}/#{project.name}/-/blob/#{project.default_branch_or_master}/#{lockfile}") }
end
end
end
......@@ -58,8 +58,8 @@ RSpec.describe Gitlab::Ci::Reports::LicenseScanning::Report do
let(:apache_license) { report.by_license_name('Apache 2.0') }
before do
mit_license.add_dependency('Library4')
apache_license.add_dependency('Library3')
mit_license.add_dependency(name: 'Library4')
apache_license.add_dependency(name: 'Library3')
subject
end
......@@ -90,7 +90,7 @@ RSpec.describe Gitlab::Ci::Reports::LicenseScanning::Report do
before do
report
.add_license(id: nil, name: 'MIT')
.add_dependency('rails')
.add_dependency(name: 'rails')
end
context 'when a denied license is found in the report' do
......@@ -182,7 +182,7 @@ RSpec.describe Gitlab::Ci::Reports::LicenseScanning::Report do
before do
base_report
.add_license(id: 'MIT', name: 'MIT License')
.add_dependency('rails')
.add_dependency(name: 'rails')
end
specify do
......@@ -197,13 +197,13 @@ RSpec.describe Gitlab::Ci::Reports::LicenseScanning::Report do
let(:head_report) { build(:license_scan_report, :version_1) }
before do
base_report.add_license(id: nil, name: 'MIT').add_dependency('Library1')
base_report.add_license(id: nil, name: 'BSD').add_dependency('Library1')
base_report.add_license(id: nil, name: 'WTFPL').add_dependency('Library2')
base_report.add_license(id: nil, name: 'MIT').add_dependency(name: 'Library1')
base_report.add_license(id: nil, name: 'BSD').add_dependency(name: 'Library1')
base_report.add_license(id: nil, name: 'WTFPL').add_dependency(name: 'Library2')
head_report.add_license(id: nil, name: 'MIT').add_dependency('Library1')
head_report.add_license(id: nil, name: 'Apache 2.0').add_dependency('Library3')
head_report.add_license(id: nil, name: 'bsd').add_dependency('Library1')
head_report.add_license(id: nil, name: 'MIT').add_dependency(name: 'Library1')
head_report.add_license(id: nil, name: 'Apache 2.0').add_dependency(name: 'Library3')
head_report.add_license(id: nil, name: 'bsd').add_dependency(name: 'Library1')
end
it { expect(names_from(subject[:added])).to contain_exactly('Apache 2.0') }
......@@ -216,13 +216,13 @@ RSpec.describe Gitlab::Ci::Reports::LicenseScanning::Report do
let(:head_report) { build(:license_scan_report, :version_2) }
before do
base_report.add_license(id: 'MIT', name: 'MIT').add_dependency('Library1')
base_report.add_license(id: 'BSD-3-Clause', name: 'BSD').add_dependency('Library1')
base_report.add_license(id: 'WTFPL', name: 'WTFPL').add_dependency('Library2')
base_report.add_license(id: 'MIT', name: 'MIT').add_dependency(name: 'Library1')
base_report.add_license(id: 'BSD-3-Clause', name: 'BSD').add_dependency(name: 'Library1')
base_report.add_license(id: 'WTFPL', name: 'WTFPL').add_dependency(name: 'Library2')
head_report.add_license(id: 'BSD-3-Clause', name: 'bsd').add_dependency('Library1')
head_report.add_license(id: 'Apache-2.0', name: 'Apache 2.0').add_dependency('Library3')
head_report.add_license(id: 'MIT', name: 'MIT License').add_dependency('Library1')
head_report.add_license(id: 'BSD-3-Clause', name: 'bsd').add_dependency(name: 'Library1')
head_report.add_license(id: 'Apache-2.0', name: 'Apache 2.0').add_dependency(name: 'Library3')
head_report.add_license(id: 'MIT', name: 'MIT License').add_dependency(name: 'Library1')
end
it { expect(names_from(subject[:added])).to contain_exactly('Apache 2.0') }
......@@ -235,13 +235,13 @@ RSpec.describe Gitlab::Ci::Reports::LicenseScanning::Report do
let(:head_report) { build(:license_scan_report, :version_2) }
before do
base_report.add_license(id: nil, name: 'MIT').add_dependency('Library1')
base_report.add_license(id: nil, name: 'BSD').add_dependency('Library1')
base_report.add_license(id: nil, name: 'WTFPL').add_dependency('Library2')
base_report.add_license(id: nil, name: 'MIT').add_dependency(name: 'Library1')
base_report.add_license(id: nil, name: 'BSD').add_dependency(name: 'Library1')
base_report.add_license(id: nil, name: 'WTFPL').add_dependency(name: 'Library2')
head_report.add_license(id: 'BSD-3-Clause', name: 'bsd').add_dependency('Library1')
head_report.add_license(id: 'Apache-2.0', name: 'Apache 2.0').add_dependency('Library3')
head_report.add_license(id: 'MIT', name: 'MIT').add_dependency('Library1')
head_report.add_license(id: 'BSD-3-Clause', name: 'bsd').add_dependency(name: 'Library1')
head_report.add_license(id: 'Apache-2.0', name: 'Apache 2.0').add_dependency(name: 'Library3')
head_report.add_license(id: 'MIT', name: 'MIT').add_dependency(name: 'Library1')
end
it { expect(names_from(subject[:added])).to contain_exactly('Apache 2.0') }
......@@ -254,13 +254,13 @@ RSpec.describe Gitlab::Ci::Reports::LicenseScanning::Report do
let(:head_report) { build(:license_scan_report, :version_1) }
before do
base_report.add_license(id: 'MIT', name: 'MIT').add_dependency('Library1')
base_report.add_license(id: 'BSD-3-Clause', name: 'BSD').add_dependency('Library1')
base_report.add_license(id: 'WTFPL', name: 'WTFPL').add_dependency('Library2')
base_report.add_license(id: 'MIT', name: 'MIT').add_dependency(name: 'Library1')
base_report.add_license(id: 'BSD-3-Clause', name: 'BSD').add_dependency(name: 'Library1')
base_report.add_license(id: 'WTFPL', name: 'WTFPL').add_dependency(name: 'Library2')
head_report.add_license(id: nil, name: 'bsd').add_dependency('Library1')
head_report.add_license(id: nil, name: 'Apache 2.0').add_dependency('Library3')
head_report.add_license(id: nil, name: 'MIT').add_dependency('Library1')
head_report.add_license(id: nil, name: 'bsd').add_dependency(name: 'Library1')
head_report.add_license(id: nil, name: 'Apache 2.0').add_dependency(name: 'Library3')
head_report.add_license(id: nil, name: 'MIT').add_dependency(name: 'Library1')
end
it { expect(names_from(subject[:added])).to contain_exactly('Apache 2.0') }
......
......@@ -8,8 +8,8 @@ RSpec.describe Gitlab::Ci::Reports::LicenseScanning::ReportsComparer do
let(:report_comparer) { described_class.new(report_1, report_2) }
before do
report_1.add_license(id: nil, name: 'BSD').add_dependency('Library1')
report_2.add_license(id: nil, name: 'bsd').add_dependency('Library1')
report_1.add_license(id: nil, name: 'BSD').add_dependency(name: 'Library1')
report_2.add_license(id: nil, name: 'bsd').add_dependency(name: 'Library1')
end
def names_from(licenses)
......
......@@ -12,7 +12,7 @@ RSpec.describe LicenseEntity do
let(:path) { 'some_path' }
before do
license.add_dependency('rails')
license.add_dependency(name: 'rails')
allow(license.dependencies.first).to receive(:path).and_return(path)
end
......
......@@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe Security::LicensePolicyEntity do
let(:license) { build(:license_scanning_license, :mit).tap { |x| x.add_dependency('rails') } }
let(:license) { build(:license_scanning_license, :mit).tap { |x| x.add_dependency(name: 'rails') } }
let(:policy) { build(:software_license_policy, :allowed) }
let(:entity) { described_class.new(SCA::LicensePolicy.new(license, policy)) }
......
......@@ -5,7 +5,9 @@ module LicenseScanningReportHelper
Gitlab::Ci::Reports::LicenseScanning::Report.new.tap do |report|
dependencies.each do |license_name, dependencies|
dependencies.each do |dependency_name|
report.add_license(id: nil, name: license_name.to_s, url: "https://opensource.org/licenses/license1").add_dependency(dependency_name)
report
.add_license(id: nil, name: license_name.to_s, url: "https://opensource.org/licenses/license1")
.add_dependency(name: dependency_name)
end
end
end
......@@ -33,12 +35,12 @@ module LicenseScanningReportHelper
def create_license
Gitlab::Ci::Reports::LicenseScanning::License.new(id: nil, name: 'License1', url: "https://opensource.org/licenses/license1").tap do |license|
license.add_dependency('Dependency1')
license.add_dependency('Dependency2')
license.add_dependency(name: 'Dependency1')
license.add_dependency(name: 'Dependency2')
end
end
def create_dependency
Gitlab::Ci::Reports::LicenseScanning::Dependency.new('Dependency1')
Gitlab::Ci::Reports::LicenseScanning::Dependency.new(name: 'Dependency1')
end
end
......@@ -48,62 +48,45 @@ module QA
mr.file_content =
<<~FILE_UPDATE
{
"version": "2.1",
"licenses": [
{
"count": 1,
"name": "WTFPL"
"id": "WTFPL",
"name": "Do What The F*ck You Want To Public License",
"url": "http://www.wtfpl.net/about/"
},
{
"count": 1,
"name": "MIT"
"id": "MIT",
"name": "MIT License",
"url": "https://opensource.org/licenses/MIT"
},
{
"count": 1,
"name": "Zlib"
"id": "Zlib",
"name": "zlib License",
"url": "https://opensource.org/licenses/Zlib"
}
],
"dependencies": [
{
"license": {
"name": "MIT",
"url": "http://opensource.org/licenses/mit-license"
},
"dependency": {
"name": "actioncable",
"url": "http://rubyonrails.org",
"description": "WebSocket framework for Rails.",
"paths": [
"."
]
}
"name": "actioncable",
"version": "6.0.3.3",
"package_manager": "bundler",
"path": "Gemfile.lock",
"licenses": ["MIT"]
},
{
"license": {
"name": "WTFPL",
"url": "http://www.wtfpl.net/"
},
"dependency": {
"name": "wtfpl_init",
"url": "https://rubygems.org/gems/wtfpl_init",
"description": "Download WTFPL license file and rename to LICENSE.md or something",
"paths": [
"."
]
}
"name": "wtfpl_init",
"version": "0.1.0",
"package_manager": "bundler",
"path": "Gemfile.lock",
"licenses": ["WTFPL"]
},
{
"license": {
"name": "Zlib",
"url": "https://www.zlib.net/"
},
"dependency": {
"name": "zlib",
"url": "https://www.zlib.net/",
"description": "Ruby interface for the zlib compression/decompression library",
"paths": [
"."
]
}
"name": "Zlib",
"version": "1.2.11",
"package_manager": "bundler",
"path": "Gemfile.lock",
"licenses": ["Zlib"]
}
]
}
......
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