licensee 6.1.1 → 7.0.0

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 (64) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +2 -2
  3. data/bin/licensee +7 -4
  4. data/lib/licensee.rb +25 -22
  5. data/lib/licensee/content_helper.rb +5 -4
  6. data/lib/licensee/license.rb +56 -45
  7. data/lib/licensee/matchers/copyright_matcher.rb +2 -2
  8. data/lib/licensee/matchers/dice_matcher.rb +7 -4
  9. data/lib/licensee/matchers/exact_matcher.rb +2 -2
  10. data/lib/licensee/matchers/gemspec_matcher.rb +5 -2
  11. data/lib/licensee/matchers/npm_bower_matcher.rb +5 -2
  12. data/lib/licensee/matchers/package_matcher.rb +2 -2
  13. data/lib/licensee/project.rb +21 -96
  14. data/lib/licensee/project_file.rb +6 -7
  15. data/lib/licensee/project_files/license_file.rb +3 -3
  16. data/lib/licensee/project_files/package_info.rb +7 -7
  17. data/lib/licensee/project_files/readme.rb +24 -0
  18. data/lib/licensee/projects/fs_project.rb +32 -0
  19. data/lib/licensee/projects/git_project.rb +55 -0
  20. data/lib/licensee/version.rb +2 -2
  21. data/test/fixtures/bower-with-readme/README.md +1 -0
  22. data/test/fixtures/bower-with-readme/bower.json +3 -0
  23. data/test/functions.rb +23 -12
  24. data/test/helper.rb +5 -0
  25. data/test/test_licensee.rb +9 -8
  26. data/test/test_licensee_bin.rb +11 -5
  27. data/test/test_licensee_copyright_matcher.rb +23 -23
  28. data/test/test_licensee_dice_matcher.rb +5 -5
  29. data/test/test_licensee_exact_matcher.rb +4 -4
  30. data/test/test_licensee_gemspec_matcher.rb +4 -4
  31. data/test/test_licensee_license.rb +82 -70
  32. data/test/test_licensee_license_file.rb +30 -28
  33. data/test/test_licensee_npm_bower_matcher.rb +11 -11
  34. data/test/test_licensee_package_info.rb +8 -7
  35. data/test/test_licensee_project.rb +45 -37
  36. data/test/test_licensee_project_file.rb +9 -9
  37. data/test/test_licensee_readme.rb +47 -0
  38. data/test/test_licensee_vendor.rb +10 -7
  39. data/vendor/choosealicense.com/_licenses/afl-3.0.txt +0 -3
  40. data/vendor/choosealicense.com/_licenses/agpl-3.0.txt +5 -5
  41. data/vendor/choosealicense.com/_licenses/apache-2.0.txt +1 -2
  42. data/vendor/choosealicense.com/_licenses/artistic-2.0.txt +14 -13
  43. data/vendor/choosealicense.com/_licenses/bsd-2-clause.txt +2 -3
  44. data/vendor/choosealicense.com/_licenses/bsd-3-clause-clear.txt +0 -6
  45. data/vendor/choosealicense.com/_licenses/bsd-3-clause.txt +2 -4
  46. data/vendor/choosealicense.com/_licenses/cc0-1.0.txt +2 -1
  47. data/vendor/choosealicense.com/_licenses/epl-1.0.txt +2 -1
  48. data/vendor/choosealicense.com/_licenses/eupl-1.1.txt +345 -0
  49. data/vendor/choosealicense.com/_licenses/gpl-2.0.txt +5 -5
  50. data/vendor/choosealicense.com/_licenses/gpl-3.0.txt +5 -4
  51. data/vendor/choosealicense.com/_licenses/isc.txt +1 -2
  52. data/vendor/choosealicense.com/_licenses/lgpl-2.1.txt +5 -6
  53. data/vendor/choosealicense.com/_licenses/lgpl-3.0.txt +8 -8
  54. data/vendor/choosealicense.com/_licenses/lppl-1.3c.txt +445 -0
  55. data/vendor/choosealicense.com/_licenses/mit.txt +1 -1
  56. data/vendor/choosealicense.com/_licenses/mpl-2.0.txt +2 -1
  57. data/vendor/choosealicense.com/_licenses/ms-pl.txt +0 -1
  58. data/vendor/choosealicense.com/_licenses/ms-rl.txt +1 -1
  59. data/vendor/choosealicense.com/_licenses/ofl-1.1.txt +1 -2
  60. data/vendor/choosealicense.com/_licenses/osl-3.0.txt +1 -3
  61. data/vendor/choosealicense.com/_licenses/unlicense.txt +1 -2
  62. data/vendor/choosealicense.com/_licenses/wtfpl.txt +0 -2
  63. metadata +33 -11
  64. data/vendor/choosealicense.com/_licenses/no-license.txt +0 -25
@@ -1,4 +1,4 @@
1
- class Licensee
1
+ module Licensee
2
2
  module Matchers
3
3
  class Package
4
4
  def initialize(file)
@@ -6,7 +6,7 @@ class Licensee
6
6
  end
7
7
 
8
8
  def match
9
- Licensee.licenses(:hidden => true).find { |l| l.key == license_property }
9
+ Licensee.licenses(hidden: true).find { |l| l.key == license_property }
10
10
  end
11
11
 
12
12
  def confidence
@@ -1,32 +1,40 @@
1
1
  require 'rugged'
2
2
 
3
- class Licensee
4
- private
3
+ module Licensee
5
4
  class Project
6
- def initialize(detect_packages)
7
- @detect_packages = detect_packages
8
- end
5
+ attr_reader :detect_readme, :detect_packages
6
+ alias detect_readme? detect_readme
7
+ alias detect_packages? detect_packages
9
8
 
10
- def detect_packages?
11
- @detect_packages
9
+ def initialize(detect_packages: false, detect_readme: false)
10
+ @detect_packages = detect_packages
11
+ @detect_readme = detect_readme
12
12
  end
13
13
 
14
- # Returns the matching Licensee::License instance if a license can be detected
14
+ # Returns the matching License instance if a license can be detected
15
15
  def license
16
16
  @license ||= matched_file && matched_file.license
17
17
  end
18
18
 
19
19
  def matched_file
20
- @matched_file ||= (license_file || package_file)
20
+ @matched_file ||= (license_file || readme || package_file)
21
21
  end
22
22
 
23
23
  def license_file
24
24
  return @license_file if defined? @license_file
25
25
  @license_file = begin
26
26
  content, name = find_file { |name| LicenseFile.name_score(name) }
27
- if content && name
28
- LicenseFile.new(content, name)
29
- end
27
+ LicenseFile.new(content, name) if content && name
28
+ end
29
+ end
30
+
31
+ def readme
32
+ return unless detect_readme?
33
+ return @readme if defined? @readme
34
+ @readme = begin
35
+ content, name = find_file { |name| Readme.name_score(name) }
36
+ content = Readme.license_content(content)
37
+ Readme.new(content, name) if content && name
30
38
  end
31
39
  end
32
40
 
@@ -35,91 +43,8 @@ class Licensee
35
43
  return @package_file if defined? @package_file
36
44
  @package_file = begin
37
45
  content, name = find_file { |name| PackageInfo.name_score(name) }
38
- if content && name
39
- PackageInfo.new(content, name)
40
- end
46
+ PackageInfo.new(content, name) if content && name
41
47
  end
42
48
  end
43
49
  end
44
-
45
- public
46
-
47
- # Git-based project
48
- #
49
- # analyze a given git repository for license information
50
- class GitProject < Project
51
- attr_reader :repository, :revision
52
-
53
- class InvalidRepository < ArgumentError; end
54
-
55
- def initialize(repo, revision: nil, detect_packages: false)
56
- if repo.kind_of? Rugged::Repository
57
- @repository = repo
58
- else
59
- @repository = Rugged::Repository.new(repo)
60
- end
61
-
62
- @revision = revision
63
- super(detect_packages)
64
- rescue Rugged::RepositoryError
65
- raise InvalidRepository
66
- end
67
-
68
- private
69
- def commit
70
- @commit ||= revision ? repository.lookup(revision) : repository.last_commit
71
- end
72
-
73
- MAX_LICENSE_SIZE = 64 * 1024
74
-
75
- def load_blob_data(oid)
76
- data, _ = Rugged::Blob.to_buffer(repository, oid, MAX_LICENSE_SIZE)
77
- data
78
- end
79
-
80
- def find_file
81
- files = commit.tree.map do |entry|
82
- next unless entry[:type] == :blob
83
- if (score = yield entry[:name]) > 0
84
- { :name => entry[:name], :oid => entry[:oid], :score => score }
85
- end
86
- end.compact
87
-
88
- return if files.empty?
89
- files.sort! { |a, b| b[:score] <=> a[:score] }
90
-
91
- f = files.first
92
- [load_blob_data(f[:oid]), f[:name]]
93
- end
94
- end
95
-
96
- # Filesystem-based project
97
- #
98
- # Analyze a folder on the filesystem for license information
99
- class FSProject < Project
100
- attr_reader :path
101
-
102
- def initialize(path, detect_packages: false)
103
- @path = path
104
- super(detect_packages)
105
- end
106
-
107
- private
108
- def find_file
109
- files = []
110
-
111
- Dir.foreach(path) do |file|
112
- next unless ::File.file?(::File.join(path, file))
113
- if (score = yield file) > 0
114
- files.push({ :name => file, :score => score })
115
- end
116
- end
117
-
118
- return if files.empty?
119
- files.sort! { |a, b| b[:score] <=> a[:score] }
120
-
121
- f = files.first
122
- [::File.read(::File.join(path, f[:name])), f[:name]]
123
- end
124
- end
125
50
  end
@@ -1,18 +1,17 @@
1
- class Licensee
1
+ module Licensee
2
2
  class Project
3
- private
4
-
5
3
  class File
6
4
  attr_reader :content, :filename
7
5
 
8
6
  def initialize(content, filename = nil)
9
7
  @content = content
10
- @content.encode!(Encoding::UTF_8, :invalid => :replace, :undef => :replace, :replace => "")
8
+ options = { invalid: :replace, undef: :replace, replace: '' }
9
+ @content.encode!(Encoding::UTF_8, options)
11
10
  @filename = filename
12
11
  end
13
12
 
14
13
  def matcher
15
- @matcher ||= possible_matchers.map { |m| m.new(self) }.find { |m| m.match }
14
+ @matcher ||= possible_matchers.map { |m| m.new(self) }.find(&:match)
16
15
  end
17
16
 
18
17
  # Returns the percent confident with the match
@@ -24,8 +23,8 @@ class Licensee
24
23
  matcher && matcher.match
25
24
  end
26
25
 
27
- alias_method :match, :license
28
- alias_method :path, :filename
26
+ alias match license
27
+ alias path filename
29
28
  end
30
29
  end
31
30
  end
@@ -1,4 +1,4 @@
1
- class Licensee
1
+ module Licensee
2
2
  class Project
3
3
  class LicenseFile < Licensee::Project::File
4
4
  include Licensee::ContentHelper
@@ -6,7 +6,7 @@ class Licensee
6
6
  def possible_matchers
7
7
  [Matchers::Copyright, Matchers::Exact, Matchers::Dice]
8
8
  end
9
-
9
+
10
10
  def attribution
11
11
  matches = /^#{Matchers::Copyright::REGEX}$/i.match(content)
12
12
  matches[0].strip if matches
@@ -18,7 +18,7 @@ class Licensee
18
18
  return 0.8 if filename =~ /\Acopy(ing|right)(\.[^.]+)?\z/i
19
19
  return 0.7 if filename =~ /\A(un)?licen[sc]e\.[^.]+\z/i
20
20
  return 0.5 if filename =~ /licen[sc]e/i
21
- return 0.0
21
+ 0.0
22
22
  end
23
23
  end
24
24
  end
@@ -1,11 +1,11 @@
1
- class Licensee
1
+ module Licensee
2
2
  class Project
3
3
  class PackageInfo < Licensee::Project::File
4
4
  def possible_matchers
5
5
  case ::File.extname(filename)
6
- when ".gemspec"
6
+ when '.gemspec'
7
7
  [Matchers::Gemspec]
8
- when ".json"
8
+ when '.json'
9
9
  [Matchers::NpmBower]
10
10
  else
11
11
  []
@@ -13,10 +13,10 @@ class Licensee
13
13
  end
14
14
 
15
15
  def self.name_score(filename)
16
- return 1.0 if ::File.extname(filename) == ".gemspec"
17
- return 1.0 if filename == "package.json"
18
- return 0.75 if filename == "bower.json"
19
- return 0.0
16
+ return 1.0 if ::File.extname(filename) == '.gemspec'
17
+ return 1.0 if filename == 'package.json'
18
+ return 0.75 if filename == 'bower.json'
19
+ 0.0
20
20
  end
21
21
  end
22
22
  end
@@ -0,0 +1,24 @@
1
+ module Licensee
2
+ class Project
3
+ class Readme < LicenseFile
4
+ SCORES = {
5
+ /\AREADME\z/i => 1.0,
6
+ /\AREADME\.(md|markdown|txt)\z/i => 0.9
7
+ }.freeze
8
+
9
+ CONTENT_REGEX = /^#+ Licen[sc]e$(.*?)(?=#+|\z)/im
10
+
11
+ def self.name_score(filename)
12
+ SCORES.each do |pattern, score|
13
+ return score if pattern =~ filename
14
+ end
15
+ 0.0
16
+ end
17
+
18
+ def self.license_content(content)
19
+ match = CONTENT_REGEX.match(content)
20
+ match[1].strip if match
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,32 @@
1
+ # Filesystem-based project
2
+ #
3
+ # Analyze a folder on the filesystem for license information
4
+ module Licensee
5
+ class FSProject < Project
6
+ attr_reader :path
7
+
8
+ def initialize(path, **args)
9
+ @path = path
10
+ super(**args)
11
+ end
12
+
13
+ private
14
+
15
+ def find_file
16
+ files = []
17
+
18
+ Dir.foreach(path) do |file|
19
+ next unless ::File.file?(::File.join(path, file))
20
+ if (score = yield file) > 0
21
+ files.push(name: file, score: score)
22
+ end
23
+ end
24
+
25
+ return if files.empty?
26
+ files.sort! { |a, b| b[:score] <=> a[:score] }
27
+
28
+ f = files.first
29
+ [::File.read(::File.join(path, f[:name])), f[:name]]
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,55 @@
1
+ # Git-based project
2
+ #
3
+ # analyze a given git repository for license information
4
+ module Licensee
5
+ class GitProject < Licensee::Project
6
+ attr_reader :repository, :revision
7
+
8
+ class InvalidRepository < ArgumentError; end
9
+
10
+ def initialize(repo, revision: nil, **args)
11
+ @repository = if repo.is_a? Rugged::Repository
12
+ repo
13
+ else
14
+ Rugged::Repository.new(repo)
15
+ end
16
+
17
+ @revision = revision
18
+ super(**args)
19
+ rescue Rugged::RepositoryError
20
+ raise InvalidRepository
21
+ end
22
+
23
+ private
24
+
25
+ def commit
26
+ @commit ||= if revision
27
+ repository.lookup(revision)
28
+ else
29
+ repository.last_commit
30
+ end
31
+ end
32
+
33
+ MAX_LICENSE_SIZE = 64 * 1024
34
+
35
+ def load_blob_data(oid)
36
+ data, = Rugged::Blob.to_buffer(repository, oid, MAX_LICENSE_SIZE)
37
+ data
38
+ end
39
+
40
+ def find_file
41
+ files = commit.tree.map do |entry|
42
+ next unless entry[:type] == :blob
43
+ if (score = yield entry[:name]) > 0
44
+ { name: entry[:name], oid: entry[:oid], score: score }
45
+ end
46
+ end.compact
47
+
48
+ return if files.empty?
49
+ files.sort! { |a, b| b[:score] <=> a[:score] }
50
+
51
+ f = files.first
52
+ [load_blob_data(f[:oid]), f[:name]]
53
+ end
54
+ end
55
+ end
@@ -1,3 +1,3 @@
1
- class Licensee
2
- VERSION = "6.1.1"
1
+ module Licensee
2
+ VERSION = '7.0.0'.freeze
3
3
  end
@@ -0,0 +1 @@
1
+ This readme doesn't have a license, so detected the license from bower.
@@ -0,0 +1,3 @@
1
+ {
2
+ "license": "mit"
3
+ }
data/test/functions.rb CHANGED
@@ -4,7 +4,7 @@ require 'securerandom'
4
4
  require_relative '../lib/licensee'
5
5
 
6
6
  def fixtures_base
7
- File.expand_path "fixtures", File.dirname( __FILE__ )
7
+ File.expand_path 'fixtures', File.dirname(__FILE__)
8
8
  end
9
9
 
10
10
  def fixture_path(fixture)
@@ -13,9 +13,9 @@ end
13
13
 
14
14
  def license_from_path(path)
15
15
  license = File.open(path).read.match(/\A(---\n.*\n---\n+)?(.*)/m).to_a[2]
16
- license.sub! "[fullname]", "Ben Balter"
17
- license.sub! "[year]", "2014"
18
- license.sub! "[email]", "ben@github.invalid"
16
+ license.sub! '[fullname]', 'Ben Balter'
17
+ license.sub! '[year]', '2014'
18
+ license.sub! '[email]', 'ben@github.invalid'
19
19
  license
20
20
  end
21
21
 
@@ -26,8 +26,8 @@ def chaos_monkey(string)
26
26
  string
27
27
  end
28
28
 
29
- def verify_license_file(license, chaos = false, wrap=false)
30
- expected = File.basename(license, ".txt")
29
+ def verify_license_file(license, chaos = false, wrap = false)
30
+ expected = File.basename(license, '.txt')
31
31
 
32
32
  text = license_from_path(license)
33
33
  text = chaos_monkey(text) if chaos
@@ -39,17 +39,28 @@ def verify_license_file(license, chaos = false, wrap=false)
39
39
  msg = "No match for #{expected}."
40
40
 
41
41
  assert actual, msg
42
- assert_equal expected, actual.key, "expeceted #{expected} but got #{actual.key} for .match. Confidence: #{license_file.confidence}. Method: #{license_file.matcher.class}"
42
+
43
+ msg = "Expeceted #{expected} but got #{actual.key} for .match. "
44
+ msg << "Confidence: #{license_file.confidence}. "
45
+ msg << "Method: #{license_file.matcher.class}"
46
+ assert_equal expected, actual.key, msg
43
47
  end
44
48
 
45
- def wrap(text, line_width=80)
49
+ def wrap(text, line_width = 80)
46
50
  text = text.clone
47
51
  copyright = /^#{Licensee::Matchers::Copyright::REGEX}$/i.match(text)
48
- text.gsub! /^#{Licensee::Matchers::Copyright::REGEX}$/i, '[COPYRIGHT]' if copyright
49
- text.gsub! /([^\n])\n([^\n])/, '\1 \2'
52
+ if copyright
53
+ text.gsub!(/^#{Licensee::Matchers::Copyright::REGEX}$/i, '[COPYRIGHT]')
54
+ end
55
+ text.gsub!(/([^\n])\n([^\n])/, '\1 \2')
56
+
50
57
  text = text.split("\n").collect do |line|
51
- line.length > line_width ? line.gsub(/(.{1,#{line_width}})(\s+|$)/, "\\1\n").strip : line
58
+ if line.length > line_width
59
+ line.gsub(/(.{1,#{line_width}})(\s+|$)/, "\\1\n").strip
60
+ else
61
+ line
62
+ end
52
63
  end * "\n"
53
- text.gsub! "[COPYRIGHT]", "\n#{copyright}\n" if copyright
64
+ text.gsub! '[COPYRIGHT]', "\n#{copyright}\n" if copyright
54
65
  text.strip
55
66
  end