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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e0e6140bf397fcff609ea09c93a2021374d9d541
4
- data.tar.gz: ab2638dcef843f3e1588e70a8e8647c2f5fc1b95
3
+ metadata.gz: 635a65cf8bd046b4f88528088de2dc0863648ed3
4
+ data.tar.gz: d3ddf6c216c07d29e868ce5772d70935a45cf75e
5
5
  SHA512:
6
- metadata.gz: 7b7466fe1eb5be7a997ede72847a02244e21cfbf9a2724a51c53a383d312b291acd7d99c3fb2a46419272be1c925538ed8137b6baa34cee5c569004e47856c61
7
- data.tar.gz: 111ae00501bc4bcd36155643cc742db0f34c86330127bfde0622891ef3d00fe8aedc294fd6df7f1728649e5d71617c0d51058159fb55fcfada2e8be8245aa3b6
6
+ metadata.gz: a4ea781352b1a409c3cf0652637a8f270b226770d8a27f93e8a590eaa3b9a320ed9a347e1c488bcd7f336b7c736e4e1262ba65420780ff569c2990fe1c8b0b88
7
+ data.tar.gz: 01c989238c40de7102e5558f3f4086c93cf65003ec451a8aa9d5ac6123cda560861d4b1486ac64923fbb5fbfed922b395d921a2215d859df6b1f4284649dd4ae
data/Rakefile CHANGED
@@ -6,7 +6,7 @@ Rake::TestTask.new(:test) do |test|
6
6
  test.pattern = 'test/**/test_licensee*.rb'
7
7
  end
8
8
 
9
- desc "Open console with Licensee loaded"
9
+ desc 'Open console with Licensee loaded'
10
10
  task :console do
11
- exec "pry -r ./lib/licensee.rb"
11
+ exec 'pry -r ./lib/licensee.rb'
12
12
  end
data/bin/licensee CHANGED
@@ -1,14 +1,17 @@
1
1
  #!/usr/bin/env ruby
2
- require_relative "../lib/licensee"
2
+ require_relative '../lib/licensee'
3
3
 
4
4
  path = ARGV[0] || Dir.pwd
5
5
 
6
- project = Licensee::GitProject.new(path, detect_packages: true)
6
+ options = { detect_packages: true, detect_readme: true }
7
+ project = Licensee::GitProject.new(path, options)
7
8
  file = project.matched_file
8
9
 
9
10
  if project.license_file
10
11
  puts "License file: #{project.license_file.filename}"
11
- puts "Attribution: #{project.license_file.attribution}" if project.license_file.attribution
12
+ if project.license_file.attribution
13
+ puts "Attribution: #{project.license_file.attribution}"
14
+ end
12
15
  end
13
16
 
14
17
  if file
@@ -16,5 +19,5 @@ if file
16
19
  puts "Confidence: #{file.confidence}%"
17
20
  puts "Method: #{file.matcher.class}"
18
21
  else
19
- puts "Unknown"
22
+ puts 'Unknown'
20
23
  end
data/lib/licensee.rb CHANGED
@@ -1,33 +1,38 @@
1
- require_relative "licensee/version"
2
- require_relative "licensee/content_helper"
3
- require_relative "licensee/license"
4
- require_relative "licensee/project"
1
+ require_relative 'licensee/version'
2
+ require_relative 'licensee/content_helper'
3
+ require_relative 'licensee/license'
4
+
5
+ # Projects
6
+ require_relative 'licensee/project'
7
+ require_relative 'licensee/projects/git_project'
8
+ require_relative 'licensee/projects/fs_project'
5
9
 
6
10
  # Project files
7
- require_relative "licensee/project_file"
8
- require_relative "licensee/project_files/license_file.rb"
9
- require_relative "licensee/project_files/package_info.rb"
11
+ require_relative 'licensee/project_file'
12
+ require_relative 'licensee/project_files/license_file'
13
+ require_relative 'licensee/project_files/package_info'
14
+ require_relative 'licensee/project_files/readme'
10
15
 
11
16
  # Matchers
12
- require_relative "licensee/matchers/exact_matcher"
13
- require_relative "licensee/matchers/copyright_matcher"
14
- require_relative "licensee/matchers/dice_matcher"
15
- require_relative "licensee/matchers/package_matcher"
16
- require_relative "licensee/matchers/gemspec_matcher"
17
- require_relative "licensee/matchers/npm_bower_matcher"
18
-
19
- class Licensee
17
+ require_relative 'licensee/matchers/exact_matcher'
18
+ require_relative 'licensee/matchers/copyright_matcher'
19
+ require_relative 'licensee/matchers/dice_matcher'
20
+ require_relative 'licensee/matchers/package_matcher'
21
+ require_relative 'licensee/matchers/gemspec_matcher'
22
+ require_relative 'licensee/matchers/npm_bower_matcher'
23
+
24
+ module Licensee
20
25
  # Over which percent is a match considered a match by default
21
26
  CONFIDENCE_THRESHOLD = 90
22
27
 
23
28
  # Base domain from which to build license URLs
24
- DOMAIN = "http://choosealicense.com"
29
+ DOMAIN = 'http://choosealicense.com'.freeze
25
30
 
26
31
  class << self
27
32
  attr_writer :confidence_threshold
28
33
 
29
34
  # Returns an array of Licensee::License instances
30
- def licenses(options={})
35
+ def licenses(options = {})
31
36
  Licensee::License.all(options)
32
37
  end
33
38
 
@@ -37,11 +42,9 @@ class Licensee
37
42
  end
38
43
 
39
44
  def project(path)
40
- begin
41
- Licensee::GitProject.new(path)
42
- rescue Licensee::GitProject::InvalidRepository
43
- Licensee::FSProject.new(path)
44
- end
45
+ Licensee::GitProject.new(path)
46
+ rescue Licensee::GitProject::InvalidRepository
47
+ Licensee::FSProject.new(path)
45
48
  end
46
49
 
47
50
  def confidence_threshold
@@ -1,13 +1,14 @@
1
1
  require 'set'
2
2
  require 'digest'
3
3
 
4
- class Licensee
4
+ module Licensee
5
5
  module ContentHelper
6
-
7
6
  DIGEST = Digest::SHA1
8
7
 
9
8
  def wordset
10
- @wordset ||= content_normalized.scan(/[\w']+/).to_set if content_normalized
9
+ @wordset ||= if content_normalized
10
+ content_normalized.scan(/[\w']+/).to_set
11
+ end
11
12
  end
12
13
 
13
14
  def hash
@@ -19,7 +20,7 @@ class Licensee
19
20
  @content_normalized ||= begin
20
21
  content_normalized = content.downcase.strip
21
22
  content_normalized.gsub!(/^#{Matchers::Copyright::REGEX}$/i, '')
22
- content_normalized.gsub("\n", " ").squeeze(" ")
23
+ content_normalized.tr("\n", ' ').squeeze(' ')
23
24
  end
24
25
  end
25
26
  end
@@ -1,39 +1,41 @@
1
1
  require 'uri'
2
2
  require 'yaml'
3
3
 
4
- class Licensee
4
+ module Licensee
5
5
  class InvalidLicense < ArgumentError; end
6
6
  class License
7
-
8
7
  class << self
9
-
10
8
  # All license objects defined via Licensee (via choosealicense.com)
11
9
  #
12
- # Options - :hidden - boolean, whether to return hidden licenses, defaults to false
13
- # Options - :featured - boolean, whether to return only (non)featured licenses, defaults to all
10
+ # Options:
11
+ # - :hidden - boolean, return hidden licenses (default: false)
12
+ # - :featured - boolean, return only (non)featured licenses (default: all)
14
13
  #
15
14
  # Returns an Array of License objects.
16
- def all(options={})
15
+ def all(options = {})
16
+ options = { hidden: false, featured: nil }.merge(options)
17
17
  output = licenses.dup
18
- output.reject! { |l| l.hidden? } unless options[:hidden]
19
- output.select! { |l| l.featured? == options[:featured] } unless options[:featured].nil?
20
- output
18
+ output.reject!(&:hidden?) unless options[:hidden]
19
+ return output if options[:featured].nil?
20
+ output.select { |l| l.featured? == options[:featured] }
21
21
  end
22
22
 
23
23
  def keys
24
- @keys ||= license_files.map { |l| File.basename(l, ".txt").downcase } + ["other"]
24
+ @keys ||= license_files.map do |license_file|
25
+ File.basename(license_file, '.txt').downcase
26
+ end + PSEUDO_LICENSES
25
27
  end
26
28
 
27
- def find(key, options={})
28
- options = {:hidden => true}.merge(options)
29
- key = key.downcase
30
- all(options).find { |license| license.key == key }
29
+ def find(key, options = {})
30
+ options = { hidden: true }.merge(options)
31
+ all(options).find { |license| key.casecmp(license.key).zero? }
31
32
  end
32
- alias_method :[], :find
33
- alias_method :find_by_key, :find
33
+ alias [] find
34
+ alias find_by_key find
34
35
 
35
36
  def license_dir
36
- File.expand_path "../../vendor/choosealicense.com/_licenses", File.dirname(__FILE__)
37
+ dir = File.dirname(__FILE__)
38
+ File.expand_path '../../vendor/choosealicense.com/_licenses', dir
37
39
  end
38
40
 
39
41
  def license_files
@@ -43,19 +45,26 @@ class Licensee
43
45
  private
44
46
 
45
47
  def licenses
46
- @licenses ||= keys.map { |key| self.new(key) }
48
+ @licenses ||= keys.map { |key| new(key) }
47
49
  end
48
50
  end
49
51
 
50
52
  attr_reader :key
51
53
 
54
+ # These should be in sync with choosealicense.com's collection defaults
52
55
  YAML_DEFAULTS = {
53
- "featured" => false,
54
- "hidden" => false,
55
- "variant" => false
56
- }
57
-
58
- HIDDEN_LICENSES = %w[other no-license]
56
+ 'featured' => false,
57
+ 'hidden' => true,
58
+ 'variant' => false
59
+ }.freeze
60
+
61
+ # Pseudo-license are license placeholders with no content
62
+ #
63
+ # `other` - The project had a license, but we were not able to detect it
64
+ # `no-license` - The project is not licensed (e.g., all rights reserved)
65
+ #
66
+ # Note: A lack of detected license will be a nil license
67
+ PSEUDO_LICENSES = %w(other no-license).freeze
59
68
 
60
69
  include Licensee::ContentHelper
61
70
 
@@ -71,10 +80,10 @@ class Licensee
71
80
  # License metadata from YAML front matter
72
81
  def meta
73
82
  @meta ||= if parts && parts[1]
74
- if YAML.respond_to? :safe_load
75
- meta = YAML.safe_load(parts[1])
83
+ meta = if YAML.respond_to? :safe_load
84
+ YAML.safe_load(parts[1])
76
85
  else
77
- meta = YAML.load(parts[1])
86
+ YAML.load(parts[1])
78
87
  end
79
88
  YAML_DEFAULTS.merge(meta)
80
89
  end
@@ -82,11 +91,11 @@ class Licensee
82
91
 
83
92
  # Returns the human-readable license name
84
93
  def name
85
- meta.nil? ? key.capitalize : meta["title"]
94
+ meta.nil? ? key.capitalize : meta['title']
86
95
  end
87
96
 
88
97
  def nickname
89
- meta["nickname"] if meta
98
+ meta['nickname'] if meta
90
99
  end
91
100
 
92
101
  def name_without_version
@@ -94,50 +103,52 @@ class Licensee
94
103
  end
95
104
 
96
105
  def featured?
97
- !!(meta["featured"] if meta)
106
+ return YAML_DEFAULTS['featured'] unless meta
107
+ meta['featured']
98
108
  end
99
- alias_method :featured, :featured?
109
+ alias featured featured?
100
110
 
101
111
  def hidden?
102
- return true if HIDDEN_LICENSES.include?(key)
103
- !!(meta["hidden"] if meta)
112
+ return true if PSEUDO_LICENSES.include?(key)
113
+ return YAML_DEFAULTS['hidden'] unless meta
114
+ meta['hidden']
104
115
  end
105
116
 
106
117
  # The license body (e.g., contents - frontmatter)
107
118
  def content
108
119
  @content ||= parts[2] if parts && parts[2]
109
120
  end
110
- alias_method :to_s, :content
111
- alias_method :text, :content
112
- alias_method :body, :content
113
-
114
- def inspect
115
- "#<Licensee::License key=\"#{key}\" name=\"#{name}\">"
116
- end
121
+ alias to_s content
122
+ alias text content
123
+ alias body content
117
124
 
118
125
  def url
119
126
  URI.join(Licensee::DOMAIN, "/licenses/#{key}/").to_s
120
127
  end
121
128
 
122
129
  def ==(other)
123
- other != nil && key == other.key
130
+ !other.nil? && key == other.key
124
131
  end
125
132
 
126
133
  private
127
134
 
135
+ def pseudo_license?
136
+ PSEUDO_LICENSES.include?(key)
137
+ end
138
+
128
139
  # Raw content of license file, including YAML front matter
129
140
  def raw_content
130
- @raw_content ||= if File.exists?(path)
141
+ return if pseudo_license?
142
+ @raw_content ||= if File.exist?(path)
131
143
  File.open(path).read
132
- elsif key == "other" # A pseudo-license with no content
133
- nil
134
144
  else
135
145
  raise Licensee::InvalidLicense, "'#{key}' is not a valid license key"
136
146
  end
137
147
  end
138
148
 
139
149
  def parts
140
- @parts ||= raw_content.match(/\A(---\n.*\n---\n+)?(.*)/m).to_a if raw_content
150
+ return unless raw_content
151
+ @parts ||= raw_content.match(/\A(---\n.*\n---\n+)?(.*)/m).to_a
141
152
  end
142
153
  end
143
154
  end
@@ -1,5 +1,5 @@
1
1
  # encoding=utf-8
2
- class Licensee
2
+ module Licensee
3
3
  module Matchers
4
4
  class Copyright
5
5
  REGEX = /\s*Copyright (©|\(c\)|\xC2\xA9)? ?(\d{4}|\[year\])(.*)?\s*/i
@@ -11,7 +11,7 @@ class Licensee
11
11
  def match
12
12
  # Note: must use content, and not content_normalized here
13
13
  if @file.content.strip =~ /\A#{REGEX}\z/i
14
- Licensee::License.find("no-license")
14
+ Licensee::License.find('no-license')
15
15
  end
16
16
  rescue
17
17
  nil
@@ -1,4 +1,4 @@
1
- class Licensee
1
+ module Licensee
2
2
  module Matchers
3
3
  class Dice
4
4
  def initialize(file)
@@ -18,7 +18,7 @@ class Licensee
18
18
  @match = if matches.empty?
19
19
  nil
20
20
  else
21
- matches.max_by { |l, sim| sim }.first
21
+ matches.max_by { |_l, sim| sim }.first
22
22
  end
23
23
  end
24
24
 
@@ -28,7 +28,7 @@ class Licensee
28
28
  # the confidence threshold / 100
29
29
  def potential_licenses
30
30
  @potential_licenses ||= begin
31
- licenses = Licensee.licenses(:hidden => true)
31
+ licenses = Licensee.licenses(hidden: true)
32
32
  licenses = licenses.select do |license|
33
33
  license.wordset && length_delta(license) <= max_delta
34
34
  end
@@ -45,7 +45,9 @@ class Licensee
45
45
  # Maximum possible difference between file length and license length
46
46
  # for a license to be a potential license to be matched
47
47
  def max_delta
48
- @max_delta ||= (@file.wordset.size * (Licensee.confidence_threshold/100.0))
48
+ @max_delta ||= (
49
+ @file.wordset.size * (Licensee.confidence_threshold / 100.0)
50
+ )
49
51
  end
50
52
 
51
53
  # Confidence that the matched license is a match
@@ -54,6 +56,7 @@ class Licensee
54
56
  end
55
57
 
56
58
  private
59
+
57
60
  # Calculate percent changed between file and potential license
58
61
  def similarity(license)
59
62
  overlap = (@file.wordset & license.wordset).size
@@ -1,4 +1,4 @@
1
- class Licensee
1
+ module Licensee
2
2
  module Matchers
3
3
  class Exact
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.wordset == @file.wordset }
9
+ Licensee.licenses(hidden: true).find { |l| l.wordset == @file.wordset }
10
10
  end
11
11
 
12
12
  def confidence
@@ -1,12 +1,15 @@
1
- class Licensee
1
+ module Licensee
2
2
  module Matchers
3
3
  class Gemspec < Package
4
4
  # We definitely don't want to be evaling arbitrary Gemspec files
5
5
  # While not 100% accurate, use some lenient regex to try to grep the
6
6
  # license declaration from the Gemspec as a string, if any
7
- LICENSE_REGEX = /^\s*[a-z0-9_]+\.license\s*\=\s*[\'\"]([a-z\-0-9\.]+)[\'\"]\s*$/i
7
+ LICENSE_REGEX = /
8
+ ^\s*[a-z0-9_]+\.license\s*\=\s*[\'\"]([a-z\-0-9\.]+)[\'\"]\s*$
9
+ /ix
8
10
 
9
11
  private
12
+
10
13
  def license_property
11
14
  match = @file.content.match LICENSE_REGEX
12
15
  match[1].downcase if match && match[1]
@@ -1,11 +1,14 @@
1
- class Licensee
1
+ module Licensee
2
2
  module Matchers
3
3
  class NpmBower < Package
4
4
  # While we could parse the package.json or bower.json file, prefer
5
5
  # a lenient regex for speed and security. Moar parsing moar problems.
6
- LICENSE_REGEX = /\s*[\"\']license[\"\']\s*\:\s*[\'\"]([a-z\-0-9\.]+)[\'\"],?\s*/i
6
+ LICENSE_REGEX = /
7
+ s*[\"\']license[\"\']\s*\:\s*[\'\"]([a-z\-0-9\.]+)[\'\"],?\s*
8
+ /ix
7
9
 
8
10
  private
11
+
9
12
  def license_property
10
13
  match = @file.content.match LICENSE_REGEX
11
14
  match[1].downcase if match && match[1]