license_finder 6.14.2 → 7.0.1

Sign up to get free protection for your applications and to get access to all the features.
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|