license_finder 6.2.0 → 6.6.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +6 -0
  3. data/CHANGELOG.md +61 -0
  4. data/Dockerfile +23 -15
  5. data/README.md +24 -2
  6. data/Rakefile +1 -1
  7. data/VERSION +1 -1
  8. data/ci/pipelines/release.yml.erb +15 -5
  9. data/ci/tasks/rubocop.yml +1 -1
  10. data/lib/license_finder/cli.rb +1 -0
  11. data/lib/license_finder/cli/base.rb +1 -0
  12. data/lib/license_finder/cli/inherited_decisions.rb +50 -0
  13. data/lib/license_finder/cli/main.rb +3 -1
  14. data/lib/license_finder/configuration.rb +4 -0
  15. data/lib/license_finder/decision_applier.rb +8 -4
  16. data/lib/license_finder/decisions.rb +83 -20
  17. data/lib/license_finder/license.rb +36 -0
  18. data/lib/license_finder/license/definitions.rb +48 -1
  19. data/lib/license_finder/license/templates/0BSD.txt +10 -0
  20. data/lib/license_finder/license/templates/OFL.txt +91 -0
  21. data/lib/license_finder/license/templates/SimplifiedBSD.txt +0 -4
  22. data/lib/license_finder/license/templates/WTFPL.txt +14 -0
  23. data/lib/license_finder/license/text.rb +24 -2
  24. data/lib/license_finder/logger.rb +2 -0
  25. data/lib/license_finder/package.rb +2 -1
  26. data/lib/license_finder/package_manager.rb +6 -2
  27. data/lib/license_finder/package_managers/bundler.rb +1 -3
  28. data/lib/license_finder/package_managers/cargo.rb +2 -1
  29. data/lib/license_finder/package_managers/composer.rb +5 -1
  30. data/lib/license_finder/package_managers/dotnet.rb +2 -1
  31. data/lib/license_finder/package_managers/go_15vendorexperiment.rb +1 -1
  32. data/lib/license_finder/package_managers/go_modules.rb +11 -4
  33. data/lib/license_finder/package_managers/nuget.rb +51 -4
  34. data/lib/license_finder/package_managers/pipenv.rb +1 -1
  35. data/lib/license_finder/package_managers/sbt.rb +3 -1
  36. data/lib/license_finder/package_managers/yarn.rb +16 -2
  37. data/lib/license_finder/package_utils/license_files.rb +2 -2
  38. data/lib/license_finder/packages/bower_package.rb +7 -0
  39. data/lib/license_finder/packages/bundler_package.rb +4 -0
  40. data/lib/license_finder/packages/cargo_package.rb +4 -0
  41. data/lib/license_finder/packages/cocoa_pods_package.rb +4 -0
  42. data/lib/license_finder/packages/composer_package.rb +4 -0
  43. data/lib/license_finder/packages/conan_package.rb +4 -0
  44. data/lib/license_finder/packages/go_package.rb +5 -1
  45. data/lib/license_finder/packages/gradle_package.rb +4 -0
  46. data/lib/license_finder/packages/maven_package.rb +6 -1
  47. data/lib/license_finder/packages/merged_package.rb +1 -1
  48. data/lib/license_finder/packages/mix_package.rb +4 -0
  49. data/lib/license_finder/packages/npm_package.rb +4 -0
  50. data/lib/license_finder/packages/nuget_package.rb +4 -0
  51. data/lib/license_finder/packages/pip_package.rb +13 -2
  52. data/lib/license_finder/packages/rebar_package.rb +4 -0
  53. data/lib/license_finder/packages/yarn_package.rb +4 -0
  54. data/lib/license_finder/reports/csv_report.rb +7 -3
  55. data/lib/license_finder/reports/json_report.rb +2 -0
  56. metadata +7 -3
@@ -1,12 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'open-uri'
4
+ require 'license_finder/license'
5
+
3
6
  module LicenseFinder
4
7
  class Decisions
5
8
  ######
6
9
  # READ
7
10
  ######
8
11
 
9
- attr_reader :packages, :permitted, :restricted, :ignored, :ignored_groups, :project_name
12
+ attr_reader :packages, :permitted, :restricted, :ignored, :ignored_groups, :project_name, :inherited_decisions
10
13
 
11
14
  def licenses_of(name)
12
15
  @licenses[name]
@@ -37,6 +40,9 @@ module LicenseFinder
37
40
  end
38
41
 
39
42
  def permitted?(lic)
43
+ return lic.sub_licenses.any? { |sub_lic| @permitted.include?(sub_lic) } if lic.is_a?(OrLicense)
44
+ return lic.sub_licenses.all? { |sub_lic| @permitted.include?(sub_lic) } if lic.is_a?(AndLicense)
45
+
40
46
  @permitted.include?(lic)
41
47
  end
42
48
 
@@ -72,40 +78,41 @@ module LicenseFinder
72
78
  @restricted = Set.new
73
79
  @ignored = Set.new
74
80
  @ignored_groups = Set.new
81
+ @inherited_decisions = Set.new
75
82
  end
76
83
 
77
84
  def add_package(name, version, txn = {})
78
- @decisions << [:add_package, name, version, txn]
85
+ add_decision [:add_package, name, version, txn]
79
86
  @packages << ManualPackage.new(name, version)
80
87
  self
81
88
  end
82
89
 
83
90
  def remove_package(name, txn = {})
84
- @decisions << [:remove_package, name, txn]
91
+ add_decision [:remove_package, name, txn]
85
92
  @packages.delete(ManualPackage.new(name))
86
93
  self
87
94
  end
88
95
 
89
96
  def license(name, lic, txn = {})
90
- @decisions << [:license, name, lic, txn]
97
+ add_decision [:license, name, lic, txn]
91
98
  @licenses[name] << License.find_by_name(lic)
92
99
  self
93
100
  end
94
101
 
95
102
  def unlicense(name, lic, txn = {})
96
- @decisions << [:unlicense, name, lic, txn]
103
+ add_decision [:unlicense, name, lic, txn]
97
104
  @licenses[name].delete(License.find_by_name(lic))
98
105
  self
99
106
  end
100
107
 
101
108
  def homepage(name, homepage, txn = {})
102
- @decisions << [:homepage, name, homepage, txn]
109
+ add_decision [:homepage, name, homepage, txn]
103
110
  @homepages[name] = homepage
104
111
  self
105
112
  end
106
113
 
107
114
  def approve(name, txn = {})
108
- @decisions << [:approve, name, txn]
115
+ add_decision [:approve, name, txn]
109
116
 
110
117
  versions = []
111
118
  versions = @approvals[name][:safe_versions] if @approvals.key?(name)
@@ -115,71 +122,128 @@ module LicenseFinder
115
122
  end
116
123
 
117
124
  def unapprove(name, txn = {})
118
- @decisions << [:unapprove, name, txn]
125
+ add_decision [:unapprove, name, txn]
119
126
  @approvals.delete(name)
120
127
  self
121
128
  end
122
129
 
123
130
  def permit(lic, txn = {})
124
- @decisions << [:permit, lic, txn]
131
+ add_decision [:permit, lic, txn]
125
132
  @permitted << License.find_by_name(lic)
126
133
  self
127
134
  end
128
135
 
129
136
  def unpermit(lic, txn = {})
130
- @decisions << [:unpermit, lic, txn]
137
+ add_decision [:unpermit, lic, txn]
131
138
  @permitted.delete(License.find_by_name(lic))
132
139
  self
133
140
  end
134
141
 
135
142
  def restrict(lic, txn = {})
136
- @decisions << [:restrict, lic, txn]
143
+ add_decision [:restrict, lic, txn]
137
144
  @restricted << License.find_by_name(lic)
138
145
  self
139
146
  end
140
147
 
141
148
  def unrestrict(lic, txn = {})
142
- @decisions << [:unrestrict, lic, txn]
149
+ add_decision [:unrestrict, lic, txn]
143
150
  @restricted.delete(License.find_by_name(lic))
144
151
  self
145
152
  end
146
153
 
147
154
  def ignore(name, txn = {})
148
- @decisions << [:ignore, name, txn]
155
+ add_decision [:ignore, name, txn]
149
156
  @ignored << name
150
157
  self
151
158
  end
152
159
 
153
160
  def heed(name, txn = {})
154
- @decisions << [:heed, name, txn]
161
+ add_decision [:heed, name, txn]
155
162
  @ignored.delete(name)
156
163
  self
157
164
  end
158
165
 
159
166
  def ignore_group(name, txn = {})
160
- @decisions << [:ignore_group, name, txn]
167
+ add_decision [:ignore_group, name, txn]
161
168
  @ignored_groups << name
162
169
  self
163
170
  end
164
171
 
165
172
  def heed_group(name, txn = {})
166
- @decisions << [:heed_group, name, txn]
173
+ add_decision [:heed_group, name, txn]
167
174
  @ignored_groups.delete(name)
168
175
  self
169
176
  end
170
177
 
171
178
  def name_project(name, txn = {})
172
- @decisions << [:name_project, name, txn]
179
+ add_decision [:name_project, name, txn]
173
180
  @project_name = name
174
181
  self
175
182
  end
176
183
 
177
184
  def unname_project(txn = {})
178
- @decisions << [:unname_project, txn]
185
+ add_decision [:unname_project, txn]
179
186
  @project_name = nil
180
187
  self
181
188
  end
182
189
 
190
+ def inherit_from(filepath_info)
191
+ decisions =
192
+ if filepath_info.is_a?(Hash)
193
+ open_uri(filepath_info['url'], filepath_info['authorization']).read
194
+ elsif filepath_info =~ %r{^https?://}
195
+ open_uri(filepath_info).read
196
+ else
197
+ Pathname(filepath_info).read
198
+ end
199
+
200
+ add_decision [:inherit_from, filepath_info]
201
+ @inherited_decisions << filepath_info
202
+ restore_inheritance(decisions)
203
+ end
204
+
205
+ def remove_inheritance(filepath)
206
+ @decisions -= [[:inherit_from, filepath]]
207
+ @inherited_decisions.delete(filepath)
208
+ self
209
+ end
210
+
211
+ def add_decision(decision)
212
+ @decisions << decision unless @inherited
213
+ end
214
+
215
+ def restore_inheritance(decisions)
216
+ @inherited = true
217
+ self.class.restore(decisions, self)
218
+ @inherited = false
219
+ self
220
+ end
221
+
222
+ def open_uri(uri, auth = nil)
223
+ header = {}
224
+ auth_header = resolve_authorization(auth)
225
+ header['Authorization'] = auth_header if auth_header
226
+
227
+ # ruby < 2.5.0 URI.open is private
228
+ if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.5.0')
229
+ # rubocop:disable Security/Open
230
+ open(uri, header)
231
+ # rubocop:enable Security/Open
232
+ else
233
+ URI.open(uri, header)
234
+ end
235
+ end
236
+
237
+ def resolve_authorization(auth)
238
+ return unless auth
239
+
240
+ token_env = auth.match(/\$(\S.*)/)
241
+ return auth unless token_env
242
+
243
+ token = ENV[token_env[1]]
244
+ auth.sub(token_env[0], token)
245
+ end
246
+
183
247
  #########
184
248
  # PERSIST
185
249
  #########
@@ -192,8 +256,7 @@ module LicenseFinder
192
256
  write!(persist, file)
193
257
  end
194
258
 
195
- def self.restore(persisted)
196
- result = new
259
+ def self.restore(persisted, result = new)
197
260
  return result unless persisted
198
261
 
199
262
  actions = YAML.load(persisted)
@@ -19,6 +19,9 @@ module LicenseFinder
19
19
 
20
20
  def find_by_name(name)
21
21
  name ||= 'unknown'
22
+ return OrLicense.new(name) if name.include?(OrLicense.operator)
23
+ return AndLicense.new(name) if name.include?(AndLicense.operator)
24
+
22
25
  all.detect { |l| l.matches_name? l.stripped_name(name) } || Definitions.build_unrecognized(name)
23
26
  end
24
27
 
@@ -61,6 +64,10 @@ module LicenseFinder
61
64
  name.hash
62
65
  end
63
66
 
67
+ def unrecognized_matcher?
68
+ matcher.is_a?(NoneMatcher)
69
+ end
70
+
64
71
  private
65
72
 
66
73
  attr_reader :short_name, :pretty_name, :other_names
@@ -70,4 +77,33 @@ module LicenseFinder
70
77
  ([short_name, pretty_name] + other_names).uniq
71
78
  end
72
79
  end
80
+ class AndLicense < License
81
+ def self.operator
82
+ ' AND '
83
+ end
84
+
85
+ def initialize(name, operator = AndLicense.operator)
86
+ @short_name = name
87
+ @pretty_name = name
88
+ @url = nil
89
+ @matcher = NoneMatcher.new
90
+ # removes heading and trailing parentesis and splits
91
+ names = name[1..-2].split(operator)
92
+ @sub_licenses = names.map do |sub_name|
93
+ License.find_by_name(sub_name)
94
+ end
95
+ end
96
+
97
+ attr_reader :sub_licenses
98
+ end
99
+
100
+ class OrLicense < AndLicense
101
+ def self.operator
102
+ ' OR '
103
+ end
104
+
105
+ def initialize(name)
106
+ super(name, OrLicense.operator)
107
+ end
108
+ end
73
109
  end
@@ -21,9 +21,12 @@ module LicenseFinder
21
21
  mit,
22
22
  mpl2,
23
23
  newbsd,
24
+ ofl,
24
25
  python,
25
26
  ruby,
26
- simplifiedbsd
27
+ simplifiedbsd,
28
+ wtfpl,
29
+ zerobsd
27
30
  ]
28
31
  end
29
32
 
@@ -234,6 +237,17 @@ module LicenseFinder
234
237
  )
235
238
  end
236
239
 
240
+ def ofl
241
+ License.new(
242
+ short_name: 'OFL',
243
+ pretty_name: 'SIL OPEN FONT LICENSE Version 1.1',
244
+ other_names: [
245
+ 'OPEN FONT LICENSE Version 1.1'
246
+ ],
247
+ url: 'https://opensource.org/licenses/OFL-1.1'
248
+ )
249
+ end
250
+
237
251
  def python
238
252
  License.new(
239
253
  short_name: 'Python',
@@ -277,6 +291,39 @@ module LicenseFinder
277
291
  url: 'http://opensource.org/licenses/bsd-license'
278
292
  )
279
293
  end
294
+
295
+ def wtfpl
296
+ License.new(
297
+ short_name: 'WTFPL',
298
+ pretty_name: 'WTFPL',
299
+ other_names: [
300
+ 'WTFPL V2',
301
+ 'Do What The Fuck You Want To Public License'
302
+ ],
303
+ url: 'http://www.wtfpl.net/'
304
+ )
305
+ end
306
+
307
+ def zerobsd
308
+ matcher = AnyMatcher.new(
309
+ Matcher.from_template(Template.named('0BSD'))
310
+ )
311
+
312
+ License.new(
313
+ short_name: '0BSD',
314
+ pretty_name: 'BSD Zero Clause License',
315
+ other_names: [
316
+ '0-Clause BSD',
317
+ 'Zero-Clause BSD',
318
+ 'BSD-0-Clause',
319
+ 'BSD-Zero-Clause',
320
+ 'BSD 0-Clause',
321
+ 'BSD Zero-Clause'
322
+ ],
323
+ url: 'https://opensource.org/licenses/0BSD',
324
+ matcher: matcher
325
+ )
326
+ end
280
327
  end
281
328
  end
282
329
  end
@@ -0,0 +1,10 @@
1
+ Permission to use, copy, modify, and/or distribute this software for any
2
+ purpose with or without fee is hereby granted.
3
+
4
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
5
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
6
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
7
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
8
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
9
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
10
+ PERFORMANCE OF THIS SOFTWARE.
@@ -0,0 +1,91 @@
1
+ This Font Software is licensed under the SIL Open Font License, Version 1.1.
2
+ This license is copied below, and is also available with a FAQ at:
3
+ http://scripts.sil.org/OFL
4
+
5
+
6
+ -----------------------------------------------------------
7
+ SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
8
+ -----------------------------------------------------------
9
+
10
+ PREAMBLE
11
+ The goals of the Open Font License (OFL) are to stimulate worldwide
12
+ development of collaborative font projects, to support the font creation
13
+ efforts of academic and linguistic communities, and to provide a free and
14
+ open framework in which fonts may be shared and improved in partnership
15
+ with others.
16
+
17
+ The OFL allows the licensed fonts to be used, studied, modified and
18
+ redistributed freely as long as they are not sold by themselves. The
19
+ fonts, including any derivative works, can be bundled, embedded,
20
+ redistributed and/or sold with any software provided that any reserved
21
+ names are not used by derivative works. The fonts and derivatives,
22
+ however, cannot be released under any other type of license. The
23
+ requirement for fonts to remain under this license does not apply
24
+ to any document created using the fonts or their derivatives.
25
+
26
+ DEFINITIONS
27
+ "Font Software" refers to the set of files released by the Copyright
28
+ Holder(s) under this license and clearly marked as such. This may
29
+ include source files, build scripts and documentation.
30
+
31
+ "Reserved Font Name" refers to any names specified as such after the
32
+ copyright statement(s).
33
+
34
+ "Original Version" refers to the collection of Font Software components as
35
+ distributed by the Copyright Holder(s).
36
+
37
+ "Modified Version" refers to any derivative made by adding to, deleting,
38
+ or substituting -- in part or in whole -- any of the components of the
39
+ Original Version, by changing formats or by porting the Font Software to a
40
+ new environment.
41
+
42
+ "Author" refers to any designer, engineer, programmer, technical
43
+ writer or other person who contributed to the Font Software.
44
+
45
+ PERMISSION & CONDITIONS
46
+ Permission is hereby granted, free of charge, to any person obtaining
47
+ a copy of the Font Software, to use, study, copy, merge, embed, modify,
48
+ redistribute, and sell modified and unmodified copies of the Font
49
+ Software, subject to the following conditions:
50
+
51
+ 1) Neither the Font Software nor any of its individual components,
52
+ in Original or Modified Versions, may be sold by itself.
53
+
54
+ 2) Original or Modified Versions of the Font Software may be bundled,
55
+ redistributed and/or sold with any software, provided that each copy
56
+ contains the above copyright notice and this license. These can be
57
+ included either as stand-alone text files, human-readable headers or
58
+ in the appropriate machine-readable metadata fields within text or
59
+ binary files as long as those fields can be easily viewed by the user.
60
+
61
+ 3) No Modified Version of the Font Software may use the Reserved Font
62
+ Name(s) unless explicit written permission is granted by the corresponding
63
+ Copyright Holder. This restriction only applies to the primary font name as
64
+ presented to the users.
65
+
66
+ 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
67
+ Software shall not be used to promote, endorse or advertise any
68
+ Modified Version, except to acknowledge the contribution(s) of the
69
+ Copyright Holder(s) and the Author(s) or with their explicit written
70
+ permission.
71
+
72
+ 5) The Font Software, modified or unmodified, in part or in whole,
73
+ must be distributed entirely under this license, and must not be
74
+ distributed under any other license. The requirement for fonts to
75
+ remain under this license does not apply to any document created
76
+ using the Font Software.
77
+
78
+ TERMINATION
79
+ This license becomes null and void if any of the above conditions are
80
+ not met.
81
+
82
+ DISCLAIMER
83
+ THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
84
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
85
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
86
+ OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
87
+ COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
88
+ INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
89
+ DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
90
+ FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
91
+ OTHER DEALINGS IN THE FONT SOFTWARE.