license_finder-rubyzip3 7.2.1.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 (196) hide show
  1. checksums.yaml +7 -0
  2. data/.force-build +0 -0
  3. data/.github/dependabot.yml +16 -0
  4. data/.gitignore +13 -0
  5. data/.pre-commit-hooks.yaml +10 -0
  6. data/.rspec +1 -0
  7. data/.rubocop.yml +84 -0
  8. data/CHANGELOG.md +1066 -0
  9. data/CONTRIBUTING.md +122 -0
  10. data/Dockerfile +275 -0
  11. data/Gemfile +2 -0
  12. data/LICENSE +22 -0
  13. data/README.md +597 -0
  14. data/Rakefile +77 -0
  15. data/TODO.md +12 -0
  16. data/VERSION +1 -0
  17. data/appveyor.yml +21 -0
  18. data/bin/license_finder +6 -0
  19. data/bin/license_finder_pip.py +43 -0
  20. data/ci/pipelines/pull-request.yml.erb +138 -0
  21. data/ci/pipelines/release.yml.erb +176 -0
  22. data/ci/scripts/containerize-tests.sh +14 -0
  23. data/ci/scripts/pushscript.sh +31 -0
  24. data/ci/scripts/run-rubocop.sh +15 -0
  25. data/ci/scripts/run-tests.sh +41 -0
  26. data/ci/scripts/test.ps1 +81 -0
  27. data/ci/scripts/updateChangelog.sh +84 -0
  28. data/ci/tasks/build-and-push-gem.yml +10 -0
  29. data/ci/tasks/build-windows.yml +6 -0
  30. data/ci/tasks/build.yml +16 -0
  31. data/ci/tasks/rubocop.yml +15 -0
  32. data/ci/tasks/run-tests.yml +10 -0
  33. data/ci/tasks/update-changelog.yml +18 -0
  34. data/dlf +21 -0
  35. data/examples/Gemfile +4 -0
  36. data/examples/custom_erb_template.rb +24 -0
  37. data/examples/extract_license_data.rb +63 -0
  38. data/examples/sample_template.erb +7 -0
  39. data/lib/license_finder/cli/approvals.rb +28 -0
  40. data/lib/license_finder/cli/base.rb +113 -0
  41. data/lib/license_finder/cli/dependencies.rb +44 -0
  42. data/lib/license_finder/cli/ignored_dependencies.rb +32 -0
  43. data/lib/license_finder/cli/ignored_groups.rb +32 -0
  44. data/lib/license_finder/cli/inherited_decisions.rb +50 -0
  45. data/lib/license_finder/cli/licenses.rb +31 -0
  46. data/lib/license_finder/cli/main.rb +229 -0
  47. data/lib/license_finder/cli/makes_decisions.rb +38 -0
  48. data/lib/license_finder/cli/patched_thor.rb +33 -0
  49. data/lib/license_finder/cli/permitted_licenses.rb +32 -0
  50. data/lib/license_finder/cli/project_name.rb +32 -0
  51. data/lib/license_finder/cli/restricted_licenses.rb +32 -0
  52. data/lib/license_finder/cli.rb +20 -0
  53. data/lib/license_finder/configuration.rb +197 -0
  54. data/lib/license_finder/core.rb +121 -0
  55. data/lib/license_finder/decision_applier.rb +70 -0
  56. data/lib/license_finder/decisions.rb +334 -0
  57. data/lib/license_finder/decisions_factory.rb +13 -0
  58. data/lib/license_finder/diff.rb +51 -0
  59. data/lib/license_finder/license/any_matcher.rb +15 -0
  60. data/lib/license_finder/license/definitions.rb +498 -0
  61. data/lib/license_finder/license/header_matcher.rb +17 -0
  62. data/lib/license_finder/license/matcher.rb +24 -0
  63. data/lib/license_finder/license/none_matcher.rb +11 -0
  64. data/lib/license_finder/license/template.rb +19 -0
  65. data/lib/license_finder/license/templates/0BSD.txt +10 -0
  66. data/lib/license_finder/license/templates/AGPL3.txt +661 -0
  67. data/lib/license_finder/license/templates/Apache1_1.txt +16 -0
  68. data/lib/license_finder/license/templates/Apache2.txt +170 -0
  69. data/lib/license_finder/license/templates/Artistic.txt +128 -0
  70. data/lib/license_finder/license/templates/BSD.txt +24 -0
  71. data/lib/license_finder/license/templates/CC01.txt +30 -0
  72. data/lib/license_finder/license/templates/CC01_alt.txt +31 -0
  73. data/lib/license_finder/license/templates/CDDL1.txt +131 -0
  74. data/lib/license_finder/license/templates/CDDL1_1.txt +123 -0
  75. data/lib/license_finder/license/templates/CPL1.txt +217 -0
  76. data/lib/license_finder/license/templates/EPL1.txt +86 -0
  77. data/lib/license_finder/license/templates/EPL2.txt +80 -0
  78. data/lib/license_finder/license/templates/GPLv2.txt +339 -0
  79. data/lib/license_finder/license/templates/GPLv3.txt +674 -0
  80. data/lib/license_finder/license/templates/ISC.txt +2 -0
  81. data/lib/license_finder/license/templates/LGPL.txt +165 -0
  82. data/lib/license_finder/license/templates/LGPL2_1.txt +169 -0
  83. data/lib/license_finder/license/templates/MIT.txt +9 -0
  84. data/lib/license_finder/license/templates/MPL1_1.txt +469 -0
  85. data/lib/license_finder/license/templates/MPL2.txt +373 -0
  86. data/lib/license_finder/license/templates/NewBSD.txt +21 -0
  87. data/lib/license_finder/license/templates/OFL.txt +91 -0
  88. data/lib/license_finder/license/templates/Python.txt +47 -0
  89. data/lib/license_finder/license/templates/Ruby.txt +52 -0
  90. data/lib/license_finder/license/templates/SimplifiedBSD.txt +19 -0
  91. data/lib/license_finder/license/templates/Unlicense.txt +24 -0
  92. data/lib/license_finder/license/templates/WTFPL.txt +14 -0
  93. data/lib/license_finder/license/templates/Zlib.txt +17 -0
  94. data/lib/license_finder/license/text.rb +49 -0
  95. data/lib/license_finder/license.rb +123 -0
  96. data/lib/license_finder/license_aggregator.rb +59 -0
  97. data/lib/license_finder/logger.rb +69 -0
  98. data/lib/license_finder/manual_licenses.rb +79 -0
  99. data/lib/license_finder/package.rb +195 -0
  100. data/lib/license_finder/package_delta.rb +61 -0
  101. data/lib/license_finder/package_manager.rb +183 -0
  102. data/lib/license_finder/package_managers/bower.rb +37 -0
  103. data/lib/license_finder/package_managers/bundler.rb +110 -0
  104. data/lib/license_finder/package_managers/cargo.rb +38 -0
  105. data/lib/license_finder/package_managers/carthage.rb +68 -0
  106. data/lib/license_finder/package_managers/cocoa_pods.rb +66 -0
  107. data/lib/license_finder/package_managers/composer.rb +63 -0
  108. data/lib/license_finder/package_managers/conan.rb +70 -0
  109. data/lib/license_finder/package_managers/conda.rb +131 -0
  110. data/lib/license_finder/package_managers/dep.rb +45 -0
  111. data/lib/license_finder/package_managers/dotnet.rb +86 -0
  112. data/lib/license_finder/package_managers/erlangmk.rb +50 -0
  113. data/lib/license_finder/package_managers/glide.rb +42 -0
  114. data/lib/license_finder/package_managers/go_15vendorexperiment.rb +87 -0
  115. data/lib/license_finder/package_managers/go_dep.rb +80 -0
  116. data/lib/license_finder/package_managers/go_modules.rb +93 -0
  117. data/lib/license_finder/package_managers/go_workspace.rb +117 -0
  118. data/lib/license_finder/package_managers/govendor.rb +73 -0
  119. data/lib/license_finder/package_managers/gradle.rb +99 -0
  120. data/lib/license_finder/package_managers/gvt.rb +69 -0
  121. data/lib/license_finder/package_managers/maven.rb +69 -0
  122. data/lib/license_finder/package_managers/mix.rb +131 -0
  123. data/lib/license_finder/package_managers/npm.rb +70 -0
  124. data/lib/license_finder/package_managers/nuget.rb +159 -0
  125. data/lib/license_finder/package_managers/pip.rb +70 -0
  126. data/lib/license_finder/package_managers/pipenv.rb +63 -0
  127. data/lib/license_finder/package_managers/pnpm.rb +126 -0
  128. data/lib/license_finder/package_managers/pub.rb +86 -0
  129. data/lib/license_finder/package_managers/rebar.rb +65 -0
  130. data/lib/license_finder/package_managers/sbt.rb +46 -0
  131. data/lib/license_finder/package_managers/spm.rb +93 -0
  132. data/lib/license_finder/package_managers/trash.rb +43 -0
  133. data/lib/license_finder/package_managers/yarn.rb +195 -0
  134. data/lib/license_finder/package_utils/activation.rb +40 -0
  135. data/lib/license_finder/package_utils/conan_info_parser.rb +77 -0
  136. data/lib/license_finder/package_utils/conan_info_parser_v2.rb +82 -0
  137. data/lib/license_finder/package_utils/gradle_dependency_finder.rb +15 -0
  138. data/lib/license_finder/package_utils/license_files.rb +51 -0
  139. data/lib/license_finder/package_utils/licensing.rb +40 -0
  140. data/lib/license_finder/package_utils/maven_dependency_finder.rb +57 -0
  141. data/lib/license_finder/package_utils/notice_files.rb +51 -0
  142. data/lib/license_finder/package_utils/possible_license_file.rb +33 -0
  143. data/lib/license_finder/package_utils/pypi.rb +43 -0
  144. data/lib/license_finder/package_utils/sbt_dependency_finder.rb +15 -0
  145. data/lib/license_finder/packages/bower_package.rb +45 -0
  146. data/lib/license_finder/packages/bundler_package.rb +33 -0
  147. data/lib/license_finder/packages/cargo_package.rb +28 -0
  148. data/lib/license_finder/packages/carthage_package.rb +18 -0
  149. data/lib/license_finder/packages/cocoa_pods_package.rb +22 -0
  150. data/lib/license_finder/packages/composer_package.rb +13 -0
  151. data/lib/license_finder/packages/conan_package.rb +23 -0
  152. data/lib/license_finder/packages/conda_package.rb +74 -0
  153. data/lib/license_finder/packages/erlangmk_package.rb +112 -0
  154. data/lib/license_finder/packages/go_package.rb +30 -0
  155. data/lib/license_finder/packages/gradle_package.rb +30 -0
  156. data/lib/license_finder/packages/manual_package.rb +27 -0
  157. data/lib/license_finder/packages/maven_package.rb +39 -0
  158. data/lib/license_finder/packages/merged_package.rb +44 -0
  159. data/lib/license_finder/packages/mix_package.rb +13 -0
  160. data/lib/license_finder/packages/npm_package.rb +219 -0
  161. data/lib/license_finder/packages/nuget_package.rb +13 -0
  162. data/lib/license_finder/packages/pip_package.rb +50 -0
  163. data/lib/license_finder/packages/pnpm_package.rb +13 -0
  164. data/lib/license_finder/packages/pubspec_package.rb +18 -0
  165. data/lib/license_finder/packages/rebar_package.rb +13 -0
  166. data/lib/license_finder/packages/sbt_package.rb +22 -0
  167. data/lib/license_finder/packages/spm_package.rb +18 -0
  168. data/lib/license_finder/packages/yarn_package.rb +13 -0
  169. data/lib/license_finder/platform.rb +15 -0
  170. data/lib/license_finder/printer.rb +39 -0
  171. data/lib/license_finder/project_finder.rb +62 -0
  172. data/lib/license_finder/report.rb +34 -0
  173. data/lib/license_finder/reports/csv_report.rb +108 -0
  174. data/lib/license_finder/reports/diff_report.rb +29 -0
  175. data/lib/license_finder/reports/erb_report.rb +62 -0
  176. data/lib/license_finder/reports/html_report.rb +13 -0
  177. data/lib/license_finder/reports/json_report.rb +31 -0
  178. data/lib/license_finder/reports/junit_report.rb +23 -0
  179. data/lib/license_finder/reports/markdown_report.rb +9 -0
  180. data/lib/license_finder/reports/merged_report.rb +16 -0
  181. data/lib/license_finder/reports/templates/bootstrap.css +9 -0
  182. data/lib/license_finder/reports/templates/html_report.erb +113 -0
  183. data/lib/license_finder/reports/templates/junit_report.erb +41 -0
  184. data/lib/license_finder/reports/templates/markdown_report.erb +49 -0
  185. data/lib/license_finder/reports/templates/xml_report.erb +19 -0
  186. data/lib/license_finder/reports/text_report.rb +12 -0
  187. data/lib/license_finder/reports/xml_report.rb +23 -0
  188. data/lib/license_finder/scanner.rb +83 -0
  189. data/lib/license_finder/shared_helpers/cmd.rb +13 -0
  190. data/lib/license_finder/shared_helpers/common_path.rb +29 -0
  191. data/lib/license_finder/version.rb +6 -0
  192. data/lib/license_finder.rb +14 -0
  193. data/license_finder.gemspec +79 -0
  194. data/release/instructions.md +8 -0
  195. data/swift-all-keys.asc +240 -0
  196. metadata +604 -0
@@ -0,0 +1,49 @@
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
+ SPECIAL_CHARACTERS = /§/.freeze
20
+ SPECIAL_DASHES = /–/.freeze
21
+
22
+ def self.normalize_punctuation(text)
23
+ text.dup.force_encoding('UTF-8')
24
+ .gsub(SPECIAL_DOUBLE_QUOTES, '"')
25
+ .gsub(SPECIAL_SINGLE_QUOTES, "'")
26
+ .gsub(QUOTE_COMMENT_CHARACTER, '')
27
+ .gsub(SPACES, ' ')
28
+ .gsub(NEWLINE_CHARACTER, ' ')
29
+ .gsub(ESCAPED_QUOTES, '"')
30
+ .gsub(QUOTES, '"')
31
+ .gsub(SPECIAL_CHARACTERS, '?')
32
+ .gsub(SPECIAL_DASHES, '-')
33
+ .strip
34
+ rescue ArgumentError => _e
35
+ text
36
+ end
37
+
38
+ def self.compile_to_regex(text)
39
+ Regexp.new(Regexp.escape(normalize_punctuation(text))
40
+ .gsub(YEAR_PLACEHOLDERS, '(\S*)')
41
+ .gsub(PLACEHOLDERS, '(.*)')
42
+ .gsub(',', '(,)?')
43
+ .gsub('HOLDER', '(HOLDER|OWNER)')
44
+ .gsub(ALPHABET_ORDERED_LIST, ALPHABET_ORDERED_LIST_OPTIONAL)
45
+ .gsub(LIST_BULLETS, LIST_BULLETS_OPTIONAL))
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,123 @@
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
+ @spdx_id = settings.fetch(:spdx_id, '')
44
+ @other_names = settings.fetch(:other_names, [])
45
+ @url = settings.fetch(:url)
46
+ @matcher = settings.fetch(:matcher) { Matcher.from_template(Template.named(short_name)) }
47
+ end
48
+
49
+ attr_reader :url
50
+
51
+ def name
52
+ pretty_name
53
+ end
54
+
55
+ def standard_id
56
+ spdx_id
57
+ end
58
+
59
+ def stripped_name(name)
60
+ name.sub(/^The /i, '')
61
+ end
62
+
63
+ def matches_name?(name)
64
+ names.map(&:downcase).include? name.to_s.downcase
65
+ end
66
+
67
+ def matches_text?(text)
68
+ matcher.matches_text?(text)
69
+ end
70
+
71
+ def eql?(other)
72
+ name == other.name
73
+ end
74
+
75
+ def hash
76
+ name.hash
77
+ end
78
+
79
+ def unrecognized_matcher?
80
+ matcher.is_a?(NoneMatcher)
81
+ end
82
+
83
+ private
84
+
85
+ attr_reader :short_name, :pretty_name, :other_names, :spdx_id, :matcher
86
+
87
+ def names
88
+ ([short_name, pretty_name, spdx_id] + other_names).uniq
89
+ end
90
+ end
91
+
92
+ class AndLicense < License
93
+ def self.operator
94
+ ' AND '
95
+ end
96
+
97
+ def initialize(name, operator = AndLicense.operator)
98
+ @short_name = name
99
+ @pretty_name = name
100
+ @url = nil
101
+ @spdx_id = nil
102
+ @matcher = NoneMatcher.new
103
+ # removes heading and trailing parentesis and splits
104
+ name = name[1..-2] if name.start_with?('(')
105
+ names = name.split(operator)
106
+ @sub_licenses = names.map do |sub_name|
107
+ License.find_by_name(sub_name)
108
+ end
109
+ end
110
+
111
+ attr_reader :sub_licenses
112
+ end
113
+
114
+ class OrLicense < AndLicense
115
+ def self.operator
116
+ ' OR '
117
+ end
118
+
119
+ def initialize(name)
120
+ super(name, OrLicense.operator)
121
+ end
122
+ end
123
+ 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,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LicenseFinder
4
+ class ManualLicenses
5
+ def initialize
6
+ @all_versions = {}
7
+ @specific_versions = {}
8
+ end
9
+
10
+ def licenses_of(name, version = nil)
11
+ return @all_versions[name] if @all_versions[name]
12
+
13
+ if version && @specific_versions[name] && @specific_versions[name][version]
14
+ @specific_versions[name][version]
15
+ else
16
+ Set.new
17
+ end
18
+ end
19
+
20
+ def assign_to_all_versions(name, lic)
21
+ # Ex: licenses add foo_gem MIT => Adds MIT at "all" versions for this gem
22
+
23
+ @all_versions[name] ||= Set.new
24
+ @all_versions[name] << to_license(lic)
25
+
26
+ @specific_versions.delete(name)
27
+ end
28
+
29
+ def assign_to_specific_versions(name, lic, versions)
30
+ # Ex: licenses add foo_gem MIT --version=1.0 => Adds MIT at only 1.0 for this gem
31
+
32
+ @specific_versions[name] ||= {}
33
+ versions.each do |version|
34
+ @specific_versions[name][version] ||= Set.new
35
+ @specific_versions[name][version] << to_license(lic)
36
+ end
37
+
38
+ @all_versions.delete(name)
39
+ end
40
+
41
+ def unassign_from_all_versions(name, lic = nil)
42
+ if lic
43
+ # Ex: licenses remove foo_gem MIT => Removes MIT at all versions for this gem
44
+ @all_versions[name]&.delete(to_license(lic))
45
+
46
+ @specific_versions[name]&.each_value do |licenses|
47
+ licenses.delete(to_license(lic))
48
+ end
49
+ else
50
+ # Ex: licenses remove foo_gem => Removes all licenses for all versions of the gem
51
+ @all_versions.delete(name)
52
+ @specific_versions.delete(name)
53
+ end
54
+ end
55
+
56
+ def unassign_from_specific_versions(name, lic, versions)
57
+ return unless @specific_versions[name]
58
+
59
+ versions.each do |version|
60
+ if @specific_versions[name][version]
61
+ if lic
62
+ # Ex: licenses remove foo_gem MIT --version=1.0 => Removes MIT at only 1.0 for this gem
63
+ @specific_versions[name][version].delete(to_license(lic))
64
+ @specific_versions[name].delete(version) if @specific_versions[name][version].empty?
65
+ else
66
+ # Ex: licenses remove foo_gem --version=1.0 => Removes all licenses at only 1.0 for the gem
67
+ @specific_versions[name].delete(version)
68
+ end
69
+ end
70
+ end
71
+ end
72
+
73
+ private
74
+
75
+ def to_license(lic)
76
+ License.find_by_name(lic)
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,195 @@
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, :name, :version, :authors, :summary, :description, :children, :parents, :groups, :manual_approval, :license_names_from_spec, :install_path
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
+ ## APPROVAL
68
+
69
+ def approved_manually!(approval)
70
+ @manual_approval = approval
71
+ end
72
+
73
+ def approved_manually?
74
+ !@manual_approval.nil?
75
+ end
76
+
77
+ def approved?
78
+ # Question: is `!restricted?` redundant?
79
+ # DecisionApplier does not call `permitted!` or `approved_manually!`
80
+ # if a Package has been restricted.
81
+ (approved_manually? || permitted?) && !restricted?
82
+ end
83
+
84
+ def permitted!
85
+ @permitted = true
86
+ end
87
+
88
+ def permitted?
89
+ @permitted
90
+ end
91
+
92
+ def restricted!
93
+ @restricted = true
94
+ end
95
+
96
+ def restricted?
97
+ @restricted
98
+ end
99
+
100
+ ## EQUALITY
101
+
102
+ def <=>(other)
103
+ eq_name = name <=> other.name
104
+ return eq_name unless eq_name.zero?
105
+
106
+ version <=> other.version
107
+ end
108
+
109
+ def eql?(other)
110
+ name == other.name && version == other.version
111
+ end
112
+
113
+ def hash
114
+ [name, version].hash
115
+ end
116
+
117
+ ## LICENSING # stubbed in tests, otherwise private # checked in tests, otherwise private
118
+
119
+ def licenses
120
+ @licenses ||= activations.map(&:license).sort_by(&:name).to_set
121
+ end
122
+
123
+ def activations
124
+ licensing.activations.tap do |activations|
125
+ activations.each { |activation| log_activation activation }
126
+ end
127
+ end
128
+
129
+ def licensing
130
+ Licensing.new(self, @decided_licenses, licenses_from_spec, license_files)
131
+ end
132
+
133
+ def decide_on_license(license)
134
+ @decided_licenses << license
135
+ end
136
+
137
+ def licenses_from_spec
138
+ license_names_from_spec
139
+ .map { |name| License.find_by_name(name) }
140
+ .to_set
141
+ end
142
+
143
+ def license_files
144
+ LicenseFiles.find(install_path, logger: logger)
145
+ end
146
+
147
+ def notice_files
148
+ NoticeFiles.find(install_path, logger: logger)
149
+ end
150
+
151
+ def package_manager
152
+ 'unknown'
153
+ end
154
+
155
+ def missing?
156
+ @missing
157
+ end
158
+
159
+ def log_activation(activation)
160
+ preamble = format('package %s:', activation.package.name)
161
+ if activation.sources.empty?
162
+ logger.debug activation.package.class, format('%s no licenses found', preamble)
163
+ else
164
+ activation.sources.each do |source|
165
+ logger.debug activation.package.class, format("%s found license '%s' %s", preamble, activation.license.name, source)
166
+ end
167
+ end
168
+ end
169
+ end
170
+ end
171
+
172
+ require 'license_finder/packages/manual_package'
173
+ require 'license_finder/packages/bower_package'
174
+ require 'license_finder/packages/go_package'
175
+ require 'license_finder/packages/bundler_package'
176
+ require 'license_finder/packages/pip_package'
177
+ require 'license_finder/packages/npm_package'
178
+ require 'license_finder/packages/maven_package'
179
+ require 'license_finder/packages/gradle_package'
180
+ require 'license_finder/packages/cocoa_pods_package'
181
+ require 'license_finder/packages/carthage_package'
182
+ require 'license_finder/packages/spm_package'
183
+ require 'license_finder/packages/rebar_package'
184
+ require 'license_finder/packages/erlangmk_package'
185
+ require 'license_finder/packages/mix_package'
186
+ require 'license_finder/packages/merged_package'
187
+ require 'license_finder/packages/nuget_package'
188
+ require 'license_finder/packages/conan_package'
189
+ require 'license_finder/packages/yarn_package'
190
+ require 'license_finder/packages/pnpm_package'
191
+ require 'license_finder/packages/sbt_package'
192
+ require 'license_finder/packages/cargo_package'
193
+ require 'license_finder/packages/composer_package'
194
+ require 'license_finder/packages/conda_package'
195
+ require 'license_finder/packages/pubspec_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.instance_of?(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