summaryrefslogtreecommitdiff
path: root/lib/license/management/repository.rb
blob: 0c428ddaa3ad742a0e77c57d71a9a62d523e5013 (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
# frozen_string_literal: true

module License
  module Management
    class Repository
      include Loggable
      include Verifiable

      def initialize(
        compatibility_path: License::Management.root.join('normalized-licenses.yml'),
        spdx_path: License::Management.root.join('spdx-licenses.json')
      )
        @compatibility_data = YAML.safe_load(IO.read(compatibility_path))
        @spdx_data = load_spdx_data_from(spdx_path)
      end

      def item_for(license)
        spdx_data_for(id_for(license)) ||
          spdx_data_for(license.send(:short_name)) ||
          generate_item_for(license)
      end

      private

      attr_reader :spdx_data, :compatibility_data

      def spdx_data_for(id)
        data = spdx_data[id]
        if data
          {
            'id' => data['licenseId'],
            'name' => data['name'],
            'url' => data['seeAlso'][-1]
          }
        else
          log_info("Could not find license `#{id}` in SPDX")
          nil
        end
      end

      def id_for(license)
        ids = compatibility_data['ids']
        ids[license.send(:short_name)] || ids[license.url]
      end

      # When `license_finder` is unable to determine the license it will use the full
      # content of the file as the name of the license. This method shrinks that name
      # down to just take the first line of the file.
      def take_first_line_from(content)
        return '' if blank?(content)

        content.split(/[\r\n]+/)[0]
      end

      def generate_item_for(license)
        log_info("detected unknown license named `#{license.send(:short_name)}`")
        {
          'id' => 'unknown',
          'name' => take_first_line_from(license.name),
          'url' => present?(license.url) ? license.url : ''
        }
      end

      def load_spdx_data_from(path)
        content = IO.read(path)
        json = JSON.parse(content)
        licenses = json['licenses']

        licenses.inject({}) do |memo, license|
          memo[license['licenseId']] = license
          memo
        end
      end
    end
  end
end