diff options
21 files changed, 300 insertions, 144 deletions
diff --git a/.rubocop.yml b/.rubocop.yml index bc6e0f1..32a0c0e 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -9,6 +9,7 @@ AllCops: TargetRubyVersion: 2.4 Exclude: - 'tmp/**/*' + - 'spec/fixtures/**/*' Naming/ClassAndModuleCamelCase: Exclude: diff --git a/CHANGELOG.md b/CHANGELOG.md index aa07fb6..bfd2648 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # GitLab License management changelog +## v3.14.0 + +- Export `BUNDLE_SSL_CA_CERT` when a `ADDITIONAL_CA_CERT_BUNDLE` is provided. (!177) + ## v3.13.0 - Upgrade to [`license_finder`](https://github.com/pivotal/LicenseFinder/) [`6.6.0`](https://github.com/pivotal/LicenseFinder/releases/tag/v6.6.0). (!162) (!166) diff --git a/Gemfile.lock b/Gemfile.lock index 05c126f..ee88458 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - license-management (3.13.0) + license-management (3.14.0) license_finder (~> 6.6.0) GEM @@ -22,7 +22,7 @@ GEM jaro_winkler (1.5.4) json-schema (2.8.1) addressable (>= 2.4) - license_finder (6.6.0) + license_finder (6.6.1) bundler rubyzip (>= 1, < 3) thor (~> 1.0.1) diff --git a/lib/license/finder/ext.rb b/lib/license/finder/ext.rb index 8d76172..da6a006 100644 --- a/lib/license/finder/ext.rb +++ b/lib/license/finder/ext.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true require 'license/finder/ext/bower' +require 'license/finder/ext/bundler' require 'license/finder/ext/conan' require 'license/finder/ext/dependency' require 'license/finder/ext/go_modules' diff --git a/lib/license/finder/ext/bundler.rb b/lib/license/finder/ext/bundler.rb new file mode 100644 index 0000000..08ab3ac --- /dev/null +++ b/lib/license/finder/ext/bundler.rb @@ -0,0 +1,61 @@ +# frozen_string_literal: true + +module LicenseFinder + class Bundler < PackageManager + def prepare + vendor_path = Pathname.pwd.join('.gitlab', 'cache', 'vendor') + shell.execute([:mkdir, '-p', vendor_path.to_s]) + + Dir.chdir(project_path) do + with_clean_bundler do + shell.execute([:bundle, :config, '--local', :path, vendor_path.to_s]) + shell.execute([:bundle, :install, '--verbose'], env: default_env) + end + end + end + + def current_packages + Dir.chdir(project_path) do + gem_details.map do |gem| + Dependency.new( + 'Bundler', + gem.name, + gem.version.to_s, + description: gem.description, + detection_path: lockfile_path, + homepage: gem.homepage, + install_path: gem.full_gem_path || '/dev/null', + spec_licenses: gem.licenses, + summary: gem.summary + ) + end + end + end + + private + + def default_env + @default_env ||= { + 'BUNDLE_ALLOW_OFFLINE_INSTALL' => 'true', + 'BUNDLE_SUPPRESS_INSTALL_USING_MESSAGES' => 'true', + 'BUNDLE_DISABLE_VERSION_CHECK' => 'true', + 'BUNDLE_ERROR_ON_STDERR' => 'true', + 'BUNDLE_IGNORE_MESSAGES' => 'true', + 'BUNDLE_JOBS' => ENV.fetch('BUNDLE_JOBS', `nproc`.chomp), + 'BUNDLE_SILENCE_ROOT_WARNING' => 'true', + 'BUNDLE_WITH' => ENV.fetch('BUNDLE_WITH', included_groups.to_a.join(':')) + }.tap do |env| + env['BUNDLE_FROZEN'] = 'true' if lockfile_path.exist? + env['BUNDLE_SSL_CA_CERT'] = shell.custom_certificate_path.to_s if shell.custom_certificate_installed? + end + end + + def with_clean_bundler + if ::Bundler.respond_to?(:with_unbundled_env) + ::Bundler.with_unbundled_env { yield } + else + ::Bundler.with_clean_env { yield } + end + end + end +end diff --git a/lib/license/management/version.rb b/lib/license/management/version.rb index eb4ecd4..de5715a 100644 --- a/lib/license/management/version.rb +++ b/lib/license/management/version.rb @@ -2,6 +2,6 @@ module License module Management - VERSION = '3.13.0' + VERSION = '3.14.0' end end @@ -3,11 +3,8 @@ set -e [[ -z ${SETUP_CMD:-} ]] && set -uo pipefail -BUNDLE_JOBS="$(nproc)" export ASDF_JAVA_VERSION="${ASDF_JAVA_VERSION:-}" export ASDF_PYTHON_VERSION="${ASDF_PYTHON_VERSION:-}" -export BUNDLE_JOBS -export BUNDLE_WITHOUT="development:test" export CI_API_V4_URL="${CI_API_V4_URL:-https://gitlab.com/api/v4}" export CI_DEBUG_TRACE=${CI_DEBUG_TRACE:='false'} export DOTNET_CLI_TELEMETRY_OPTOUT=1 diff --git a/spec/fixtures/expected/ruby/bundler/v2.1.json b/spec/fixtures/expected/ruby/bundler/v2.1.json index ae83b84..9081ff6 100644 --- a/spec/fixtures/expected/ruby/bundler/v2.1.json +++ b/spec/fixtures/expected/ruby/bundler/v2.1.json @@ -22,7 +22,7 @@ "name": "bundler", "version": "2.1.4", "package_manager": "bundler", - "path": ".", + "path": "Gemfile.lock", "licenses": [ "MIT" ] @@ -31,7 +31,7 @@ "name": "concurrent-ruby", "version": "1.0.5", "package_manager": "bundler", - "path": ".", + "path": "Gemfile.lock", "licenses": [ "MIT" ] @@ -40,7 +40,7 @@ "name": "connection_pool", "version": "2.2.1", "package_manager": "bundler", - "path": ".", + "path": "Gemfile.lock", "licenses": [ "MIT" ] @@ -49,7 +49,7 @@ "name": "mini_portile2", "version": "2.0.0", "package_manager": "bundler", - "path": ".", + "path": "Gemfile.lock", "licenses": [ "MIT" ] @@ -58,7 +58,7 @@ "name": "mustermann", "version": "1.0.1", "package_manager": "bundler", - "path": ".", + "path": "Gemfile.lock", "licenses": [ "MIT" ] @@ -67,7 +67,7 @@ "name": "nokogiri", "version": "1.6.7.2", "package_manager": "bundler", - "path": ".", + "path": "Gemfile.lock", "licenses": [ "MIT" ] @@ -76,7 +76,7 @@ "name": "pg", "version": "1.0.0", "package_manager": "bundler", - "path": ".", + "path": "Gemfile.lock", "licenses": [ "BSD-3-Clause" ] @@ -85,7 +85,7 @@ "name": "puma", "version": "3.12.0", "package_manager": "bundler", - "path": ".", + "path": "Gemfile.lock", "licenses": [ "BSD-3-Clause" ] @@ -94,7 +94,7 @@ "name": "rack", "version": "2.0.4", "package_manager": "bundler", - "path": ".", + "path": "Gemfile.lock", "licenses": [ "MIT" ] @@ -103,7 +103,7 @@ "name": "rack-protection", "version": "2.0.0", "package_manager": "bundler", - "path": ".", + "path": "Gemfile.lock", "licenses": [ "MIT" ] @@ -112,7 +112,7 @@ "name": "redis", "version": "3.3.5", "package_manager": "bundler", - "path": ".", + "path": "Gemfile.lock", "licenses": [ "MIT" ] @@ -121,7 +121,7 @@ "name": "sidekiq", "version": "4.2.10", "package_manager": "bundler", - "path": ".", + "path": "Gemfile.lock", "licenses": [ "LGPL-3.0-only" ] @@ -130,7 +130,7 @@ "name": "sinatra", "version": "2.0.0", "package_manager": "bundler", - "path": ".", + "path": "Gemfile.lock", "licenses": [ "MIT" ] @@ -139,7 +139,7 @@ "name": "slim", "version": "3.0.9", "package_manager": "bundler", - "path": ".", + "path": "Gemfile.lock", "licenses": [ "MIT" ] @@ -148,7 +148,7 @@ "name": "temple", "version": "0.8.0", "package_manager": "bundler", - "path": ".", + "path": "Gemfile.lock", "licenses": [ "MIT" ] @@ -157,10 +157,10 @@ "name": "tilt", "version": "2.0.8", "package_manager": "bundler", - "path": ".", + "path": "Gemfile.lock", "licenses": [ "MIT" ] } ] -} +}
\ No newline at end of file diff --git a/spec/fixtures/haproxy.cfg b/spec/fixtures/haproxy.cfg index ef11e48..1f98421 100644 --- a/spec/fixtures/haproxy.cfg +++ b/spec/fixtures/haproxy.cfg @@ -20,9 +20,17 @@ defaults frontend www-https bind *:443 ssl crt wildcard.test.pem + acl rubygems-backend ssl_fc_sni rubygems.test acl goproxy-backend ssl_fc_sni goproxy.test + + http-request replace-header Host .* rubygems.org if rubygems-backend http-request replace-header Host .* proxy.golang.org if goproxy-backend + + use_backend rubygems-backend if rubygems-backend use_backend goproxy-backend if goproxy-backend backend goproxy-backend server www1 proxy.golang.org:443 ssl verify none + +backend rubygems-backend + server www1 rubygems.org:443 ssl verify none diff --git a/spec/fixtures/ruby/bundler-custom-tls/Gemfile b/spec/fixtures/ruby/bundler-custom-tls/Gemfile new file mode 100644 index 0000000..1e46ec3 --- /dev/null +++ b/spec/fixtures/ruby/bundler-custom-tls/Gemfile @@ -0,0 +1,3 @@ +source "https://rubygems.test" + +gem "spandx" diff --git a/spec/fixtures/ruby/bundler-custom-tls/Gemfile.lock b/spec/fixtures/ruby/bundler-custom-tls/Gemfile.lock new file mode 100644 index 0000000..0568b0f --- /dev/null +++ b/spec/fixtures/ruby/bundler-custom-tls/Gemfile.lock @@ -0,0 +1,40 @@ +GEM + remote: https://rubygems.test/ + specs: + addressable (2.7.0) + public_suffix (>= 2.0.2, < 5.0) + mini_portile2 (2.4.0) + net-hippie (0.3.2) + nokogiri (1.10.9) + mini_portile2 (~> 2.4.0) + oj (3.10.6) + parslet (2.0.0) + public_suffix (4.0.5) + spandx (0.13.5) + addressable (~> 2.7) + bundler (>= 1.16, < 3.0.0) + net-hippie (~> 0.3) + nokogiri (~> 1.10) + oj (~> 3.10) + parslet (~> 2.0) + terminal-table (~> 1.8) + thor + tty-spinner (~> 0.9) + zeitwerk (~> 2.3) + terminal-table (1.8.0) + unicode-display_width (~> 1.1, >= 1.1.1) + thor (1.0.1) + tty-cursor (0.7.1) + tty-spinner (0.9.3) + tty-cursor (~> 0.7) + unicode-display_width (1.7.0) + zeitwerk (2.3.1) + +PLATFORMS + ruby + +DEPENDENCIES + spandx + +BUNDLED WITH + 2.1.4 diff --git a/spec/fixtures/ruby/bundler-git-source/Gemfile b/spec/fixtures/ruby/bundler-git-source/Gemfile new file mode 100644 index 0000000..d2d64ad --- /dev/null +++ b/spec/fixtures/ruby/bundler-git-source/Gemfile @@ -0,0 +1 @@ +gem 'net-hippie', git: 'https://github.com/mokhan/net-hippie.git' diff --git a/spec/fixtures/ruby/bundler-git-source/Gemfile.lock b/spec/fixtures/ruby/bundler-git-source/Gemfile.lock new file mode 100644 index 0000000..918db60 --- /dev/null +++ b/spec/fixtures/ruby/bundler-git-source/Gemfile.lock @@ -0,0 +1,14 @@ +GIT + remote: https://github.com/mokhan/net-hippie.git + revision: 6d1a48bee3dd8ec90a198b636cc9ccfd8c4e9bc5 + specs: + net-hippie (1.0.0) + +GEM + specs: + +PLATFORMS + ruby + +DEPENDENCIES + net-hippie! diff --git a/spec/fixtures/ruby/bundler-ruby-2.4.9-no-lockfile/.ruby-version b/spec/fixtures/ruby/bundler-ruby-2.4.9-no-lockfile/.ruby-version new file mode 100644 index 0000000..e4b8527 --- /dev/null +++ b/spec/fixtures/ruby/bundler-ruby-2.4.9-no-lockfile/.ruby-version @@ -0,0 +1 @@ +ruby-2.4.9 diff --git a/spec/fixtures/ruby/bundler-ruby-2.4.9-no-lockfile/Gemfile b/spec/fixtures/ruby/bundler-ruby-2.4.9-no-lockfile/Gemfile new file mode 100644 index 0000000..9020f0a --- /dev/null +++ b/spec/fixtures/ruby/bundler-ruby-2.4.9-no-lockfile/Gemfile @@ -0,0 +1,3 @@ +source 'https://rubygems.org' + +gem 'saml-kit' diff --git a/spec/fixtures/ruby/bundler-v1.17/Gemfile b/spec/fixtures/ruby/bundler-v1.17/Gemfile new file mode 100644 index 0000000..9020f0a --- /dev/null +++ b/spec/fixtures/ruby/bundler-v1.17/Gemfile @@ -0,0 +1,3 @@ +source 'https://rubygems.org' + +gem 'saml-kit' diff --git a/spec/fixtures/ruby/bundler-v1.17/Gemfile.lock b/spec/fixtures/ruby/bundler-v1.17/Gemfile.lock new file mode 100644 index 0000000..1dbdf7a --- /dev/null +++ b/spec/fixtures/ruby/bundler-v1.17/Gemfile.lock @@ -0,0 +1,46 @@ +GEM + remote: https://rubygems.org/ + specs: + activemodel (6.0.2.1) + activesupport (= 6.0.2.1) + activesupport (6.0.2.1) + concurrent-ruby (~> 1.0, >= 1.0.2) + i18n (>= 0.7, < 2) + minitest (~> 5.1) + tzinfo (~> 1.1) + zeitwerk (~> 2.2) + builder (3.2.4) + concurrent-ruby (1.1.5) + i18n (1.7.1) + concurrent-ruby (~> 1.0) + mini_portile2 (2.4.0) + minitest (5.13.0) + net-hippie (0.2.7) + nokogiri (1.10.7) + mini_portile2 (~> 2.4.0) + saml-kit (1.1.0) + activemodel (>= 4.2.0) + net-hippie (~> 0.1) + xml-kit (>= 0.3.0, < 1.0.0) + thread_safe (0.3.6) + tilt (2.0.10) + tzinfo (1.2.6) + thread_safe (~> 0.1) + xml-kit (0.4.0) + activemodel (>= 4.2.0) + builder (~> 3.2) + nokogiri (~> 1.10) + tilt (>= 1.4.1) + xmldsig (~> 0.6) + xmldsig (0.6.6) + nokogiri (>= 1.6.8, < 2.0.0) + zeitwerk (2.2.2) + +PLATFORMS + ruby + +DEPENDENCIES + saml-kit + +BUNDLED WITH + 1.17.3 diff --git a/spec/fixtures/ruby/bundler-v2.1/Gemfile b/spec/fixtures/ruby/bundler-v2.1/Gemfile new file mode 100644 index 0000000..78a8bfb --- /dev/null +++ b/spec/fixtures/ruby/bundler-v2.1/Gemfile @@ -0,0 +1,3 @@ +source 'https://rubygems.org' + +gem 'net-hippie' diff --git a/spec/fixtures/ruby/bundler-v2.1/Gemfile.lock b/spec/fixtures/ruby/bundler-v2.1/Gemfile.lock new file mode 100644 index 0000000..76c9f5c --- /dev/null +++ b/spec/fixtures/ruby/bundler-v2.1/Gemfile.lock @@ -0,0 +1,13 @@ +GEM + remote: https://rubygems.org/ + specs: + net-hippie (0.3.2) + +PLATFORMS + ruby + +DEPENDENCIES + net-hippie + +BUNDLED WITH + 2.1.4 diff --git a/spec/integration/ruby/bundler_spec.rb b/spec/integration/ruby/bundler_spec.rb index 428b357..6961067 100644 --- a/spec/integration/ruby/bundler_spec.rb +++ b/spec/integration/ruby/bundler_spec.rb @@ -1,148 +1,67 @@ require 'spec_helper' RSpec.describe "bundler" do + subject { runner.scan(env: env) } + + let(:env) { {} } + include_examples "each report version", "ruby", "bundler" context "when the project depends on an older version of ruby specified in a `.ruby-version` file" do - it 'installs the required ruby and produces a valid report' do - runner.add_file('.ruby-version', 'ruby-2.4.9') - runner.add_file('Gemfile') do - <<~RAW -source 'https://rubygems.org' - -gem 'saml-kit' - RAW - end + before do + runner.mount(dir: fixture_file('ruby/bundler-ruby-2.4.9-no-lockfile')) + end - report = runner.scan - expect(report).to match_schema - expect(report[:licenses]).not_to be_empty - expect(report[:dependencies].map { |x| x[:name] }).to include("saml-kit") + it 'installs the required ruby and produces a valid report' do + expect(subject).to match_schema + expect(subject[:licenses]).not_to be_empty + expect(subject[:dependencies].map { |x| x[:name] }).to include("saml-kit") end end context "when a project depends on an older version of bundler" do - it 'produces a valid report' do - runner.add_file('Gemfile') do - <<~RAW -source 'https://rubygems.org' - -gem 'saml-kit' - RAW - end - runner.add_file('Gemfile.lock') do - <<~RAW -GEM - remote: https://rubygems.org/ - specs: - activemodel (6.0.2.1) - activesupport (= 6.0.2.1) - activesupport (6.0.2.1) - concurrent-ruby (~> 1.0, >= 1.0.2) - i18n (>= 0.7, < 2) - minitest (~> 5.1) - tzinfo (~> 1.1) - zeitwerk (~> 2.2) - builder (3.2.4) - concurrent-ruby (1.1.5) - i18n (1.7.1) - concurrent-ruby (~> 1.0) - mini_portile2 (2.4.0) - minitest (5.13.0) - net-hippie (0.2.7) - nokogiri (1.10.7) - mini_portile2 (~> 2.4.0) - saml-kit (1.1.0) - activemodel (>= 4.2.0) - net-hippie (~> 0.1) - xml-kit (>= 0.3.0, < 1.0.0) - thread_safe (0.3.6) - tilt (2.0.10) - tzinfo (1.2.6) - thread_safe (~> 0.1) - xml-kit (0.4.0) - activemodel (>= 4.2.0) - builder (~> 3.2) - nokogiri (~> 1.10) - tilt (>= 1.4.1) - xmldsig (~> 0.6) - xmldsig (0.6.6) - nokogiri (>= 1.6.8, < 2.0.0) - zeitwerk (2.2.2) - -PLATFORMS - ruby - -DEPENDENCIES - saml-kit - -BUNDLED WITH - 1.17.3 - RAW - end - - report = runner.scan - - expect(report).to match_schema - expect(report[:licenses]).not_to be_empty - expect(report.dependency_names).to include("saml-kit") + before do + runner.mount(dir: fixture_file('ruby/bundler-v1.17')) end - end - context "when a project depends on bundler `~> 2.0`" do it 'produces a valid report' do - runner.add_file('Gemfile') do - <<~RAW -source 'https://rubygems.org' - -gem 'net-hippie' - RAW - end - runner.add_file('Gemfile.lock') do - <<~RAW -GEM - remote: https://rubygems.org/ - specs: - net-hippie (0.3.2) - -PLATFORMS - ruby - -DEPENDENCIES - net-hippie - -BUNDLED WITH - 2.1.4 - RAW - end + expect(subject).to match_schema + expect(subject[:licenses]).not_to be_empty + expect(subject.dependency_names).to include("saml-kit") + end + end - report = runner.scan + context "when a project depends on bundler `~> 2.1`" do + before do + runner.mount(dir: fixture_file('ruby/bundler-v2.1')) + end - expect(report).to match_schema - expect(report[:licenses]).not_to be_empty - expect(report.find('net-hippie')).to eql({ - name: 'net-hippie', - description: "net/http for hippies. ☮️", - url: "https://github.com/mokhan/net-hippie/", - paths: ['.'], - licenses: ['MIT'] - }) + it 'produces a valid report' do + expect(subject).to match_schema + expect(subject[:licenses]).not_to be_empty + expect(subject.dependency_names).to include('net-hippie') + expect(subject.licenses_for('net-hippie')).to match_array(['MIT']) end end context "when passing custom options to license finder" do - it 'forwards the options to license finder' do - report = runner.scan(env: { + let(:env) do + { 'LICENSE_FINDER_CLI_OPTS' => "--debug --aggregate-paths=. ruby" - }) + } + end + + before do + runner.clone('https://gitlab.com/gitlab-org/gitaly.git', branch: 'v12.10.13') + end - expect(report).to match_schema + it 'forwards the options to license finder' do + expect(subject).to match_schema + expect(subject.dependency_names).to include('rbtrace') end end context "when parsing a project with versions of gems that conflict with license_finder" do - subject { runner.scan } - before do runner.mount(dir: fixture_file('ruby/bundler-gem-conflict')) end @@ -156,8 +75,6 @@ BUNDLED WITH end context "when scanning the `gitlab` project" do - subject { runner.scan } - before do runner.clone('https://gitlab.com/gitlab-org/gitlab.git') system("rm #{runner.project_path}/config/dependency_decisions.yml") @@ -171,4 +88,43 @@ BUNDLED WITH expect(subject.dependency_names).to include('vue') end end + + context "when fetching dependencies from a custom registry" do + before do + add_host('rubygems.test', '127.0.0.1') + start_proxy_server + runner.mount(dir: fixture_file('ruby/bundler-custom-tls')) + end + + context "when the CA certificate is provided" do + let(:env) { { 'ADDITIONAL_CA_CERT_BUNDLE' => x509_certificate('wildcard.test').read } } + + specify do + expect(subject).to match_schema + expect(subject.dependency_names).to include("spandx") + expect(subject.licenses_for('spandx')).to match_array('MIT') + end + end + + context "when the CA certificate is NOT provided" do + let(:env) { {} } + + specify do + expect(subject).to match_schema + expect(subject.dependency_names).to be_empty + end + end + end + + context "when fetching dependencies from a git repo" do + before do + runner.mount(dir: fixture_file('ruby/bundler-git-source')) + end + + specify do + expect(subject).to match_schema + expect(subject.dependency_names).to include("net-hippie") + expect(subject.licenses_for('net-hippie')).to match_array(['MIT']) + end + end end diff --git a/spec/support/proxy_helper.rb b/spec/support/proxy_helper.rb index b79d0e3..cf9e306 100644 --- a/spec/support/proxy_helper.rb +++ b/spec/support/proxy_helper.rb @@ -35,5 +35,6 @@ RSpec.configure do |config| config.after(:example, type: :integration) do stop_proxy_server + system("rm -f /usr/local/share/ca-certificates/custom.*") end end |
