licensee 9.13.0 → 9.15.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (138) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.md +1 -1
  3. data/bin/licensee +2 -2
  4. data/lib/licensee.rb +4 -4
  5. data/lib/licensee/commands/detect.rb +3 -5
  6. data/lib/licensee/commands/diff.rb +3 -5
  7. data/lib/licensee/content_helper.rb +41 -44
  8. data/lib/licensee/hash_helper.rb +1 -1
  9. data/lib/licensee/license.rb +29 -15
  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 -8
  14. data/lib/licensee/matchers/cran.rb +1 -1
  15. data/lib/licensee/matchers/dice.rb +2 -2
  16. data/lib/licensee/matchers/dist_zilla.rb +1 -1
  17. data/lib/licensee/matchers/gemspec.rb +4 -4
  18. data/lib/licensee/matchers/npm_bower.rb +5 -2
  19. data/lib/licensee/matchers/nuget.rb +43 -0
  20. data/lib/licensee/matchers/spdx.rb +1 -1
  21. data/lib/licensee/project_files/license_file.rb +29 -22
  22. data/lib/licensee/project_files/package_manager_file.rb +3 -2
  23. data/lib/licensee/project_files/project_file.rb +3 -4
  24. data/lib/licensee/project_files/readme_file.rb +1 -1
  25. data/lib/licensee/projects/fs_project.rb +8 -5
  26. data/lib/licensee/projects/git_project.rb +6 -4
  27. data/lib/licensee/projects/github_project.rb +1 -1
  28. data/lib/licensee/projects/project.rb +11 -10
  29. data/lib/licensee/version.rb +1 -1
  30. data/licensee.gemspec +7 -8
  31. data/spec/fixture_spec.rb +3 -3
  32. data/spec/fixtures/bom/LICENSE.txt +21 -0
  33. data/spec/fixtures/bsd-3-authorowner/LICENSE +27 -0
  34. data/spec/fixtures/bsd-3-noendorseslash/LICENSE +30 -0
  35. data/spec/fixtures/cc-by-sa-mdlinks/License.md +173 -0
  36. data/spec/fixtures/cc-by-sa-nocclicensor/License.md +425 -0
  37. data/spec/fixtures/crlf-bsd/LICENSE.md +27 -0
  38. data/spec/fixtures/detect.json +16 -22
  39. data/spec/fixtures/eupl-cal2017/LICENSE.txt +274 -0
  40. data/spec/fixtures/fixtures.yml +68 -20
  41. data/spec/fixtures/license-hashes.json +39 -37
  42. data/spec/fixtures/markdown-artistic/LICENSE.md +192 -0
  43. data/spec/fixtures/multiple-arrs/LICENSE +30 -0
  44. data/spec/fixtures/pixar-modified-apache/LICENSE.txt +174 -0
  45. data/spec/fixtures/readme-invalid-encoding/README.md +24 -0
  46. data/spec/fixtures/vim/LICENSE +78 -0
  47. data/spec/integration_spec.rb +104 -9
  48. data/spec/licensee/commands/detect_spec.rb +2 -2
  49. data/spec/licensee/content_helper_spec.rb +17 -21
  50. data/spec/licensee/hash_helper_spec.rb +22 -22
  51. data/spec/licensee/license_meta_spec.rb +5 -11
  52. data/spec/licensee/license_spec.rb +14 -10
  53. data/spec/licensee/matchers/dice_matcher_spec.rb +4 -11
  54. data/spec/licensee/matchers/matcher_spec.rb +6 -6
  55. data/spec/licensee/matchers/npm_bower_matcher_spec.rb +9 -0
  56. data/spec/licensee/matchers/nu_get_matcher_spec.rb +91 -0
  57. data/spec/licensee/project_files/license_file_spec.rb +35 -28
  58. data/spec/licensee/project_files/package_info_spec.rb +8 -0
  59. data/spec/licensee/project_spec.rb +1 -3
  60. data/spec/licensee/rule_spec.rb +1 -1
  61. data/spec/licensee_spec.rb +1 -1
  62. data/spec/spec_helper.rb +3 -3
  63. data/spec/vendored_license_spec.rb +2 -2
  64. data/vendor/choosealicense.com/_data/meta.yml +1 -1
  65. data/vendor/choosealicense.com/_data/rules.yml +13 -13
  66. data/vendor/choosealicense.com/_licenses/0bsd.txt +3 -3
  67. data/vendor/choosealicense.com/_licenses/apache-2.0.txt +4 -4
  68. data/vendor/choosealicense.com/_licenses/artistic-2.0.txt +1 -1
  69. data/vendor/choosealicense.com/_licenses/bsd-2-clause.txt +3 -3
  70. data/vendor/choosealicense.com/_licenses/bsd-3-clause.txt +3 -3
  71. data/vendor/choosealicense.com/_licenses/bsd-4-clause.txt +3 -3
  72. data/vendor/choosealicense.com/_licenses/bsl-1.0.txt +4 -3
  73. data/vendor/choosealicense.com/_licenses/cc-by-4.0.txt +16 -16
  74. data/vendor/choosealicense.com/_licenses/cc-by-sa-4.0.txt +16 -16
  75. data/vendor/choosealicense.com/_licenses/cc0-1.0.txt +4 -4
  76. data/vendor/choosealicense.com/_licenses/cecill-2.1.txt +6 -6
  77. data/vendor/choosealicense.com/_licenses/ecl-2.0.txt +4 -4
  78. data/vendor/choosealicense.com/_licenses/epl-1.0.txt +3 -3
  79. data/vendor/choosealicense.com/_licenses/epl-2.0.txt +5 -5
  80. data/vendor/choosealicense.com/_licenses/eupl-1.2.txt +77 -60
  81. data/vendor/choosealicense.com/_licenses/gpl-2.0.txt +3 -3
  82. data/vendor/choosealicense.com/_licenses/gpl-3.0.txt +4 -4
  83. data/vendor/choosealicense.com/_licenses/isc.txt +3 -3
  84. data/vendor/choosealicense.com/_licenses/lgpl-3.0.txt +0 -1
  85. data/vendor/choosealicense.com/_licenses/lppl-1.3c.txt +1 -1
  86. data/vendor/choosealicense.com/_licenses/mit-0.txt +45 -0
  87. data/vendor/choosealicense.com/_licenses/mit.txt +3 -3
  88. data/vendor/choosealicense.com/_licenses/mpl-2.0.txt +3 -3
  89. data/vendor/choosealicense.com/_licenses/ncsa.txt +24 -24
  90. data/vendor/choosealicense.com/_licenses/odbl-1.0.txt +3 -3
  91. data/vendor/choosealicense.com/_licenses/ofl-1.1.txt +4 -4
  92. data/vendor/choosealicense.com/_licenses/osl-3.0.txt +3 -3
  93. data/vendor/choosealicense.com/_licenses/postgresql.txt +5 -5
  94. data/vendor/choosealicense.com/_licenses/unlicense.txt +3 -3
  95. data/vendor/choosealicense.com/_licenses/upl-1.0.txt +4 -4
  96. data/vendor/choosealicense.com/_licenses/vim.txt +111 -0
  97. data/vendor/choosealicense.com/_licenses/zlib.txt +3 -3
  98. data/vendor/license-list-XML/src/0BSD.xml +21 -0
  99. data/vendor/license-list-XML/src/AFL-3.0.xml +212 -0
  100. data/vendor/license-list-XML/src/AGPL-3.0.xml +852 -0
  101. data/vendor/license-list-XML/src/Apache-2.0.xml +223 -0
  102. data/vendor/license-list-XML/src/Artistic-2.0.xml +238 -0
  103. data/vendor/license-list-XML/src/BSD-2-Clause.xml +42 -0
  104. data/vendor/license-list-XML/src/BSD-3-Clause-Clear.xml +59 -0
  105. data/vendor/license-list-XML/src/BSD-3-Clause.xml +46 -0
  106. data/vendor/license-list-XML/src/BSD-4-Clause.xml +59 -0
  107. data/vendor/license-list-XML/src/BSL-1.0.xml +30 -0
  108. data/vendor/license-list-XML/src/CC-BY-4.0.xml +444 -0
  109. data/vendor/license-list-XML/src/CC-BY-SA-4.0.xml +475 -0
  110. data/vendor/license-list-XML/src/CC0-1.0.xml +153 -0
  111. data/vendor/license-list-XML/src/CECILL-2.1.xml +669 -0
  112. data/vendor/license-list-XML/src/ECL-2.0.xml +242 -0
  113. data/vendor/license-list-XML/src/EPL-1.0.xml +255 -0
  114. data/vendor/license-list-XML/src/EPL-2.0.xml +639 -0
  115. data/vendor/license-list-XML/src/EUPL-1.1.xml +337 -0
  116. data/vendor/license-list-XML/src/EUPL-1.2.xml +502 -0
  117. data/vendor/license-list-XML/src/GPL-2.0.xml +474 -0
  118. data/vendor/license-list-XML/src/GPL-3.0.xml +858 -0
  119. data/vendor/license-list-XML/src/ISC.xml +29 -0
  120. data/vendor/license-list-XML/src/LGPL-2.1.xml +662 -0
  121. data/vendor/license-list-XML/src/LGPL-3.0.xml +260 -0
  122. data/vendor/license-list-XML/src/LPPL-1.3c.xml +380 -0
  123. data/vendor/license-list-XML/src/MIT-0.xml +40 -0
  124. data/vendor/license-list-XML/src/MIT.xml +32 -0
  125. data/vendor/license-list-XML/src/MPL-2.0.xml +438 -0
  126. data/vendor/license-list-XML/src/MS-PL.xml +89 -0
  127. data/vendor/license-list-XML/src/MS-RL.xml +97 -0
  128. data/vendor/license-list-XML/src/NCSA.xml +60 -0
  129. data/vendor/license-list-XML/src/ODbL-1.0.xml +660 -0
  130. data/vendor/license-list-XML/src/OFL-1.1.xml +94 -0
  131. data/vendor/license-list-XML/src/OSL-3.0.xml +209 -0
  132. data/vendor/license-list-XML/src/PostgreSQL.xml +32 -0
  133. data/vendor/license-list-XML/src/UPL-1.0.xml +46 -0
  134. data/vendor/license-list-XML/src/Unlicense.xml +27 -0
  135. data/vendor/license-list-XML/src/Vim.xml +124 -0
  136. data/vendor/license-list-XML/src/WTFPL.xml +30 -0
  137. data/vendor/license-list-XML/src/Zlib.xml +38 -0
  138. metadata +97 -29
@@ -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,16 +5,11 @@ module Licensee
5
5
  class Copyright < Licensee::Matchers::Matcher
6
6
  attr_reader :file
7
7
 
8
- # rubocop:disable Metrics/LineLength
9
8
  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
12
-
9
+ REGEX = /#{ContentHelper::START_REGEX}(?:portions )?([_*\-\s]*#{COPYRIGHT_SYMBOLS}.*$)+$/i.freeze
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.
@@ -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
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Licensee
4
+ module Matchers
5
+ class NuGet < Licensee::Matchers::Package
6
+ # While we could parse the nuspec file, prefer a lenient regex for speed and security.
7
+ # Moar parsing moar problems.
8
+ LICENSE_REGEX = %r{
9
+ <license\s*type\s*=\s*["']expression["']\s*>([a-z\-0-9. +()]+)</license\s*>
10
+ }ix.freeze
11
+
12
+ LICENSE_URL_REGEX = %r{<licenseUrl>\s*(.*)\s*</licenseUrl>}i.freeze
13
+
14
+ NUGET_REGEX = %r{https?://licenses.nuget.org/(.*)}i.freeze
15
+ OPENSOURCE_REGEX = %r{https?://(?:www\.)?opensource.org/licenses/(.*)}i.freeze
16
+ SPDX_REGEX = %r{https?://(?:www\.)?spdx.org/licenses/(.*?)(?:\.html|\.txt)?$}i.freeze
17
+ APACHE_REGEX = %r{https?://(?:www\.)?apache.org/licenses/(.*?)(?:\.html|\.txt)?$}i.freeze
18
+
19
+ private
20
+
21
+ def license_from_first_capture(url, pattern)
22
+ match = url.match(pattern)
23
+ match[1].downcase if match && match[1]
24
+ end
25
+
26
+ def license_from_url(url)
27
+ license_from_first_capture(url, NUGET_REGEX) ||
28
+ license_from_first_capture(url, OPENSOURCE_REGEX) ||
29
+ license_from_first_capture(url, SPDX_REGEX) ||
30
+ license_from_first_capture(url, APACHE_REGEX)&.gsub('license', 'apache')
31
+ end
32
+
33
+ def license_property
34
+ # Prefer the explicit <license type="expression"> element
35
+ match = @file.content.match LICENSE_REGEX
36
+ return match[1].downcase if match && match[1]
37
+
38
+ url_match = @file.content.match LICENSE_URL_REGEX
39
+ license_from_url(url_match[1]) if url_match && url_match[1]
40
+ end
41
+ end
42
+ end
43
+ end
@@ -5,7 +5,7 @@ module Licensee
5
5
  class Spdx < Licensee::Matchers::Package
6
6
  # While we could parse the LICENSE.spdx file, prefer
7
7
  # a lenient regex for speed and security. Moar parsing moar problems.
8
- LICENSE_REGEX = /PackageLicenseDeclared:\s*([a-z\-0-9\. +()]+)\s*/i.freeze
8
+ LICENSE_REGEX = /PackageLicenseDeclared:\s*([a-z\-0-9. +()]+)\s*/i.freeze
9
9
 
10
10
  private
11
11
 
@@ -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
- /[-_]#{LICENSE_REGEX}/ => 0.60, # MIT-LICENSE-MIT
38
- /[-_]#{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 =~ /\[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
 
@@ -7,7 +7,8 @@ module Licensee
7
7
  MATCHERS_EXTENSIONS = {
8
8
  '.gemspec' => [Matchers::Gemspec],
9
9
  '.json' => [Matchers::NpmBower],
10
- '.cabal' => [Matchers::Cabal]
10
+ '.cabal' => [Matchers::Cabal],
11
+ '.nuspec' => [Matchers::NuGet]
11
12
  }.freeze
12
13
 
13
14
  # Hash of Filename => [possible matchers]
@@ -33,7 +34,7 @@ module Licensee
33
34
  end
34
35
 
35
36
  def self.name_score(filename)
36
- return 1.0 if ['.gemspec', '.cabal'].include?(File.extname(filename))
37
+ return 1.0 if ['.gemspec', '.cabal', '.nuspec'].include?(File.extname(filename))
37
38
 
38
39
  FILENAMES_SCORES[filename] || 0.0
39
40
  end
@@ -37,9 +37,8 @@ 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?
41
+ @content.encode!(ENCODING, universal_newline: true)
43
42
 
44
43
  metadata = { name: metadata } if metadata.is_a? String
45
44
  @data = metadata || {}
@@ -92,7 +91,7 @@ module Licensee
92
91
  return false unless is_a?(LicenseFile)
93
92
  return false unless matcher.is_a?(Matchers::Copyright)
94
93
 
95
- filename =~ /\Acopyright(?:#{LicenseFile::OTHER_EXT_REGEX})?\z/i
94
+ filename =~ /\Acopyright(?:#{LicenseFile::OTHER_EXT_REGEX})?\z/io
96
95
  end
97
96
 
98
97
  def content_hash
@@ -35,7 +35,7 @@ module Licensee
35
35
 
36
36
  def self.name_score(filename)
37
37
  SCORES.each do |pattern, score|
38
- return score if pattern =~ filename
38
+ return score if pattern&.match?(filename)
39
39
  end
40
40
  0.0
41
41
  end
@@ -20,9 +20,7 @@ module Licensee
20
20
  end
21
21
 
22
22
  @root = File.expand_path(args.delete(:search_root) || @dir)
23
- unless valid_search_root?
24
- raise 'Search root must be the project path directory or its ancestor'
25
- end
23
+ raise 'Search root must be the project path directory or its ancestor' unless valid_search_root?
26
24
 
27
25
  super(**args)
28
26
  end
@@ -44,13 +42,18 @@ module Licensee
44
42
  end
45
43
  end
46
44
 
47
- # Retrieve a file's content from disk
45
+ # Retrieve a file's content from disk, enforcing encoding
48
46
  #
49
47
  # file - the file hash, with the :name key as the file's relative path
50
48
  #
51
49
  # Returns the file contents as a string
52
50
  def load_file(file)
53
- File.read dir_path.join(file[:dir], file[:name])
51
+ content = File.read dir_path.join(file[:dir], file[:name])
52
+ content.force_encoding(ProjectFiles::ProjectFile::ENCODING)
53
+
54
+ return content if content.valid_encoding?
55
+
56
+ content.encode(ProjectFiles::ProjectFile::ENCODING, **ProjectFiles::ProjectFile::ENCODING_OPTIONS)
54
57
  end
55
58
 
56
59
  # Returns true if @dir is @root or it's descendant
@@ -28,9 +28,11 @@ module Licensee
28
28
 
29
29
  def repository
30
30
  @repository ||= begin
31
- return @raw_repo if @raw_repo.is_a? Rugged::Repository
32
-
33
- Rugged::Repository.new(@raw_repo)
31
+ if @raw_repo.is_a? Rugged::Repository
32
+ @raw_repo
33
+ else
34
+ Rugged::Repository.new(@raw_repo)
35
+ end
34
36
  end
35
37
  rescue Rugged::OSError, Rugged::RepositoryError
36
38
  raise InvalidRepository
@@ -47,7 +49,7 @@ module Licensee
47
49
  repository.lookup(revision)
48
50
  else
49
51
  repository.last_commit
50
- end
52
+ end
51
53
  end
52
54
 
53
55
  MAX_LICENSE_SIZE = 64 * 1024
@@ -15,7 +15,7 @@ module Licensee
15
15
  # If there's any trailing data (e.g. `.git`) this pattern will ignore it:
16
16
  # we're going to use the API rather than clone the repo.
17
17
  GITHUB_REPO_PATTERN =
18
- %r{https://github.com/([^\/]+\/([^\/]+(?=\.git)|[^\/]+)).*}.freeze
18
+ %r{https://github.com/([^/]+/([^/]+(?=\.git)|[^/]+)).*}.freeze
19
19
 
20
20
  class RepoNotFound < StandardError; end
21
21
 
@@ -28,7 +28,7 @@ module Licensee
28
28
  licenses_without_copyright.first
29
29
  elsif licenses_without_copyright.count > 1
30
30
  Licensee::License.find('other')
31
- end
31
+ end
32
32
  end
33
33
 
34
34
  # Returns an array of detected Licenses
@@ -55,16 +55,17 @@ module Licensee
55
55
 
56
56
  def license_files
57
57
  @license_files ||= begin
58
- return [] if files.empty? || files.nil?
59
-
60
- files = find_files do |n|
61
- Licensee::ProjectFiles::LicenseFile.name_score(n)
58
+ if files.empty? || files.nil?
59
+ []
60
+ else
61
+ files = find_files do |n|
62
+ Licensee::ProjectFiles::LicenseFile.name_score(n)
63
+ end
64
+ files = files.map do |file|
65
+ Licensee::ProjectFiles::LicenseFile.new(load_file(file), file)
66
+ end
67
+ prioritize_lgpl(files)
62
68
  end
63
- files = files.map do |file|
64
- Licensee::ProjectFiles::LicenseFile.new(load_file(file), file)
65
- end
66
-
67
- prioritize_lgpl(files)
68
69
  end
69
70
  end
70
71
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Licensee
4
- VERSION = '9.13.0'
4
+ VERSION = '9.15.0'
5
5
  end
data/licensee.gemspec CHANGED
@@ -21,26 +21,25 @@ Gem::Specification.new do |gem|
21
21
  gem.executables << 'licensee'
22
22
 
23
23
  gem.add_dependency('dotenv', '~> 2.0')
24
- gem.add_dependency('octokit', '~> 4.8')
24
+ gem.add_dependency('octokit', '~> 4.20')
25
25
  gem.add_dependency('reverse_markdown', '~> 1.0')
26
- gem.add_dependency('rugged', '~> 0.24')
27
- gem.add_dependency('thor', '~> 0.19')
26
+ gem.add_dependency('rugged', '>= 0.24', '<2.0')
27
+ gem.add_dependency('thor', '>= 0.19', '< 2.0')
28
28
 
29
+ gem.add_development_dependency('gem-release', '~> 2.0')
29
30
  gem.add_development_dependency('mustache', '>= 0.9', '< 2.0')
30
31
  gem.add_development_dependency('pry', '~> 0.9')
31
- gem.add_development_dependency('rake', '~> 10.3')
32
32
  gem.add_development_dependency('rspec', '~> 3.5')
33
- gem.add_development_dependency('rubocop', '~> 0.76')
33
+ gem.add_development_dependency('rubocop', '~> 1.0')
34
34
  gem.add_development_dependency('rubocop-performance', '~> 1.5')
35
- gem.add_development_dependency('rubocop-rspec', '~> 1.36')
35
+ gem.add_development_dependency('rubocop-rspec', '~> 2.0')
36
36
  gem.add_development_dependency('simplecov', '~> 0.16')
37
37
  gem.add_development_dependency('webmock', '~> 3.1')
38
38
 
39
- gem.required_ruby_version = '> 2.3'
39
+ gem.required_ruby_version = '>= 2.5'
40
40
 
41
41
  # ensure the gem is built out of versioned files
42
42
  gem.files = Dir[
43
- 'Rakefile',
44
43
  '{bin,lib,man,test,vendor,spec}/**/*',
45
44
  'README*', 'LICENSE*'
46
45
  ] & `git ls-files -z`.split("\0")