licensee 6.1.1 → 7.0.0

Sign up to get free protection for your applications and to get access to all the features.
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