licensee 9.12.0 → 9.14.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 (112) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.md +1 -1
  3. data/bin/licensee +4 -4
  4. data/lib/licensee.rb +3 -3
  5. data/lib/licensee/commands/detect.rb +6 -6
  6. data/lib/licensee/commands/diff.rb +2 -2
  7. data/lib/licensee/content_helper.rb +72 -26
  8. data/lib/licensee/hash_helper.rb +5 -5
  9. data/lib/licensee/license.rb +17 -21
  10. data/lib/licensee/matchers.rb +1 -0
  11. data/lib/licensee/matchers/cabal.rb +1 -1
  12. data/lib/licensee/matchers/cargo.rb +1 -1
  13. data/lib/licensee/matchers/copyright.rb +3 -3
  14. data/lib/licensee/matchers/dice.rb +4 -4
  15. data/lib/licensee/matchers/dist_zilla.rb +1 -1
  16. data/lib/licensee/matchers/gemspec.rb +4 -4
  17. data/lib/licensee/matchers/npm_bower.rb +5 -2
  18. data/lib/licensee/matchers/nuget.rb +43 -0
  19. data/lib/licensee/matchers/spdx.rb +1 -1
  20. data/lib/licensee/project_files/license_file.rb +3 -3
  21. data/lib/licensee/project_files/package_manager_file.rb +3 -2
  22. data/lib/licensee/project_files/project_file.rb +2 -1
  23. data/lib/licensee/projects/fs_project.rb +7 -2
  24. data/lib/licensee/projects/git_project.rb +3 -3
  25. data/lib/licensee/projects/github_project.rb +1 -1
  26. data/lib/licensee/projects/project.rb +3 -3
  27. data/lib/licensee/version.rb +1 -1
  28. data/licensee.gemspec +45 -0
  29. data/spec/bin_spec.rb +1 -1
  30. data/spec/fixture_spec.rb +5 -5
  31. data/spec/fixtures/bom/LICENSE.txt +21 -0
  32. data/spec/fixtures/bsd-3-noendorseslash/LICENSE +30 -0
  33. data/spec/fixtures/cc0-cal2013/LICENSE +116 -0
  34. data/spec/fixtures/cc0-cc/LICENSE +121 -0
  35. data/spec/fixtures/crlf-bsd/LICENSE.md +27 -0
  36. data/spec/fixtures/detect.json +14 -20
  37. data/spec/fixtures/fixtures.yml +43 -3
  38. data/spec/fixtures/license-hashes.json +10 -8
  39. data/spec/fixtures/markdown-artistic/LICENSE.md +192 -0
  40. data/spec/fixtures/multiple-arrs/LICENSE +30 -0
  41. data/spec/fixtures/readme-invalid-encoding/README.md +24 -0
  42. data/spec/fixtures/unlicense-noinfo/LICENSE +22 -0
  43. data/spec/fixtures/vim/LICENSE +78 -0
  44. data/spec/integration_spec.rb +87 -4
  45. data/spec/licensee/commands/detect_spec.rb +5 -5
  46. data/spec/licensee/commands/license_path_spec.rb +1 -1
  47. data/spec/licensee/commands/version_spec.rb +1 -1
  48. data/spec/licensee/content_helper_spec.rb +46 -50
  49. data/spec/licensee/hash_helper_spec.rb +23 -23
  50. data/spec/licensee/license_field_spec.rb +3 -3
  51. data/spec/licensee/license_meta_spec.rb +18 -22
  52. data/spec/licensee/license_rules_spec.rb +4 -2
  53. data/spec/licensee/license_spec.rb +43 -39
  54. data/spec/licensee/matchers/cabal_matcher_spec.rb +4 -2
  55. data/spec/licensee/matchers/cargo_matcher_spec.rb +3 -2
  56. data/spec/licensee/matchers/copyright_matcher_spec.rb +3 -3
  57. data/spec/licensee/matchers/cran_matcher_spec.rb +3 -2
  58. data/spec/licensee/matchers/dice_matcher_spec.rb +15 -21
  59. data/spec/licensee/matchers/dist_zilla_matcher_spec.rb +3 -2
  60. data/spec/licensee/matchers/exact_matcher_spec.rb +3 -2
  61. data/spec/licensee/matchers/gemspec_matcher_spec.rb +3 -2
  62. data/spec/licensee/matchers/matcher_spec.rb +10 -8
  63. data/spec/licensee/matchers/npm_bower_matcher_spec.rb +12 -3
  64. data/spec/licensee/matchers/nu_get_matcher_spec.rb +91 -0
  65. data/spec/licensee/matchers/package_matcher_spec.rb +4 -2
  66. data/spec/licensee/matchers/reference_matcher_spec.rb +2 -2
  67. data/spec/licensee/matchers/spdx_matcher_spec.rb +3 -2
  68. data/spec/licensee/project_files/license_file_spec.rb +43 -42
  69. data/spec/licensee/project_files/package_info_spec.rb +11 -1
  70. data/spec/licensee/project_files/project_file_spec.rb +5 -2
  71. data/spec/licensee/project_files/readme_file_spec.rb +2 -1
  72. data/spec/licensee/project_spec.rb +22 -17
  73. data/spec/licensee/projects/github_project_spec.rb +6 -5
  74. data/spec/licensee/rule_spec.rb +5 -4
  75. data/spec/licensee_spec.rb +10 -9
  76. data/spec/spec_helper.rb +2 -2
  77. data/spec/vendored_license_spec.rb +5 -5
  78. data/vendor/choosealicense.com/_data/meta.yml +1 -1
  79. data/vendor/choosealicense.com/_data/rules.yml +15 -12
  80. data/vendor/choosealicense.com/_licenses/0bsd.txt +3 -3
  81. data/vendor/choosealicense.com/_licenses/apache-2.0.txt +4 -4
  82. data/vendor/choosealicense.com/_licenses/artistic-2.0.txt +1 -1
  83. data/vendor/choosealicense.com/_licenses/bsd-2-clause.txt +3 -3
  84. data/vendor/choosealicense.com/_licenses/bsd-3-clause-clear.txt +1 -0
  85. data/vendor/choosealicense.com/_licenses/bsd-3-clause.txt +3 -3
  86. data/vendor/choosealicense.com/_licenses/bsd-4-clause.txt +61 -0
  87. data/vendor/choosealicense.com/_licenses/bsl-1.0.txt +5 -1
  88. data/vendor/choosealicense.com/_licenses/cc-by-4.0.txt +16 -13
  89. data/vendor/choosealicense.com/_licenses/cc-by-sa-4.0.txt +16 -13
  90. data/vendor/choosealicense.com/_licenses/cc0-1.0.txt +113 -104
  91. data/vendor/choosealicense.com/_licenses/cecill-2.1.txt +6 -6
  92. data/vendor/choosealicense.com/_licenses/ecl-2.0.txt +4 -4
  93. data/vendor/choosealicense.com/_licenses/epl-1.0.txt +3 -3
  94. data/vendor/choosealicense.com/_licenses/epl-2.0.txt +5 -5
  95. data/vendor/choosealicense.com/_licenses/eupl-1.2.txt +3 -3
  96. data/vendor/choosealicense.com/_licenses/gpl-2.0.txt +3 -3
  97. data/vendor/choosealicense.com/_licenses/gpl-3.0.txt +4 -4
  98. data/vendor/choosealicense.com/_licenses/isc.txt +3 -3
  99. data/vendor/choosealicense.com/_licenses/lgpl-3.0.txt +0 -1
  100. data/vendor/choosealicense.com/_licenses/lppl-1.3c.txt +1 -1
  101. data/vendor/choosealicense.com/_licenses/mit.txt +3 -3
  102. data/vendor/choosealicense.com/_licenses/mpl-2.0.txt +3 -3
  103. data/vendor/choosealicense.com/_licenses/ncsa.txt +24 -24
  104. data/vendor/choosealicense.com/_licenses/odbl-1.0.txt +3 -3
  105. data/vendor/choosealicense.com/_licenses/ofl-1.1.txt +4 -1
  106. data/vendor/choosealicense.com/_licenses/osl-3.0.txt +3 -3
  107. data/vendor/choosealicense.com/_licenses/postgresql.txt +5 -5
  108. data/vendor/choosealicense.com/_licenses/unlicense.txt +3 -3
  109. data/vendor/choosealicense.com/_licenses/upl-1.0.txt +4 -4
  110. data/vendor/choosealicense.com/_licenses/vim.txt +111 -0
  111. data/vendor/choosealicense.com/_licenses/zlib.txt +4 -1
  112. metadata +62 -21
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d7dc009b0467cfb305e8dac051ed4e78d2f35d0454f2e14cef0952338540f8ae
4
- data.tar.gz: 3c27bb3dd3cea6d62fab826b81fab93d9152893851b541c91d69406cdf9fcbd8
3
+ metadata.gz: 0cdac44039e6185c028d41ab8112b43d7e1ba66f2c8bd02be490255d14dfac38
4
+ data.tar.gz: 895ffc0aa9296fef49193b6282edb6286a9115ba4b3207be4c15df5755ca3bf7
5
5
  SHA512:
6
- metadata.gz: 07f19b33f70b0b73611d34e474f2aa4e4d7f62c7451cdf70f76774beceac2c75ab3d1cc5048061a848b979a54032aad6dd1ba278c79cd798029efd6873d54425
7
- data.tar.gz: 96c5e66f65307e7feb2c00b3f06661b093c60995d049f7fd19cc27b76881965a1d33768a16b0a3a3b085e9392ef828dce9cf692ee04255dd9ea2c6d22da38da6
6
+ metadata.gz: eb7c6c9d1b2a8c8258b8d499efa96ab7b25b83108bb47ed163eabd5d78e83a2443a0bbf6f43eb1abda0b441e8696a17f79066ec4356c80a1b88d3c40338c726b
7
+ data.tar.gz: e1bfeb5c75d28b334d880351acf7977c71e5efa9b61c407c204921475070c3ede8b2331b82cc64446fa81577ede499cf8d2d5b6d70ae1fc507cc238ee4a52a08
data/LICENSE.md CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2014-2017 Ben Balter
3
+ Copyright (c) 2014-2020 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
@@ -16,9 +16,9 @@ class LicenseeCLI < Thor
16
16
 
17
17
  def path
18
18
  @path ||= if !options[:remote] || args.first =~ %r{^https://}
19
- args.first || Dir.pwd
20
- else
21
- "https://github.com/#{args.first}"
19
+ args.first || Dir.pwd
20
+ else
21
+ "https://github.com/#{args.first}"
22
22
  end
23
23
  end
24
24
 
@@ -33,6 +33,6 @@ class LicenseeCLI < Thor
33
33
  end
34
34
 
35
35
  commands_dir = File.expand_path '../lib/licensee/commands/', __dir__
36
- Dir["#{commands_dir}/*.rb"].each { |c| require(c) }
36
+ Dir["#{commands_dir}/*.rb"].sort.each { |c| require(c) }
37
37
 
38
38
  LicenseeCLI.start(ARGV)
@@ -38,12 +38,12 @@ module Licensee
38
38
 
39
39
  def project(path, **args)
40
40
  if path =~ %r{\Ahttps://github.com}
41
- Licensee::Projects::GitHubProject.new(path, args)
41
+ Licensee::Projects::GitHubProject.new(path, **args)
42
42
  else
43
- Licensee::Projects::GitProject.new(path, args)
43
+ Licensee::Projects::GitProject.new(path, **args)
44
44
  end
45
45
  rescue Licensee::Projects::GitProject::InvalidRepository
46
- Licensee::Projects::FSProject.new(path, args)
46
+ Licensee::Projects::FSProject.new(path, **args)
47
47
  end
48
48
 
49
49
  def confidence_threshold
@@ -23,11 +23,11 @@ class LicenseeCLI < Thor
23
23
 
24
24
  rows = []
25
25
  rows << if project.license
26
- ['License:', project.license.spdx_id]
27
- elsif !project.licenses.empty?
28
- ['Licenses:', project.licenses.map(&:spdx_id)]
29
- else
30
- ['License:', set_color('None', :red)]
26
+ ['License:', project.license.spdx_id]
27
+ elsif !project.licenses.empty?
28
+ ['Licenses:', project.licenses.map(&:spdx_id)]
29
+ else
30
+ ['License:', set_color('None', :red)]
31
31
  end
32
32
 
33
33
  unless project.matched_files.empty?
@@ -88,7 +88,7 @@ class LicenseeCLI < Thor
88
88
  when :confidence
89
89
  Licensee::ContentHelper.format_percent(value)
90
90
  when :method
91
- value.to_s.tr('_', ' ').capitalize + ':'
91
+ "#{value.to_s.tr('_', ' ').capitalize}:"
92
92
  else
93
93
  value
94
94
  end
@@ -41,10 +41,10 @@ class LicenseeCLI < Thor
41
41
 
42
42
  def license_to_diff
43
43
  return options[:license_to_diff] if options[:license_to_diff]
44
- return project.license_file if remote? || STDIN.tty? && project.license_file
44
+ return project.license_file if remote? || $stdin.tty? && project.license_file
45
45
 
46
46
  @license_to_diff ||= begin
47
- Licensee::ProjectFiles::LicenseFile.new(STDIN.read, 'LICENSE')
47
+ Licensee::ProjectFiles::LicenseFile.new($stdin.read, 'LICENSE')
48
48
  end
49
49
  end
50
50
 
@@ -7,24 +7,28 @@ module Licensee
7
7
  module ContentHelper
8
8
  DIGEST = Digest::SHA1
9
9
  START_REGEX = /\A\s*/.freeze
10
- END_OF_TERMS_REGEX = /^[\s#*_]*end of terms and conditions\s*$/i.freeze
11
- ALT_TITLE_REGEX = License::ALT_TITLE_REGEX
10
+ END_OF_TERMS_REGEX = /^[\s#*_]*end of terms and conditions[\s#*_]*$/i.freeze
12
11
  REGEXES = {
13
- hrs: /^\s*[=\-\*]{3,}\s*$/,
12
+ bom: /#{START_REGEX}\xEF\xBB\xBF/,
13
+ hrs: /^\s*[=\-*]{3,}\s*$/,
14
14
  all_rights_reserved: /#{START_REGEX}all rights reserved\.?$/i,
15
15
  whitespace: /\s+/,
16
- markdown_headings: /#{START_REGEX}#+/,
16
+ markdown_headings: /^\s*#+/,
17
17
  version: /#{START_REGEX}version.*$/i,
18
18
  span_markup: /[_*~]+(.*?)[_*~]+/,
19
19
  link_markup: /\[(.+?)\]\(.+?\)/,
20
20
  block_markup: /^\s*>/,
21
- border_markup: /^[\*-](.*?)[\*-]$/,
22
- comment_markup: %r{^\s*?[/\*]{1,2}},
21
+ border_markup: /^[*-](.*?)[*-]$/,
22
+ comment_markup: %r{^\s*?[/*]{1,2}},
23
23
  url: %r{#{START_REGEX}https?://[^ ]+\n},
24
- bullet: /\n\n\s*(?:[*-]|\(?[\da-z]{1,2}[)\.])\s+/i,
24
+ bullet: /\n\n\s*(?:[*-]|\(?[\da-z]{1,2}[).])\s+/i,
25
25
  developed_by: /#{START_REGEX}developed by:.*?\n\n/im,
26
26
  quote_begin: /[`'"‘“]/,
27
27
  quote_end: /[`'"’”]/,
28
+ cc_legal_code: /^\s*Creative Commons Legal Code\s*$/i,
29
+ cc0_info: /For more information, please see\s*\S+zero\S+/im,
30
+ cc0_disclaimer: /CREATIVE COMMONS CORPORATION.*?\n\n/im,
31
+ unlicense_info: /For more information, please.*\S+unlicense\S+/im,
28
32
  mit_optional: /\(including the next paragraph\)/i
29
33
  }.freeze
30
34
  NORMALIZATIONS = {
@@ -85,43 +89,51 @@ module Licensee
85
89
  'owner' => 'holder'
86
90
  }.freeze
87
91
  STRIP_METHODS = %i[
88
- hrs markdown_headings borders title version url copyright
89
- block_markup span_markup link_markup
90
- all_rights_reserved developed_by end_of_terms whitespace
92
+ bom
93
+ cc0_optional
94
+ unlicense_optional
95
+ hrs
96
+ markdown_headings
97
+ borders
98
+ title
99
+ version
100
+ url
101
+ copyright
102
+ title
103
+ block_markup
104
+ link_markup
105
+ developed_by
106
+ end_of_terms
107
+ whitespace
91
108
  mit_optional
92
109
  ].freeze
93
110
 
94
111
  # A set of each word in the license, without duplicates
95
112
  def wordset
96
- @wordset ||= content_normalized&.scan(/(?:\w(?:'s|(?<=s)')?)+/)&.to_set
113
+ @wordset ||= content_normalized&.scan(%r{(?:[\w/](?:'s|(?<=s)')?)+})&.to_set
97
114
  end
98
115
 
99
- # Number of characteres in the normalized content
116
+ # Number of characters in the normalized content
100
117
  def length
101
118
  return 0 unless content_normalized
102
119
 
103
120
  content_normalized.length
104
121
  end
105
122
 
106
- # Number of characters that could be added/removed to still be
107
- # considered a potential match
108
- def max_delta
109
- @max_delta ||= (length * Licensee.inverse_confidence_threshold).to_i
110
- end
111
-
112
123
  # Given another license or project file, calculates the difference in length
113
124
  def length_delta(other)
114
125
  (length - other.length).abs
115
126
  end
116
127
 
117
128
  # Given another license or project file, calculates the similarity
118
- # as a percentage of words in common
129
+ # as a percentage of words in common, minus a tiny penalty that
130
+ # increases with size difference between licenses so that false
131
+ # positives for long licnses are ruled out by this score alone.
119
132
  def similarity(other)
120
- wordset_fieldless = wordset - LicenseField.keys
121
- fields_removed = wordset.size - wordset_fieldless.size
122
133
  overlap = (wordset_fieldless & other.wordset).size
123
- total = wordset_fieldless.size + other.wordset.size - fields_removed
124
- 100.0 * (overlap * 2.0 / total)
134
+ total = wordset_fieldless.size + other.wordset.size -
135
+ fields_normalized_set.size
136
+ (overlap * 200.0) / (total + fields_adjusted_length_delta(other) / 10)
125
137
  end
126
138
 
127
139
  # SHA1 of the normalized content
@@ -146,7 +158,7 @@ module Licensee
146
158
  @content_normalized ||= begin
147
159
  @_content = content_without_title_and_version.downcase
148
160
 
149
- (NORMALIZATIONS.keys + %i[spelling bullets]).each { |op| normalize(op) }
161
+ (NORMALIZATIONS.keys + %i[spelling span_markup bullets]).each { |op| normalize(op) }
150
162
  STRIP_METHODS.each { |op| strip(op) }
151
163
 
152
164
  _content
@@ -250,16 +262,30 @@ module Licensee
250
262
  end
251
263
 
252
264
  def strip_copyright
253
- regex = Matchers::Copyright::REGEX
265
+ regex = Regexp.union(Matchers::Copyright::REGEX, REGEXES[:all_rights_reserved])
254
266
  strip(regex) while _content =~ regex
255
267
  end
256
268
 
269
+ def strip_cc0_optional
270
+ return unless _content.include? 'associating cc0'
271
+
272
+ strip(REGEXES[:cc_legal_code])
273
+ strip(REGEXES[:cc0_info])
274
+ strip(REGEXES[:cc0_disclaimer])
275
+ end
276
+
277
+ def strip_unlicense_optional
278
+ return unless _content.include? 'unlicense'
279
+
280
+ strip(REGEXES[:unlicense_info])
281
+ end
282
+
257
283
  def strip_end_of_terms
258
284
  body, _partition, _instructions = _content.partition(END_OF_TERMS_REGEX)
259
285
  @_content = body
260
286
  end
261
287
 
262
- def strip_span_markup
288
+ def normalize_span_markup
263
289
  normalize(REGEXES[:span_markup], '\1')
264
290
  end
265
291
 
@@ -296,5 +322,25 @@ module Licensee
296
322
  normalize(REGEXES[:bullet], "\n\n* ")
297
323
  normalize(/\)\s+\(/, ')(')
298
324
  end
325
+
326
+ def wordset_fieldless
327
+ @wordset_fieldless ||= wordset - fields_normalized_set
328
+ end
329
+
330
+ # Returns an array of strings of substitutable fields in normalized content
331
+ def fields_normalized
332
+ @fields_normalized ||=
333
+ content_normalized.scan(LicenseField::FIELD_REGEX).flatten
334
+ end
335
+
336
+ def fields_normalized_set
337
+ @fields_normalized_set ||= fields_normalized.to_set
338
+ end
339
+
340
+ def fields_adjusted_length_delta(other)
341
+ delta = length_delta(other)
342
+ adjusted_delta = delta - fields_normalized.size * 2
343
+ adjusted_delta.positive? ? adjusted_delta : delta
344
+ end
299
345
  end
300
346
  end
@@ -8,11 +8,11 @@ module Licensee
8
8
  key = method.to_s.delete('?').to_sym
9
9
  value = public_send(method)
10
10
  hash[key] = if value.is_a?(Array)
11
- value.map { |v| v.respond_to?(:to_h) ? v.to_h : v }
12
- elsif value.respond_to?(:to_h) && !value.nil?
13
- value.to_h
14
- else
15
- value
11
+ value.map { |v| v.respond_to?(:to_h) ? v.to_h : v }
12
+ elsif value.respond_to?(:to_h) && !value.nil?
13
+ value.to_h
14
+ else
15
+ value
16
16
  end
17
17
  end
18
18
 
@@ -92,14 +92,8 @@ module Licensee
92
92
  pseudo: true
93
93
  }.freeze
94
94
 
95
- ALT_TITLE_REGEX = {
96
- 'bsd-2-clause' => /bsd 2-clause(?: \"simplified\")?/i,
97
- 'bsd-3-clause' => /bsd 3-clause(?: \"new\" or \"revised\")?/i,
98
- 'bsd-3-clause-clear' => /(?:clear bsd|bsd 3-clause(?: clear)?)/i
99
- }.freeze
100
-
101
95
  SOURCE_PREFIX = %r{https?://(?:www\.)?}i.freeze
102
- SOURCE_SUFFIX = %r{(?:\.html?|\.txt|\/)(?:\?[^\s]*)?}i.freeze
96
+ SOURCE_SUFFIX = %r{(?:\.html?|\.txt|/)(?:\?[^\s]*)?}i.freeze
103
97
 
104
98
  HASH_METHODS = %i[
105
99
  key spdx_id meta url rules fields other? gpl? lgpl? cc?
@@ -144,20 +138,22 @@ module Licensee
144
138
  def title_regex
145
139
  return @title_regex if defined? @title_regex
146
140
 
147
- title_regex = ALT_TITLE_REGEX[key]
148
- title_regex ||= begin
149
- string = name.downcase.sub('*', 'u')
150
- string.sub!(/\Athe /i, '')
151
- string.sub!(/,? version /, ' ')
152
- string.sub!(/v(\d+\.\d+)/, '\1')
153
- string = Regexp.escape(string)
154
- string = string.sub(/\\ licen[sc]e/i, '(?:\ licen[sc]e)?')
155
- string = string.sub(/\\ (\d+\\.\d+)/, ',?\s+(?:version\ |v(?:\. )?)?\1')
156
- string = string.sub(/\bgnu\\ /, '(?:GNU )?')
157
- Regexp.new string, 'i'
158
- end
159
-
160
- parts = [title_regex, key]
141
+ string = name.downcase.sub('*', 'u')
142
+ string.sub!(/\Athe /i, '')
143
+ string.sub!(/,? version /, ' ')
144
+ string.sub!(/v(\d+\.\d+)/, '\1')
145
+ string = Regexp.escape(string)
146
+ string = string.sub(/\\ licen[sc]e/i, '(?:\ licen[sc]e)?')
147
+ string = string.sub(/\\ (\d+\\.\d+)/, ',?\s+(?:version\ |v(?:\. )?)?\1')
148
+ string = string.sub(/\bgnu\\ /, '(?:GNU )?')
149
+ title_regex = Regexp.new string, 'i'
150
+
151
+ string = key.sub('-', '[- ]')
152
+ string.sub!('.', '\.')
153
+ string << '(?:\ licen[sc]e)?'
154
+ key_regex = Regexp.new string, 'i'
155
+
156
+ parts = [title_regex, key_regex]
161
157
  if meta.nickname
162
158
  parts.push Regexp.new meta.nickname.sub(/\bGNU /i, '(?:GNU )?')
163
159
  end
@@ -12,6 +12,7 @@ module Licensee
12
12
  autoload :Exact, 'licensee/matchers/exact'
13
13
  autoload :Gemspec, 'licensee/matchers/gemspec'
14
14
  autoload :NpmBower, 'licensee/matchers/npm_bower'
15
+ autoload :NuGet, 'licensee/matchers/nuget'
15
16
  autoload :Package, 'licensee/matchers/package'
16
17
  autoload :Reference, 'licensee/matchers/reference'
17
18
  autoload :Spdx, 'licensee/matchers/spdx'
@@ -5,7 +5,7 @@ module Licensee
5
5
  class Cabal < Licensee::Matchers::Package
6
6
  # While we could parse the cabal file, prefer
7
7
  # a lenient regex for speed and security. Moar parsing moar problems.
8
- LICENSE_REGEX = /^\s*license\s*\:\s*([a-z\-0-9\.]+)\s*$/ix.freeze
8
+ LICENSE_REGEX = /^\s*license\s*:\s*([a-z\-0-9.]+)\s*$/ix.freeze
9
9
  LICENSE_CONVERSIONS = {
10
10
  'GPL-2' => 'GPL-2.0',
11
11
  'GPL-3' => 'GPL-3.0',
@@ -4,7 +4,7 @@ module Licensee
4
4
  module Matchers
5
5
  class Cargo < Licensee::Matchers::Package
6
6
  LICENSE_REGEX = %r{
7
- ^\s*[\'\"]?license[\'\"]?\s*=\s*[\'\"]([a-z\-0-9\. +()\/]+)[\'\"]\s*
7
+ ^\s*['"]?license['"]?\s*=\s*['"]([a-z\-0-9. +()/]+)['"]\s*
8
8
  }ix.freeze
9
9
 
10
10
  private
@@ -5,10 +5,10 @@ module Licensee
5
5
  class Copyright < Licensee::Matchers::Matcher
6
6
  attr_reader :file
7
7
 
8
- # rubocop:disable Metrics/LineLength
8
+ # rubocop:disable Layout/LineLength
9
9
  COPYRIGHT_SYMBOLS = Regexp.union([/copyright/i, /\(c\)/i, "\u00A9", "\xC2\xA9"])
10
- REGEX = /#{ContentHelper::START_REGEX}(?:portions )?(\s*#{COPYRIGHT_SYMBOLS}.*$)+$/i.freeze
11
- # rubocop:enable Metrics/LineLength
10
+ REGEX = /#{ContentHelper::START_REGEX}(?:portions )?([_*\-\s]*#{COPYRIGHT_SYMBOLS}.*$)+$/i.freeze
11
+ # rubocop:enable Layout/LineLength
12
12
 
13
13
  def match
14
14
  # Note: must use content, and not content_normalized here
@@ -7,9 +7,9 @@ module Licensee
7
7
  # than the confidence threshold
8
8
  def match
9
9
  @match ||= if matches.empty?
10
- nil
11
- else
12
- matches.first[0]
10
+ nil
11
+ else
12
+ matches.first[0]
13
13
  end
14
14
  end
15
15
 
@@ -26,7 +26,7 @@ module Licensee
26
26
  if license.creative_commons? && file.potential_false_positive?
27
27
  false
28
28
  else
29
- license.wordset && license.length_delta(file) <= license.max_delta
29
+ license.wordset
30
30
  end
31
31
  end
32
32
  end
@@ -5,7 +5,7 @@ module Licensee
5
5
  class DistZilla < Licensee::Matchers::Package
6
6
  attr_reader :file
7
7
 
8
- LICENSE_REGEX = /^license\s*=\s*([a-z\-0-9\._]+)/i.freeze
8
+ LICENSE_REGEX = /^license\s*=\s*([a-z\-0-9._]+)/i.freeze
9
9
 
10
10
  private
11
11
 
@@ -5,7 +5,7 @@ module Licensee
5
5
  class Gemspec < Licensee::Matchers::Package
6
6
  # a value is a string surrounded by any amount of whitespace
7
7
  # optionally ended with (non-captured) ".freeze"
8
- VALUE_REGEX = /\s*[\'\"]([a-z\-0-9\.]+)[\'\"](?:\.freeze)?\s*/i.freeze
8
+ VALUE_REGEX = /\s*['"]([a-z\-0-9.]+)['"](?:\.freeze)?\s*/i.freeze
9
9
 
10
10
  # an array contains one or more values. all values, or array itself,
11
11
  # can be surrounded by any amount of whitespace. do not capture
@@ -13,15 +13,15 @@ module Licensee
13
13
  ARRAY_REGEX = /\s*\[#{VALUE_REGEX}(?:,#{VALUE_REGEX})*\]\s*/i.freeze
14
14
 
15
15
  DECLARATION_REGEX = /
16
- ^\s*[a-z0-9_]+\.([a-z0-9_]+)\s*\=#{VALUE_REGEX}$
16
+ ^\s*[a-z0-9_]+\.([a-z0-9_]+)\s*=#{VALUE_REGEX}$
17
17
  /ix.freeze
18
18
 
19
19
  LICENSE_REGEX = /
20
- ^\s*[a-z0-9_]+\.license\s*\=#{VALUE_REGEX}$
20
+ ^\s*[a-z0-9_]+\.license\s*=#{VALUE_REGEX}$
21
21
  /ix.freeze
22
22
 
23
23
  LICENSE_ARRAY_REGEX = /
24
- ^\s*[a-z0-9_]+\.licenses\s*\=#{ARRAY_REGEX}$
24
+ ^\s*[a-z0-9_]+\.licenses\s*=#{ARRAY_REGEX}$
25
25
  /ix.freeze
26
26
 
27
27
  private
@@ -6,14 +6,17 @@ module Licensee
6
6
  # While we could parse the package.json or bower.json file, prefer
7
7
  # a lenient regex for speed and security. Moar parsing moar problems.
8
8
  LICENSE_REGEX = /
9
- \s*[\"\']license[\"\']\s*\:\s*[\'\"]([a-z\-0-9\.+ ()]+)[\'\"],?\s*
9
+ \s*["']license["']\s*:\s*['"]([a-z\-0-9.+ ()]+)['"],?\s*
10
10
  /ix.freeze
11
11
 
12
12
  private
13
13
 
14
14
  def license_property
15
15
  match = @file.content.match LICENSE_REGEX
16
- match[1].downcase if match && match[1]
16
+ return unless match && match[1]
17
+ return 'no-license' if match[1] == 'UNLICENSED'
18
+
19
+ match[1].downcase
17
20
  end
18
21
  end
19
22
  end