licensee 9.14.1 → 9.15.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.md +1 -1
  3. data/bin/licensee +1 -1
  4. data/lib/licensee.rb +1 -1
  5. data/lib/licensee/commands/detect.rb +2 -4
  6. data/lib/licensee/commands/diff.rb +1 -3
  7. data/lib/licensee/content_helper.rb +23 -27
  8. data/lib/licensee/hash_helper.rb +1 -1
  9. data/lib/licensee/license.rb +28 -14
  10. data/lib/licensee/matchers/copyright.rb +2 -7
  11. data/lib/licensee/matchers/cran.rb +1 -1
  12. data/lib/licensee/matchers/dice.rb +1 -1
  13. data/lib/licensee/project_files/license_file.rb +29 -22
  14. data/lib/licensee/project_files/project_file.rb +2 -4
  15. data/lib/licensee/project_files/readme_file.rb +1 -1
  16. data/lib/licensee/projects/fs_project.rb +1 -3
  17. data/lib/licensee/projects/git_project.rb +6 -4
  18. data/lib/licensee/projects/project.rb +11 -10
  19. data/lib/licensee/version.rb +1 -1
  20. data/licensee.gemspec +5 -4
  21. data/spec/fixture_spec.rb +2 -2
  22. data/spec/fixtures/bsd-3-authorowner/LICENSE +27 -0
  23. data/spec/fixtures/cc-by-sa-mdlinks/License.md +173 -0
  24. data/spec/fixtures/cc-by-sa-nocclicensor/License.md +425 -0
  25. data/spec/fixtures/detect.json +5 -5
  26. data/spec/fixtures/eupl-cal2017/LICENSE.txt +274 -0
  27. data/spec/fixtures/fixtures.yml +45 -25
  28. data/spec/fixtures/license-hashes.json +39 -38
  29. data/spec/fixtures/pixar-modified-apache/LICENSE.txt +174 -0
  30. data/spec/integration_spec.rb +46 -6
  31. data/spec/licensee/commands/detect_spec.rb +2 -2
  32. data/spec/licensee/content_helper_spec.rb +14 -13
  33. data/spec/licensee/license_spec.rb +5 -5
  34. data/spec/licensee/matchers/dice_matcher_spec.rb +2 -2
  35. data/spec/licensee/project_files/license_file_spec.rb +8 -2
  36. data/spec/licensee/project_spec.rb +1 -3
  37. data/spec/licensee_spec.rb +1 -1
  38. data/spec/spec_helper.rb +3 -3
  39. data/spec/vendored_license_spec.rb +1 -1
  40. data/vendor/choosealicense.com/_licenses/apache-2.0.txt +1 -1
  41. data/vendor/choosealicense.com/_licenses/bsl-1.0.txt +1 -1
  42. data/vendor/choosealicense.com/_licenses/eupl-1.2.txt +75 -58
  43. data/vendor/choosealicense.com/_licenses/mit-0.txt +45 -0
  44. data/vendor/choosealicense.com/_licenses/odbl-1.0.txt +1 -1
  45. data/vendor/choosealicense.com/_licenses/unlicense.txt +1 -1
  46. data/vendor/license-list-XML/src/0BSD.xml +21 -0
  47. data/vendor/license-list-XML/src/AFL-3.0.xml +212 -0
  48. data/vendor/license-list-XML/src/AGPL-3.0.xml +852 -0
  49. data/vendor/license-list-XML/src/Apache-2.0.xml +223 -0
  50. data/vendor/license-list-XML/src/Artistic-2.0.xml +238 -0
  51. data/vendor/license-list-XML/src/BSD-2-Clause.xml +42 -0
  52. data/vendor/license-list-XML/src/BSD-3-Clause-Clear.xml +59 -0
  53. data/vendor/license-list-XML/src/BSD-3-Clause.xml +46 -0
  54. data/vendor/license-list-XML/src/BSD-4-Clause.xml +59 -0
  55. data/vendor/license-list-XML/src/BSL-1.0.xml +30 -0
  56. data/vendor/license-list-XML/src/CC-BY-4.0.xml +444 -0
  57. data/vendor/license-list-XML/src/CC-BY-SA-4.0.xml +475 -0
  58. data/vendor/license-list-XML/src/CC0-1.0.xml +153 -0
  59. data/vendor/license-list-XML/src/CECILL-2.1.xml +669 -0
  60. data/vendor/license-list-XML/src/ECL-2.0.xml +242 -0
  61. data/vendor/license-list-XML/src/EPL-1.0.xml +255 -0
  62. data/vendor/license-list-XML/src/EPL-2.0.xml +639 -0
  63. data/vendor/license-list-XML/src/EUPL-1.1.xml +337 -0
  64. data/vendor/license-list-XML/src/EUPL-1.2.xml +502 -0
  65. data/vendor/license-list-XML/src/GPL-2.0.xml +474 -0
  66. data/vendor/license-list-XML/src/GPL-3.0.xml +858 -0
  67. data/vendor/license-list-XML/src/ISC.xml +29 -0
  68. data/vendor/license-list-XML/src/LGPL-2.1.xml +662 -0
  69. data/vendor/license-list-XML/src/LGPL-3.0.xml +260 -0
  70. data/vendor/license-list-XML/src/LPPL-1.3c.xml +380 -0
  71. data/vendor/license-list-XML/src/MIT-0.xml +40 -0
  72. data/vendor/license-list-XML/src/MIT.xml +32 -0
  73. data/vendor/license-list-XML/src/MPL-2.0.xml +438 -0
  74. data/vendor/license-list-XML/src/MS-PL.xml +89 -0
  75. data/vendor/license-list-XML/src/MS-RL.xml +97 -0
  76. data/vendor/license-list-XML/src/NCSA.xml +60 -0
  77. data/vendor/license-list-XML/src/ODbL-1.0.xml +660 -0
  78. data/vendor/license-list-XML/src/OFL-1.1.xml +94 -0
  79. data/vendor/license-list-XML/src/OSL-3.0.xml +209 -0
  80. data/vendor/license-list-XML/src/PostgreSQL.xml +32 -0
  81. data/vendor/license-list-XML/src/UPL-1.0.xml +46 -0
  82. data/vendor/license-list-XML/src/Unlicense.xml +27 -0
  83. data/vendor/license-list-XML/src/Vim.xml +124 -0
  84. data/vendor/license-list-XML/src/WTFPL.xml +30 -0
  85. data/vendor/license-list-XML/src/Zlib.xml +38 -0
  86. metadata +73 -13
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0cdac44039e6185c028d41ab8112b43d7e1ba66f2c8bd02be490255d14dfac38
4
- data.tar.gz: 895ffc0aa9296fef49193b6282edb6286a9115ba4b3207be4c15df5755ca3bf7
3
+ metadata.gz: 63f3f7938e9e0c58907e71bcf9de72e69d2d494d2dbbba6c71e150b44190eda3
4
+ data.tar.gz: 51583db05dee9239fb50e373f3dc4c79dfa4515a5461facc2722dabe5ee0fb9a
5
5
  SHA512:
6
- metadata.gz: eb7c6c9d1b2a8c8258b8d499efa96ab7b25b83108bb47ed163eabd5d78e83a2443a0bbf6f43eb1abda0b441e8696a17f79066ec4356c80a1b88d3c40338c726b
7
- data.tar.gz: e1bfeb5c75d28b334d880351acf7977c71e5efa9b61c407c204921475070c3ede8b2331b82cc64446fa81577ede499cf8d2d5b6d70ae1fc507cc238ee4a52a08
6
+ metadata.gz: 87b8a85992cec7c2e7c30fab5b96e33a0fdd4271df34a99ca2b99584f1f94cdcb70c5663d9a584ccf1164fd10eca2b1e7b26f09bb7b43a81a8c3705dc6341666
7
+ data.tar.gz: b261c2cf6a2b40fd5b4b10bd4644d179dda3e35686b6f6361af4177dcda852eb45c22bf0dafc43291824a2c48b30f1297c2f933a7786f12dbefbb0bde6dfb83b
data/LICENSE.md CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2014-2020 Ben Balter and Licensee contributors
3
+ Copyright (c) 2014-2021 Ben Balter and Licensee contributors
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/bin/licensee CHANGED
@@ -19,7 +19,7 @@ class LicenseeCLI < Thor
19
19
  args.first || Dir.pwd
20
20
  else
21
21
  "https://github.com/#{args.first}"
22
- end
22
+ end
23
23
  end
24
24
 
25
25
  def project
data/lib/licensee.rb CHANGED
@@ -37,7 +37,7 @@ module Licensee
37
37
  end
38
38
 
39
39
  def project(path, **args)
40
- if path =~ %r{\Ahttps://github.com}
40
+ if %r{\Ahttps://github.com}.match?(path)
41
41
  Licensee::Projects::GitHubProject.new(path, **args)
42
42
  else
43
43
  Licensee::Projects::GitProject.new(path, **args)
@@ -28,11 +28,9 @@ class LicenseeCLI < Thor
28
28
  ['Licenses:', project.licenses.map(&:spdx_id)]
29
29
  else
30
30
  ['License:', set_color('None', :red)]
31
- end
31
+ end
32
32
 
33
- unless project.matched_files.empty?
34
- rows << ['Matched files:', project.matched_files.map(&:filename).join(', ')]
35
- end
33
+ rows << ['Matched files:', project.matched_files.map(&:filename).join(', ')] unless project.matched_files.empty?
36
34
 
37
35
  print_table rows
38
36
 
@@ -49,9 +49,7 @@ class LicenseeCLI < Thor
49
49
  end
50
50
 
51
51
  def expected_license
52
- if options[:license]
53
- @expected_license ||= Licensee::License.find options[:license]
54
- end
52
+ @expected_license ||= Licensee::License.find options[:license] if options[:license]
55
53
  return @expected_license if @expected_license
56
54
 
57
55
  if options[:license]
@@ -23,8 +23,8 @@ module Licensee
23
23
  url: %r{#{START_REGEX}https?://[^ ]+\n},
24
24
  bullet: /\n\n\s*(?:[*-]|\(?[\da-z]{1,2}[).])\s+/i,
25
25
  developed_by: /#{START_REGEX}developed by:.*?\n\n/im,
26
- quote_begin: /[`'"‘“]/,
27
- quote_end: /[`'"’”]/,
26
+ cc_dedication: /The\s+text\s+of\s+the\s+Creative\s+Commons.*?Public\s+Domain\s+Dedication./im,
27
+ cc_wiki: /wiki.creativecommons.org/i,
28
28
  cc_legal_code: /^\s*Creative Commons Legal Code\s*$/i,
29
29
  cc0_info: /For more information, please see\s*\S+zero\S+/im,
30
30
  cc0_disclaimer: /CREATIVE COMMONS CORPORATION.*?\n\n/im,
@@ -36,10 +36,7 @@ module Licensee
36
36
  https: { from: /http:/, to: 'https:' },
37
37
  ampersands: { from: '&', to: 'and' },
38
38
  dashes: { from: /(?<!^)([—–-]+)(?!$)/, to: '-' },
39
- quotes: {
40
- from: /#{REGEXES[:quote_begin]}+([\w -]*?\w)#{REGEXES[:quote_end]}+/,
41
- to: '"\1"'
42
- }
39
+ quote: { from: /[`'"‘“’”]/, to: "'" }
43
40
  }.freeze
44
41
 
45
42
  # Legally equivalent words that schould be ignored for comparison
@@ -90,10 +87,9 @@ module Licensee
90
87
  }.freeze
91
88
  STRIP_METHODS = %i[
92
89
  bom
90
+ cc_optional
93
91
  cc0_optional
94
92
  unlicense_optional
95
- hrs
96
- markdown_headings
97
93
  borders
98
94
  title
99
95
  version
@@ -101,7 +97,6 @@ module Licensee
101
97
  copyright
102
98
  title
103
99
  block_markup
104
- link_markup
105
100
  developed_by
106
101
  end_of_terms
107
102
  whitespace
@@ -110,7 +105,7 @@ module Licensee
110
105
 
111
106
  # A set of each word in the license, without duplicates
112
107
  def wordset
113
- @wordset ||= content_normalized&.scan(%r{(?:[\w/](?:'s|(?<=s)')?)+})&.to_set
108
+ @wordset ||= content_normalized&.scan(%r{(?:[\w/-](?:'s|(?<=s)')?)+})&.to_set
114
109
  end
115
110
 
116
111
  # Number of characters in the normalized content
@@ -133,7 +128,7 @@ module Licensee
133
128
  overlap = (wordset_fieldless & other.wordset).size
134
129
  total = wordset_fieldless.size + other.wordset.size -
135
130
  fields_normalized_set.size
136
- (overlap * 200.0) / (total + fields_adjusted_length_delta(other) / 10)
131
+ (overlap * 200.0) / (total + variation_adjusted_length_delta(other) / 4)
137
132
  end
138
133
 
139
134
  # SHA1 of the normalized content
@@ -148,7 +143,7 @@ module Licensee
148
143
  def content_without_title_and_version
149
144
  @content_without_title_and_version ||= begin
150
145
  @_content = nil
151
- ops = %i[html hrs comments markdown_headings title version]
146
+ ops = %i[html hrs comments markdown_headings link_markup title version]
152
147
  ops.each { |op| strip(op) }
153
148
  _content
154
149
  end
@@ -186,12 +181,10 @@ module Licensee
186
181
  text.gsub!(/([^\n])\n([^\n])/, '\1 \2')
187
182
 
188
183
  text = text.split("\n").collect do |line|
189
- if line =~ REGEXES[:hrs]
184
+ if line =~ REGEXES[:hrs] || line.length <= line_width
190
185
  line
191
- elsif line.length > line_width
192
- line.gsub(/(.{1,#{line_width}})(\s+|$)/, "\\1\n").strip
193
186
  else
194
- line
187
+ line.gsub(/(.{1,#{line_width}})(\s+|$)/, "\\1\n").strip
195
188
  end
196
189
  end * "\n"
197
190
 
@@ -233,9 +226,7 @@ module Licensee
233
226
  meth = "strip_#{regex_or_sym}"
234
227
  return send(meth) if respond_to?(meth, true)
235
228
 
236
- unless REGEXES[regex_or_sym]
237
- raise ArgumentError, "#{regex_or_sym} is an invalid regex reference"
238
- end
229
+ raise ArgumentError, "#{regex_or_sym} is an invalid regex reference" unless REGEXES[regex_or_sym]
239
230
 
240
231
  regex_or_sym = REGEXES[regex_or_sym]
241
232
  end
@@ -244,9 +235,7 @@ module Licensee
244
235
  end
245
236
 
246
237
  def strip_title
247
- while _content =~ ContentHelper.title_regex
248
- strip(ContentHelper.title_regex)
249
- end
238
+ strip(ContentHelper.title_regex) while _content =~ ContentHelper.title_regex
250
239
  end
251
240
 
252
241
  def strip_borders
@@ -274,6 +263,13 @@ module Licensee
274
263
  strip(REGEXES[:cc0_disclaimer])
275
264
  end
276
265
 
266
+ def strip_cc_optional
267
+ return unless _content.include? 'creative commons'
268
+
269
+ strip(REGEXES[:cc_dedication])
270
+ strip(REGEXES[:cc_wiki])
271
+ end
272
+
277
273
  def strip_unlicense_optional
278
274
  return unless _content.include? 'unlicense'
279
275
 
@@ -295,7 +291,7 @@ module Licensee
295
291
 
296
292
  def strip_html
297
293
  return unless respond_to?(:filename) && filename
298
- return unless File.extname(filename) =~ /\.html?/i
294
+ return unless /\.html?/i.match?(File.extname(filename))
299
295
 
300
296
  require 'reverse_markdown'
301
297
  @_content = ReverseMarkdown.convert(_content, unknown_tags: :bypass)
@@ -319,7 +315,7 @@ module Licensee
319
315
  end
320
316
 
321
317
  def normalize_bullets
322
- normalize(REGEXES[:bullet], "\n\n* ")
318
+ normalize(REGEXES[:bullet], "\n\n- ")
323
319
  normalize(/\)\s+\(/, ')(')
324
320
  end
325
321
 
@@ -337,10 +333,10 @@ module Licensee
337
333
  @fields_normalized_set ||= fields_normalized.to_set
338
334
  end
339
335
 
340
- def fields_adjusted_length_delta(other)
336
+ def variation_adjusted_length_delta(other)
341
337
  delta = length_delta(other)
342
- adjusted_delta = delta - fields_normalized.size * 2
343
- adjusted_delta.positive? ? adjusted_delta : delta
338
+ adjusted_delta = delta - [fields_normalized.size, spdx_alt_segments].max * 4
339
+ adjusted_delta.positive? ? adjusted_delta : 0
344
340
  end
345
341
  end
346
342
  end
@@ -13,7 +13,7 @@ module Licensee
13
13
  value.to_h
14
14
  else
15
15
  value
16
- end
16
+ end
17
17
  end
18
18
 
19
19
  hash
@@ -4,6 +4,7 @@ require 'uri'
4
4
 
5
5
  module Licensee
6
6
  class InvalidLicense < ArgumentError; end
7
+
7
8
  class License
8
9
  @all = {}
9
10
  @keys_licenses = {}
@@ -26,9 +27,11 @@ module Licensee
26
27
  output.reject!(&:hidden?) unless options[:hidden]
27
28
  output.reject!(&:pseudo_license?) unless options[:pseudo]
28
29
  output.sort_by!(&:key)
29
- return output if options[:featured].nil?
30
-
31
- output.select { |l| l.featured? == options[:featured] }
30
+ if options[:featured].nil?
31
+ output
32
+ else
33
+ output.select { |l| l.featured? == options[:featured] }
34
+ end
32
35
  end
33
36
  end
34
37
 
@@ -53,14 +56,17 @@ module Licensee
53
56
  end
54
57
 
55
58
  def license_dir
56
- dir = ::File.dirname(__FILE__)
57
- ::File.expand_path '../../vendor/choosealicense.com/_licenses', dir
59
+ ::File.expand_path '../../vendor/choosealicense.com/_licenses', __dir__
58
60
  end
59
61
 
60
62
  def license_files
61
63
  @license_files ||= Dir.glob("#{license_dir}/*.txt")
62
64
  end
63
65
 
66
+ def spdx_dir
67
+ ::File.expand_path '../../vendor/license-list-XML/src', __dir__
68
+ end
69
+
64
70
  private
65
71
 
66
72
  def licenses
@@ -82,7 +88,7 @@ module Licensee
82
88
  # `other` - The project had a license, but we were not able to detect it
83
89
  # `no-license` - The project is not licensed (e.g., all rights reserved)
84
90
  #
85
- # Note: A lack of detected license will be a nil license
91
+ # NOTE: A lack of detected license will be a nil license
86
92
  PSEUDO_LICENSES = %w[other no-license].freeze
87
93
 
88
94
  # Default options to use when retrieving licenses via #all
@@ -154,9 +160,7 @@ module Licensee
154
160
  key_regex = Regexp.new string, 'i'
155
161
 
156
162
  parts = [title_regex, key_regex]
157
- if meta.nickname
158
- parts.push Regexp.new meta.nickname.sub(/\bGNU /i, '(?:GNU )?')
159
- end
163
+ parts.push Regexp.new meta.nickname.sub(/\bGNU /i, '(?:GNU )?') if meta.nickname
160
164
 
161
165
  @title_regex = Regexp.union parts
162
166
  end
@@ -173,8 +177,8 @@ module Licensee
173
177
  return @source_regex if defined? @source_regex
174
178
  return unless meta.source
175
179
 
176
- source = meta.source.dup.sub(/\A#{SOURCE_PREFIX}/, '')
177
- source = source.sub(/#{SOURCE_SUFFIX}\z/, '')
180
+ source = meta.source.dup.sub(/\A#{SOURCE_PREFIX}/o, '')
181
+ source = source.sub(/#{SOURCE_SUFFIX}\z/o, '')
178
182
 
179
183
  escaped_source = Regexp.escape(source)
180
184
  @source_regex = /#{SOURCE_PREFIX}#{escaped_source}(?:#{SOURCE_SUFFIX})?/i
@@ -244,9 +248,7 @@ module Licensee
244
248
  # Raw content of license file, including YAML front matter
245
249
  def raw_content
246
250
  return if pseudo_license?
247
- unless File.exist?(path)
248
- raise Licensee::InvalidLicense, "'#{key}' is not a valid license key"
249
- end
251
+ raise Licensee::InvalidLicense, "'#{key}' is not a valid license key" unless File.exist?(path)
250
252
 
251
253
  @raw_content ||= File.read(path, encoding: 'utf-8')
252
254
  end
@@ -260,5 +262,17 @@ module Licensee
260
262
  def yaml
261
263
  @yaml ||= parts[1] if parts
262
264
  end
265
+
266
+ def spdx_alt_segments
267
+ @spdx_alt_segments ||= begin
268
+ path = File.expand_path "#{spdx_id}.xml", Licensee::License.spdx_dir
269
+ raw_xml = File.read(path, encoding: 'utf-8')
270
+ text = raw_xml.match(%r{<text>(.*)</text>}m)[1]
271
+ text.gsub!(%r{<copyrightText>.*?</copyrightText>}m, '')
272
+ text.gsub!(%r{<titleText>.*?</titleText>}m, '')
273
+ text.gsub!(%r{<optional.*?>.*?</optional>}m, '')
274
+ text.scan(/<alt .*?>/m).size
275
+ end
276
+ end
263
277
  end
264
278
  end
@@ -5,16 +5,11 @@ module Licensee
5
5
  class Copyright < Licensee::Matchers::Matcher
6
6
  attr_reader :file
7
7
 
8
- # rubocop:disable Layout/LineLength
9
8
  COPYRIGHT_SYMBOLS = Regexp.union([/copyright/i, /\(c\)/i, "\u00A9", "\xC2\xA9"])
10
9
  REGEX = /#{ContentHelper::START_REGEX}(?:portions )?([_*\-\s]*#{COPYRIGHT_SYMBOLS}.*$)+$/i.freeze
11
- # rubocop:enable Layout/LineLength
12
-
13
10
  def match
14
- # Note: must use content, and not content_normalized here
15
- if file.content.strip =~ /#{REGEX}+\z/i
16
- Licensee::License.find('no-license')
17
- end
11
+ # NOTE: must use content, and not content_normalized here
12
+ Licensee::License.find('no-license') if /#{REGEX}+\z/io.match?(file.content.strip)
18
13
  rescue Encoding::CompatibilityError
19
14
  nil
20
15
  end
@@ -26,7 +26,7 @@ module Licensee
26
26
  # Otherwise, returns `nil`
27
27
  def gpl_version(license_key)
28
28
  match = license_key.match GPL_VERSION_REGEX
29
- match ? "gpl-#{(match[1] || match[2])}.0" : nil
29
+ match ? "gpl-#{match[1] || match[2]}.0" : nil
30
30
  end
31
31
 
32
32
  # Normalizes the license field value to an SPDX ID
@@ -10,7 +10,7 @@ module Licensee
10
10
  nil
11
11
  else
12
12
  matches.first[0]
13
- end
13
+ end
14
14
  end
15
15
 
16
16
  # Licenses that may be a match for this file.
@@ -10,7 +10,14 @@ module Licensee
10
10
  PREFERRED_EXT_REGEX = /\.#{Regexp.union(PREFERRED_EXT)}\z/.freeze
11
11
 
12
12
  # Regex to match any extension except .spdx or .header
13
- OTHER_EXT_REGEX = %r{\.(?!spdx|header|gemspec)[^./]+\z}i.freeze
13
+ LICENSE_EXT_REGEX = %r{\.(?!spdx|header)[^./]+\z}i.freeze
14
+
15
+ # Regex to match any extension except a few unlikely as license
16
+ # texts with complex filenames
17
+ OTHER_EXT_REGEX = %r{\.(?!xml|go|gemspec)[^./]+\z}i.freeze
18
+
19
+ # Regex to match any extension
20
+ ANY_EXT_REGEX = %r{\.[^./]+\z}i.freeze
14
21
 
15
22
  # Regex to match, LICENSE, LICENCE, unlicense, etc.
16
23
  LICENSE_REGEX = /(un)?licen[sc]e/i.freeze
@@ -26,22 +33,22 @@ module Licensee
26
33
 
27
34
  # Hash of Regex => score with which to score potential license files
28
35
  FILENAME_REGEXES = {
29
- /\A#{LICENSE_REGEX}\z/ => 1.00, # LICENSE
30
- /\A#{LICENSE_REGEX}#{PREFERRED_EXT_REGEX}\z/ => 0.95, # LICENSE.md
31
- /\A#{COPYING_REGEX}\z/ => 0.90, # COPYING
32
- /\A#{COPYING_REGEX}#{PREFERRED_EXT_REGEX}\z/ => 0.85, # COPYING.md
33
- /\A#{LICENSE_REGEX}#{OTHER_EXT_REGEX}\z/ => 0.80, # LICENSE.textile
34
- /\A#{COPYING_REGEX}#{OTHER_EXT_REGEX}\z/ => 0.75, # COPYING.textile
35
- /\A#{LICENSE_REGEX}[-_]/ => 0.70, # LICENSE-MIT
36
- /\A#{COPYING_REGEX}[-_]/ => 0.65, # COPYING-MIT
37
- /\A\w+[-_]#{LICENSE_REGEX}/ => 0.60, # MIT-LICENSE-MIT
38
- /\A\w+[-_]#{COPYING_REGEX}/ => 0.55, # MIT-COPYING
39
- /\A#{OFL_REGEX}#{PREFERRED_EXT_REGEX}/ => 0.50, # OFL.md
40
- /\A#{OFL_REGEX}#{OTHER_EXT_REGEX}/ => 0.45, # OFL.textile
41
- /\A#{OFL_REGEX}\z/ => 0.40, # OFL
42
- /\A#{PATENTS_REGEX}\z/ => 0.35, # PATENTS
43
- /\A#{PATENTS_REGEX}#{OTHER_EXT_REGEX}\z/ => 0.30, # PATENTS.txt
44
- // => 0.00 # Catch all
36
+ /\A#{LICENSE_REGEX}\z/ => 1.00, # LICENSE
37
+ /\A#{LICENSE_REGEX}#{PREFERRED_EXT_REGEX}\z/ => 0.95, # LICENSE.md
38
+ /\A#{COPYING_REGEX}\z/ => 0.90, # COPYING
39
+ /\A#{COPYING_REGEX}#{PREFERRED_EXT_REGEX}\z/ => 0.85, # COPYING.md
40
+ /\A#{LICENSE_REGEX}#{LICENSE_EXT_REGEX}\z/ => 0.80, # LICENSE.textile
41
+ /\A#{COPYING_REGEX}#{ANY_EXT_REGEX}\z/ => 0.75, # COPYING.textile
42
+ /\A#{LICENSE_REGEX}[-_][^.]*#{OTHER_EXT_REGEX}?\z/ => 0.70, # LICENSE-MIT
43
+ /\A#{COPYING_REGEX}[-_][^.]*#{OTHER_EXT_REGEX}?\z/ => 0.65, # COPYING-MIT
44
+ /\A\w+[-_]#{LICENSE_REGEX}[^.]*#{OTHER_EXT_REGEX}?\z/ => 0.60, # MIT-LICENSE-MIT
45
+ /\A\w+[-_]#{COPYING_REGEX}[^.]*#{OTHER_EXT_REGEX}?\z/ => 0.55, # MIT-COPYING
46
+ /\A#{OFL_REGEX}#{PREFERRED_EXT_REGEX}/ => 0.50, # OFL.md
47
+ /\A#{OFL_REGEX}#{OTHER_EXT_REGEX}/ => 0.45, # OFL.textile
48
+ /\A#{OFL_REGEX}\z/ => 0.40, # OFL
49
+ /\A#{PATENTS_REGEX}\z/ => 0.35, # PATENTS
50
+ /\A#{PATENTS_REGEX}#{OTHER_EXT_REGEX}\z/ => 0.30, # PATENTS.txt
51
+ // => 0.00 # Catch all
45
52
  }.freeze
46
53
 
47
54
  # CC-NC and CC-ND are not open source licenses and should not be
@@ -56,11 +63,11 @@ module Licensee
56
63
 
57
64
  def attribution
58
65
  @attribution ||= begin
59
- return unless copyright? || license.content&.include?('[fullname]')
60
-
61
- matches = Matchers::Copyright::REGEX
62
- .match(content_without_title_and_version)
63
- matches[0] if matches
66
+ if copyright? || license.content&.include?('[fullname]')
67
+ matches = Matchers::Copyright::REGEX
68
+ .match(content_without_title_and_version)
69
+ matches[0] if matches
70
+ end
64
71
  end
65
72
  end
66
73
 
@@ -37,9 +37,7 @@ module Licensee
37
37
  def initialize(content, metadata = {})
38
38
  @content = content.dup
39
39
  @content.force_encoding(ENCODING)
40
- unless @content.valid_encoding?
41
- @content.encode!(ENCODING, **ENCODING_OPTIONS)
42
- end
40
+ @content.encode!(ENCODING, **ENCODING_OPTIONS) unless @content.valid_encoding?
43
41
  @content.encode!(ENCODING, universal_newline: true)
44
42
 
45
43
  metadata = { name: metadata } if metadata.is_a? String
@@ -93,7 +91,7 @@ module Licensee
93
91
  return false unless is_a?(LicenseFile)
94
92
  return false unless matcher.is_a?(Matchers::Copyright)
95
93
 
96
- filename =~ /\Acopyright(?:#{LicenseFile::OTHER_EXT_REGEX})?\z/i
94
+ filename =~ /\Acopyright(?:#{LicenseFile::OTHER_EXT_REGEX})?\z/io
97
95
  end
98
96
 
99
97
  def content_hash