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
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]