1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
# 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])
with_clean_bundler do
_stdout, _stderr, status = shell.execute([:asdf, :current, :ruby], env: default_env)
shell.execute([:asdf, :install], env: default_env) unless status.success?
shell.execute([:bundle, :config, '--local', :path, vendor_path.to_s], env: default_env)
shell.execute([:bundle, :install, '--verbose'], env: default_env)
end
end
def current_packages
with_clean_bundler do
stdout, _stderr, status = shell.execute(scan_command, env: default_env)
return super unless status.success?
stdout.each_line.map do |line|
map_from(JSON.parse(line, symbolize_names: true))
end
end
end
def possible_package_paths
if ENV['BUNDLE_GEMFILE'] && File.exist?(ENV['BUNDLE_GEMFILE'])
[project_path.join(File.basename(ENV['BUNDLE_GEMFILE']))]
else
[project_path.join('Gemfile'), project_path.join('gems.rb')]
end
end
private
def gemfile
if ENV['BUNDLE_GEMFILE']
custom_gemfile = project_path.join(File.basename(ENV['BUNDLE_GEMFILE']))
return custom_gemfile.basename.to_s if custom_gemfile.exist?
end
project_path.join("gems.rb").exist? ? "gems.rb" : "Gemfile"
end
def lockfile
gemfile == 'gems.rb' ? 'gems.locked' : "#{gemfile}.lock"
end
def lockfile_path
project_path.join(lockfile)
end
def scan_command
[
'/opt/asdf/shims/ruby',
'-W0',
::License::Management.root.join('exe', 'scan_bundler').to_s,
detected_package_path.to_s,
lockfile_path.to_s
]
end
def default_env
@default_env ||= {
'BUNDLE_ALLOW_OFFLINE_INSTALL' => 'true',
'BUNDLE_DISABLE_VERSION_CHECK' => 'true',
'BUNDLE_ERROR_ON_STDERR' => 'true',
'BUNDLE_GEMFILE' => "#{project_path}/#{gemfile}",
'BUNDLE_IGNORE_MESSAGES' => 'true',
'BUNDLE_JOBS' => ENV.fetch('BUNDLE_JOBS', `nproc`.chomp),
'BUNDLE_SILENCE_ROOT_WARNING' => 'true',
'BUNDLE_SUPPRESS_INSTALL_USING_MESSAGES' => 'true',
'BUNDLE_WITHOUT' => ENV.fetch('BUNDLE_WITHOUT', ignored_groups.to_a.join(':')),
'PATH' => "/opt/asdf/shims:/opt/asdf/bin:#{ENV['PATH']}"
}.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
::Gem.clear_paths
::Bundler.reset!
::Bundler.configure
Dir.chdir(project_path) do
if ::Bundler.respond_to?(:with_unbundled_env)
::Bundler.with_unbundled_env { yield }
else
::Bundler.with_clean_env { yield }
end
end
end
def map_from(gem)
Dependency.new(
'Bundler',
gem[:name],
gem[:version],
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
|