licensee 9.9.1 → 9.9.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/lib/licensee.rb +0 -1
  3. data/lib/licensee/commands/detect.rb +7 -7
  4. data/lib/licensee/content_helper.rb +11 -3
  5. data/lib/licensee/license.rb +1 -1
  6. data/lib/licensee/license_meta.rb +4 -0
  7. data/lib/licensee/matchers/dice.rb +11 -9
  8. data/lib/licensee/matchers/exact.rb +2 -2
  9. data/lib/licensee/matchers/matcher.rb +6 -0
  10. data/lib/licensee/project_files/license_file.rb +1 -1
  11. data/lib/licensee/project_files/project_file.rb +14 -1
  12. data/lib/licensee/projects/fs_project.rb +13 -10
  13. data/lib/licensee/projects/git_project.rb +9 -3
  14. data/lib/licensee/projects/project.rb +13 -13
  15. data/lib/licensee/version.rb +1 -1
  16. data/spec/fixtures/bsd-3-lists/LICENSE.BULLETS +27 -0
  17. data/spec/fixtures/bsd-3-lists/LICENSE.NUMBERS +27 -0
  18. data/spec/fixtures/detect.json +2 -2
  19. data/spec/integration_spec.rb +9 -0
  20. data/spec/licensee/content_helper_spec.rb +1 -1
  21. data/spec/licensee/license_meta_spec.rb +1 -1
  22. data/spec/licensee/license_spec.rb +1 -1
  23. data/spec/licensee/matchers/dice_matcher_spec.rb +5 -5
  24. data/spec/licensee/project_files/project_file_spec.rb +3 -3
  25. data/vendor/choosealicense.com/_licenses/agpl-3.0.txt +3 -3
  26. data/vendor/choosealicense.com/_licenses/cc0-1.0.txt +1 -1
  27. data/vendor/choosealicense.com/_licenses/ecl-2.0.txt +1 -1
  28. data/vendor/choosealicense.com/_licenses/epl-1.0.txt +1 -2
  29. data/vendor/choosealicense.com/_licenses/epl-2.0.txt +1 -1
  30. data/vendor/choosealicense.com/_licenses/gpl-3.0.txt +4 -4
  31. data/vendor/choosealicense.com/_licenses/lgpl-3.0.txt +1 -1
  32. data/vendor/choosealicense.com/_licenses/postgresql.txt +1 -1
  33. metadata +6 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 930a96d1bd7ed3b84fa727cf70d71740a5471500fdbdc3f5736f54eafd67e8e6
4
- data.tar.gz: af48a6336b6de9b1f97d344bfcff49dedb4169e31000a3a981ffbc43aa514cc3
3
+ metadata.gz: 9d245d544a683bfaff9448e8654a409cea3b6ddc808ba7f7b966c84e031255ea
4
+ data.tar.gz: 801c8048260b692571828fce99aa754afeb99063849e3e330e7fbb0b1b7117db
5
5
  SHA512:
6
- metadata.gz: f4f2e0f847843640551f0ac5369b13880a06326cfd262c8909a176722828ad0435f9ff803aaf4223550462d36d21f9535f4cf2bc9e23f299ec6d62454788c157
7
- data.tar.gz: f13add2cdd94ae3e02b0a55cb445d8c2e1b4907eea902860fee3a7508abd9f979da2dba73caddd56a468d724b36251cea7565e73b015fcb4ad5db3a629f24c90
6
+ metadata.gz: 918b6abcf12b00722fb85c64112f2e11334a4b43d6f3b7d3335156a6bb21b0077432030f6c132aa0950af0b4860102a9a1c2d8548a5de5e1529852ae13e29ed1
7
+ data.tar.gz: 919b0c1a4390a2dd964e7f4d245194ef47e108e1336fc4f04b9795a97f17475ebc64dce12ff1bbd97bb805f5d1fc95774ece1878af17a89f4d57cf974582944b
@@ -1,7 +1,6 @@
1
1
  require_relative 'licensee/version'
2
2
  require 'forwardable'
3
3
  require 'pathname'
4
- require 'rugged'
5
4
  require 'yaml'
6
5
 
7
6
  module Licensee
@@ -21,12 +21,12 @@ class LicenseeCLI < Thor
21
21
 
22
22
  rows = []
23
23
  rows << if project.license
24
- ['License:', project.license.spdx_id]
25
- elsif !project.licenses.empty?
26
- ['Licenses:', project.licenses.map(&:spdx_id)]
27
- else
28
- ['License:', set_color('None', :red)]
29
- end
24
+ ['License:', project.license.spdx_id]
25
+ elsif !project.licenses.empty?
26
+ ['Licenses:', project.licenses.map(&:spdx_id)]
27
+ else
28
+ ['License:', set_color('None', :red)]
29
+ end
30
30
 
31
31
  unless project.matched_files.empty?
32
32
  rows << ['Matched files:', project.matched_files.map(&:filename).join(', ')]
@@ -51,7 +51,7 @@ class LicenseeCLI < Thor
51
51
 
52
52
  licenses = licenses_by_similiarity(matched_file)
53
53
  next if licenses.empty?
54
- say ' Closest licenses:'
54
+ say ' Closest non-matching licenses:'
55
55
  rows = licenses[0...3].map do |license, similarity|
56
56
  spdx_id = license.meta['spdx-id']
57
57
  percent = Licensee::ContentHelper.format_percent(similarity)
@@ -13,6 +13,8 @@ module Licensee
13
13
  VERSION_REGEX = /\Aversion.*$/i
14
14
  MARKUP_REGEX = /[#_*=~\[\]()`|>]+/
15
15
  DEVELOPED_BY_REGEX = /\Adeveloped by:.*?\n\n/im
16
+ QUOTE_BEGIN_REGEX = /[`'"‘“]/
17
+ QUOTE_END_REGEX = /['"’”]/
16
18
 
17
19
  # A set of each word in the license, without duplicates
18
20
  def wordset
@@ -80,9 +82,10 @@ module Licensee
80
82
  string = strip_all_rights_reserved(string)
81
83
  string = strip_developed_by(string)
82
84
  string, _partition, _instructions = string.partition(END_OF_TERMS_REGEX)
83
- string = strip_markup(string)
85
+ string = normalize_lists(string)
84
86
  string = normalize_quotes(string)
85
87
  string = normalize_https(string)
88
+ string = strip_markup(string)
86
89
  strip_whitespace(string)
87
90
  end
88
91
 
@@ -173,15 +176,20 @@ module Licensee
173
176
  string.gsub(regex, ' ').squeeze(' ').strip
174
177
  end
175
178
 
176
- # Replace all single quotes with double quotes
179
+ # Replace all enclosing quotes with double quotes
177
180
  # Single versus double quotes don't alter the meaning, and it's easier to
178
181
  # strip double quotes if we still want to allow possessives
179
182
  def normalize_quotes(string)
180
- string.gsub(/\s'([\w -]*?\w)'/, ' "\1"')
183
+ string.gsub(/#{QUOTE_BEGIN_REGEX}+([\w -]*?\w)#{QUOTE_END_REGEX}+/,
184
+ '"\1"')
181
185
  end
182
186
 
183
187
  def normalize_https(string)
184
188
  string.gsub(/http:/, 'https:')
185
189
  end
190
+
191
+ def normalize_lists(string)
192
+ string.gsub(/^\s*(\d\.|\*)/, '-')
193
+ end
186
194
  end
187
195
  end
@@ -125,7 +125,7 @@ module Licensee
125
125
 
126
126
  # Returns the human-readable license name
127
127
  def name
128
- title ? title : key.capitalize
128
+ title || spdx_id
129
129
  end
130
130
 
131
131
  def name_without_version
@@ -53,5 +53,9 @@ module Licensee
53
53
  key = 'spdx_id' if key == 'spdx-id'
54
54
  super(key)
55
55
  end
56
+
57
+ def source
58
+ "https://spdx.org/licenses/#{spdx_id}.html" if spdx_id
59
+ end
56
60
  end
57
61
  end
@@ -18,9 +18,9 @@ module Licensee
18
18
  # that begin with the title of a non-open source CC license variant
19
19
  # 2. The percentage change in file length may not exceed the inverse
20
20
  # of the confidence threshold
21
- def potential_licenses
22
- @potential_licenses ||= begin
23
- Licensee.licenses(hidden: true).select do |license|
21
+ def potential_matches
22
+ @potential_matches ||= begin
23
+ super.select do |license|
24
24
  if license.creative_commons? && file.potential_false_positive?
25
25
  false
26
26
  else
@@ -29,18 +29,20 @@ module Licensee
29
29
  end
30
30
  end
31
31
  end
32
+ alias potential_licenses potential_matches
32
33
 
33
- def licenses_by_similiarity
34
- @licenses_by_similiarity ||= begin
35
- licenses = potential_licenses.map do |license|
36
- [license, license.similarity(file)]
34
+ def matches_by_similarity
35
+ @matches_by_similarity ||= begin
36
+ matches = potential_matches.map do |potential_match|
37
+ [potential_match, potential_match.similarity(file)]
37
38
  end
38
- licenses.sort_by { |_, similarity| similarity }.reverse
39
+ matches.sort_by { |_, similarity| similarity }.reverse
39
40
  end
40
41
  end
42
+ alias licenses_by_similarity matches_by_similarity
41
43
 
42
44
  def matches
43
- @matches ||= licenses_by_similiarity.select do |_, similarity|
45
+ @matches ||= matches_by_similarity.select do |_, similarity|
44
46
  similarity >= Licensee.confidence_threshold
45
47
  end
46
48
  end
@@ -3,8 +3,8 @@ module Licensee
3
3
  class Exact < Licensee::Matchers::Matcher
4
4
  def match
5
5
  return @match if defined? @match
6
- @match = Licensee.licenses(hidden: true).find do |license|
7
- license.length == @file.length && license.wordset == @file.wordset
6
+ @match = potential_matches.find do |potential_match|
7
+ potential_match.wordset == file.wordset
8
8
  end
9
9
  end
10
10
 
@@ -21,6 +21,12 @@ module Licensee
21
21
  def confidence
22
22
  raise 'Not implemented'
23
23
  end
24
+
25
+ private
26
+
27
+ def potential_matches
28
+ @potential_matches ||= Licensee.licenses(hidden: true)
29
+ end
24
30
  end
25
31
  end
26
32
  end
@@ -8,7 +8,7 @@ module Licensee
8
8
  PREFERRED_EXT_REGEX = /\.#{Regexp.union(PREFERRED_EXT)}\z/
9
9
 
10
10
  # Regex to match any extension except .spdx or .header
11
- OTHER_EXT_REGEX = %r{\.(?!spdx|header)[^./]+\z}i
11
+ OTHER_EXT_REGEX = %r{\.(?!spdx|header|gemspec)[^./]+\z}i
12
12
 
13
13
  # Regex to match, LICENSE, LICENCE, unlicense, etc.
14
14
  LICENSE_REGEX = /(un)?licen[sc]e/i
@@ -42,9 +42,23 @@ module Licensee
42
42
  @data = metadata || {}
43
43
  end
44
44
 
45
+ # TODO: In the next major release, filename should be the basename
46
+ # and path should be either the absolute path or the relative path to
47
+ # the project root, but maintaining the alias for backward compatability
45
48
  def filename
46
49
  @data[:name]
47
50
  end
51
+ alias path filename
52
+
53
+ def directory
54
+ @data[:dir] || '.'
55
+ end
56
+ alias dir directory
57
+
58
+ def path_relative_to_root
59
+ File.join(directory, filename)
60
+ end
61
+ alias relative_path path_relative_to_root
48
62
 
49
63
  def possible_matchers
50
64
  raise 'Not implemented'
@@ -64,7 +78,6 @@ module Licensee
64
78
  end
65
79
 
66
80
  alias match license
67
- alias path filename
68
81
 
69
82
  def matched_license
70
83
  license.spdx_id if license
@@ -10,14 +10,14 @@ module Licensee
10
10
  class FSProject < Licensee::Projects::Project
11
11
  def initialize(path, **args)
12
12
  if ::File.file?(path)
13
- @pattern = ::File.basename(path)
14
- @dir = ::File.dirname(path)
13
+ @pattern = File.basename(path)
14
+ @dir = File.expand_path File.dirname(path)
15
15
  else
16
16
  @pattern = '*'
17
- @dir = path
17
+ @dir = File.expand_path(path)
18
18
  end
19
19
 
20
- @root = args.delete(:search_root) || @dir
20
+ @root = File.expand_path(args.delete(:search_root) || @dir)
21
21
  unless valid_search_root?
22
22
  raise 'Search root must be the project path directory or its ancestor'
23
23
  end
@@ -33,9 +33,10 @@ module Licensee
33
33
  # :dir - the directory path containing the file
34
34
  def files
35
35
  @files ||= search_directories.flat_map do |dir|
36
+ relative_dir = Pathname.new(dir).relative_path_from(dir_path).to_s
36
37
  Dir.glob(::File.join(dir, @pattern).tr('\\', '/')).map do |file|
37
38
  next unless ::File.file?(file)
38
- { name: ::File.basename(file), dir: dir }
39
+ { name: ::File.basename(file), dir: relative_dir }
39
40
  end.compact
40
41
  end
41
42
  end
@@ -46,13 +47,12 @@ module Licensee
46
47
  #
47
48
  # Returns the file contents as a string
48
49
  def load_file(file)
49
- ::File.read(::File.join(file[:dir], file[:name]))
50
+ File.read dir_path.join(file[:dir], file[:name])
50
51
  end
51
52
 
52
53
  # Returns true if @dir is @root or it's descendant
53
54
  def valid_search_root?
54
- dir = Pathname.new(@dir)
55
- dir.fnmatch?(@root) || dir.fnmatch?(::File.join(@root, '**'))
55
+ dir_path.fnmatch?(@root) || dir_path.fnmatch?(::File.join(@root, '**'))
56
56
  end
57
57
 
58
58
  # Returns the set of unique paths to search for project files
@@ -66,13 +66,16 @@ module Licensee
66
66
  # Enumerates all directories to search, from @dir to @root
67
67
  def search_enumerator
68
68
  root = Pathname.new(@root)
69
- dir = Pathname.new(@dir)
70
69
  Enumerator.new do |yielder|
71
- dir.relative_path_from(root).ascend do |relative|
70
+ dir_path.relative_path_from(root).ascend do |relative|
72
71
  yielder.yield root.join(relative)
73
72
  end
74
73
  end
75
74
  end
75
+
76
+ def dir_path
77
+ @dir_path ||= Pathname.new(@dir)
78
+ end
76
79
  end
77
80
  end
78
81
  end
@@ -5,6 +5,9 @@
5
5
  # Project files for this project type will contain the following keys:
6
6
  # :name - the file's path relative to the repo root
7
7
  # :oid - the file's OID
8
+
9
+ autoload :Rugged, 'rugged'
10
+
8
11
  module Licensee
9
12
  module Projects
10
13
  class GitProject < Licensee::Projects::Project
@@ -56,9 +59,12 @@ module Licensee
56
59
  # :name - the file's path relative to the repo root
57
60
  # :oid - the file's OID
58
61
  def files
59
- @files ||= commit.tree.map do |entry|
60
- next unless entry[:type] == :blob
61
- { name: entry[:name], oid: entry[:oid] }
62
+ @files ||= files_from_tree(commit.tree)
63
+ end
64
+
65
+ def files_from_tree(tree, dir = '.')
66
+ tree.select { |e| e[:type] == :blob }.map do |entry|
67
+ entry.merge(dir: dir)
62
68
  end.compact
63
69
  end
64
70
  end
@@ -68,13 +68,13 @@ module Licensee
68
68
  return unless detect_readme?
69
69
  return @readme if defined? @readme
70
70
  @readme = begin
71
- content, name = find_file do |n|
71
+ content, file = find_file do |n|
72
72
  Licensee::ProjectFiles::ReadmeFile.name_score(n)
73
73
  end
74
74
  content = Licensee::ProjectFiles::ReadmeFile.license_content(content)
75
75
 
76
- return unless content && name
77
- Licensee::ProjectFiles::ReadmeFile.new(content, name)
76
+ return unless content && file
77
+ Licensee::ProjectFiles::ReadmeFile.new(content, file)
78
78
  end
79
79
  end
80
80
  alias readme readme_file
@@ -83,12 +83,12 @@ module Licensee
83
83
  return unless detect_packages?
84
84
  return @package_file if defined? @package_file
85
85
  @package_file = begin
86
- content, name = find_file do |n|
86
+ content, file = find_file do |n|
87
87
  Licensee::ProjectFiles::PackageManagerFile.name_score(n)
88
88
  end
89
89
 
90
- return unless content && name
91
- Licensee::ProjectFiles::PackageManagerFile.new(content, name)
90
+ return unless content && file
91
+ Licensee::ProjectFiles::PackageManagerFile.new(content, file)
92
92
  end
93
93
  end
94
94
 
@@ -115,7 +115,7 @@ module Licensee
115
115
  def find_file(&block)
116
116
  return if files.empty? || files.nil?
117
117
  file = find_files(&block).first
118
- [load_file(file), file[:name]] if file
118
+ [load_file(file), file] if file
119
119
  end
120
120
 
121
121
  # Given an array of LicenseFiles, ensures LGPL is the first entry,
@@ -147,14 +147,14 @@ module Licensee
147
147
  matched_files.reject(&:copyright?).map(&:license).uniq
148
148
  end
149
149
  end
150
- end
151
150
 
152
- def files
153
- raise 'Not implemented'
154
- end
151
+ def files
152
+ raise 'Not implemented'
153
+ end
155
154
 
156
- def load_file(_file)
157
- raise 'Not implemented'
155
+ def load_file(_file)
156
+ raise 'Not implemented'
157
+ end
158
158
  end
159
159
  end
160
160
  end
@@ -1,3 +1,3 @@
1
1
  module Licensee
2
- VERSION = '9.9.1'.freeze
2
+ VERSION = '9.9.3'.freeze
3
3
  end
@@ -0,0 +1,27 @@
1
+ Copyright (c) 2018, Ben Balter
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+
7
+ * Redistributions of source code must retain the above copyright notice, this
8
+ list of conditions and the following disclaimer.
9
+
10
+ * Redistributions in binary form must reproduce the above copyright notice,
11
+ this list of conditions and the following disclaimer in the documentation
12
+ and/or other materials provided with the distribution.
13
+
14
+ * Neither the name of the copyright holder nor the names of its
15
+ contributors may be used to endorse or promote products derived from
16
+ this software without specific prior written permission.
17
+
18
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,27 @@
1
+ Copyright (c) 2018, Ben Balter
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+
7
+ 1. Redistributions of source code must retain the above copyright notice, this
8
+ list of conditions and the following disclaimer.
9
+
10
+ 2. Redistributions in binary form must reproduce the above copyright notice,
11
+ this list of conditions and the following disclaimer in the documentation
12
+ and/or other materials provided with the distribution.
13
+
14
+ 3. Neither the name of the copyright holder nor the names of its
15
+ contributors may be used to endorse or promote products derived from
16
+ this software without specific prior written permission.
17
+
18
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -5,7 +5,7 @@
5
5
  "spdx_id": "MIT",
6
6
  "meta": {
7
7
  "title": "MIT License",
8
- "source": "https://opensource.org/licenses/MIT",
8
+ "source": "https://spdx.org/licenses/MIT.html",
9
9
  "description": "A short and simple permissive license with conditions only requiring preservation of copyright and license notices. Licensed works, modifications, and larger works may be distributed under different terms and without source code.",
10
10
  "how": "Create a text file (typically named LICENSE or LICENSE.txt) in the root of your source code and copy the text of the license into the file. Replace [year] with the current year and [fullname] with the name (or names) of the copyright holders.",
11
11
  "using": [
@@ -98,7 +98,7 @@
98
98
  },
99
99
  {
100
100
  "filename": "licensee.gemspec",
101
- "content": "require File.expand_path('lib/licensee/version', __dir__)\n\nGem::Specification.new do |gem|\n gem.name = 'licensee'\n gem.version = Licensee::VERSION\n\n gem.summary = 'A Ruby Gem to detect open source project licenses'\n gem.description = <<-DESC\n Licensee automates the process of reading LICENSE files and\n compares their contents to known licenses using a fancy maths.\n DESC\n\n gem.authors = ['Ben Balter']\n gem.email = 'ben.balter@github.com'\n gem.homepage = 'https://github.com/benbalter/licensee'\n gem.license = 'MIT'\n\n gem.bindir = 'bin'\n gem.executables << 'licensee'\n\n gem.add_dependency('dotenv', '~> 2.0')\n gem.add_dependency('octokit', '~> 4.8.0')\n gem.add_dependency('rugged', '~> 0.24')\n gem.add_dependency('thor', '~> 0.19')\n\n gem.add_development_dependency('coveralls', '~> 0.8')\n gem.add_development_dependency('mustache', '>= 0.9', '< 2.0')\n gem.add_development_dependency('pry', '~> 0.9')\n gem.add_development_dependency('rake', '~> 10.3')\n gem.add_development_dependency('rspec', '~> 3.5')\n gem.add_development_dependency('rubocop', '~> 0.49')\n gem.add_development_dependency('webmock', '~> 3.1')\n\n gem.required_ruby_version = '>= 2.1'\n\n # ensure the gem is built out of versioned files\n gem.files = Dir[\n 'Rakefile',\n '{bin,lib,man,test,vendor,spec}/**/*',\n 'README*', 'LICENSE*'\n ] & `git ls-files -z`.split(\"\\0\")\nend\n",
101
+ "content": "require File.expand_path('lib/licensee/version', __dir__)\n\nGem::Specification.new do |gem|\n gem.name = 'licensee'\n gem.version = Licensee::VERSION\n\n gem.summary = 'A Ruby Gem to detect open source project licenses'\n gem.description = <<-DESC\n Licensee automates the process of reading LICENSE files and\n compares their contents to known licenses using a fancy maths.\n DESC\n\n gem.authors = ['Ben Balter']\n gem.email = 'ben.balter@github.com'\n gem.homepage = 'https://github.com/benbalter/licensee'\n gem.license = 'MIT'\n\n gem.bindir = 'bin'\n gem.executables << 'licensee'\n\n gem.add_dependency('dotenv', '~> 2.0')\n gem.add_dependency('octokit', '~> 4.8.0')\n gem.add_dependency('rugged', '~> 0.24')\n gem.add_dependency('thor', '~> 0.19')\n\n gem.add_development_dependency('coveralls', '~> 0.8')\n gem.add_development_dependency('mustache', '>= 0.9', '< 2.0')\n gem.add_development_dependency('pry', '~> 0.9')\n gem.add_development_dependency('rake', '~> 10.3')\n gem.add_development_dependency('rspec', '~> 3.5')\n gem.add_development_dependency('rubocop', '~> 0.49')\n gem.add_development_dependency('webmock', '~> 3.1')\n\n gem.required_ruby_version = '> 2.2'\n\n # ensure the gem is built out of versioned files\n gem.files = Dir[\n 'Rakefile',\n '{bin,lib,man,test,vendor,spec}/**/*',\n 'README*', 'LICENSE*'\n ] & `git ls-files -z`.split(\"\\0\")\nend\n",
102
102
  "content_hash": null,
103
103
  "content_normalized": null,
104
104
  "matcher": {
@@ -186,6 +186,15 @@ RSpec.describe 'integration test' do
186
186
  expect(subject.license).to eql(license)
187
187
  end
188
188
  end
189
+
190
+ context 'BSD-3-Clause numbered and bulleted' do
191
+ let(:license) { Licensee::License.find('bsd-3-clause') }
192
+ let(:fixture) { 'bsd-3-lists' }
193
+
194
+ it 'determines the project is BSD-3-Clause' do
195
+ expect(subject.license).to eql(license)
196
+ end
197
+ end
189
198
  end
190
199
 
191
200
  context 'with the license file stubbed' do
@@ -25,7 +25,7 @@ RSpec.describe Licensee::ContentHelper do
25
25
  This license provided 'as is'. Please respect the contributors' wishes when
26
26
  implementing the license's "software".
27
27
  -----------
28
- LICENSE
28
+ LICENSE
29
29
  end
30
30
  subject { ContentHelperTestHelper.new(content) }
31
31
  let(:mit) { Licensee::License.find('mit') }
@@ -126,7 +126,7 @@ RSpec.describe Licensee::LicenseMeta do
126
126
  let(:expected) do
127
127
  {
128
128
  title: 'MIT License',
129
- source: 'https://opensource.org/licenses/MIT',
129
+ source: 'https://spdx.org/licenses/MIT.html',
130
130
  description: subject.description.to_s,
131
131
  how: subject.how.to_s,
132
132
  using: using,
@@ -201,7 +201,7 @@ RSpec.describe Licensee::License do
201
201
  end
202
202
 
203
203
  it 'uses the default name when none exists' do
204
- expect(other.name).to eql('Other')
204
+ expect(other.name).to eql('NOASSERTION')
205
205
  end
206
206
 
207
207
  it 'expoeses the nickname' do
@@ -17,17 +17,17 @@ RSpec.describe Licensee::Matchers::Dice do
17
17
  end
18
18
 
19
19
  it 'builds a list of potential licenses' do
20
- expect(subject.potential_licenses).to eql([agpl, gpl])
20
+ expect(subject.potential_matches).to eql([agpl, gpl])
21
21
  end
22
22
 
23
23
  it 'sorts licenses by similarity' do
24
- expect(subject.licenses_by_similiarity[0]).to eql([gpl, 100.0])
25
- expect(subject.licenses_by_similiarity[1]).to eql([agpl, 95.73361082206036])
24
+ expect(subject.matches_by_similarity[0]).to eql([gpl, 100.0])
25
+ expect(subject.matches_by_similarity[1]).to eql([agpl, 95.76581285938317])
26
26
  end
27
27
 
28
28
  it 'returns a list of licenses above the confidence threshold' do
29
- expect(subject.licenses_by_similiarity[0]).to eql([gpl, 100.0])
30
- expect(subject.licenses_by_similiarity[1]).to eql([agpl, 95.73361082206036])
29
+ expect(subject.matches_by_similarity[0]).to eql([gpl, 100.0])
30
+ expect(subject.matches_by_similarity[1]).to eql([agpl, 95.76581285938317])
31
31
  end
32
32
 
33
33
  it 'returns the match confidence' do
@@ -4,7 +4,7 @@ RSpec.describe Licensee::ProjectFiles::ProjectFile do
4
4
  let(:content) { mit.content }
5
5
  let(:possible_matchers) { [Licensee::Matchers::Exact] }
6
6
 
7
- subject { described_class.new(content, filename) }
7
+ subject { Licensee::ProjectFiles::LicenseFile.new(content, filename) }
8
8
  before do
9
9
  allow(subject).to receive(:possible_matchers).and_return(possible_matchers)
10
10
  end
@@ -50,8 +50,8 @@ RSpec.describe Licensee::ProjectFiles::ProjectFile do
50
50
  {
51
51
  filename: 'LICENSE.txt',
52
52
  content: mit.content.to_s,
53
- content_hash: nil,
54
- content_normalized: nil,
53
+ content_hash: subject.content_hash,
54
+ content_normalized: subject.content_normalized,
55
55
  matcher: {
56
56
  name: :exact,
57
57
  confidence: 100
@@ -37,7 +37,7 @@ limitations:
37
37
  GNU AFFERO GENERAL PUBLIC LICENSE
38
38
  Version 3, 19 November 2007
39
39
 
40
- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
40
+ Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
41
41
  Everyone is permitted to copy and distribute verbatim copies
42
42
  of this license document, but changing it is not allowed.
43
43
 
@@ -679,7 +679,7 @@ the "copyright" line and a pointer to where the full notice is found.
679
679
  GNU Affero General Public License for more details.
680
680
 
681
681
  You should have received a copy of the GNU Affero General Public License
682
- along with this program. If not, see <http://www.gnu.org/licenses/>.
682
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
683
683
 
684
684
  Also add information on how to contact you by electronic and paper mail.
685
685
 
@@ -694,4 +694,4 @@ specific requirements.
694
694
  You should also get your employer (if you work as a programmer) or school,
695
695
  if any, to sign a "copyright disclaimer" for the program, if necessary.
696
696
  For more information on this, and how to apply and follow the GNU AGPL, see
697
- <http://www.gnu.org/licenses/>.
697
+ <https://www.gnu.org/licenses/>.
@@ -4,7 +4,7 @@ spdx-id: CC0-1.0
4
4
  redirect_from: /licenses/cc0/
5
5
  source: https://creativecommons.org/publicdomain/zero/1.0/
6
6
 
7
- description: The <a href="https://creativecommons.org/publicdomain/zero/1.0/">Creative Commons CC0 Public Domain Dedication</a> waives copyright interest in any a work you've created and dedicates it to the world-wide public domain. Use CC0 to opt out of copyright entirely and ensure your work has the widest reach. As with the Unlicense and typical software licenses, CC0 disclaims warranties. CC0 is very similar to the Unlicense.
7
+ description: The <a href="https://creativecommons.org/publicdomain/zero/1.0/">Creative Commons CC0 Public Domain Dedication</a> waives copyright interest in a work you've created and dedicates it to the world-wide public domain. Use CC0 to opt out of copyright entirely and ensure your work has the widest reach. As with the Unlicense and typical software licenses, CC0 disclaims warranties. CC0 is very similar to the Unlicense.
8
8
 
9
9
  how: Create a text file (typically named LICENSE or LICENSE.txt) in the root of your source code and copy the text of the CC0 into the file.
10
10
 
@@ -12,7 +12,7 @@ note: The Apereo Foundation recommends taking the additional step of adding a bo
12
12
  using:
13
13
  - Sakai: https://github.com/sakaiproject/sakai/blob/master/LICENSE
14
14
  - OAE: https://github.com/oaeproject/Hilary/blob/master/LICENSE
15
- - Opencast: https://bitbucket.org/opencast-community/opencast/src/905077ba5e6483f8c49869a1fc13bf9268790a79/LICENSE
15
+ - Opencast: https://github.com/opencast/opencast/blob/develop/LICENSE
16
16
 
17
17
  permissions:
18
18
  - commercial-use
@@ -2,14 +2,13 @@
2
2
  title: Eclipse Public License 1.0
3
3
  spdx-id: EPL-1.0
4
4
  source: https://www.eclipse.org/legal/epl-v10.html
5
- hidden: true
6
5
 
7
6
  description: This commercially-friendly copyleft license provides the ability to commercially license binaries; a modern royalty-free patent license grant; and the ability for linked works to use other licenses, including commercial ones.
8
7
 
9
8
  how: Create a text file (typically named LICENSE or LICENSE.txt) in the root of your source code and copy the text of the license into the file.
10
9
 
11
10
  using:
12
- - Eclipse Che: https://github.com/eclipse/che/blob/master/LICENSE
11
+ - Eclipse hawkBit: https://github.com/eclipse/hawkbit/blob/master/LICENSE
13
12
  - JUnit: https://github.com/junit-team/junit4/blob/master/LICENSE-junit.txt
14
13
  - openHAB: https://github.com/openhab/openhab-distro/blob/master/LICENSE
15
14
 
@@ -12,7 +12,7 @@ how: Create a text file (typically named LICENSE or LICENSE.txt) in the root of
12
12
  using:
13
13
  - Eclipse Ditto: https://github.com/eclipse/ditto/blob/master/LICENSE
14
14
  - Eclipse SmartHome: https://github.com/eclipse/smarthome/blob/master/LICENSE
15
- - SUMO: https://github.com/DLR-TS/sumo/blob/master/COPYING
15
+ - SUMO: https://github.com/eclipse/sumo/blob/master/LICENSE
16
16
 
17
17
  permissions:
18
18
  - commercial-use
@@ -40,7 +40,7 @@ limitations:
40
40
  GNU GENERAL PUBLIC LICENSE
41
41
  Version 3, 29 June 2007
42
42
 
43
- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
43
+ Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
44
44
  Everyone is permitted to copy and distribute verbatim copies
45
45
  of this license document, but changing it is not allowed.
46
46
 
@@ -684,7 +684,7 @@ the "copyright" line and a pointer to where the full notice is found.
684
684
  GNU General Public License for more details.
685
685
 
686
686
  You should have received a copy of the GNU General Public License
687
- along with this program. If not, see <http://www.gnu.org/licenses/>.
687
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
688
688
 
689
689
  Also add information on how to contact you by electronic and paper mail.
690
690
 
@@ -703,11 +703,11 @@ might be different; for a GUI interface, you would use an "about box".
703
703
  You should also get your employer (if you work as a programmer) or school,
704
704
  if any, to sign a "copyright disclaimer" for the program, if necessary.
705
705
  For more information on this, and how to apply and follow the GNU GPL, see
706
- <http://www.gnu.org/licenses/>.
706
+ <https://www.gnu.org/licenses/>.
707
707
 
708
708
  The GNU General Public License does not permit incorporating your program
709
709
  into proprietary programs. If your program is a subroutine library, you
710
710
  may consider it more useful to permit linking proprietary applications with
711
711
  the library. If this is what you want to do, use the GNU Lesser General
712
712
  Public License instead of this License. But first, please read
713
- <http://www.gnu.org/philosophy/why-not-lgpl.html>.
713
+ <https://www.gnu.org/licenses/why-not-lgpl.html>.
@@ -36,7 +36,7 @@ limitations:
36
36
  GNU LESSER GENERAL PUBLIC LICENSE
37
37
  Version 3, 29 June 2007
38
38
 
39
- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
39
+ Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
40
40
  Everyone is permitted to copy and distribute verbatim copies
41
41
  of this license document, but changing it is not allowed.
42
42
 
@@ -10,7 +10,7 @@ how: To use it, say that it is The PostgreSQL License, and then substitute the c
10
10
  using:
11
11
  - pgBadger: https://github.com/dalibo/pgbadger/blob/master/LICENSE
12
12
  - pgAdmin: https://github.com/postgres/pgadmin4/blob/master/LICENSE
13
- - .NET Access to PostgreSQL: https://github.com/npgsql/npgsql/blob/dev/LICENSE.txt
13
+ - .NET Access to PostgreSQL: https://github.com/npgsql/npgsql/blob/dev/LICENSE
14
14
 
15
15
  permissions:
16
16
  - commercial-use
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: licensee
3
3
  version: !ruby/object:Gem::Version
4
- version: 9.9.1
4
+ version: 9.9.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ben Balter
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-06-04 00:00:00.000000000 Z
11
+ date: 2018-08-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dotenv
@@ -222,6 +222,8 @@ files:
222
222
  - spec/fixtures/apache-with-readme-notice/LICENSE
223
223
  - spec/fixtures/apache-with-readme-notice/LICENSE.header
224
224
  - spec/fixtures/apache-with-readme-notice/README.md
225
+ - spec/fixtures/bsd-3-lists/LICENSE.BULLETS
226
+ - spec/fixtures/bsd-3-lists/LICENSE.NUMBERS
225
227
  - spec/fixtures/bsd-plus-patents/PATENTS
226
228
  - spec/fixtures/bsd-plus-patents/license.txt
227
229
  - spec/fixtures/bsl/LICENSE_1_0.txt
@@ -335,9 +337,9 @@ require_paths:
335
337
  - lib
336
338
  required_ruby_version: !ruby/object:Gem::Requirement
337
339
  requirements:
338
- - - ">="
340
+ - - ">"
339
341
  - !ruby/object:Gem::Version
340
- version: '2.1'
342
+ version: '2.2'
341
343
  required_rubygems_version: !ruby/object:Gem::Requirement
342
344
  requirements:
343
345
  - - ">="