licensee 9.9.2 → 9.9.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/licensee/license_meta.rb +4 -0
- data/lib/licensee/matchers/dice.rb +11 -9
- data/lib/licensee/matchers/exact.rb +2 -2
- data/lib/licensee/matchers/matcher.rb +6 -0
- data/lib/licensee/project_files/project_file.rb +14 -1
- data/lib/licensee/projects/fs_project.rb +13 -10
- data/lib/licensee/projects/git_project.rb +6 -3
- data/lib/licensee/projects/project.rb +13 -13
- data/lib/licensee/version.rb +1 -1
- data/spec/fixtures/detect.json +1 -1
- data/spec/licensee/license_meta_spec.rb +1 -1
- data/spec/licensee/matchers/dice_matcher_spec.rb +5 -5
- data/spec/licensee/project_files/project_file_spec.rb +3 -3
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9d245d544a683bfaff9448e8654a409cea3b6ddc808ba7f7b966c84e031255ea
|
4
|
+
data.tar.gz: 801c8048260b692571828fce99aa754afeb99063849e3e330e7fbb0b1b7117db
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 918b6abcf12b00722fb85c64112f2e11334a4b43d6f3b7d3335156a6bb21b0077432030f6c132aa0950af0b4860102a9a1c2d8548a5de5e1529852ae13e29ed1
|
7
|
+
data.tar.gz: 919b0c1a4390a2dd964e7f4d245194ef47e108e1336fc4f04b9795a97f17475ebc64dce12ff1bbd97bb805f5d1fc95774ece1878af17a89f4d57cf974582944b
|
@@ -18,9 +18,9 @@ module Licensee
|
|
18
18
|
# that begin with the title of a non-open source CC license variant
|
19
19
|
# 2. The percentage change in file length may not exceed the inverse
|
20
20
|
# of the confidence threshold
|
21
|
-
def
|
22
|
-
@
|
23
|
-
|
21
|
+
def potential_matches
|
22
|
+
@potential_matches ||= begin
|
23
|
+
super.select do |license|
|
24
24
|
if license.creative_commons? && file.potential_false_positive?
|
25
25
|
false
|
26
26
|
else
|
@@ -29,18 +29,20 @@ module Licensee
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
end
|
32
|
+
alias potential_licenses potential_matches
|
32
33
|
|
33
|
-
def
|
34
|
-
@
|
35
|
-
|
36
|
-
[
|
34
|
+
def matches_by_similarity
|
35
|
+
@matches_by_similarity ||= begin
|
36
|
+
matches = potential_matches.map do |potential_match|
|
37
|
+
[potential_match, potential_match.similarity(file)]
|
37
38
|
end
|
38
|
-
|
39
|
+
matches.sort_by { |_, similarity| similarity }.reverse
|
39
40
|
end
|
40
41
|
end
|
42
|
+
alias licenses_by_similarity matches_by_similarity
|
41
43
|
|
42
44
|
def matches
|
43
|
-
@matches ||=
|
45
|
+
@matches ||= matches_by_similarity.select do |_, similarity|
|
44
46
|
similarity >= Licensee.confidence_threshold
|
45
47
|
end
|
46
48
|
end
|
@@ -3,8 +3,8 @@ module Licensee
|
|
3
3
|
class Exact < Licensee::Matchers::Matcher
|
4
4
|
def match
|
5
5
|
return @match if defined? @match
|
6
|
-
@match =
|
7
|
-
|
6
|
+
@match = potential_matches.find do |potential_match|
|
7
|
+
potential_match.wordset == file.wordset
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
@@ -42,9 +42,23 @@ module Licensee
|
|
42
42
|
@data = metadata || {}
|
43
43
|
end
|
44
44
|
|
45
|
+
# TODO: In the next major release, filename should be the basename
|
46
|
+
# and path should be either the absolute path or the relative path to
|
47
|
+
# the project root, but maintaining the alias for backward compatability
|
45
48
|
def filename
|
46
49
|
@data[:name]
|
47
50
|
end
|
51
|
+
alias path filename
|
52
|
+
|
53
|
+
def directory
|
54
|
+
@data[:dir] || '.'
|
55
|
+
end
|
56
|
+
alias dir directory
|
57
|
+
|
58
|
+
def path_relative_to_root
|
59
|
+
File.join(directory, filename)
|
60
|
+
end
|
61
|
+
alias relative_path path_relative_to_root
|
48
62
|
|
49
63
|
def possible_matchers
|
50
64
|
raise 'Not implemented'
|
@@ -64,7 +78,6 @@ module Licensee
|
|
64
78
|
end
|
65
79
|
|
66
80
|
alias match license
|
67
|
-
alias path filename
|
68
81
|
|
69
82
|
def matched_license
|
70
83
|
license.spdx_id if license
|
@@ -10,14 +10,14 @@ module Licensee
|
|
10
10
|
class FSProject < Licensee::Projects::Project
|
11
11
|
def initialize(path, **args)
|
12
12
|
if ::File.file?(path)
|
13
|
-
@pattern =
|
14
|
-
@dir =
|
13
|
+
@pattern = File.basename(path)
|
14
|
+
@dir = File.expand_path File.dirname(path)
|
15
15
|
else
|
16
16
|
@pattern = '*'
|
17
|
-
@dir = path
|
17
|
+
@dir = File.expand_path(path)
|
18
18
|
end
|
19
19
|
|
20
|
-
@root = args.delete(:search_root) || @dir
|
20
|
+
@root = File.expand_path(args.delete(:search_root) || @dir)
|
21
21
|
unless valid_search_root?
|
22
22
|
raise 'Search root must be the project path directory or its ancestor'
|
23
23
|
end
|
@@ -33,9 +33,10 @@ module Licensee
|
|
33
33
|
# :dir - the directory path containing the file
|
34
34
|
def files
|
35
35
|
@files ||= search_directories.flat_map do |dir|
|
36
|
+
relative_dir = Pathname.new(dir).relative_path_from(dir_path).to_s
|
36
37
|
Dir.glob(::File.join(dir, @pattern).tr('\\', '/')).map do |file|
|
37
38
|
next unless ::File.file?(file)
|
38
|
-
{ name: ::File.basename(file), dir:
|
39
|
+
{ name: ::File.basename(file), dir: relative_dir }
|
39
40
|
end.compact
|
40
41
|
end
|
41
42
|
end
|
@@ -46,13 +47,12 @@ module Licensee
|
|
46
47
|
#
|
47
48
|
# Returns the file contents as a string
|
48
49
|
def load_file(file)
|
49
|
-
|
50
|
+
File.read dir_path.join(file[:dir], file[:name])
|
50
51
|
end
|
51
52
|
|
52
53
|
# Returns true if @dir is @root or it's descendant
|
53
54
|
def valid_search_root?
|
54
|
-
|
55
|
-
dir.fnmatch?(@root) || dir.fnmatch?(::File.join(@root, '**'))
|
55
|
+
dir_path.fnmatch?(@root) || dir_path.fnmatch?(::File.join(@root, '**'))
|
56
56
|
end
|
57
57
|
|
58
58
|
# Returns the set of unique paths to search for project files
|
@@ -66,13 +66,16 @@ module Licensee
|
|
66
66
|
# Enumerates all directories to search, from @dir to @root
|
67
67
|
def search_enumerator
|
68
68
|
root = Pathname.new(@root)
|
69
|
-
dir = Pathname.new(@dir)
|
70
69
|
Enumerator.new do |yielder|
|
71
|
-
|
70
|
+
dir_path.relative_path_from(root).ascend do |relative|
|
72
71
|
yielder.yield root.join(relative)
|
73
72
|
end
|
74
73
|
end
|
75
74
|
end
|
75
|
+
|
76
|
+
def dir_path
|
77
|
+
@dir_path ||= Pathname.new(@dir)
|
78
|
+
end
|
76
79
|
end
|
77
80
|
end
|
78
81
|
end
|
@@ -59,9 +59,12 @@ module Licensee
|
|
59
59
|
# :name - the file's path relative to the repo root
|
60
60
|
# :oid - the file's OID
|
61
61
|
def files
|
62
|
-
@files ||= commit.tree
|
63
|
-
|
64
|
-
|
62
|
+
@files ||= files_from_tree(commit.tree)
|
63
|
+
end
|
64
|
+
|
65
|
+
def files_from_tree(tree, dir = '.')
|
66
|
+
tree.select { |e| e[:type] == :blob }.map do |entry|
|
67
|
+
entry.merge(dir: dir)
|
65
68
|
end.compact
|
66
69
|
end
|
67
70
|
end
|
@@ -68,13 +68,13 @@ module Licensee
|
|
68
68
|
return unless detect_readme?
|
69
69
|
return @readme if defined? @readme
|
70
70
|
@readme = begin
|
71
|
-
content,
|
71
|
+
content, file = find_file do |n|
|
72
72
|
Licensee::ProjectFiles::ReadmeFile.name_score(n)
|
73
73
|
end
|
74
74
|
content = Licensee::ProjectFiles::ReadmeFile.license_content(content)
|
75
75
|
|
76
|
-
return unless content &&
|
77
|
-
Licensee::ProjectFiles::ReadmeFile.new(content,
|
76
|
+
return unless content && file
|
77
|
+
Licensee::ProjectFiles::ReadmeFile.new(content, file)
|
78
78
|
end
|
79
79
|
end
|
80
80
|
alias readme readme_file
|
@@ -83,12 +83,12 @@ module Licensee
|
|
83
83
|
return unless detect_packages?
|
84
84
|
return @package_file if defined? @package_file
|
85
85
|
@package_file = begin
|
86
|
-
content,
|
86
|
+
content, file = find_file do |n|
|
87
87
|
Licensee::ProjectFiles::PackageManagerFile.name_score(n)
|
88
88
|
end
|
89
89
|
|
90
|
-
return unless content &&
|
91
|
-
Licensee::ProjectFiles::PackageManagerFile.new(content,
|
90
|
+
return unless content && file
|
91
|
+
Licensee::ProjectFiles::PackageManagerFile.new(content, file)
|
92
92
|
end
|
93
93
|
end
|
94
94
|
|
@@ -115,7 +115,7 @@ module Licensee
|
|
115
115
|
def find_file(&block)
|
116
116
|
return if files.empty? || files.nil?
|
117
117
|
file = find_files(&block).first
|
118
|
-
[load_file(file), file
|
118
|
+
[load_file(file), file] if file
|
119
119
|
end
|
120
120
|
|
121
121
|
# Given an array of LicenseFiles, ensures LGPL is the first entry,
|
@@ -147,14 +147,14 @@ module Licensee
|
|
147
147
|
matched_files.reject(&:copyright?).map(&:license).uniq
|
148
148
|
end
|
149
149
|
end
|
150
|
-
end
|
151
150
|
|
152
|
-
|
153
|
-
|
154
|
-
|
151
|
+
def files
|
152
|
+
raise 'Not implemented'
|
153
|
+
end
|
155
154
|
|
156
|
-
|
157
|
-
|
155
|
+
def load_file(_file)
|
156
|
+
raise 'Not implemented'
|
157
|
+
end
|
158
158
|
end
|
159
159
|
end
|
160
160
|
end
|
data/lib/licensee/version.rb
CHANGED
data/spec/fixtures/detect.json
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
"spdx_id": "MIT",
|
6
6
|
"meta": {
|
7
7
|
"title": "MIT License",
|
8
|
-
"source": "https://
|
8
|
+
"source": "https://spdx.org/licenses/MIT.html",
|
9
9
|
"description": "A short and simple permissive license with conditions only requiring preservation of copyright and license notices. Licensed works, modifications, and larger works may be distributed under different terms and without source code.",
|
10
10
|
"how": "Create a text file (typically named LICENSE or LICENSE.txt) in the root of your source code and copy the text of the license into the file. Replace [year] with the current year and [fullname] with the name (or names) of the copyright holders.",
|
11
11
|
"using": [
|
@@ -126,7 +126,7 @@ RSpec.describe Licensee::LicenseMeta do
|
|
126
126
|
let(:expected) do
|
127
127
|
{
|
128
128
|
title: 'MIT License',
|
129
|
-
source: 'https://
|
129
|
+
source: 'https://spdx.org/licenses/MIT.html',
|
130
130
|
description: subject.description.to_s,
|
131
131
|
how: subject.how.to_s,
|
132
132
|
using: using,
|
@@ -17,17 +17,17 @@ RSpec.describe Licensee::Matchers::Dice do
|
|
17
17
|
end
|
18
18
|
|
19
19
|
it 'builds a list of potential licenses' do
|
20
|
-
expect(subject.
|
20
|
+
expect(subject.potential_matches).to eql([agpl, gpl])
|
21
21
|
end
|
22
22
|
|
23
23
|
it 'sorts licenses by similarity' do
|
24
|
-
expect(subject.
|
25
|
-
expect(subject.
|
24
|
+
expect(subject.matches_by_similarity[0]).to eql([gpl, 100.0])
|
25
|
+
expect(subject.matches_by_similarity[1]).to eql([agpl, 95.76581285938317])
|
26
26
|
end
|
27
27
|
|
28
28
|
it 'returns a list of licenses above the confidence threshold' do
|
29
|
-
expect(subject.
|
30
|
-
expect(subject.
|
29
|
+
expect(subject.matches_by_similarity[0]).to eql([gpl, 100.0])
|
30
|
+
expect(subject.matches_by_similarity[1]).to eql([agpl, 95.76581285938317])
|
31
31
|
end
|
32
32
|
|
33
33
|
it 'returns the match confidence' do
|
@@ -4,7 +4,7 @@ RSpec.describe Licensee::ProjectFiles::ProjectFile do
|
|
4
4
|
let(:content) { mit.content }
|
5
5
|
let(:possible_matchers) { [Licensee::Matchers::Exact] }
|
6
6
|
|
7
|
-
subject {
|
7
|
+
subject { Licensee::ProjectFiles::LicenseFile.new(content, filename) }
|
8
8
|
before do
|
9
9
|
allow(subject).to receive(:possible_matchers).and_return(possible_matchers)
|
10
10
|
end
|
@@ -50,8 +50,8 @@ RSpec.describe Licensee::ProjectFiles::ProjectFile do
|
|
50
50
|
{
|
51
51
|
filename: 'LICENSE.txt',
|
52
52
|
content: mit.content.to_s,
|
53
|
-
content_hash:
|
54
|
-
content_normalized:
|
53
|
+
content_hash: subject.content_hash,
|
54
|
+
content_normalized: subject.content_normalized,
|
55
55
|
matcher: {
|
56
56
|
name: :exact,
|
57
57
|
confidence: 100
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: licensee
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 9.9.
|
4
|
+
version: 9.9.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ben Balter
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-08-
|
11
|
+
date: 2018-08-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dotenv
|