licensee 9.8.0 → 9.9.0.beta.2
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.
- checksums.yaml +4 -4
- data/bin/licensee +25 -52
- data/lib/licensee/commands/detect.rb +103 -0
- data/lib/licensee/commands/diff.rb +67 -0
- data/lib/licensee/commands/license_path.rb +14 -0
- data/lib/licensee/commands/version.rb +6 -0
- data/lib/licensee/content_helper.rb +6 -0
- data/lib/licensee/hash_helper.rb +20 -0
- data/lib/licensee/license.rb +6 -1
- data/lib/licensee/license_meta.rb +3 -0
- data/lib/licensee/license_rules.rb +4 -1
- data/lib/licensee/matchers/exact.rb +1 -7
- data/lib/licensee/matchers/matcher.rb +7 -0
- data/lib/licensee/project_files/project_file.rb +17 -0
- data/lib/licensee/projects/project.rb +3 -0
- data/lib/licensee/rule.rb +3 -0
- data/lib/licensee/version.rb +1 -1
- data/lib/licensee.rb +1 -0
- data/spec/bin_spec.rb +7 -50
- data/spec/fixtures/detect.json +111 -0
- data/spec/licensee/commands/detect_spec.rb +86 -0
- data/spec/licensee/commands/license_path_spec.rb +21 -0
- data/spec/licensee/commands/version_spec.rb +21 -0
- data/spec/licensee/hash_helper_spec.rb +78 -0
- data/spec/licensee/license_field_spec.rb +11 -2
- data/spec/licensee/license_meta_spec.rb +34 -0
- data/spec/licensee/license_rules_spec.rb +15 -0
- data/spec/licensee/license_spec.rb +24 -2
- data/spec/licensee/matchers/matcher_spec.rb +35 -0
- data/spec/licensee/project_files/license_file_spec.rb +1 -1
- data/spec/licensee/project_files/project_file_spec.rb +21 -0
- data/spec/licensee/project_spec.rb +14 -0
- data/spec/licensee/rule_spec.rb +27 -8
- data/spec/licensee_spec.rb +1 -1
- data/spec/spec_helper.rb +14 -6
- data/spec/vendored_license_spec.rb +4 -0
- data/vendor/choosealicense.com/_data/fields.yml +3 -0
- data/vendor/choosealicense.com/_licenses/eupl-1.2.txt +309 -0
- data/vendor/choosealicense.com/_licenses/ncsa.txt +22 -22
- metadata +45 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 07cb2f24a84e1c09c9e8b18b8d884fe167075294883c7bdc38a41d96ac43e7cd
|
|
4
|
+
data.tar.gz: 0a5884c9abec6b33e3883cde81533a4b2d9c4b2e6f196dc93a3f8148500f91d0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1413f1609224bcc6c0220c9838a9959af8b008231ece109f2d4cf58042c64f6be9df66618b7d15c46ff08b67f90cdb9260693baa189c91a9aa49150731d178b9
|
|
7
|
+
data.tar.gz: f143548da667914c309269e54da37cf449efdf51baa05b1a8bb24a91d82c80def6b01f3d2b804db3be914045f03048a3e111a1145f7674cce0a3086df5eff280
|
data/bin/licensee
CHANGED
|
@@ -1,64 +1,37 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
# Given a string or object, prepares it for output and human consumption
|
|
8
|
-
def humanize(value, type = nil)
|
|
9
|
-
case type
|
|
10
|
-
when :license
|
|
11
|
-
value.name
|
|
12
|
-
when :matcher
|
|
13
|
-
value.class
|
|
14
|
-
when :confidence
|
|
15
|
-
Licensee::ContentHelper.format_percent(value)
|
|
16
|
-
when :method
|
|
17
|
-
value.to_s.tr('_', ' ').capitalize
|
|
18
|
-
else
|
|
19
|
-
value
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
# Methods to call when displaying information about ProjectFiles
|
|
24
|
-
MATCHED_FILE_METHODS = %i[
|
|
25
|
-
content_hash attribution confidence matcher license
|
|
26
|
-
].freeze
|
|
3
|
+
require 'dotenv/load'
|
|
4
|
+
require 'thor'
|
|
5
|
+
require 'json'
|
|
27
6
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
if project.license
|
|
31
|
-
puts "License: #{project.license.name}"
|
|
32
|
-
elsif project.licenses
|
|
33
|
-
puts "Licenses: #{project.licenses.map(&:name)}"
|
|
34
|
-
else
|
|
35
|
-
puts 'License: Not detected'
|
|
36
|
-
end
|
|
7
|
+
require_relative '../lib/licensee'
|
|
37
8
|
|
|
38
|
-
|
|
9
|
+
class LicenseeCLI < Thor
|
|
10
|
+
package_name 'Licensee'
|
|
11
|
+
class_option :remote, type: :boolean, desc: 'Assume PATH is a GitHub owner/repo path'
|
|
12
|
+
default_task :detect
|
|
39
13
|
|
|
40
|
-
|
|
41
|
-
puts "#{matched_file.filename}:"
|
|
14
|
+
private
|
|
42
15
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
16
|
+
def path
|
|
17
|
+
@path ||= if !options[:remote] || args.first =~ %r{^https://}
|
|
18
|
+
args.first || Dir.pwd
|
|
19
|
+
else
|
|
20
|
+
"https://github.com/#{args.first}"
|
|
21
|
+
end
|
|
48
22
|
end
|
|
49
23
|
|
|
50
|
-
|
|
51
|
-
|
|
24
|
+
def project
|
|
25
|
+
@project ||= Licensee.project(path,
|
|
26
|
+
detect_packages: options[:packages], detect_readme: options[:readme])
|
|
27
|
+
end
|
|
52
28
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
next if licenses.empty?
|
|
56
|
-
puts ' Closest licenses:'
|
|
57
|
-
licenses[0...3].each do |license, similarity|
|
|
58
|
-
spdx_id = license.meta['spdx-id']
|
|
59
|
-
percent = Licensee::ContentHelper.format_percent(similarity)
|
|
60
|
-
puts " * #{spdx_id} similarity: #{percent}"
|
|
29
|
+
def remote?
|
|
30
|
+
path =~ %r{^https://}
|
|
61
31
|
end
|
|
62
32
|
end
|
|
63
33
|
|
|
64
|
-
|
|
34
|
+
commands_dir = File.expand_path 'lib/licensee/commands/'
|
|
35
|
+
Dir["#{commands_dir}/*.rb"].each { |c| require(c) }
|
|
36
|
+
|
|
37
|
+
LicenseeCLI.start(ARGV)
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
class LicenseeCLI < Thor
|
|
2
|
+
# Methods to call when displaying information about ProjectFiles
|
|
3
|
+
MATCHED_FILE_METHODS = %i[
|
|
4
|
+
content_hash attribution confidence matcher license
|
|
5
|
+
].freeze
|
|
6
|
+
|
|
7
|
+
desc 'detect [PATH]', 'Detect the license of the given project'
|
|
8
|
+
option :json, type: :boolean, desc: 'Return output as JSON'
|
|
9
|
+
option :packages, type: :boolean, default: true, desc: 'Detect licenses in package manager files'
|
|
10
|
+
option :readme, type: :boolean, default: true, desc: 'Detect licenses in README files'
|
|
11
|
+
option :confidence, type: :numeric, default: Licensee.confidence_threshold, desc: 'Confidence threshold'
|
|
12
|
+
option :license, type: :string, desc: 'The SPDX ID or key of the license to compare (implies --diff)'
|
|
13
|
+
option :diff, type: :boolean, desc: 'Compare the license to the closest match'
|
|
14
|
+
def detect(_path = nil)
|
|
15
|
+
Licensee.confidence_threshold = options[:confidence]
|
|
16
|
+
|
|
17
|
+
if options[:json]
|
|
18
|
+
say project.to_h.to_json
|
|
19
|
+
exit !project.licenses.empty?
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
rows = []
|
|
23
|
+
rows << if project.license
|
|
24
|
+
['License:', project.license.name]
|
|
25
|
+
elsif !project.licenses.empty?
|
|
26
|
+
['Licenses:', project.licenses.map(&:name)]
|
|
27
|
+
else
|
|
28
|
+
['License:', set_color('None', :red)]
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
unless project.matched_files.empty?
|
|
32
|
+
rows << ['Matched files:', project.matched_files.map(&:filename).join(', ')]
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
print_table rows
|
|
36
|
+
|
|
37
|
+
project.matched_files.each do |matched_file|
|
|
38
|
+
rows = []
|
|
39
|
+
say "#{matched_file.filename}:"
|
|
40
|
+
|
|
41
|
+
MATCHED_FILE_METHODS.each do |method|
|
|
42
|
+
next unless matched_file.respond_to? method
|
|
43
|
+
value = matched_file.public_send method
|
|
44
|
+
next if value.nil?
|
|
45
|
+
rows << [humanize(method, :method), humanize(value, method)]
|
|
46
|
+
end
|
|
47
|
+
print_table rows, indent: 2
|
|
48
|
+
|
|
49
|
+
next unless matched_file.is_a? Licensee::ProjectFiles::LicenseFile
|
|
50
|
+
next if matched_file.confidence == 100
|
|
51
|
+
|
|
52
|
+
licenses = licenses_by_similiarity(matched_file)
|
|
53
|
+
next if licenses.empty?
|
|
54
|
+
say ' Closest licenses:'
|
|
55
|
+
rows = licenses[0...3].map do |license, similarity|
|
|
56
|
+
spdx_id = license.meta['spdx-id']
|
|
57
|
+
percent = Licensee::ContentHelper.format_percent(similarity)
|
|
58
|
+
["#{spdx_id} similarity:", percent]
|
|
59
|
+
end
|
|
60
|
+
print_table rows, indent: 4
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
if project.license_file && (options[:license] || options[:diff])
|
|
64
|
+
license = options[:license] || closest_license_key(project.license_file)
|
|
65
|
+
if license
|
|
66
|
+
invoke(:diff, nil,
|
|
67
|
+
license: license, license_to_diff: project.license_file)
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
exit !project.licenses.empty?
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
private
|
|
75
|
+
|
|
76
|
+
# Given a string or object, prepares it for output and human consumption
|
|
77
|
+
def humanize(value, type = nil)
|
|
78
|
+
case type
|
|
79
|
+
when :license
|
|
80
|
+
value.name
|
|
81
|
+
when :matcher
|
|
82
|
+
value.class
|
|
83
|
+
when :confidence
|
|
84
|
+
Licensee::ContentHelper.format_percent(value)
|
|
85
|
+
when :method
|
|
86
|
+
value.to_s.tr('_', ' ').capitalize + ':'
|
|
87
|
+
else
|
|
88
|
+
value
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def licenses_by_similiarity(matched_file)
|
|
93
|
+
matcher = Licensee::Matchers::Dice.new(matched_file)
|
|
94
|
+
potential_licenses = Licensee.licenses(hidden: true).select(&:wordset)
|
|
95
|
+
matcher.instance_variable_set('@potential_licenses', potential_licenses)
|
|
96
|
+
matcher.licenses_by_similiarity
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def closest_license_key(matched_file)
|
|
100
|
+
licenses = licenses_by_similiarity(matched_file)
|
|
101
|
+
licenses.first.first.key unless licenses.empty?
|
|
102
|
+
end
|
|
103
|
+
end
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
require 'tmpdir'
|
|
2
|
+
|
|
3
|
+
class LicenseeCLI < Thor
|
|
4
|
+
desc 'diff [PATH]', 'Compare the given license text to a known license'
|
|
5
|
+
option :license, type: :string, desc: 'The SPDX ID or key of the license to compare'
|
|
6
|
+
def diff(_path = nil)
|
|
7
|
+
say "Comparing to #{expected_license.name}:"
|
|
8
|
+
rows = []
|
|
9
|
+
|
|
10
|
+
left = expected_license.content_normalized(wrap: 80)
|
|
11
|
+
right = license_to_diff.content_normalized(wrap: 80)
|
|
12
|
+
similarity = expected_license.similarity(license_to_diff)
|
|
13
|
+
similarity = Licensee::ContentHelper.format_percent(similarity)
|
|
14
|
+
|
|
15
|
+
rows << ['Input Length:', license_to_diff.length]
|
|
16
|
+
rows << ['License length:', expected_license.length]
|
|
17
|
+
rows << ['Similarity:', similarity]
|
|
18
|
+
print_table rows
|
|
19
|
+
|
|
20
|
+
if left == right
|
|
21
|
+
say 'Exact match!', :green
|
|
22
|
+
exit
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
Dir.mktmpdir do |dir|
|
|
26
|
+
path = File.expand_path 'LICENSE', dir
|
|
27
|
+
Dir.chdir(dir) do
|
|
28
|
+
`git init`
|
|
29
|
+
File.write(path, left)
|
|
30
|
+
`git add LICENSE`
|
|
31
|
+
`git commit -m 'left'`
|
|
32
|
+
File.write(path, right)
|
|
33
|
+
say `git diff --word-diff`
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
private
|
|
39
|
+
|
|
40
|
+
def license_to_diff
|
|
41
|
+
return options[:license_to_diff] if options[:license_to_diff]
|
|
42
|
+
return project.license_file if remote?
|
|
43
|
+
|
|
44
|
+
@license_via_stdin ||= begin
|
|
45
|
+
if STDIN.tty?
|
|
46
|
+
error 'You must pipe license contents to the command via STDIN'
|
|
47
|
+
exit 1
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
Licensee::ProjectFiles::LicenseFile.new(STDIN.read, 'LICENSE')
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def expected_license
|
|
55
|
+
@expected_license ||= Licensee::License.find options[:license] if options[:license]
|
|
56
|
+
return @expected_license if @expected_license
|
|
57
|
+
|
|
58
|
+
if options[:license]
|
|
59
|
+
error "#{options[:license]} is not a valid license"
|
|
60
|
+
else
|
|
61
|
+
error 'You must provide an expected license'
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
error "Valid licenses: #{Licensee::License.all(hidden: true).map(&:key).join(', ')}"
|
|
65
|
+
exit 1
|
|
66
|
+
end
|
|
67
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
class LicenseeCLI < Thor
|
|
2
|
+
desc 'license-path [PATH]', "Returns the path to the given project's license file"
|
|
3
|
+
def license_path(_path)
|
|
4
|
+
if project.license_file
|
|
5
|
+
if remote?
|
|
6
|
+
say project.license_file.path
|
|
7
|
+
else
|
|
8
|
+
say File.expand_path project.license_file.path
|
|
9
|
+
end
|
|
10
|
+
else
|
|
11
|
+
exit 1
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -12,6 +12,7 @@ module Licensee
|
|
|
12
12
|
MARKDOWN_HEADING_REGEX = /\A\s*#+/
|
|
13
13
|
VERSION_REGEX = /\Aversion.*$/i
|
|
14
14
|
MARKUP_REGEX = /[#_*=~\[\]()`|>]+/
|
|
15
|
+
DEVELOPED_BY_REGEX = /\Adeveloped by:.*?\n\n/im
|
|
15
16
|
|
|
16
17
|
# A set of each word in the license, without duplicates
|
|
17
18
|
def wordset
|
|
@@ -77,6 +78,7 @@ module Licensee
|
|
|
77
78
|
string = strip_copyright(string)
|
|
78
79
|
end
|
|
79
80
|
string = strip_all_rights_reserved(string)
|
|
81
|
+
string = strip_developed_by(string)
|
|
80
82
|
string, _partition, _instructions = string.partition(END_OF_TERMS_REGEX)
|
|
81
83
|
string = strip_markup(string)
|
|
82
84
|
string = normalize_quotes(string)
|
|
@@ -162,6 +164,10 @@ module Licensee
|
|
|
162
164
|
strip(string, MARKUP_REGEX)
|
|
163
165
|
end
|
|
164
166
|
|
|
167
|
+
def strip_developed_by(string)
|
|
168
|
+
strip(string, DEVELOPED_BY_REGEX)
|
|
169
|
+
end
|
|
170
|
+
|
|
165
171
|
def strip(string, regex)
|
|
166
172
|
string.gsub(regex, ' ').squeeze(' ').strip
|
|
167
173
|
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module Licensee
|
|
2
|
+
module HashHelper
|
|
3
|
+
def to_h
|
|
4
|
+
hash = {}
|
|
5
|
+
self.class::HASH_METHODS.each do |method|
|
|
6
|
+
key = method.to_s.delete('?').to_sym
|
|
7
|
+
value = public_send(method)
|
|
8
|
+
hash[key] = if value.is_a?(Array)
|
|
9
|
+
value.map { |v| v.respond_to?(:to_h) ? v.to_h : v }
|
|
10
|
+
elsif value.respond_to?(:to_h) && !value.nil?
|
|
11
|
+
value.to_h
|
|
12
|
+
else
|
|
13
|
+
value
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
hash
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
data/lib/licensee/license.rb
CHANGED
|
@@ -92,9 +92,14 @@ module Licensee
|
|
|
92
92
|
}.freeze
|
|
93
93
|
|
|
94
94
|
SOURCE_PREFIX = %r{https?://(?:www\.)?}i
|
|
95
|
-
SOURCE_SUFFIX = %r{(?:\.html?|\.txt|\/)}i
|
|
95
|
+
SOURCE_SUFFIX = %r{(?:\.html?|\.txt|\/)(?:\?[^\s]*)?}i
|
|
96
|
+
|
|
97
|
+
HASH_METHODS = %i[
|
|
98
|
+
key spdx_id meta url rules fields other? gpl? lgpl? cc?
|
|
99
|
+
].freeze
|
|
96
100
|
|
|
97
101
|
include Licensee::ContentHelper
|
|
102
|
+
include Licensee::HashHelper
|
|
98
103
|
extend Forwardable
|
|
99
104
|
def_delegators :meta, *LicenseMeta.helper_methods
|
|
100
105
|
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
module Licensee
|
|
2
2
|
# Exposes #conditions, #permissions, and #limitation arrays of LicenseRules
|
|
3
3
|
class LicenseRules < Struct.new(:conditions, :permissions, :limitations)
|
|
4
|
+
include Licensee::HashHelper
|
|
5
|
+
HASH_METHODS = Rule.groups
|
|
6
|
+
|
|
4
7
|
class << self
|
|
5
8
|
def from_license(license)
|
|
6
9
|
from_meta(license.meta)
|
|
@@ -9,7 +12,7 @@ module Licensee
|
|
|
9
12
|
def from_meta(meta)
|
|
10
13
|
rules = {}
|
|
11
14
|
Rule.groups.each do |group|
|
|
12
|
-
rules[group] = meta[group].map do |tag|
|
|
15
|
+
rules[group] = (meta[group] || []).map do |tag|
|
|
13
16
|
Rule.find_by_tag_and_group(tag, group)
|
|
14
17
|
end
|
|
15
18
|
end
|
|
@@ -1,12 +1,6 @@
|
|
|
1
1
|
module Licensee
|
|
2
2
|
module Matchers
|
|
3
|
-
class Exact
|
|
4
|
-
attr_reader :file
|
|
5
|
-
|
|
6
|
-
def initialize(file)
|
|
7
|
-
@file = file
|
|
8
|
-
end
|
|
9
|
-
|
|
3
|
+
class Exact < Licensee::Matchers::Matcher
|
|
10
4
|
def match
|
|
11
5
|
return @match if defined? @match
|
|
12
6
|
@match = Licensee.licenses(hidden: true).find do |license|
|
|
@@ -3,10 +3,17 @@ module Licensee
|
|
|
3
3
|
class Matcher
|
|
4
4
|
attr_reader :file
|
|
5
5
|
|
|
6
|
+
include Licensee::HashHelper
|
|
7
|
+
HASH_METHODS = %i[name confidence].freeze
|
|
8
|
+
|
|
6
9
|
def initialize(file)
|
|
7
10
|
@file = file
|
|
8
11
|
end
|
|
9
12
|
|
|
13
|
+
def name
|
|
14
|
+
@name ||= self.class.to_s.split('::').last.downcase.to_sym
|
|
15
|
+
end
|
|
16
|
+
|
|
10
17
|
def match
|
|
11
18
|
raise 'Not implemented'
|
|
12
19
|
end
|
|
@@ -10,6 +10,11 @@ module Licensee
|
|
|
10
10
|
|
|
11
11
|
attr_reader :content
|
|
12
12
|
|
|
13
|
+
include Licensee::HashHelper
|
|
14
|
+
HASH_METHODS = %i[
|
|
15
|
+
filename content content_hash content_normalized matcher matched_license
|
|
16
|
+
].freeze
|
|
17
|
+
|
|
13
18
|
ENCODING = Encoding::UTF_8
|
|
14
19
|
ENCODING_OPTIONS = {
|
|
15
20
|
invalid: :replace,
|
|
@@ -61,6 +66,10 @@ module Licensee
|
|
|
61
66
|
alias match license
|
|
62
67
|
alias path filename
|
|
63
68
|
|
|
69
|
+
def matched_license
|
|
70
|
+
license.key if license
|
|
71
|
+
end
|
|
72
|
+
|
|
64
73
|
# Is this file a COPYRIGHT file with only a copyright statement?
|
|
65
74
|
# If so, it can be excluded from determining if a project has >1 license
|
|
66
75
|
def copyright?
|
|
@@ -68,6 +77,14 @@ module Licensee
|
|
|
68
77
|
return false unless matcher.is_a?(Matchers::Copyright)
|
|
69
78
|
filename =~ /\Acopyright(?:#{LicenseFile::OTHER_EXT_REGEX})?\z/i
|
|
70
79
|
end
|
|
80
|
+
|
|
81
|
+
def content_hash
|
|
82
|
+
nil
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def content_normalized
|
|
86
|
+
nil
|
|
87
|
+
end
|
|
71
88
|
end
|
|
72
89
|
end
|
|
73
90
|
end
|
|
@@ -10,6 +10,9 @@ module Licensee
|
|
|
10
10
|
alias detect_readme? detect_readme
|
|
11
11
|
alias detect_packages? detect_packages
|
|
12
12
|
|
|
13
|
+
include Licensee::HashHelper
|
|
14
|
+
HASH_METHODS = %i[licenses matched_files].freeze
|
|
15
|
+
|
|
13
16
|
def initialize(detect_packages: false, detect_readme: false)
|
|
14
17
|
@detect_packages = detect_packages
|
|
15
18
|
@detect_readme = detect_readme
|
data/lib/licensee/rule.rb
CHANGED
data/lib/licensee/version.rb
CHANGED
data/lib/licensee.rb
CHANGED
|
@@ -6,6 +6,7 @@ require 'yaml'
|
|
|
6
6
|
|
|
7
7
|
module Licensee
|
|
8
8
|
autoload :ContentHelper, 'licensee/content_helper'
|
|
9
|
+
autoload :HashHelper, 'licensee/hash_helper'
|
|
9
10
|
autoload :License, 'licensee/license'
|
|
10
11
|
autoload :LicenseField, 'licensee/license_field'
|
|
11
12
|
autoload :LicenseMeta, 'licensee/license_meta'
|
data/spec/bin_spec.rb
CHANGED
|
@@ -1,64 +1,21 @@
|
|
|
1
1
|
RSpec.describe 'command line invocation' do
|
|
2
|
-
let(:command) { ['
|
|
2
|
+
let(:command) { ['bundle', 'exec', 'bin/licensee', 'help'] }
|
|
3
|
+
let(:arguments) { [] }
|
|
3
4
|
let(:output) do
|
|
4
5
|
Dir.chdir project_root do
|
|
5
6
|
Open3.capture3(*[command, arguments].flatten)
|
|
6
7
|
end
|
|
7
8
|
end
|
|
9
|
+
let(:parsed_output) { YAML.safe_load(stdout) }
|
|
8
10
|
let(:stdout) { output[0] }
|
|
9
11
|
let(:stderr) { output[1] }
|
|
10
12
|
let(:status) { output[2] }
|
|
11
|
-
let(:hash) { '46cdc03462b9af57968df67b450cc4372ac41f53' }
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
it 'Returns a zero exit code' do
|
|
17
|
-
expect(status.exitstatus).to eql(0)
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
it "detects the folder's license" do
|
|
21
|
-
expect(stdout).to match('License: MIT License')
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
it 'outputs the hash' do
|
|
25
|
-
expect(stdout).to match(hash)
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
it 'outputs the attribution' do
|
|
29
|
-
expect(stdout).to match('2014-2017 Ben Balter')
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
it 'outputs the confidence' do
|
|
33
|
-
expect(stdout).to match('Confidence: 100.00%')
|
|
34
|
-
expect(stdout).to match('Confidence: 90.00%')
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
it 'outputs the method' do
|
|
38
|
-
expect(stdout).to match('Matcher: Licensee::Matchers::Exact')
|
|
39
|
-
expect(stdout).to match('Matcher: Licensee::Matchers::Gemspec')
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
it 'outputs the matched files' do
|
|
43
|
-
matched_files = 'Matched files: ["LICENSE.md", "licensee.gemspec"]'
|
|
44
|
-
expect(stdout).to include(matched_files)
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
context 'when given a folder path' do
|
|
49
|
-
let(:arguments) { [project_root] }
|
|
50
|
-
|
|
51
|
-
it "detects the folder's license" do
|
|
52
|
-
expect(stdout).to match('License: MIT License')
|
|
53
|
-
end
|
|
14
|
+
it 'Returns a zero exit code' do
|
|
15
|
+
expect(status.exitstatus).to eql(0)
|
|
54
16
|
end
|
|
55
17
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
let(:arguments) { [license_path] }
|
|
59
|
-
|
|
60
|
-
it "detects the file's license" do
|
|
61
|
-
expect(stdout).to match('License: MIT License')
|
|
62
|
-
end
|
|
18
|
+
it 'returns the help text' do
|
|
19
|
+
expect(stdout).to include('Licensee commands:')
|
|
63
20
|
end
|
|
64
21
|
end
|