license_finder 0.6.0 → 0.7.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.
- data/.gitignore +4 -0
- data/Gemfile +0 -1
- data/bin/license_finder +21 -1
- data/features/approve_dependencies.feature +10 -0
- data/features/license_finder.feature +13 -3
- data/features/license_finder_rake_task.feature +3 -3
- data/features/set_license.feature +14 -0
- data/features/step_definitions/steps.rb +5 -0
- data/lib/license_finder.rb +13 -2
- data/lib/license_finder/bundle.rb +25 -3
- data/lib/license_finder/bundle_syncer.rb +12 -0
- data/lib/license_finder/bundled_gem.rb +12 -1
- data/lib/license_finder/cli.rb +42 -3
- data/lib/license_finder/configuration.rb +1 -31
- data/lib/license_finder/dependency.rb +30 -94
- data/lib/license_finder/dependency_report.rb +30 -0
- data/lib/license_finder/html_report.rb +14 -0
- data/lib/license_finder/persistence.rb +1 -0
- data/lib/license_finder/persistence/yaml.rb +7 -0
- data/lib/license_finder/persistence/yaml/configuration.rb +34 -0
- data/lib/license_finder/persistence/yaml/dependency.rb +127 -0
- data/lib/license_finder/reporter.rb +7 -38
- data/lib/license_finder/source_syncer.rb +40 -0
- data/lib/license_finder/text_report.rb +9 -0
- data/lib/templates/dependency.html.erb +2 -2
- data/lib/templates/html_report.erb +93 -0
- data/lib/templates/text_report.erb +2 -0
- data/license_finder.gemspec +2 -2
- data/{README.markdown → readme.md} +22 -11
- data/spec/lib/license_finder/bundle_spec.rb +58 -0
- data/spec/lib/license_finder/bundle_syncer_spec.rb +22 -0
- data/spec/lib/license_finder/bundled_gem_spec.rb +17 -14
- data/spec/lib/license_finder/cli_spec.rb +38 -0
- data/spec/lib/license_finder/dependency_spec.rb +130 -223
- data/spec/lib/license_finder/html_report_spec.rb +67 -0
- data/spec/lib/license_finder/persistence/yaml/configuration_spec.rb +5 -0
- data/spec/lib/license_finder/persistence/yaml/dependency_spec.rb +5 -0
- data/spec/lib/license_finder/possible_license_file_spec.rb +4 -9
- data/spec/lib/license_finder/reporter_spec.rb +0 -1
- data/spec/lib/license_finder/source_syncer_spec.rb +37 -0
- data/spec/lib/license_finder/text_report_spec.rb +29 -0
- data/spec/lib/license_finder_spec.rb +9 -11
- data/spec/spec_helper.rb +1 -1
- data/spec/support/license_examples.rb +1 -1
- data/spec/support/shared_examples/persistence/configuration.rb +34 -0
- data/spec/support/shared_examples/persistence/dependency.rb +139 -0
- metadata +38 -26
- data/lib/license_finder/dependency_list.rb +0 -80
- data/lib/license_finder/viewable.rb +0 -31
- data/lib/templates/dependency_list.html.erb +0 -38
- data/spec/lib/license_finder/dependency_list_spec.rb +0 -243
@@ -0,0 +1,30 @@
|
|
1
|
+
module LicenseFinder
|
2
|
+
class DependencyReport
|
3
|
+
def self.underscored_name
|
4
|
+
@underscored_name ||= begin
|
5
|
+
str = name.dup
|
6
|
+
str.sub!(/.*::/, '')
|
7
|
+
str.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2')
|
8
|
+
str.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
|
9
|
+
str.downcase!
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(dependencies=[])
|
14
|
+
@dependencies = Array dependencies
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_s
|
18
|
+
filename = File.join(File.dirname(__FILE__), '..', 'templates', "#{self.class.underscored_name}.erb")
|
19
|
+
template = ERB.new(File.read(filename))
|
20
|
+
template.result(binding)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
attr_reader :dependencies
|
25
|
+
|
26
|
+
def sorted_dependencies
|
27
|
+
dependencies.sort_by(&:name)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module LicenseFinder
|
4
|
+
class HtmlReport < DependencyReport
|
5
|
+
private
|
6
|
+
def unapproved_dependencies
|
7
|
+
dependencies.reject(&:approved)
|
8
|
+
end
|
9
|
+
|
10
|
+
def grouped_dependencies
|
11
|
+
dependencies.group_by(&:license).sort_by { |_, group| group.size }.reverse
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module LicenseFinder
|
2
|
+
module Persistence
|
3
|
+
class Configuration
|
4
|
+
attr_reader :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
|
@@ -0,0 +1,127 @@
|
|
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,51 +1,20 @@
|
|
1
1
|
module LicenseFinder
|
2
|
-
|
3
|
-
|
4
|
-
unless File.exists?(LicenseFinder.config.config_file_path)
|
5
|
-
FileUtils.mkdir_p(File.join('.', 'config'))
|
6
|
-
FileUtils.cp(
|
7
|
-
File.join(File.dirname(__FILE__), '..', '..', 'files', 'license_finder.yml'),
|
8
|
-
LicenseFinder.config.config_file_path
|
9
|
-
)
|
10
|
-
end
|
11
|
-
end
|
2
|
+
module Reporter
|
3
|
+
extend self
|
12
4
|
|
13
|
-
def
|
14
|
-
|
15
|
-
@dependency_list = generate_list
|
16
|
-
save_reports
|
17
|
-
end
|
5
|
+
def write_reports
|
6
|
+
dependencies = Dependency.all
|
18
7
|
|
19
|
-
|
20
|
-
|
8
|
+
write_file LicenseFinder.config.dependencies_text, TextReport.new(dependencies).to_s
|
9
|
+
write_file LicenseFinder.config.dependencies_html, HtmlReport.new(dependencies).to_s
|
21
10
|
end
|
22
11
|
|
23
12
|
private
|
24
|
-
|
25
|
-
attr_reader :dependency_list
|
26
|
-
|
27
|
-
def save_reports
|
28
|
-
write_file LicenseFinder.config.dependencies_yaml, dependency_list.to_yaml
|
29
|
-
write_file LicenseFinder.config.dependencies_text, dependency_list.to_s
|
30
|
-
write_file LicenseFinder.config.dependencies_html, dependency_list.to_html
|
31
|
-
end
|
32
|
-
|
33
13
|
def write_file(file_path, content)
|
34
14
|
File.open(file_path, 'w+') do |f|
|
35
15
|
f.puts content
|
36
16
|
end
|
37
17
|
end
|
38
|
-
|
39
|
-
def generate_list
|
40
|
-
bundler_list = DependencyList.from_bundler
|
41
|
-
|
42
|
-
if File.exists?(LicenseFinder.config.dependencies_yaml)
|
43
|
-
yml = File.open(LicenseFinder.config.dependencies_yaml).readlines.join
|
44
|
-
existing_list = DependencyList.from_yaml(yml)
|
45
|
-
existing_list.merge(bundler_list)
|
46
|
-
else
|
47
|
-
bundler_list
|
48
|
-
end
|
49
|
-
end
|
50
18
|
end
|
51
19
|
end
|
20
|
+
|
@@ -0,0 +1,40 @@
|
|
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
|
@@ -38,7 +38,7 @@
|
|
38
38
|
<dl>
|
39
39
|
<dt>Parents</dt>
|
40
40
|
<% parents.each do |parent| %>
|
41
|
-
<dd><%= parent
|
41
|
+
<dd><%= parent %></dd>
|
42
42
|
<% end %>
|
43
43
|
</dl>
|
44
44
|
<% end %>
|
@@ -47,7 +47,7 @@
|
|
47
47
|
<dl>
|
48
48
|
<dt>Children</dt>
|
49
49
|
<% children.each do |child| %>
|
50
|
-
<dd><%= child
|
50
|
+
<dd><%= child %></dd>
|
51
51
|
<% end %>
|
52
52
|
</dl>
|
53
53
|
<% end %>
|
@@ -0,0 +1,93 @@
|
|
1
|
+
<html>
|
2
|
+
<head>
|
3
|
+
<link href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.1.1/css/bootstrap.min.css" rel="stylesheet">
|
4
|
+
<style type="text/css">
|
5
|
+
body {
|
6
|
+
margin: 50px;
|
7
|
+
}
|
8
|
+
|
9
|
+
.unapproved h2, .unapproved h2 a {
|
10
|
+
color: red;
|
11
|
+
}
|
12
|
+
</style>
|
13
|
+
</head>
|
14
|
+
<body>
|
15
|
+
<div class="container">
|
16
|
+
<div class="summary hero-unit">
|
17
|
+
<h1>Dependencies</h1>
|
18
|
+
|
19
|
+
<h4>
|
20
|
+
<%= dependencies.size %> total
|
21
|
+
|
22
|
+
<% if unapproved_dependencies.any? %>
|
23
|
+
<span class="badge badge-important"><%= unapproved_dependencies.size %> unapproved</span>
|
24
|
+
<% end %>
|
25
|
+
</h4>
|
26
|
+
|
27
|
+
<ul>
|
28
|
+
<% grouped_dependencies.each do |license, group| %>
|
29
|
+
<li><%= group.size %> <%= license %></li>
|
30
|
+
<% end %>
|
31
|
+
</ul>
|
32
|
+
</div>
|
33
|
+
<div class="dependencies">
|
34
|
+
<% sorted_dependencies.each do |dependency| %>
|
35
|
+
<div id="<%= dependency.name %>" class="<%= dependency.approved ? "approved" : "unapproved" %>">
|
36
|
+
<h2>
|
37
|
+
<% if dependency.homepage && !dependency.homepage.empty? %>
|
38
|
+
<a href="<%= dependency.homepage %>"><%= dependency.name %></a>
|
39
|
+
<% else %>
|
40
|
+
<%= dependency.name %>
|
41
|
+
<% end %>
|
42
|
+
v<%= dependency.version %>
|
43
|
+
<% if dependency.bundler_groups.any? %>
|
44
|
+
(<%= dependency.bundler_groups.join(", ") %>)
|
45
|
+
<% end %>
|
46
|
+
</h2>
|
47
|
+
<table class="table table-striped table-bordered">
|
48
|
+
<thead>
|
49
|
+
<tr>
|
50
|
+
<th>Summary</th>
|
51
|
+
<th>Description</th>
|
52
|
+
<th>License</th>
|
53
|
+
</tr>
|
54
|
+
</thead>
|
55
|
+
<tbody>
|
56
|
+
<tr>
|
57
|
+
<td><%= dependency.summary %></td>
|
58
|
+
<td><%= dependency.description %></td>
|
59
|
+
<td>
|
60
|
+
<% if dependency.license_url && !dependency.license_url.empty? %>
|
61
|
+
<a href="<%= dependency.license_url %>"><%= dependency.license %></a>
|
62
|
+
<% else %>
|
63
|
+
<%= dependency.license %>
|
64
|
+
<% end %>
|
65
|
+
</td>
|
66
|
+
</td>
|
67
|
+
</tr>
|
68
|
+
</tbody>
|
69
|
+
</table>
|
70
|
+
|
71
|
+
<% if dependency.parents.any? %>
|
72
|
+
<dl>
|
73
|
+
<dt>Parents</dt>
|
74
|
+
<% dependency.parents.each do |parent| %>
|
75
|
+
<dd><%= parent %></dd>
|
76
|
+
<% end %>
|
77
|
+
</dl>
|
78
|
+
<% end %>
|
79
|
+
|
80
|
+
<% if dependency.children.any? %>
|
81
|
+
<dl>
|
82
|
+
<dt>Children</dt>
|
83
|
+
<% dependency.children.each do |child| %>
|
84
|
+
<dd><%= child %></dd>
|
85
|
+
<% end %>
|
86
|
+
</dl>
|
87
|
+
<% end %>
|
88
|
+
</div>
|
89
|
+
<% end %>
|
90
|
+
</div>
|
91
|
+
</div>
|
92
|
+
</body>
|
93
|
+
</html>
|