summaryrefslogtreecommitdiff
path: root/lib/license/finder/ext/cargo.rb
blob: c957e0e1107a0a3e5ce7a98bb34cc21cf4011041 (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
# frozen_string_literal: true

module LicenseFinder
  class Cargo < PackageManager
    SENTINEL = ' -|- '

    def installed?(*)
      true
    end

    def prepare
      create_vendor_path

      within_project_path do
        tool_box.install(tool: :rust)
        shell.execute([:cargo, :fetch, '-vv'], env: default_env)
      end
    end

    def current_packages
      within_project_path do
        stdout, _stderr, status = shell.execute(scan_command)
        status.success? ? parse(stdout) : []
      end
    end

    def possible_package_paths
      [
        project_path.join('Cargo.lock'),
        project_path.join('Cargo.toml')
      ]
    end

    private

    def parse(stdout)
      stdout.each_line.map do |line|
        next if line.include?(project_path.to_s)

        map_from(line.chomp)
      end.compact
    end

    def scan_command
      [
        :cargo, :tree, '--edges=no-dev',
        "--color=never",
        "--offline",
        "--prefix=none",
        "-f='{p}#{SENTINEL}{l}'"
      ]
    end

    def default_env
      @default_env ||= {
        'CARGO_HOME' => vendor_path.to_s,
        'CARGO_TARGET_DIR' => vendor_path.to_s,
        'HTTP_TIMEOUT' => '10',
        'HTTP_CAINFO' => shell.default_certificate_path.to_s,
        'TERM' => 'dumb'
      }
    end

    def map_from(line)
      name_version, license = line.split(SENTINEL, 2)
      name, version = name_version.split(' ', 2)

      Dependency.new(
        'Cargo',
        name,
        version,
        detection_path: detected_package_path,
        install_path: path_to(name, version),
        spec_licenses: license ? license.split('/') : []
      )
    end

    def path_to(name, version)
      Dir.glob("/opt/asdf/installs/rust/**/registry/src/**/#{name}-#{version}")[0]
    end
  end
end