license_finder 6.14.2 → 7.0.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 (61) hide show
  1. checksums.yaml +4 -4
  2. data/.github/dependabot.yml +9 -0
  3. data/.rubocop.yml +12 -2
  4. data/CHANGELOG.md +35 -4
  5. data/Dockerfile +26 -5
  6. data/README.md +30 -27
  7. data/Rakefile +2 -2
  8. data/VERSION +1 -1
  9. data/ci/pipelines/release.yml.erb +1 -1
  10. data/ci/scripts/pushscript.sh +2 -3
  11. data/ci/scripts/run-tests.sh +4 -3
  12. data/ci/tasks/rubocop.yml +1 -1
  13. data/dlf +9 -5
  14. data/lib/license_finder/cli/approvals.rb +2 -2
  15. data/lib/license_finder/cli/base.rb +9 -5
  16. data/lib/license_finder/cli/dependencies.rb +4 -4
  17. data/lib/license_finder/cli/ignored_dependencies.rb +3 -3
  18. data/lib/license_finder/cli/ignored_groups.rb +3 -3
  19. data/lib/license_finder/cli/inherited_decisions.rb +5 -5
  20. data/lib/license_finder/cli/licenses.rb +2 -2
  21. data/lib/license_finder/cli/main.rb +17 -11
  22. data/lib/license_finder/cli/permitted_licenses.rb +3 -3
  23. data/lib/license_finder/cli/project_name.rb +4 -4
  24. data/lib/license_finder/cli/restricted_licenses.rb +3 -3
  25. data/lib/license_finder/configuration.rb +6 -3
  26. data/lib/license_finder/core.rb +2 -1
  27. data/lib/license_finder/decisions.rb +9 -5
  28. data/lib/license_finder/license/definitions.rb +22 -0
  29. data/lib/license_finder/license/text.rb +5 -3
  30. data/lib/license_finder/license.rb +8 -2
  31. data/lib/license_finder/logger.rb +1 -1
  32. data/lib/license_finder/package.rb +3 -11
  33. data/lib/license_finder/package_delta.rb +1 -1
  34. data/lib/license_finder/package_manager.rb +1 -0
  35. data/lib/license_finder/package_managers/cocoa_pods.rb +14 -9
  36. data/lib/license_finder/package_managers/conan.rb +2 -2
  37. data/lib/license_finder/package_managers/conda.rb +1 -1
  38. data/lib/license_finder/package_managers/glide.rb +7 -1
  39. data/lib/license_finder/package_managers/go_15vendorexperiment.rb +2 -2
  40. data/lib/license_finder/package_managers/go_dep.rb +1 -1
  41. data/lib/license_finder/package_managers/go_workspace.rb +1 -1
  42. data/lib/license_finder/package_managers/maven.rb +2 -6
  43. data/lib/license_finder/package_managers/nuget.rb +1 -1
  44. data/lib/license_finder/package_managers/pub.rb +86 -0
  45. data/lib/license_finder/package_managers/sbt.rb +1 -5
  46. data/lib/license_finder/package_managers/yarn.rb +48 -9
  47. data/lib/license_finder/package_utils/license_files.rb +2 -2
  48. data/lib/license_finder/packages/bower_package.rb +5 -2
  49. data/lib/license_finder/packages/erlangmk_package.rb +2 -4
  50. data/lib/license_finder/packages/npm_package.rb +1 -0
  51. data/lib/license_finder/packages/pubspec_package.rb +18 -0
  52. data/lib/license_finder/printer.rb +39 -0
  53. data/lib/license_finder/report.rb +2 -1
  54. data/lib/license_finder/reports/csv_report.rb +1 -1
  55. data/lib/license_finder/reports/erb_report.rb +7 -3
  56. data/lib/license_finder/reports/json_report.rb +2 -1
  57. data/lib/license_finder/reports/junit_report.rb +5 -1
  58. data/lib/license_finder/reports/xml_report.rb +5 -1
  59. data/lib/license_finder/scanner.rb +1 -1
  60. data/license_finder.gemspec +15 -13
  61. metadata +58 -26
@@ -7,6 +7,7 @@ require 'license_finder/package_delta'
7
7
  require 'license_finder/license_aggregator'
8
8
  require 'license_finder/project_finder'
9
9
  require 'license_finder/logger'
10
+ require 'license_finder/printer'
10
11
 
11
12
  module LicenseFinder
12
13
  module CLI
@@ -90,6 +91,11 @@ module LicenseFinder
90
91
  method_option :columns,
91
92
  desc: "For text or CSV reports, which columns to print. Pick from: #{CsvReport::AVAILABLE_COLUMNS}",
92
93
  type: :array
94
+
95
+ method_option :use_spdx_id,
96
+ type: :boolean,
97
+ desc: 'For reports, use the SPDX identifier instead of license name (useful to match license with other standard tools)',
98
+ default: false
93
99
  end
94
100
 
95
101
  desc 'project_roots', 'List project directories to be scanned'
@@ -102,7 +108,7 @@ module LicenseFinder
102
108
 
103
109
  filtered_project_roots << project_path if aggregate_paths.include?(project_path) && !filtered_project_roots.include?(project_path)
104
110
 
105
- say(filtered_project_roots)
111
+ printer.say(filtered_project_roots)
106
112
  end
107
113
 
108
114
  desc 'action_items', 'List unapproved dependencies (the default action for `license_finder`)'
@@ -115,25 +121,25 @@ module LicenseFinder
115
121
  restricted = finder.restricted
116
122
 
117
123
  # Ensure to start output on a new line even with dot progress indicators.
118
- say "\n"
124
+ printer.say "\n"
119
125
 
120
126
  unless any_packages
121
- say 'No dependencies recognized!', :red
127
+ printer.say 'No dependencies recognized!', :red
122
128
  exit 0
123
129
  end
124
130
 
125
131
  if unapproved.empty?
126
- say 'All dependencies are approved for use', :green
132
+ printer.say 'All dependencies are approved for use', :green
127
133
  else
128
134
  unless restricted.empty?
129
- say 'Restricted dependencies:', :red
130
- say report_of(restricted)
135
+ printer.say 'Restricted dependencies:', :red
136
+ printer.say report_of(restricted)
131
137
  end
132
138
 
133
139
  other_unapproved = unapproved - restricted
134
140
  unless other_unapproved.empty?
135
- say 'Dependencies that need approval:', :yellow
136
- say report_of(other_unapproved)
141
+ printer.say 'Dependencies that need approval:', :yellow
142
+ printer.say report_of(other_unapproved)
137
143
  end
138
144
 
139
145
  exit 1
@@ -151,7 +157,7 @@ module LicenseFinder
151
157
  def report
152
158
  finder = LicenseAggregator.new(config, aggregate_paths)
153
159
  report = report_of(finder.dependencies)
154
- save? ? save_report(report, config.save_file) : say(report)
160
+ save? ? save_report(report, config.save_file) : printer.say(report)
155
161
  end
156
162
 
157
163
  desc 'version', 'Print the version of LicenseFinder'
@@ -166,7 +172,7 @@ module LicenseFinder
166
172
  f1 = IO.read(file1)
167
173
  f2 = IO.read(file2)
168
174
  report = DiffReport.new(Diff.compare(f1, f2))
169
- save? ? save_report(report, config.save_file) : say(report)
175
+ save? ? save_report(report, config.save_file) : printer.say(report)
170
176
  end
171
177
 
172
178
  subcommand 'dependencies', Dependencies, 'Add or remove dependencies that your package managers are not aware of'
@@ -210,7 +216,7 @@ module LicenseFinder
210
216
  def report_of(content)
211
217
  report = FORMATS[config.format] || FORMATS['text']
212
218
  report = MergedReport if report == CsvReport && config.aggregate_paths
213
- report.of(content, columns: config.columns, project_name: decisions.project_name || config.project_path.basename.to_s, write_headers: config.write_headers)
219
+ report.of(content, columns: config.columns, project_name: decisions.project_name || config.project_path.basename.to_s, write_headers: config.write_headers, use_spdx_id: config.use_spdx_id)
214
220
  end
215
221
 
216
222
  def save?
@@ -8,7 +8,7 @@ module LicenseFinder
8
8
 
9
9
  desc 'list', 'List all the permitted licenses'
10
10
  def list
11
- say 'Permitted Licenses:', :blue
11
+ printer.say 'Permitted Licenses:', :blue
12
12
  say_each(decisions.permitted, &:name)
13
13
  end
14
14
 
@@ -17,7 +17,7 @@ module LicenseFinder
17
17
  def add(*licenses)
18
18
  assert_some licenses
19
19
  modifying { licenses.each { |l| decisions.permit(l, txn) } }
20
- say "Added #{licenses.join(', ')} to the permitted licenses"
20
+ printer.say "Added #{licenses.join(', ')} to the permitted licenses"
21
21
  end
22
22
 
23
23
  auditable
@@ -25,7 +25,7 @@ module LicenseFinder
25
25
  def remove(*licenses)
26
26
  assert_some licenses
27
27
  modifying { licenses.each { |l| decisions.unpermit(l, txn) } }
28
- say "Removed #{licenses.join(', ')} from the license permitted licenses"
28
+ printer.say "Removed #{licenses.join(', ')} from the license permitted licenses"
29
29
  end
30
30
  end
31
31
  end
@@ -8,8 +8,8 @@ module LicenseFinder
8
8
 
9
9
  desc 'show', 'Show the project name'
10
10
  def show
11
- say 'Project Name:', :blue
12
- say decisions.project_name
11
+ printer.say 'Project Name:', :blue
12
+ printer.say decisions.project_name
13
13
  end
14
14
 
15
15
  auditable
@@ -17,7 +17,7 @@ module LicenseFinder
17
17
  def add(name)
18
18
  modifying { decisions.name_project(name, txn) }
19
19
 
20
- say "Set the project name to #{name}", :green
20
+ printer.say "Set the project name to #{name}", :green
21
21
  end
22
22
 
23
23
  auditable
@@ -25,7 +25,7 @@ module LicenseFinder
25
25
  def remove
26
26
  modifying { decisions.unname_project(txn) }
27
27
 
28
- say 'Removed the project name'
28
+ printer.say 'Removed the project name'
29
29
  end
30
30
  end
31
31
  end
@@ -8,7 +8,7 @@ module LicenseFinder
8
8
 
9
9
  desc 'list', 'List all the restricted licenses'
10
10
  def list
11
- say 'Restricted Licenses:', :blue
11
+ printer.say 'Restricted Licenses:', :blue
12
12
  say_each(decisions.restricted, &:name)
13
13
  end
14
14
 
@@ -17,7 +17,7 @@ module LicenseFinder
17
17
  def add(*licenses)
18
18
  assert_some licenses
19
19
  modifying { licenses.each { |l| decisions.restrict(l, txn) } }
20
- say "Added #{licenses.join(', ')} to the restricted licenses"
20
+ printer.say "Added #{licenses.join(', ')} to the restricted licenses"
21
21
  end
22
22
 
23
23
  auditable
@@ -25,7 +25,7 @@ module LicenseFinder
25
25
  def remove(*licenses)
26
26
  assert_some licenses
27
27
  modifying { licenses.each { |l| decisions.unrestrict(l, txn) } }
28
- say "Removed #{licenses.join(', ')} from the restricted licenses"
28
+ printer.say "Removed #{licenses.join(', ')} from the restricted licenses"
29
29
  end
30
30
  end
31
31
  end
@@ -145,6 +145,10 @@ module LicenseFinder
145
145
  get(:columns)
146
146
  end
147
147
 
148
+ def use_spdx_id
149
+ get(:use_spdx_id)
150
+ end
151
+
148
152
  def sbt_include_groups
149
153
  get(:sbt_include_groups)
150
154
  end
@@ -153,13 +157,12 @@ module LicenseFinder
153
157
  get(:composer_check_require_only)
154
158
  end
155
159
 
156
- attr_writer :strict_matching
157
-
158
- attr_reader :strict_matching
160
+ attr_accessor :strict_matching
159
161
 
160
162
  protected
161
163
 
162
164
  attr_accessor :primary_config
165
+
163
166
  def dup_with(other_hash)
164
167
  dup.tap do |dup|
165
168
  dup.primary_config.merge!(other_hash)
@@ -31,6 +31,7 @@ module LicenseFinder
31
31
  # rebar_deps_dir: "deps",
32
32
  # }
33
33
  def initialize(configuration)
34
+ @printer = Printer.new
34
35
  @logger = Logger.new(configuration.logger_mode)
35
36
  @config = configuration
36
37
  @scanner = Scanner.new(options)
@@ -68,7 +69,7 @@ module LicenseFinder
68
69
 
69
70
  private
70
71
 
71
- attr_reader :logger
72
+ attr_reader :logger, :printer
72
73
 
73
74
  # The core of the system. The saved decisions are applied to the current
74
75
  # packages.
@@ -194,9 +194,10 @@ module LicenseFinder
194
194
 
195
195
  def inherit_from(filepath_info)
196
196
  decisions =
197
- if filepath_info.is_a?(Hash)
197
+ case filepath_info
198
+ when Hash
198
199
  resolve_inheritance(filepath_info)
199
- elsif filepath_info =~ %r{^https?://}
200
+ when %r{^https?://}
200
201
  open_uri(filepath_info).read
201
202
  else
202
203
  Pathname(filepath_info).read
@@ -247,9 +248,7 @@ module LicenseFinder
247
248
 
248
249
  # ruby < 2.5.0 URI.open is private
249
250
  if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.5.0')
250
- # rubocop:disable Security/Open
251
251
  open(uri, header)
252
- # rubocop:enable Security/Open
253
252
  else
254
253
  URI.open(uri, header)
255
254
  end
@@ -280,7 +279,12 @@ module LicenseFinder
280
279
  def self.restore(persisted, result = new)
281
280
  return result unless persisted
282
281
 
283
- actions = YAML.load(persisted)
282
+ # From https://makandracards.com/makandra/465149-ruby-the-yaml-safe_load-method-hides-some-pitfalls
283
+ actions = if Gem::Version.new(Psych::VERSION) >= Gem::Version.new('3.1.0.pre1')
284
+ YAML.safe_load(persisted, permitted_classes: [Symbol, Time], aliases: true)
285
+ else
286
+ YAML.safe_load(persisted, [Symbol, Time], [], true)
287
+ end
284
288
 
285
289
  list_of_actions = (actions || []).map(&:first)
286
290
 
@@ -46,6 +46,7 @@ module LicenseFinder
46
46
  License.new(
47
47
  short_name: 'Apache1_1',
48
48
  pretty_name: 'Apache 1.1',
49
+ spdx_id: 'Apache-1.1',
49
50
  other_names: [
50
51
  'Apache-1.1',
51
52
  'The Apache Software License, Version 1.1'
@@ -58,6 +59,7 @@ module LicenseFinder
58
59
  License.new(
59
60
  short_name: 'Apache2',
60
61
  pretty_name: 'Apache 2.0',
62
+ spdx_id: 'Apache-2.0',
61
63
  other_names: [
62
64
  'Apache-2.0',
63
65
  'Apache Software License',
@@ -79,6 +81,7 @@ module LicenseFinder
79
81
  def bsd
80
82
  License.new(
81
83
  short_name: 'BSD',
84
+ spdx_id: 'BSD-4-Clause',
82
85
  other_names: ['BSD4', 'bsd-old', '4-clause BSD', 'BSD-4-Clause', 'BSD 4-Clause', 'BSD License'],
83
86
  url: 'http://en.wikipedia.org/wiki/BSD_licenses#4-clause_license_.28original_.22BSD_License.22.29'
84
87
  )
@@ -87,6 +90,7 @@ module LicenseFinder
87
90
  def cc01
88
91
  License.new(
89
92
  short_name: 'CC01',
93
+ spdx_id: 'CC0-1.0',
90
94
  pretty_name: 'CC0 1.0 Universal',
91
95
  other_names: ['CC0 1.0'],
92
96
  url: 'http://creativecommons.org/publicdomain/zero/1.0'
@@ -96,6 +100,7 @@ module LicenseFinder
96
100
  def cddl1
97
101
  License.new(
98
102
  short_name: 'CDDL1',
103
+ spdx_id: 'CDDL-1.0',
99
104
  pretty_name: 'Common Development and Distribution License 1.0',
100
105
  other_names: [
101
106
  'CDDL-1.0',
@@ -109,6 +114,7 @@ module LicenseFinder
109
114
  def eclipse1
110
115
  License.new(
111
116
  short_name: 'EPL1',
117
+ spdx_id: 'EPL-1.0',
112
118
  pretty_name: 'Eclipse Public License 1.0',
113
119
  other_names: [
114
120
  'EPL-1.0',
@@ -122,6 +128,7 @@ module LicenseFinder
122
128
  def gplv2
123
129
  License.new(
124
130
  short_name: 'GPLv2',
131
+ spdx_id: 'GPL-2.0-only',
125
132
  other_names: ['GPL V2', 'gpl-v2', 'GNU GENERAL PUBLIC LICENSE Version 2'],
126
133
  url: 'http://www.gnu.org/licenses/gpl-2.0.txt'
127
134
  )
@@ -130,6 +137,7 @@ module LicenseFinder
130
137
  def gplv3
131
138
  License.new(
132
139
  short_name: 'GPLv3',
140
+ spdx_id: 'GPL-3.0-only',
133
141
  other_names: ['GPL V3', 'gpl-v3', 'GNU GENERAL PUBLIC LICENSE Version 3'],
134
142
  url: 'http://www.gnu.org/licenses/gpl-3.0.txt'
135
143
  )
@@ -138,6 +146,7 @@ module LicenseFinder
138
146
  def isc
139
147
  License.new(
140
148
  short_name: 'ISC',
149
+ spdx_id: 'ISC',
141
150
  url: 'http://en.wikipedia.org/wiki/ISC_license'
142
151
  )
143
152
  end
@@ -145,6 +154,7 @@ module LicenseFinder
145
154
  def lgpl
146
155
  License.new(
147
156
  short_name: 'LGPL',
157
+ spdx_id: 'LGPL-3.0-only',
148
158
  other_names: ['LGPL-3', 'LGPLv3', 'LGPL-3.0'],
149
159
  url: 'http://www.gnu.org/licenses/lgpl.txt'
150
160
  )
@@ -153,6 +163,7 @@ module LicenseFinder
153
163
  def lgpl2_1
154
164
  License.new(
155
165
  short_name: 'LGPL2_1',
166
+ spdx_id: 'LGPL-2.1-only',
156
167
  pretty_name: 'GNU Lesser General Public License version 2.1',
157
168
  other_names: [
158
169
  'LGPL-2.1-only',
@@ -178,6 +189,7 @@ module LicenseFinder
178
189
 
179
190
  License.new(
180
191
  short_name: 'MIT',
192
+ spdx_id: 'MIT',
181
193
  other_names: ['Expat', 'MIT license', 'MIT License', 'The MIT License (MIT)'],
182
194
  url: 'http://opensource.org/licenses/mit-license',
183
195
  matcher: matcher
@@ -197,6 +209,7 @@ module LicenseFinder
197
209
 
198
210
  License.new(
199
211
  short_name: 'MPL1_1',
212
+ spdx_id: 'MPL-1.1',
200
213
  pretty_name: 'Mozilla Public License 1.1',
201
214
  other_names: [
202
215
  'MPL-1.1',
@@ -218,6 +231,7 @@ module LicenseFinder
218
231
 
219
232
  License.new(
220
233
  short_name: 'MPL2',
234
+ spdx_id: 'MPL-2.0',
221
235
  pretty_name: 'Mozilla Public License 2.0',
222
236
  other_names: [
223
237
  'MPL-2.0',
@@ -243,6 +257,7 @@ module LicenseFinder
243
257
 
244
258
  License.new(
245
259
  short_name: 'NewBSD',
260
+ spdx_id: 'BSD-3-Clause',
246
261
  pretty_name: 'New BSD',
247
262
  other_names: [
248
263
  'Modified BSD',
@@ -266,6 +281,7 @@ module LicenseFinder
266
281
  def ofl
267
282
  License.new(
268
283
  short_name: 'OFL',
284
+ spdx_id: 'OFL-1.1',
269
285
  pretty_name: 'SIL OPEN FONT LICENSE Version 1.1',
270
286
  other_names: [
271
287
  'OPEN FONT LICENSE Version 1.1'
@@ -277,6 +293,7 @@ module LicenseFinder
277
293
  def python
278
294
  License.new(
279
295
  short_name: 'Python',
296
+ spdx_id: 'PSF-2.0',
280
297
  pretty_name: 'Python Software Foundation License',
281
298
  other_names: [
282
299
  'PSF',
@@ -297,6 +314,7 @@ module LicenseFinder
297
314
 
298
315
  License.new(
299
316
  short_name: 'Ruby',
317
+ spdx_id: 'Ruby',
300
318
  pretty_name: 'ruby',
301
319
  url: url,
302
320
  matcher: matcher
@@ -306,6 +324,7 @@ module LicenseFinder
306
324
  def simplifiedbsd
307
325
  License.new(
308
326
  short_name: 'SimplifiedBSD',
327
+ spdx_id: 'BSD-2-Clause',
309
328
  pretty_name: 'Simplified BSD',
310
329
  other_names: [
311
330
  'FreeBSD',
@@ -321,6 +340,7 @@ module LicenseFinder
321
340
  def wtfpl
322
341
  License.new(
323
342
  short_name: 'WTFPL',
343
+ spdx_id: 'WTFPL',
324
344
  pretty_name: 'WTFPL',
325
345
  other_names: [
326
346
  'WTFPL V2',
@@ -337,6 +357,7 @@ module LicenseFinder
337
357
 
338
358
  License.new(
339
359
  short_name: '0BSD',
360
+ spdx_id: '0BSD',
340
361
  pretty_name: 'BSD Zero Clause License',
341
362
  other_names: [
342
363
  '0-Clause BSD',
@@ -354,6 +375,7 @@ module LicenseFinder
354
375
  def zlib
355
376
  License.new(
356
377
  short_name: 'Zlib',
378
+ spdx_id: 'Zlib',
357
379
  pretty_name: 'zlib/libpng license',
358
380
  other_names: [
359
381
  'zlib License'
@@ -5,16 +5,17 @@ module LicenseFinder
5
5
  module Text
6
6
  SPACES = /\s+/.freeze
7
7
  QUOTES = /['`"]{1,2}/.freeze
8
+ YEAR_PLACEHOLDERS = /<year>/.freeze
8
9
  PLACEHOLDERS = /<[^<>]+>/.freeze
9
10
  SPECIAL_SINGLE_QUOTES = /[‘’]/.freeze
10
11
  SPECIAL_DOUBLE_QUOTES = /[“”„«»]/.freeze
11
12
  ALPHABET_ORDERED_LIST = /\\\([a-z]\\\)\\\s/.freeze
12
13
  ALPHABET_ORDERED_LIST_OPTIONAL = '(\([a-z]\)\s)?'
13
- LIST_BULLETS = /(\d{1,2}\\\.|\\\*|\\\-)\\\s/.freeze
14
+ LIST_BULLETS = /(\d{1,2}\\\.|\\\*|\\-)\\\s/.freeze
14
15
  LIST_BULLETS_OPTIONAL = '(\d{1,2}.|\*|\-)?\s*'
15
16
  NEWLINE_CHARACTER = /\n+/.freeze
16
- QUOTE_COMMENT_CHARACTER = /^\s*\>+/.freeze
17
- ESCAPED_QUOTES = /\\\"/.freeze
17
+ QUOTE_COMMENT_CHARACTER = /^\s*>+/.freeze
18
+ ESCAPED_QUOTES = /\\"/.freeze
18
19
 
19
20
  def self.normalize_punctuation(text)
20
21
  text.dup.force_encoding('UTF-8')
@@ -32,6 +33,7 @@ module LicenseFinder
32
33
 
33
34
  def self.compile_to_regex(text)
34
35
  Regexp.new(Regexp.escape(normalize_punctuation(text))
36
+ .gsub(YEAR_PLACEHOLDERS, '(\S*)')
35
37
  .gsub(PLACEHOLDERS, '(.*)')
36
38
  .gsub(',', '(,)?')
37
39
  .gsub('HOLDER', '(HOLDER|OWNER)')
@@ -40,6 +40,7 @@ module LicenseFinder
40
40
  def initialize(settings)
41
41
  @short_name = settings.fetch(:short_name)
42
42
  @pretty_name = settings.fetch(:pretty_name, short_name)
43
+ @spdx_id = settings.fetch(:spdx_id, '')
43
44
  @other_names = settings.fetch(:other_names, [])
44
45
  @url = settings.fetch(:url)
45
46
  @matcher = settings.fetch(:matcher) { Matcher.from_template(Template.named(short_name)) }
@@ -51,6 +52,10 @@ module LicenseFinder
51
52
  pretty_name
52
53
  end
53
54
 
55
+ def standard_id
56
+ spdx_id
57
+ end
58
+
54
59
  def stripped_name(name)
55
60
  name.sub(/^The /i, '')
56
61
  end
@@ -77,13 +82,13 @@ module LicenseFinder
77
82
 
78
83
  private
79
84
 
80
- attr_reader :short_name, :pretty_name, :other_names
81
- attr_reader :matcher
85
+ attr_reader :short_name, :pretty_name, :other_names, :spdx_id, :matcher
82
86
 
83
87
  def names
84
88
  ([short_name, pretty_name] + other_names).uniq
85
89
  end
86
90
  end
91
+
87
92
  class AndLicense < License
88
93
  def self.operator
89
94
  ' AND '
@@ -93,6 +98,7 @@ module LicenseFinder
93
98
  @short_name = name
94
99
  @pretty_name = name
95
100
  @url = nil
101
+ @spdx_id = nil
96
102
  @matcher = NoneMatcher.new
97
103
  # removes heading and trailing parentesis and splits
98
104
  name = name[1..-2] if name.start_with?('(')
@@ -11,7 +11,7 @@ module LicenseFinder
11
11
  attr_reader :mode
12
12
 
13
13
  def initialize(mode = nil)
14
- @system_logger = ::Logger.new(STDOUT)
14
+ @system_logger = ::Logger.new($stdout)
15
15
  @system_logger.formatter = proc do |_, _, _, msg|
16
16
  "#{msg}\n"
17
17
  end
@@ -18,7 +18,7 @@ module LicenseFinder
18
18
  # the constructor options
19
19
  # - otherwise, override #licenses_from_spec or #license_files
20
20
  class Package
21
- attr_reader :logger
21
+ attr_reader :logger, :name, :version, :authors, :summary, :description, :children, :parents, :groups, :manual_approval, :license_names_from_spec, :install_path
22
22
 
23
23
  def self.license_names_from_standard_spec(spec)
24
24
  licenses = spec['licenses'] || [spec['license']].compact
@@ -64,10 +64,6 @@ module LicenseFinder
64
64
 
65
65
  attr_accessor :homepage, :package_url
66
66
 
67
- attr_reader :name, :version, :authors,
68
- :summary, :description,
69
- :children, :parents, :groups
70
-
71
67
  ## APPROVAL
72
68
 
73
69
  def approved_manually!(approval)
@@ -101,8 +97,6 @@ module LicenseFinder
101
97
  @restricted
102
98
  end
103
99
 
104
- attr_reader :manual_approval
105
-
106
100
  ## EQUALITY
107
101
 
108
102
  def <=>(other)
@@ -120,10 +114,7 @@ module LicenseFinder
120
114
  [name, version].hash
121
115
  end
122
116
 
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
117
+ ## LICENSING # stubbed in tests, otherwise private # checked in tests, otherwise private
127
118
 
128
119
  def licenses
129
120
  @licenses ||= activations.map(&:license).sort_by(&:name).to_set
@@ -200,3 +191,4 @@ require 'license_finder/packages/sbt_package'
200
191
  require 'license_finder/packages/cargo_package'
201
192
  require 'license_finder/packages/composer_package'
202
193
  require 'license_finder/packages/conda_package'
194
+ require 'license_finder/packages/pubspec_package'
@@ -29,7 +29,7 @@ module LicenseFinder
29
29
  end
30
30
 
31
31
  def merged_package?
32
- pick_package.class == MergedPackage
32
+ pick_package.instance_of?(MergedPackage)
33
33
  end
34
34
 
35
35
  def method_missing(_method_name)
@@ -177,5 +177,6 @@ require 'license_finder/package_managers/sbt'
177
177
  require 'license_finder/package_managers/cargo'
178
178
  require 'license_finder/package_managers/composer'
179
179
  require 'license_finder/package_managers/conda'
180
+ require 'license_finder/package_managers/pub'
180
181
 
181
182
  require 'license_finder/package'
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'json'
4
+ require 'open3'
4
5
 
5
6
  module LicenseFinder
6
7
  class CocoaPods < PackageManager
@@ -42,20 +43,24 @@ module LicenseFinder
42
43
  end
43
44
 
44
45
  def acknowledgements_path
45
- search_paths = ['Pods/Pods-acknowledgements.plist',
46
- 'Pods/Target Support Files/Pods/Pods-acknowledgements.plist',
47
- 'Pods/Target Support Files/Pods-*/Pods-*-acknowledgements.plist']
48
-
49
- result = Dir[*search_paths.map { |path| File.join(project_path, path) }].first
50
- raise "Found a Podfile but no Pods directory in #{project_path}. Try running pod install before running license_finder." if result.nil?
46
+ if !ENV['ACKNOWLEDGEMENTS_PATH'].nil?
47
+ result = Dir[*ENV['ACKNOWLEDGEMENTS_PATH']].first
48
+ else
49
+ search_paths = ['Pods/Pods-acknowledgements.plist',
50
+ 'Pods/Target Support Files/Pods/Pods-acknowledgements.plist',
51
+ 'Pods/Target Support Files/Pods-*/Pods-*-acknowledgements.plist']
51
52
 
53
+ result = Dir[*search_paths.map { |path| File.join(project_path, path) }].first
54
+ raise "Found a Podfile but no Pods directory in #{project_path}. Try running pod install before running license_finder." if result.nil?
55
+ end
52
56
  result
53
57
  end
54
58
 
55
59
  def read_plist(pathname)
56
- transformed_pathname = pathname.gsub!(%r{[^0-9A-Za-z. \-'/]}, '')
57
- transformed_pathname = pathname if transformed_pathname.nil?
58
- JSON.parse(`plutil -convert json -o - '#{transformed_pathname}'`)
60
+ out, err, status = Open3.capture3('plutil', '-convert', 'json', '-o', '-', pathname)
61
+ raise "#{out}\n\n#{err}" unless status.success?
62
+
63
+ JSON.parse(out)
59
64
  end
60
65
  end
61
66
  end
@@ -18,10 +18,10 @@ module LicenseFinder
18
18
 
19
19
  deps = info_parser.parse(info_output)
20
20
  deps.map do |dep|
21
- name, version = dep['name'].split('@').first.split('/')
21
+ name, version = dep['name'].split('/')
22
22
  url = dep['URL']
23
23
  license_file_path = Dir.glob("#{project_path}/licenses/#{name}/**/LICENSE*").first
24
- ConanPackage.new(name, version, File.open(license_file_path).read, url) unless name == 'PROJECT'
24
+ ConanPackage.new(name, version, File.open(license_file_path).read, url) unless name == 'conanfile.txt'
25
25
  end.compact
26
26
  end
27
27
  end
@@ -90,7 +90,7 @@ module LicenseFinder
90
90
  if status.success?
91
91
  conda_list = []
92
92
  stdout.each_line do |line|
93
- next if line =~ /^\s*#/
93
+ next if /^\s*#/.match?(line)
94
94
 
95
95
  name, version, build, channel = line.split
96
96
  conda_list << {
@@ -9,7 +9,13 @@ module LicenseFinder
9
9
  def current_packages
10
10
  detected_path = detected_package_path
11
11
 
12
- YAML.load_file(detected_path).fetch('imports').map do |package_hash|
12
+ imports = if Gem::Version.new(Psych::VERSION) >= Gem::Version.new('3.1.0.pre1')
13
+ YAML.safe_load(File.read(detected_path), permitted_classes: [Symbol, Time], aliases: true).fetch('imports')
14
+ else
15
+ YAML.safe_load(File.read(detected_path), [Symbol, Time], [], true).fetch('imports')
16
+ end
17
+
18
+ imports.map do |package_hash|
13
19
  import_path = package_hash.fetch('name')
14
20
  license_path = project_path.join('vendor', import_path)
15
21
 
@@ -37,7 +37,7 @@ module LicenseFinder
37
37
  GoPackage.from_dependency({
38
38
  'ImportPath' => dep,
39
39
  'InstallPath' => detected_package_path.join(dep),
40
- 'Rev' => 'vendored-' + project_sha(detected_package_path.join(dep)),
40
+ 'Rev' => "vendored-#{project_sha(detected_package_path.join(dep))}",
41
41
  'Homepage' => repo_name(dep)
42
42
  }, nil, true)
43
43
  end
@@ -70,7 +70,7 @@ module LicenseFinder
70
70
  deps = val.split("\n")
71
71
  Cmd.run('go list std').first.split("\n").each do |std|
72
72
  deps.delete_if do |dep|
73
- dep =~ %r{(\/|^)#{std}(\/|$)}
73
+ dep =~ %r{(/|^)#{std}(/|$)}
74
74
  end
75
75
  end
76
76
  deps.map do |d|