license_finder 0.7.3 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -3
- data/.travis.yml +1 -8
- data/bin/license_finder +31 -1
- data/db/migrate/201303290935_create_dependencies.rb +14 -0
- data/db/migrate/201303291155_create_licenses.rb +13 -0
- data/db/migrate/201303291402_create_approvals.rb +13 -0
- data/db/migrate/201303291456_create_ancestries.rb +9 -0
- data/db/migrate/201303291519_create_bundler_groups.rb +13 -0
- data/db/migrate/201303291720_move_manual_from_approvals_to_licenses.rb +11 -0
- data/db/migrate/201303291753_allow_null_license_names.rb +7 -0
- data/db/migrate/201304011027_allow_null_dependency_version.rb +7 -0
- data/db/migrate/201304020947_change_table_name_licenses_to_license_aliases.rb +5 -0
- data/features/approve_dependencies.feature +0 -45
- data/features/html_report.feature +1 -11
- data/features/license_finder.feature +13 -27
- data/features/license_finder_rake_task.feature +2 -1
- data/features/set_license.feature +2 -4
- data/features/step_definitions/license_finder_steps.rb +25 -0
- data/features/step_definitions/steps.rb +40 -26
- data/features/text_report.feature +2 -2
- data/files/license_finder.yml +1 -1
- data/lib/license_finder.rb +14 -6
- data/lib/license_finder/bundle.rb +4 -17
- data/lib/license_finder/bundle_syncer.rb +2 -3
- data/lib/license_finder/bundled_gem.rb +4 -47
- data/lib/license_finder/cli.rb +9 -16
- data/lib/license_finder/configuration.rb +55 -3
- data/lib/license_finder/dependency_report.rb +1 -1
- data/lib/license_finder/gem_saver.rb +69 -0
- data/lib/license_finder/html_report.rb +2 -2
- data/lib/license_finder/license.rb +60 -58
- data/lib/license_finder/license_files.rb +36 -0
- data/lib/license_finder/license_url.rb +8 -6
- data/lib/license_finder/platform.rb +32 -0
- data/lib/license_finder/possible_license_file.rb +1 -1
- data/lib/license_finder/tables.rb +7 -0
- data/lib/license_finder/tables/approval.rb +4 -0
- data/lib/license_finder/tables/bundler_group.rb +4 -0
- data/lib/license_finder/tables/dependency.rb +31 -0
- data/lib/license_finder/tables/license_alias.rb +22 -0
- data/lib/license_finder/yml_to_sql.rb +127 -0
- data/lib/tasks/license_finder.rake +3 -0
- data/lib/templates/html_report.erb +50 -32
- data/lib/templates/text_report.erb +3 -2
- data/license_finder.gemspec +14 -5
- data/readme.md +10 -50
- data/spec/lib/license_finder/bundle_spec.rb +22 -19
- data/spec/lib/license_finder/bundle_syncer_spec.rb +4 -10
- data/spec/lib/license_finder/bundled_gem_spec.rb +40 -108
- data/spec/lib/license_finder/cli_spec.rb +3 -3
- data/spec/lib/license_finder/configuration_spec.rb +53 -21
- data/spec/lib/license_finder/gem_saver_spec.rb +155 -0
- data/spec/lib/license_finder/html_report_spec.rb +32 -15
- data/spec/lib/license_finder/license_files_spec.rb +50 -0
- data/spec/lib/license_finder/tables/dependency_spec.rb +102 -0
- data/spec/lib/license_finder/tables/license_alias_spec.rb +54 -0
- data/spec/lib/license_finder/text_report_spec.rb +6 -4
- data/spec/lib/license_finder/yml_to_sql_spec.rb +99 -0
- data/spec/lib/license_finder_spec.rb +5 -5
- data/spec/spec_helper.rb +17 -1
- metadata +79 -32
- data/lib/license_finder/dependency.rb +0 -50
- data/lib/license_finder/persistence.rb +0 -1
- data/lib/license_finder/persistence/yaml.rb +0 -7
- data/lib/license_finder/persistence/yaml/configuration.rb +0 -34
- data/lib/license_finder/persistence/yaml/dependency.rb +0 -127
- data/lib/license_finder/source_syncer.rb +0 -40
- data/lib/templates/dependency.html.erb +0 -54
- data/spec/lib/license_finder/dependency_spec.rb +0 -188
- data/spec/lib/license_finder/persistence/yaml/dependency_spec.rb +0 -5
- data/spec/lib/license_finder/source_syncer_spec.rb +0 -37
- data/spec/support/shared_examples/persistence/configuration.rb +0 -28
- data/spec/support/shared_examples/persistence/dependency.rb +0 -138
@@ -1,50 +0,0 @@
|
|
1
|
-
module LicenseFinder
|
2
|
-
class Dependency < LicenseFinder::Persistence::Dependency
|
3
|
-
def approved
|
4
|
-
self.approved = !!(config.whitelisted?(license) || super)
|
5
|
-
end
|
6
|
-
|
7
|
-
def license_files
|
8
|
-
super || (self.license_files = [])
|
9
|
-
end
|
10
|
-
|
11
|
-
def bundler_groups
|
12
|
-
super || (self.bundler_groups = [])
|
13
|
-
end
|
14
|
-
|
15
|
-
def children
|
16
|
-
super || (self.children = [])
|
17
|
-
end
|
18
|
-
|
19
|
-
def parents
|
20
|
-
super || (self.parents = [])
|
21
|
-
end
|
22
|
-
|
23
|
-
def approve!
|
24
|
-
self.approved = true
|
25
|
-
save
|
26
|
-
end
|
27
|
-
|
28
|
-
def license_url
|
29
|
-
LicenseFinder::LicenseUrl.find_by_name license
|
30
|
-
end
|
31
|
-
|
32
|
-
def merge(other)
|
33
|
-
raise "Cannot merge dependencies with different names. Expected #{name}, was #{other.name}." unless other.name == name
|
34
|
-
|
35
|
-
new_attributes = other.attributes.merge("notes" => notes)
|
36
|
-
|
37
|
-
if other.license == license || other.license == 'other'
|
38
|
-
new_attributes["approved"] = approved
|
39
|
-
new_attributes["license"] = license
|
40
|
-
else
|
41
|
-
new_attributes["approved"] = nil
|
42
|
-
end
|
43
|
-
|
44
|
-
update_attributes new_attributes
|
45
|
-
|
46
|
-
self
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
@@ -1 +0,0 @@
|
|
1
|
-
|
@@ -1,34 +0,0 @@
|
|
1
|
-
module LicenseFinder
|
2
|
-
module Persistence
|
3
|
-
class Configuration
|
4
|
-
attr_accessor :whitelist, :ignore_groups, :dependencies_dir
|
5
|
-
|
6
|
-
def initialize(config={})
|
7
|
-
if File.exists?(config_file_path)
|
8
|
-
yaml = File.read(config_file_path)
|
9
|
-
config = YAML.load(yaml).merge config
|
10
|
-
end
|
11
|
-
|
12
|
-
@whitelist = config['whitelist'] || []
|
13
|
-
@ignore_groups = (config["ignore_groups"] || []).map(&:to_sym)
|
14
|
-
@dependencies_dir = config['dependencies_file_dir'] || '.'
|
15
|
-
end
|
16
|
-
|
17
|
-
def config_file_path
|
18
|
-
File.join('.', 'config', 'license_finder.yml')
|
19
|
-
end
|
20
|
-
|
21
|
-
def dependencies_yaml
|
22
|
-
File.join(dependencies_dir, "dependencies.yml")
|
23
|
-
end
|
24
|
-
|
25
|
-
def dependencies_text
|
26
|
-
File.join(dependencies_dir, "dependencies.txt")
|
27
|
-
end
|
28
|
-
|
29
|
-
def dependencies_html
|
30
|
-
File.join(dependencies_dir, "dependencies.html")
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
@@ -1,127 +0,0 @@
|
|
1
|
-
module LicenseFinder
|
2
|
-
module Persistence
|
3
|
-
class Dependency
|
4
|
-
class Database
|
5
|
-
def initialize
|
6
|
-
@dependency_attributes = YAML.load File.read(LicenseFinder.config.dependencies_yaml) if File.exists?(LicenseFinder.config.dependencies_yaml)
|
7
|
-
end
|
8
|
-
|
9
|
-
def find(&block)
|
10
|
-
dependency_attributes.detect &block
|
11
|
-
end
|
12
|
-
|
13
|
-
def update(dependency_hash)
|
14
|
-
destroy_by_name_without_saving dependency_hash['name']
|
15
|
-
dependency_attributes << dependency_hash
|
16
|
-
persist!
|
17
|
-
end
|
18
|
-
|
19
|
-
def delete_all
|
20
|
-
File.delete(LicenseFinder.config.dependencies_yaml) if File.exists?(LicenseFinder.config.dependencies_yaml)
|
21
|
-
@dependency_attributes = nil
|
22
|
-
end
|
23
|
-
|
24
|
-
def destroy_by_name(name)
|
25
|
-
destroy_by_name_without_saving name
|
26
|
-
persist!
|
27
|
-
end
|
28
|
-
|
29
|
-
def persist!
|
30
|
-
File.open(LicenseFinder.config.dependencies_yaml, 'w+') do |f|
|
31
|
-
f.write dependency_attributes.to_yaml
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
def all
|
36
|
-
dependency_attributes
|
37
|
-
end
|
38
|
-
|
39
|
-
private
|
40
|
-
def destroy_by_name_without_saving(name)
|
41
|
-
dependency_attributes.reject! { |a| a['name'] == name }
|
42
|
-
end
|
43
|
-
|
44
|
-
def dependency_attributes
|
45
|
-
@dependency_attributes ||= []
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
attr_accessor *LicenseFinder::DEPENDENCY_ATTRIBUTES
|
50
|
-
|
51
|
-
class << self
|
52
|
-
def find_by_name(name)
|
53
|
-
attributes = database.find { |a| a['name'] == name }
|
54
|
-
new(attributes) if attributes
|
55
|
-
end
|
56
|
-
|
57
|
-
def delete_all
|
58
|
-
database.delete_all
|
59
|
-
end
|
60
|
-
|
61
|
-
def all
|
62
|
-
database.all.map { |attributes| new(attributes) }
|
63
|
-
end
|
64
|
-
|
65
|
-
def unapproved
|
66
|
-
all.select {|d| d.approved == false }
|
67
|
-
end
|
68
|
-
|
69
|
-
def update(attributes)
|
70
|
-
database.update attributes
|
71
|
-
end
|
72
|
-
|
73
|
-
def destroy_by_name(name)
|
74
|
-
database.destroy_by_name name
|
75
|
-
end
|
76
|
-
|
77
|
-
private
|
78
|
-
def database
|
79
|
-
@database ||= Database.new
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
def initialize(attributes = {})
|
84
|
-
update_attributes_without_saving attributes
|
85
|
-
end
|
86
|
-
|
87
|
-
def config
|
88
|
-
LicenseFinder.config
|
89
|
-
end
|
90
|
-
|
91
|
-
def update_attributes new_values
|
92
|
-
update_attributes_without_saving(new_values)
|
93
|
-
save
|
94
|
-
end
|
95
|
-
|
96
|
-
def approved?
|
97
|
-
!!approved
|
98
|
-
end
|
99
|
-
|
100
|
-
def save
|
101
|
-
self.class.update(attributes)
|
102
|
-
end
|
103
|
-
|
104
|
-
def destroy
|
105
|
-
self.class.destroy_by_name(name)
|
106
|
-
end
|
107
|
-
|
108
|
-
def attributes
|
109
|
-
attributes = {}
|
110
|
-
|
111
|
-
LicenseFinder::DEPENDENCY_ATTRIBUTES.each do |attrib|
|
112
|
-
attributes[attrib] = send attrib
|
113
|
-
end
|
114
|
-
|
115
|
-
attributes
|
116
|
-
end
|
117
|
-
|
118
|
-
private
|
119
|
-
def update_attributes_without_saving(new_values)
|
120
|
-
new_values.each do |key, value|
|
121
|
-
send("#{key}=", value)
|
122
|
-
end
|
123
|
-
end
|
124
|
-
end
|
125
|
-
end
|
126
|
-
end
|
127
|
-
|
@@ -1,40 +0,0 @@
|
|
1
|
-
module LicenseFinder
|
2
|
-
class SourceSyncer
|
3
|
-
def initialize(source_dependencies, dependencies)
|
4
|
-
@source_dependencies = Array source_dependencies
|
5
|
-
@dependencies = dependencies
|
6
|
-
end
|
7
|
-
|
8
|
-
def sync!
|
9
|
-
destroy_obsolete_dependencies
|
10
|
-
update_existing_dependencies
|
11
|
-
create_new_dependencies
|
12
|
-
dependencies
|
13
|
-
end
|
14
|
-
|
15
|
-
protected
|
16
|
-
attr_accessor :dependencies, :source_dependencies
|
17
|
-
|
18
|
-
def destroy_obsolete_dependencies
|
19
|
-
obsolete_dependencies = dependencies.select {|d| !source_dependencies.detect {|s| s.name == d.name }}
|
20
|
-
obsolete_dependencies.map &:destroy
|
21
|
-
|
22
|
-
self.dependencies -= obsolete_dependencies
|
23
|
-
end
|
24
|
-
|
25
|
-
def update_existing_dependencies
|
26
|
-
dependencies.each do |d|
|
27
|
-
source_dep = source_dependencies.detect { |s| s.name == d.name }
|
28
|
-
d.merge(source_dep)
|
29
|
-
self.source_dependencies -= [source_dep]
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def create_new_dependencies
|
34
|
-
source_dependencies.each do |d|
|
35
|
-
dependencies << d
|
36
|
-
d.save
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
@@ -1,54 +0,0 @@
|
|
1
|
-
<div id="<%= name %>" class="<%= approved ? "approved" : "unapproved" %>">
|
2
|
-
<h2>
|
3
|
-
<% if homepage && !homepage.empty? %>
|
4
|
-
<a href="<%= homepage %>"><%= name %></a>
|
5
|
-
<% else %>
|
6
|
-
<%= name %>
|
7
|
-
<% end %>
|
8
|
-
v<%= version %>
|
9
|
-
<% if bundler_groups.any? %>
|
10
|
-
(<%= bundler_groups.join(", ") %>)
|
11
|
-
<% end %>
|
12
|
-
</h2>
|
13
|
-
<table class="table table-striped table-bordered">
|
14
|
-
<thead>
|
15
|
-
<tr>
|
16
|
-
<th>Summary</th>
|
17
|
-
<th>Description</th>
|
18
|
-
<th>License</th>
|
19
|
-
</tr>
|
20
|
-
</thead>
|
21
|
-
<tbody>
|
22
|
-
<tr>
|
23
|
-
<td><%= summary %></td>
|
24
|
-
<td><%= description %></td>
|
25
|
-
<td>
|
26
|
-
<% if license_url && !license_url.empty? %>
|
27
|
-
<a href="<%= license_url %>"><%= license %></a>
|
28
|
-
<% else %>
|
29
|
-
<%= license %>
|
30
|
-
<% end %>
|
31
|
-
</td>
|
32
|
-
</td>
|
33
|
-
</tr>
|
34
|
-
</tbody>
|
35
|
-
</table>
|
36
|
-
|
37
|
-
<% if parents.any? %>
|
38
|
-
<dl>
|
39
|
-
<dt>Parents</dt>
|
40
|
-
<% parents.each do |parent| %>
|
41
|
-
<dd><%= parent %></dd>
|
42
|
-
<% end %>
|
43
|
-
</dl>
|
44
|
-
<% end %>
|
45
|
-
|
46
|
-
<% if children.any? %>
|
47
|
-
<dl>
|
48
|
-
<dt>Children</dt>
|
49
|
-
<% children.each do |child| %>
|
50
|
-
<dd><%= child %></dd>
|
51
|
-
<% end %>
|
52
|
-
</dl>
|
53
|
-
<% end %>
|
54
|
-
</div>
|
@@ -1,188 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
module LicenseFinder
|
4
|
-
describe Dependency do
|
5
|
-
let(:attributes) do
|
6
|
-
{
|
7
|
-
'name' => "spec_name",
|
8
|
-
'version' => "2.1.3",
|
9
|
-
'license' => "GPLv2",
|
10
|
-
'approved' => false,
|
11
|
-
'notes' => 'some notes',
|
12
|
-
'homepage' => 'homepage',
|
13
|
-
'license_files' => ['/Users/pivotal/foo/lic1', '/Users/pivotal/bar/lic2'],
|
14
|
-
'source' => "bundle",
|
15
|
-
'bundler_groups' => ["test"]
|
16
|
-
}
|
17
|
-
end
|
18
|
-
|
19
|
-
let(:config) { LicenseFinder::Configuration.new }
|
20
|
-
|
21
|
-
before do
|
22
|
-
LicenseFinder.stub(:config).and_return config
|
23
|
-
config.whitelist = ["MIT", "other"]
|
24
|
-
end
|
25
|
-
|
26
|
-
describe "#approved" do
|
27
|
-
it "should return true when the license is whitelisted" do
|
28
|
-
dependency = Dependency.new('license' => 'MIT')
|
29
|
-
dependency.should be_approved
|
30
|
-
end
|
31
|
-
|
32
|
-
it "should return true when the license is an alternative name of a whitelisted license" do
|
33
|
-
dependency = Dependency.new('license' => 'Expat')
|
34
|
-
dependency.should be_approved
|
35
|
-
end
|
36
|
-
|
37
|
-
it "should return true when the license has no matching license class, but is whitelisted anyways" do
|
38
|
-
dependency = Dependency.new('license' => 'other')
|
39
|
-
dependency.should be_approved
|
40
|
-
end
|
41
|
-
|
42
|
-
it "should return false when the license is not whitelisted" do
|
43
|
-
dependency = Dependency.new('license' => 'GPL')
|
44
|
-
dependency.approved.should == false
|
45
|
-
end
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
it "should be overridable" do
|
50
|
-
dependency = Dependency.new
|
51
|
-
dependency.approved = true
|
52
|
-
dependency.approved.should == true
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
describe '#license_url' do
|
57
|
-
it "should delegate to LicenseUrl.find_by_name" do
|
58
|
-
LicenseFinder::LicenseUrl.stub(:find_by_name).with("MIT").and_return "http://license-url.com"
|
59
|
-
Dependency.new(:license => "MIT").license_url.should == "http://license-url.com"
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
describe '#merge' do
|
64
|
-
subject do
|
65
|
-
Dependency.new(
|
66
|
-
'name' => 'foo',
|
67
|
-
'license' => 'MIT',
|
68
|
-
'version' => '0.0.1',
|
69
|
-
'license_files' => "old license files"
|
70
|
-
)
|
71
|
-
end
|
72
|
-
|
73
|
-
let(:new_dep) do
|
74
|
-
Dependency.new(
|
75
|
-
'name' => 'foo',
|
76
|
-
'license' => 'MIT',
|
77
|
-
'version' => '0.0.2',
|
78
|
-
'license_files' => "new license files",
|
79
|
-
'summary' => 'foo summary',
|
80
|
-
'description' => 'awesome foo description!',
|
81
|
-
'bundler_groups' => [1, 2, 3],
|
82
|
-
'homepage' => "http://new.homepage"
|
83
|
-
)
|
84
|
-
end
|
85
|
-
|
86
|
-
it 'should raise an error if the names do not match' do
|
87
|
-
new_dep.name = 'bar'
|
88
|
-
|
89
|
-
expect {
|
90
|
-
subject.merge(new_dep)
|
91
|
-
}.to raise_error
|
92
|
-
end
|
93
|
-
|
94
|
-
it 'should return the new version, license files, source, and homepage' do
|
95
|
-
merged = subject.merge(new_dep)
|
96
|
-
|
97
|
-
merged.version.should == '0.0.2'
|
98
|
-
merged.license_files.should == new_dep.license_files
|
99
|
-
merged.source.should == new_dep.source
|
100
|
-
merged.homepage.should == new_dep.homepage
|
101
|
-
end
|
102
|
-
|
103
|
-
it 'should return the new summary and description and bundle groups' do
|
104
|
-
merged = subject.merge new_dep
|
105
|
-
|
106
|
-
merged.summary.should == new_dep.summary
|
107
|
-
merged.description.should == new_dep.description
|
108
|
-
merged.bundler_groups.should == new_dep.bundler_groups
|
109
|
-
end
|
110
|
-
|
111
|
-
it 'should return the old notes' do
|
112
|
-
subject.notes = 'old notes'
|
113
|
-
new_dep.notes = 'new notes'
|
114
|
-
|
115
|
-
merged = subject.merge(new_dep)
|
116
|
-
|
117
|
-
merged.notes.should == 'old notes'
|
118
|
-
end
|
119
|
-
|
120
|
-
context "license changes to something other than 'other'" do
|
121
|
-
before { new_dep.license = 'new license' }
|
122
|
-
|
123
|
-
context "new license is whitelisted" do
|
124
|
-
before { LicenseFinder.config.stub(:whitelist).and_return [new_dep.license] }
|
125
|
-
|
126
|
-
it "should set the approval to true" do
|
127
|
-
merged = subject.merge new_dep
|
128
|
-
merged.should be_approved
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
|
-
context "new license is not whitelisted" do
|
133
|
-
it "should set the approval to false" do
|
134
|
-
merged = subject.merge new_dep
|
135
|
-
merged.should_not be_approved
|
136
|
-
end
|
137
|
-
end
|
138
|
-
end
|
139
|
-
|
140
|
-
context "license changes to unknown (i.e., 'other')" do
|
141
|
-
before { new_dep.license = 'other' }
|
142
|
-
|
143
|
-
it "should not change the license" do
|
144
|
-
merged = subject.merge new_dep
|
145
|
-
merged.license.should == 'MIT'
|
146
|
-
end
|
147
|
-
|
148
|
-
it "should not change the approval" do
|
149
|
-
approved = subject.approved?
|
150
|
-
merged = subject.merge new_dep
|
151
|
-
merged.approved?.should == approved
|
152
|
-
end
|
153
|
-
end
|
154
|
-
|
155
|
-
context "license does not change" do
|
156
|
-
before { new_dep.license.should == subject.license }
|
157
|
-
|
158
|
-
it "should not change the license or approval" do
|
159
|
-
existing_license = subject.license
|
160
|
-
existing_approval = subject.approved?
|
161
|
-
merged = subject.merge new_dep
|
162
|
-
merged.approved?.should == existing_approval
|
163
|
-
merged.license.should == existing_license
|
164
|
-
end
|
165
|
-
end
|
166
|
-
end
|
167
|
-
|
168
|
-
describe '#approve!' do
|
169
|
-
it "should update the yaml file to show the gem is approved" do
|
170
|
-
gem = Dependency.new(name: "foo")
|
171
|
-
gem.approve!
|
172
|
-
reloaded_gem = Dependency.find_by_name(gem.name)
|
173
|
-
reloaded_gem.approved.should be_true
|
174
|
-
end
|
175
|
-
end
|
176
|
-
|
177
|
-
describe "defaults" do
|
178
|
-
%w(license_files bundler_groups children parents).each do |attribute|
|
179
|
-
describe "##{attribute}" do
|
180
|
-
it "should default to an empty array" do
|
181
|
-
Dependency.new.send(attribute).should == []
|
182
|
-
end
|
183
|
-
end
|
184
|
-
end
|
185
|
-
end
|
186
|
-
end
|
187
|
-
end
|
188
|
-
|