summaryrefslogtreecommitdiff
path: root/lib/license/finder/ext/bundler.rb
blob: ddf30f5c6011a80eabac6d58fc795a9cb7ae3336 (plain)
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
# 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

    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

      if project_path.join("gems.rb").exist?
        "gems.rb"
      else
        "Gemfile"
      end
    end

    def lockfile
      gemfile == 'gems.rb' ? 'gems.locked' : "#{gemfile}.lock"
    end

    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