gitlab-license_finder 6.14.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (180) hide show
  1. checksums.yaml +7 -0
  2. data/.force-build +0 -0
  3. data/.gitignore +13 -0
  4. data/.rspec +1 -0
  5. data/.rubocop.yml +70 -0
  6. data/CHANGELOG.md +981 -0
  7. data/CONTRIBUTING.md +121 -0
  8. data/Dockerfile +249 -0
  9. data/Gemfile +2 -0
  10. data/LICENSE +22 -0
  11. data/README.md +555 -0
  12. data/Rakefile +77 -0
  13. data/TODO.md +12 -0
  14. data/VERSION +1 -0
  15. data/appveyor.yml +21 -0
  16. data/bin/license_finder +6 -0
  17. data/bin/license_finder_pip.py +43 -0
  18. data/ci/pipelines/pull-request.yml.erb +141 -0
  19. data/ci/pipelines/release.yml.erb +200 -0
  20. data/ci/scripts/containerize-tests.sh +14 -0
  21. data/ci/scripts/pushscript.sh +32 -0
  22. data/ci/scripts/run-rubocop.sh +15 -0
  23. data/ci/scripts/run-tests.sh +24 -0
  24. data/ci/scripts/test.ps1 +81 -0
  25. data/ci/scripts/updateChangelog.sh +84 -0
  26. data/ci/tasks/build-and-push-gem.yml +10 -0
  27. data/ci/tasks/build-windows.yml +6 -0
  28. data/ci/tasks/build.yml +16 -0
  29. data/ci/tasks/rubocop.yml +15 -0
  30. data/ci/tasks/run-tests.yml +10 -0
  31. data/ci/tasks/update-changelog.yml +18 -0
  32. data/dlf +12 -0
  33. data/examples/Gemfile +4 -0
  34. data/examples/custom_erb_template.rb +24 -0
  35. data/examples/extract_license_data.rb +63 -0
  36. data/examples/sample_template.erb +7 -0
  37. data/lib/license_finder/cli/approvals.rb +28 -0
  38. data/lib/license_finder/cli/base.rb +107 -0
  39. data/lib/license_finder/cli/dependencies.rb +44 -0
  40. data/lib/license_finder/cli/ignored_dependencies.rb +32 -0
  41. data/lib/license_finder/cli/ignored_groups.rb +32 -0
  42. data/lib/license_finder/cli/inherited_decisions.rb +50 -0
  43. data/lib/license_finder/cli/licenses.rb +26 -0
  44. data/lib/license_finder/cli/main.rb +221 -0
  45. data/lib/license_finder/cli/makes_decisions.rb +38 -0
  46. data/lib/license_finder/cli/patched_thor.rb +33 -0
  47. data/lib/license_finder/cli/permitted_licenses.rb +32 -0
  48. data/lib/license_finder/cli/project_name.rb +32 -0
  49. data/lib/license_finder/cli/restricted_licenses.rb +32 -0
  50. data/lib/license_finder/cli.rb +20 -0
  51. data/lib/license_finder/configuration.rb +186 -0
  52. data/lib/license_finder/core.rb +118 -0
  53. data/lib/license_finder/decision_applier.rb +70 -0
  54. data/lib/license_finder/decisions.rb +312 -0
  55. data/lib/license_finder/decisions_factory.rb +13 -0
  56. data/lib/license_finder/diff.rb +51 -0
  57. data/lib/license_finder/license/any_matcher.rb +15 -0
  58. data/lib/license_finder/license/definitions.rb +366 -0
  59. data/lib/license_finder/license/header_matcher.rb +17 -0
  60. data/lib/license_finder/license/matcher.rb +24 -0
  61. data/lib/license_finder/license/none_matcher.rb +11 -0
  62. data/lib/license_finder/license/template.rb +19 -0
  63. data/lib/license_finder/license/templates/0BSD.txt +10 -0
  64. data/lib/license_finder/license/templates/Apache1_1.txt +16 -0
  65. data/lib/license_finder/license/templates/Apache2.txt +172 -0
  66. data/lib/license_finder/license/templates/BSD.txt +24 -0
  67. data/lib/license_finder/license/templates/CC01.txt +30 -0
  68. data/lib/license_finder/license/templates/CDDL1.txt +131 -0
  69. data/lib/license_finder/license/templates/EPL1.txt +86 -0
  70. data/lib/license_finder/license/templates/GPLv2.txt +339 -0
  71. data/lib/license_finder/license/templates/GPLv3.txt +674 -0
  72. data/lib/license_finder/license/templates/ISC.txt +2 -0
  73. data/lib/license_finder/license/templates/LGPL.txt +165 -0
  74. data/lib/license_finder/license/templates/LGPL2_1.txt +169 -0
  75. data/lib/license_finder/license/templates/MIT.txt +9 -0
  76. data/lib/license_finder/license/templates/MPL1_1.txt +469 -0
  77. data/lib/license_finder/license/templates/MPL2.txt +373 -0
  78. data/lib/license_finder/license/templates/NewBSD.txt +21 -0
  79. data/lib/license_finder/license/templates/OFL.txt +91 -0
  80. data/lib/license_finder/license/templates/Python.txt +47 -0
  81. data/lib/license_finder/license/templates/Ruby.txt +52 -0
  82. data/lib/license_finder/license/templates/SimplifiedBSD.txt +19 -0
  83. data/lib/license_finder/license/templates/WTFPL.txt +14 -0
  84. data/lib/license_finder/license/templates/Zlib.txt +17 -0
  85. data/lib/license_finder/license/text.rb +45 -0
  86. data/lib/license_finder/license.rb +117 -0
  87. data/lib/license_finder/license_aggregator.rb +59 -0
  88. data/lib/license_finder/logger.rb +69 -0
  89. data/lib/license_finder/package.rb +202 -0
  90. data/lib/license_finder/package_delta.rb +61 -0
  91. data/lib/license_finder/package_manager.rb +181 -0
  92. data/lib/license_finder/package_managers/bower.rb +37 -0
  93. data/lib/license_finder/package_managers/bundler.rb +110 -0
  94. data/lib/license_finder/package_managers/cargo.rb +38 -0
  95. data/lib/license_finder/package_managers/carthage.rb +68 -0
  96. data/lib/license_finder/package_managers/cocoa_pods.rb +61 -0
  97. data/lib/license_finder/package_managers/composer.rb +63 -0
  98. data/lib/license_finder/package_managers/conan.rb +28 -0
  99. data/lib/license_finder/package_managers/conda.rb +131 -0
  100. data/lib/license_finder/package_managers/dep.rb +43 -0
  101. data/lib/license_finder/package_managers/dotnet.rb +83 -0
  102. data/lib/license_finder/package_managers/erlangmk.rb +50 -0
  103. data/lib/license_finder/package_managers/glide.rb +36 -0
  104. data/lib/license_finder/package_managers/go_15vendorexperiment.rb +87 -0
  105. data/lib/license_finder/package_managers/go_dep.rb +80 -0
  106. data/lib/license_finder/package_managers/go_modules.rb +93 -0
  107. data/lib/license_finder/package_managers/go_workspace.rb +116 -0
  108. data/lib/license_finder/package_managers/govendor.rb +73 -0
  109. data/lib/license_finder/package_managers/gradle.rb +99 -0
  110. data/lib/license_finder/package_managers/gvt.rb +69 -0
  111. data/lib/license_finder/package_managers/maven.rb +65 -0
  112. data/lib/license_finder/package_managers/mix.rb +131 -0
  113. data/lib/license_finder/package_managers/npm.rb +57 -0
  114. data/lib/license_finder/package_managers/nuget.rb +154 -0
  115. data/lib/license_finder/package_managers/pip.rb +70 -0
  116. data/lib/license_finder/package_managers/pipenv.rb +63 -0
  117. data/lib/license_finder/package_managers/rebar.rb +65 -0
  118. data/lib/license_finder/package_managers/sbt.rb +50 -0
  119. data/lib/license_finder/package_managers/spm.rb +93 -0
  120. data/lib/license_finder/package_managers/trash.rb +43 -0
  121. data/lib/license_finder/package_managers/yarn.rb +107 -0
  122. data/lib/license_finder/package_utils/activation.rb +40 -0
  123. data/lib/license_finder/package_utils/conan_info_parser.rb +77 -0
  124. data/lib/license_finder/package_utils/gradle_dependency_finder.rb +15 -0
  125. data/lib/license_finder/package_utils/license_files.rb +41 -0
  126. data/lib/license_finder/package_utils/licensing.rb +39 -0
  127. data/lib/license_finder/package_utils/maven_dependency_finder.rb +15 -0
  128. data/lib/license_finder/package_utils/notice_files.rb +40 -0
  129. data/lib/license_finder/package_utils/possible_license_file.rb +27 -0
  130. data/lib/license_finder/package_utils/pypi.rb +41 -0
  131. data/lib/license_finder/package_utils/sbt_dependency_finder.rb +15 -0
  132. data/lib/license_finder/packages/bower_package.rb +42 -0
  133. data/lib/license_finder/packages/bundler_package.rb +33 -0
  134. data/lib/license_finder/packages/cargo_package.rb +28 -0
  135. data/lib/license_finder/packages/carthage_package.rb +18 -0
  136. data/lib/license_finder/packages/cocoa_pods_package.rb +22 -0
  137. data/lib/license_finder/packages/composer_package.rb +13 -0
  138. data/lib/license_finder/packages/conan_package.rb +23 -0
  139. data/lib/license_finder/packages/conda_package.rb +74 -0
  140. data/lib/license_finder/packages/erlangmk_package.rb +114 -0
  141. data/lib/license_finder/packages/go_package.rb +32 -0
  142. data/lib/license_finder/packages/gradle_package.rb +30 -0
  143. data/lib/license_finder/packages/manual_package.rb +27 -0
  144. data/lib/license_finder/packages/maven_package.rb +27 -0
  145. data/lib/license_finder/packages/merged_package.rb +44 -0
  146. data/lib/license_finder/packages/mix_package.rb +13 -0
  147. data/lib/license_finder/packages/npm_package.rb +171 -0
  148. data/lib/license_finder/packages/nuget_package.rb +13 -0
  149. data/lib/license_finder/packages/pip_package.rb +50 -0
  150. data/lib/license_finder/packages/rebar_package.rb +13 -0
  151. data/lib/license_finder/packages/sbt_package.rb +22 -0
  152. data/lib/license_finder/packages/spm_package.rb +18 -0
  153. data/lib/license_finder/packages/yarn_package.rb +13 -0
  154. data/lib/license_finder/platform.rb +15 -0
  155. data/lib/license_finder/project_finder.rb +62 -0
  156. data/lib/license_finder/report.rb +33 -0
  157. data/lib/license_finder/reports/csv_report.rb +99 -0
  158. data/lib/license_finder/reports/diff_report.rb +29 -0
  159. data/lib/license_finder/reports/erb_report.rb +58 -0
  160. data/lib/license_finder/reports/html_report.rb +13 -0
  161. data/lib/license_finder/reports/json_report.rb +30 -0
  162. data/lib/license_finder/reports/junit_report.rb +19 -0
  163. data/lib/license_finder/reports/markdown_report.rb +9 -0
  164. data/lib/license_finder/reports/merged_report.rb +16 -0
  165. data/lib/license_finder/reports/templates/bootstrap.css +9 -0
  166. data/lib/license_finder/reports/templates/html_report.erb +113 -0
  167. data/lib/license_finder/reports/templates/junit_report.erb +41 -0
  168. data/lib/license_finder/reports/templates/markdown_report.erb +49 -0
  169. data/lib/license_finder/reports/templates/xml_report.erb +19 -0
  170. data/lib/license_finder/reports/text_report.rb +12 -0
  171. data/lib/license_finder/reports/xml_report.rb +19 -0
  172. data/lib/license_finder/scanner.rb +83 -0
  173. data/lib/license_finder/shared_helpers/cmd.rb +13 -0
  174. data/lib/license_finder/shared_helpers/common_path.rb +29 -0
  175. data/lib/license_finder/version.rb +6 -0
  176. data/lib/license_finder.rb +14 -0
  177. data/license_finder.gemspec +72 -0
  178. data/release/instructions.md +8 -0
  179. data/swift-all-keys.asc +240 -0
  180. metadata +544 -0
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LicenseFinder
4
+ class License
5
+ module Text
6
+ SPACES = /\s+/.freeze
7
+ QUOTES = /['`"]{1,2}/.freeze
8
+ YEAR_PLACEHOLDERS = /<year>/.freeze
9
+ PLACEHOLDERS = /<[^<>]+>/.freeze
10
+ SPECIAL_SINGLE_QUOTES = /[‘’]/.freeze
11
+ SPECIAL_DOUBLE_QUOTES = /[“”„«»]/.freeze
12
+ ALPHABET_ORDERED_LIST = /\\\([a-z]\\\)\\\s/.freeze
13
+ ALPHABET_ORDERED_LIST_OPTIONAL = '(\([a-z]\)\s)?'
14
+ LIST_BULLETS = /(\d{1,2}\\\.|\\\*|\\\-)\\\s/.freeze
15
+ LIST_BULLETS_OPTIONAL = '(\d{1,2}.|\*|\-)?\s*'
16
+ NEWLINE_CHARACTER = /\n+/.freeze
17
+ QUOTE_COMMENT_CHARACTER = /^\s*\>+/.freeze
18
+ ESCAPED_QUOTES = /\\\"/.freeze
19
+
20
+ def self.normalize_punctuation(text)
21
+ text.dup.force_encoding('UTF-8')
22
+ .gsub(SPECIAL_DOUBLE_QUOTES, '"')
23
+ .gsub(SPECIAL_SINGLE_QUOTES, "'")
24
+ .gsub(QUOTE_COMMENT_CHARACTER, '')
25
+ .gsub(SPACES, ' ')
26
+ .gsub(NEWLINE_CHARACTER, ' ')
27
+ .gsub(ESCAPED_QUOTES, '"')
28
+ .gsub(QUOTES, '"')
29
+ .strip
30
+ rescue ArgumentError => _e
31
+ text
32
+ end
33
+
34
+ def self.compile_to_regex(text)
35
+ Regexp.new(Regexp.escape(normalize_punctuation(text))
36
+ .gsub(YEAR_PLACEHOLDERS, '(\S*)')
37
+ .gsub(PLACEHOLDERS, '(.*)')
38
+ .gsub(',', '(,)?')
39
+ .gsub('HOLDER', '(HOLDER|OWNER)')
40
+ .gsub(ALPHABET_ORDERED_LIST, ALPHABET_ORDERED_LIST_OPTIONAL)
41
+ .gsub(LIST_BULLETS, LIST_BULLETS_OPTIONAL))
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,117 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'license_finder/license/text'
4
+ require 'license_finder/license/template'
5
+
6
+ require 'license_finder/license/matcher'
7
+ require 'license_finder/license/header_matcher'
8
+ require 'license_finder/license/any_matcher'
9
+ require 'license_finder/license/none_matcher'
10
+
11
+ require 'license_finder/license/definitions'
12
+
13
+ module LicenseFinder
14
+ class License
15
+ class << self
16
+ def all
17
+ @all ||= Definitions.all
18
+ end
19
+
20
+ def find_by_name(name)
21
+ name ||= 'unknown'
22
+ license = all.detect { |l| l.matches_name? l.stripped_name(name) }
23
+
24
+ if license
25
+ license
26
+ elsif name.include?(OrLicense.operator)
27
+ OrLicense.new(name)
28
+ elsif name.include?(AndLicense.operator)
29
+ AndLicense.new(name)
30
+ else
31
+ Definitions.build_unrecognized(name)
32
+ end
33
+ end
34
+
35
+ def find_by_text(text)
36
+ all.detect { |l| l.matches_text? text }
37
+ end
38
+ end
39
+
40
+ def initialize(settings)
41
+ @short_name = settings.fetch(:short_name)
42
+ @pretty_name = settings.fetch(:pretty_name, short_name)
43
+ @other_names = settings.fetch(:other_names, [])
44
+ @url = settings.fetch(:url)
45
+ @matcher = settings.fetch(:matcher) { Matcher.from_template(Template.named(short_name)) }
46
+ end
47
+
48
+ attr_reader :url
49
+
50
+ def name
51
+ pretty_name
52
+ end
53
+
54
+ def stripped_name(name)
55
+ name.sub(/^The /i, '')
56
+ end
57
+
58
+ def matches_name?(name)
59
+ names.map(&:downcase).include? name.to_s.downcase
60
+ end
61
+
62
+ def matches_text?(text)
63
+ matcher.matches_text?(text)
64
+ end
65
+
66
+ def eql?(other)
67
+ name == other.name
68
+ end
69
+
70
+ def hash
71
+ name.hash
72
+ end
73
+
74
+ def unrecognized_matcher?
75
+ matcher.is_a?(NoneMatcher)
76
+ end
77
+
78
+ private
79
+
80
+ attr_reader :short_name, :pretty_name, :other_names
81
+ attr_reader :matcher
82
+
83
+ def names
84
+ ([short_name, pretty_name] + other_names).uniq
85
+ end
86
+ end
87
+ class AndLicense < License
88
+ def self.operator
89
+ ' AND '
90
+ end
91
+
92
+ def initialize(name, operator = AndLicense.operator)
93
+ @short_name = name
94
+ @pretty_name = name
95
+ @url = nil
96
+ @matcher = NoneMatcher.new
97
+ # removes heading and trailing parentesis and splits
98
+ name = name[1..-2] if name.start_with?('(')
99
+ names = name.split(operator)
100
+ @sub_licenses = names.map do |sub_name|
101
+ License.find_by_name(sub_name)
102
+ end
103
+ end
104
+
105
+ attr_reader :sub_licenses
106
+ end
107
+
108
+ class OrLicense < AndLicense
109
+ def self.operator
110
+ ' OR '
111
+ end
112
+
113
+ def initialize(name)
114
+ super(name, OrLicense.operator)
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LicenseFinder
4
+ class LicenseAggregator
5
+ def initialize(config, aggregate_paths)
6
+ @config = config
7
+ @aggregate_paths = aggregate_paths
8
+ end
9
+
10
+ def dependencies
11
+ aggregate_packages
12
+ end
13
+
14
+ def any_packages?
15
+ finders.map do |finder|
16
+ finder.prepare_projects if @config.prepare
17
+ finder.any_packages?
18
+ end.reduce(:|)
19
+ end
20
+
21
+ def unapproved
22
+ aggregate_packages.reject(&:approved?)
23
+ end
24
+
25
+ def restricted
26
+ aggregate_packages.select(&:restricted?)
27
+ end
28
+
29
+ private
30
+
31
+ def finders
32
+ return @finders unless @finders.nil?
33
+
34
+ @finders = if @aggregate_paths.nil?
35
+ [LicenseFinder::Core.new(@config)]
36
+ else
37
+ @aggregate_paths.map do |path|
38
+ # Passing file paths as values instead of allowing them to evaluate in config
39
+ LicenseFinder::Core.new(@config.merge(project_path: path,
40
+ log_directory: @config.log_directory || @config.project_path,
41
+ decisions_file: @config.decisions_file_path))
42
+ end
43
+ end
44
+ end
45
+
46
+ def aggregate_packages
47
+ return @packages unless @packages.nil?
48
+
49
+ all_packages = finders.flat_map do |finder|
50
+ finder.prepare_projects if @config.prepare
51
+ finder.acknowledged.map { |dep| MergedPackage.new(dep, [finder.project_path]) }
52
+ end
53
+ @packages = all_packages.group_by { |package| [package.name, package.version] }
54
+ .map do |_, packages|
55
+ MergedPackage.new(packages[0].dependency, packages.flat_map(&:aggregate_paths))
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'logger'
4
+
5
+ module LicenseFinder
6
+ class Logger
7
+ MODE_QUIET = :quiet
8
+ MODE_INFO = :info
9
+ MODE_DEBUG = :debug
10
+
11
+ attr_reader :mode
12
+
13
+ def initialize(mode = nil)
14
+ @system_logger = ::Logger.new(STDOUT)
15
+ @system_logger.formatter = proc do |_, _, _, msg|
16
+ "#{msg}\n"
17
+ end
18
+
19
+ self.mode = mode || MODE_INFO
20
+ end
21
+
22
+ [MODE_INFO, MODE_DEBUG].each do |level|
23
+ define_method level do |prefix, string, options = {}|
24
+ msg = format('%s: %s', prefix, colorize(string, options[:color]))
25
+ log(msg, level)
26
+ end
27
+ end
28
+
29
+ private
30
+
31
+ attr_reader :system_logger
32
+
33
+ def colorize(string, color)
34
+ case color
35
+ when :red
36
+ "\e[31m#{string}\e[0m"
37
+ when :green
38
+ "\e[32m#{string}\e[0m"
39
+ when :magenta
40
+ "\e[35m#{string}\e[0m"
41
+ else
42
+ string
43
+ end
44
+ end
45
+
46
+ def mode=(verbose)
47
+ @mode = verbose
48
+
49
+ return if quiet?
50
+
51
+ level = @mode.equal?(MODE_DEBUG) ? ::Logger::DEBUG : ::Logger::INFO
52
+ system_logger.level = level
53
+ end
54
+
55
+ def log(msg, method)
56
+ return if quiet?
57
+
58
+ system_logger.send(method, msg)
59
+ end
60
+
61
+ def debug?
62
+ @mode.equal?(MODE_DEBUG)
63
+ end
64
+
65
+ def quiet?
66
+ @mode.equal?(MODE_QUIET)
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,202 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'license_finder/package_utils/licensing'
4
+ require 'license_finder/package_utils/license_files'
5
+ require 'license_finder/package_utils/notice_files'
6
+
7
+ module LicenseFinder
8
+ # Super-class that adapts data from different package management
9
+ # systems (gems, npm, pip, etc.) to a common interface.
10
+ #
11
+ # Guidance on adding a new system
12
+ #
13
+ # - subclass Package, and initialize based on the data you receive from the
14
+ # package manager
15
+ # - if the package specs will report license names, pass :spec_licenses in the
16
+ # constructor options
17
+ # - if the package's files can be searched for licenses pass :install_path in
18
+ # the constructor options
19
+ # - otherwise, override #licenses_from_spec or #license_files
20
+ class Package
21
+ attr_reader :logger
22
+
23
+ def self.license_names_from_standard_spec(spec)
24
+ licenses = spec['licenses'] || [spec['license']].compact
25
+ licenses = [licenses] unless licenses.is_a?(Array)
26
+ licenses = licenses.flatten
27
+ licenses.map do |license|
28
+ if license.is_a? Hash
29
+ license['type']
30
+ else
31
+ license
32
+ end
33
+ end
34
+ end
35
+
36
+ def initialize(name, version = nil, options = {})
37
+ @logger = options[:logger] || Core.default_logger
38
+
39
+ ## DESCRIPTION
40
+ @name = name
41
+ @version = version || ''
42
+ @authors = options[:authors] || ''
43
+ @summary = options[:summary] || ''
44
+ @description = options[:description] || ''
45
+ @homepage = options[:homepage] || ''
46
+ @package_url = options[:package_url].to_s
47
+ @children = options[:children] || []
48
+ @parents = Set.new # will be figured out later by package manager
49
+ @groups = options[:groups] || []
50
+
51
+ ## APPROVAL
52
+ @permitted = false
53
+ @restricted = false
54
+ @manual_approval = nil
55
+
56
+ ## LICENSING
57
+ @license_names_from_spec = options[:spec_licenses] || []
58
+ @install_path = options[:install_path]
59
+ @missing = options[:missing] || false
60
+ @decided_licenses = Set.new
61
+ end
62
+
63
+ ## DESCRIPTION
64
+
65
+ attr_accessor :homepage, :package_url
66
+
67
+ attr_reader :name, :version, :authors,
68
+ :summary, :description,
69
+ :children, :parents, :groups
70
+
71
+ ## APPROVAL
72
+
73
+ def approved_manually!(approval)
74
+ @manual_approval = approval
75
+ end
76
+
77
+ def approved_manually?
78
+ !@manual_approval.nil?
79
+ end
80
+
81
+ def approved?
82
+ # Question: is `!restricted?` redundant?
83
+ # DecisionApplier does not call `permitted!` or `approved_manually!`
84
+ # if a Package has been restricted.
85
+ (approved_manually? || permitted?) && !restricted?
86
+ end
87
+
88
+ def permitted!
89
+ @permitted = true
90
+ end
91
+
92
+ def permitted?
93
+ @permitted
94
+ end
95
+
96
+ def restricted!
97
+ @restricted = true
98
+ end
99
+
100
+ def restricted?
101
+ @restricted
102
+ end
103
+
104
+ attr_reader :manual_approval
105
+
106
+ ## EQUALITY
107
+
108
+ def <=>(other)
109
+ eq_name = name <=> other.name
110
+ return eq_name unless eq_name.zero?
111
+
112
+ version <=> other.version
113
+ end
114
+
115
+ def eql?(other)
116
+ name == other.name && version == other.version
117
+ end
118
+
119
+ def hash
120
+ [name, version].hash
121
+ end
122
+
123
+ ## LICENSING
124
+
125
+ attr_reader :license_names_from_spec # stubbed in tests, otherwise private
126
+ attr_reader :install_path # checked in tests, otherwise private
127
+
128
+ def licenses
129
+ @licenses ||= activations.map(&:license).sort_by(&:name).to_set
130
+ end
131
+
132
+ def activations
133
+ licensing.activations.tap do |activations|
134
+ activations.each { |activation| log_activation activation }
135
+ end
136
+ end
137
+
138
+ def licensing
139
+ Licensing.new(self, @decided_licenses, licenses_from_spec, license_files)
140
+ end
141
+
142
+ def decide_on_license(license)
143
+ @decided_licenses << license
144
+ end
145
+
146
+ def licenses_from_spec
147
+ license_names_from_spec
148
+ .map { |name| License.find_by_name(name) }
149
+ .to_set
150
+ end
151
+
152
+ def license_files
153
+ LicenseFiles.find(install_path, logger: logger)
154
+ end
155
+
156
+ def notice_files
157
+ NoticeFiles.find(install_path, logger: logger)
158
+ end
159
+
160
+ def package_manager
161
+ 'unknown'
162
+ end
163
+
164
+ def missing?
165
+ @missing
166
+ end
167
+
168
+ def log_activation(activation)
169
+ preamble = format('package %s:', activation.package.name)
170
+ if activation.sources.empty?
171
+ logger.debug activation.package.class, format('%s no licenses found', preamble)
172
+ else
173
+ activation.sources.each do |source|
174
+ logger.debug activation.package.class, format("%s found license '%s' %s", preamble, activation.license.name, source)
175
+ end
176
+ end
177
+ end
178
+ end
179
+ end
180
+
181
+ require 'license_finder/packages/manual_package'
182
+ require 'license_finder/packages/bower_package'
183
+ require 'license_finder/packages/go_package'
184
+ require 'license_finder/packages/bundler_package'
185
+ require 'license_finder/packages/pip_package'
186
+ require 'license_finder/packages/npm_package'
187
+ require 'license_finder/packages/maven_package'
188
+ require 'license_finder/packages/gradle_package'
189
+ require 'license_finder/packages/cocoa_pods_package'
190
+ require 'license_finder/packages/carthage_package'
191
+ require 'license_finder/packages/spm_package'
192
+ require 'license_finder/packages/rebar_package'
193
+ require 'license_finder/packages/erlangmk_package'
194
+ require 'license_finder/packages/mix_package'
195
+ require 'license_finder/packages/merged_package'
196
+ require 'license_finder/packages/nuget_package'
197
+ require 'license_finder/packages/conan_package'
198
+ require 'license_finder/packages/yarn_package'
199
+ require 'license_finder/packages/sbt_package'
200
+ require 'license_finder/packages/cargo_package'
201
+ require 'license_finder/packages/composer_package'
202
+ require 'license_finder/packages/conda_package'
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LicenseFinder
4
+ class PackageDelta
5
+ STATUSES = %i[added removed unchanged].freeze
6
+
7
+ def initialize(status, current_package, previous_package)
8
+ @status = status
9
+ @current_package = current_package
10
+ @previous_package = previous_package
11
+ end
12
+
13
+ def name
14
+ pick_package.name
15
+ end
16
+
17
+ def version
18
+ pick_package.version
19
+ end
20
+
21
+ def aggregate_paths
22
+ pick_package.aggregate_paths
23
+ end
24
+
25
+ attr_reader :status
26
+
27
+ def licenses
28
+ pick_package.licenses
29
+ end
30
+
31
+ def merged_package?
32
+ pick_package.class == MergedPackage
33
+ end
34
+
35
+ def method_missing(_method_name)
36
+ nil
37
+ end
38
+
39
+ def self.added(package)
40
+ new(:added, package, nil)
41
+ end
42
+
43
+ def self.removed(package)
44
+ new(:removed, nil, package)
45
+ end
46
+
47
+ def self.unchanged(current_package, previous_package)
48
+ new(:unchanged, current_package, previous_package)
49
+ end
50
+
51
+ def <=>(other)
52
+ STATUSES.index(status) <=> STATUSES.index(other.status)
53
+ end
54
+
55
+ private
56
+
57
+ def pick_package
58
+ @current_package || @previous_package
59
+ end
60
+ end
61
+ end