license_finder 0.4.5 → 0.5.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/README.markdown +43 -11
- data/bin/license_finder +2 -5
- data/features/executables/license_finder.feature +19 -0
- data/features/rake_tasks/action_items.feature +18 -4
- data/features/rake_tasks/action_items_ok.feature +10 -7
- data/features/rake_tasks/generate_dependencies.feature +43 -12
- data/features/rake_tasks/init.feature +8 -1
- data/features/rake_tasks/regressions.feature +18 -0
- data/features/step_definitions/steps.rb +163 -43
- data/lib/license_finder.rb +9 -4
- data/lib/license_finder/{gem_spec_details.rb → bundled_gem.rb} +12 -41
- data/lib/license_finder/bundler_dependency_query.rb +51 -0
- data/lib/license_finder/cli.rb +16 -0
- data/lib/license_finder/dependency.rb +80 -28
- data/lib/license_finder/dependency_list.rb +20 -35
- data/lib/license_finder/finder.rb +2 -2
- data/lib/license_finder/license.rb +74 -0
- data/lib/license_finder/license/apache.rb +5 -0
- data/lib/license_finder/license/bsd.rb +2 -0
- data/lib/license_finder/license/gplv2.rb +2 -0
- data/lib/license_finder/license/isc.rb +2 -0
- data/lib/license_finder/license/lgpl.rb +2 -0
- data/lib/license_finder/license/mit.rb +20 -0
- data/lib/license_finder/license/new_bsd.rb +5 -0
- data/lib/license_finder/license/ruby.rb +11 -0
- data/lib/license_finder/license/simplified_bsd.rb +5 -0
- data/lib/license_finder/{file_parser.rb → possible_license_file.rb} +9 -17
- data/lib/tasks/license_finder.rake +8 -8
- data/lib/templates/{Apache-2.0-body → Apache.txt} +0 -0
- data/lib/templates/BSD.txt +24 -0
- data/lib/templates/{GPL-2.0-body → GPLv2.txt} +0 -0
- data/lib/templates/{ISC-body → ISC.txt} +0 -0
- data/lib/templates/{LGPL-body → LGPL.txt} +0 -0
- data/lib/templates/{MIT-body → MIT.txt} +0 -0
- data/lib/templates/NewBSD.txt +21 -0
- data/lib/templates/Ruby.txt +52 -0
- data/lib/templates/SimplifiedBSD.txt +23 -0
- data/license_finder.gemspec +4 -3
- data/spec/fixtures/{no_license/.gitkeep → license_names/Licence.rdoc} +0 -0
- data/spec/lib/license_finder/bundled_gem_spec.rb +148 -0
- data/spec/lib/license_finder/dependency_list_spec.rb +133 -144
- data/spec/lib/license_finder/dependency_spec.rb +189 -5
- data/spec/lib/license_finder/license/apache_spec.rb +7 -0
- data/spec/lib/license_finder/license/bsd_spec.rb +41 -0
- data/spec/lib/license_finder/license/gplv2_spec.rb +7 -0
- data/spec/lib/license_finder/license/isc_spec.rb +7 -0
- data/spec/lib/license_finder/license/lgpl_spec.rb +7 -0
- data/spec/lib/license_finder/license/mit_spec.rb +33 -0
- data/spec/lib/license_finder/license/new_bsd_spec.rb +35 -0
- data/spec/lib/license_finder/license/ruby_spec.rb +19 -0
- data/spec/lib/license_finder/license/simplified_bsd_spec.rb +7 -0
- data/spec/lib/license_finder/possible_license_file_spec.rb +42 -0
- data/spec/spec_helper.rb +6 -0
- data/spec/support/license_examples.rb +24 -0
- metadata +89 -33
- data/lib/license_finder/license_file.rb +0 -98
- data/spec/fixtures/apache_licensed_gem/LICENSE +0 -191
- data/spec/fixtures/gplv2_licensed_gem/LICENSE +0 -339
- data/spec/fixtures/isc_licensed_gem/LICENSE +0 -10
- data/spec/fixtures/lgpl_licensed_gem/LICENSE +0 -165
- data/spec/fixtures/mit_licensed_gem_in_README/README.rdoc +0 -222
- data/spec/fixtures/mit_licensed_gem_via_url/README +0 -210
- data/spec/fixtures/mit_licensed_with_hashes/MIT-LICENSE +0 -20
- data/spec/lib/license_finder/file_parser_spec.rb +0 -16
- data/spec/lib/license_finder/gem_spec_details_spec.rb +0 -229
- data/spec/lib/license_finder/license_file_spec.rb +0 -155
data/lib/license_finder.rb
CHANGED
@@ -32,13 +32,18 @@ module LicenseFinder
|
|
32
32
|
def self.config
|
33
33
|
@config ||= Configuration.new
|
34
34
|
end
|
35
|
+
|
36
|
+
def self.load_rake_tasks
|
37
|
+
load 'tasks/license_finder.rake'
|
38
|
+
end
|
35
39
|
end
|
36
40
|
|
37
41
|
require 'license_finder/railtie' if defined?(Rails)
|
42
|
+
require 'license_finder/bundler_dependency_query'
|
38
43
|
require 'license_finder/finder'
|
39
|
-
require 'license_finder/
|
40
|
-
require 'license_finder/
|
41
|
-
require 'license_finder/
|
42
|
-
|
44
|
+
require 'license_finder/bundled_gem'
|
45
|
+
require 'license_finder/license'
|
46
|
+
require 'license_finder/possible_license_file'
|
43
47
|
require 'license_finder/dependency'
|
44
48
|
require 'license_finder/dependency_list'
|
49
|
+
require 'license_finder/cli'
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module LicenseFinder
|
2
|
-
class
|
3
|
-
LICENSE_FILE_NAMES = '*{LICENSE,License,COPYING,README,Readme,ReadMe}*' # follows Dir.glob format
|
2
|
+
class BundledGem
|
3
|
+
LICENSE_FILE_NAMES = '*{LICENSE,License,Licence,COPYING,README,Readme,ReadMe}*' # follows Dir.glob format
|
4
4
|
README_FILE_NAMES = '*{README,Readme,ReadMe}*' # follows Dir.glob format
|
5
5
|
|
6
6
|
def initialize(spec)
|
@@ -22,26 +22,22 @@ module LicenseFinder
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def dependency
|
25
|
-
license = determine_license
|
26
|
-
|
27
25
|
@dependency ||= Dependency.new(
|
28
26
|
'name' => @spec.name,
|
29
|
-
'version' => @spec.version,
|
30
|
-
'license' =>
|
27
|
+
'version' => @spec.version.to_s,
|
28
|
+
'license' => determine_license,
|
31
29
|
'license_files' => license_files.map(&:full_file_path),
|
32
|
-
'readme_files' => readme_files.map(&:full_file_path)
|
30
|
+
'readme_files' => readme_files.map(&:full_file_path),
|
31
|
+
'source' => 'bundle',
|
32
|
+
'summary' => @spec.summary,
|
33
|
+
'description' => @spec.description
|
33
34
|
)
|
34
35
|
end
|
35
36
|
|
36
37
|
def determine_license
|
37
38
|
return @spec.license if @spec.license
|
38
|
-
|
39
|
-
|
40
|
-
return 'GPLv2' if license_files.any?(&:gplv2_license_body?)
|
41
|
-
return 'ruby' if license_files.any?(&:ruby_license_body?)
|
42
|
-
return 'LGPL' if license_files.any?(&:lgpl_license_body?)
|
43
|
-
return 'ISC' if license_files.any?(&:isc_license_body?)
|
44
|
-
'other'
|
39
|
+
|
40
|
+
license_files.map(&:license).compact.first || 'other'
|
45
41
|
end
|
46
42
|
|
47
43
|
def license_files
|
@@ -54,9 +50,7 @@ module LicenseFinder
|
|
54
50
|
|
55
51
|
def readme_files
|
56
52
|
Dir.glob(File.join(install_path, '**', README_FILE_NAMES)).map do |path|
|
57
|
-
|
58
|
-
file.include_license_text = include_license_text?
|
59
|
-
file
|
53
|
+
get_file_for_path path
|
60
54
|
end
|
61
55
|
end
|
62
56
|
|
@@ -64,37 +58,14 @@ module LicenseFinder
|
|
64
58
|
spec.full_gem_path
|
65
59
|
end
|
66
60
|
|
67
|
-
def to_s(include_license_text = true)
|
68
|
-
self.include_license_text = include_license_text
|
69
|
-
|
70
|
-
{ name => to_hash }.to_yaml
|
71
|
-
end
|
72
|
-
|
73
|
-
def to_hash
|
74
|
-
{
|
75
|
-
'dependency_name' => dependency_name,
|
76
|
-
'dependency_version' => dependency_version,
|
77
|
-
'install_path' => install_path,
|
78
|
-
'license_files' => license_files.map { |file| file.to_hash }
|
79
|
-
}
|
80
|
-
end
|
81
|
-
|
82
61
|
def sort_order
|
83
62
|
dependency_name.downcase
|
84
63
|
end
|
85
64
|
|
86
65
|
private
|
87
66
|
|
88
|
-
attr_writer :include_license_text
|
89
|
-
|
90
|
-
def include_license_text?
|
91
|
-
@include_license_text
|
92
|
-
end
|
93
|
-
|
94
67
|
def get_file_for_path(path)
|
95
|
-
|
96
|
-
file.include_license_text = include_license_text?
|
97
|
-
file
|
68
|
+
PossibleLicenseFile.new(install_path, path)
|
98
69
|
end
|
99
70
|
|
100
71
|
def paths_for_files_in_license_directory(path)
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module LicenseFinder
|
2
|
+
class BundlerDependencyQuery
|
3
|
+
def dependencies
|
4
|
+
bundler_definition.specs_for(requested_groups).map do |spec|
|
5
|
+
dependency = define_a_new_dependency_from_a_gemspec(spec)
|
6
|
+
add_additional_information_from_bundler_to_a_dependency(dependency)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def add_additional_information_from_bundler_to_a_dependency(dependency)
|
13
|
+
bundler_dependency = find_bundlers_representation_of_a_dependency_by_name(dependency.name)
|
14
|
+
|
15
|
+
if bundler_dependency
|
16
|
+
dependency.bundler_groups = bundler_dependency.groups
|
17
|
+
end
|
18
|
+
|
19
|
+
dependency
|
20
|
+
end
|
21
|
+
|
22
|
+
def define_a_new_dependency_from_a_gemspec(gemspec)
|
23
|
+
BundledGem.new(gemspec).dependency
|
24
|
+
end
|
25
|
+
|
26
|
+
def find_bundlers_representation_of_a_dependency_by_name(name)
|
27
|
+
bundler_dependencies.detect { |dep| dep.name == name }
|
28
|
+
end
|
29
|
+
|
30
|
+
def requested_groups
|
31
|
+
bundler_definition.groups - LicenseFinder.config.ignore_groups
|
32
|
+
end
|
33
|
+
|
34
|
+
def gemfile_path
|
35
|
+
Pathname.new("Gemfile").expand_path
|
36
|
+
end
|
37
|
+
|
38
|
+
def lockfile_path
|
39
|
+
root = gemfile_path.dirname
|
40
|
+
root.join('Gemfile.lock')
|
41
|
+
end
|
42
|
+
|
43
|
+
def bundler_dependencies
|
44
|
+
@bundler_dependencies ||= bundler_definition.dependencies
|
45
|
+
end
|
46
|
+
|
47
|
+
def bundler_definition
|
48
|
+
@bundler_definition ||= Bundler::Definition.build(gemfile_path, lockfile_path, nil)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module LicenseFinder
|
2
|
+
class CLI
|
3
|
+
def check_for_action_items
|
4
|
+
found = LicenseFinder::Finder.new.action_items
|
5
|
+
|
6
|
+
if found.size == 0
|
7
|
+
puts "All gems are approved for use"
|
8
|
+
exit 0
|
9
|
+
else
|
10
|
+
puts "Dependencies that need approval:"
|
11
|
+
puts found
|
12
|
+
exit 1
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -1,6 +1,12 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require "erb"
|
3
|
+
|
1
4
|
module LicenseFinder
|
2
5
|
class Dependency
|
3
|
-
|
6
|
+
attr_accessor :name, :version, :license, :approved, :license_url, :notes, :license_files,
|
7
|
+
:readme_files, :source, :bundler_groups
|
8
|
+
|
9
|
+
attr_reader :summary, :description
|
4
10
|
|
5
11
|
def self.from_hash(attrs)
|
6
12
|
attrs['license_files'] = attrs['license_files'].map { |lf| lf['path'] } if attrs['license_files']
|
@@ -10,6 +16,7 @@ module LicenseFinder
|
|
10
16
|
end
|
11
17
|
|
12
18
|
def initialize(attributes = {})
|
19
|
+
@source = attributes['source']
|
13
20
|
@name = attributes['name']
|
14
21
|
@version = attributes['version']
|
15
22
|
@license = attributes['license']
|
@@ -18,44 +25,89 @@ module LicenseFinder
|
|
18
25
|
@notes = attributes['notes'] || ''
|
19
26
|
@license_files = attributes['license_files'] || []
|
20
27
|
@readme_files = attributes['readme_files'] || []
|
28
|
+
@bundler_groups = attributes['bundler_groups'] || []
|
29
|
+
@summary = attributes['summary']
|
30
|
+
@description = attributes['description']
|
21
31
|
end
|
22
32
|
|
23
|
-
def
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
33
|
+
def merge(other)
|
34
|
+
raise "Cannot merge dependencies with different names. Expected #{name}, was #{other.name}." unless other.name == name
|
35
|
+
|
36
|
+
merged = self.class.new(
|
37
|
+
'name' => name,
|
38
|
+
'version' => other.version,
|
39
|
+
'license_files' => other.license_files,
|
40
|
+
'readme_files' => other.readme_files,
|
41
|
+
'license_url' => other.license_url,
|
42
|
+
'notes' => notes,
|
43
|
+
'source' => other.source,
|
44
|
+
'summary' => other.summary,
|
45
|
+
'description' => other.description,
|
46
|
+
'bundler_groups' => other.bundler_groups,
|
47
|
+
)
|
48
|
+
|
49
|
+
case other.license
|
50
|
+
when license, 'other'
|
51
|
+
merged.license = license
|
52
|
+
merged.approved = approved
|
53
|
+
else
|
54
|
+
merged.license = other.license
|
55
|
+
merged.approved = other.approved
|
56
|
+
end
|
57
|
+
|
58
|
+
merged
|
59
|
+
end
|
60
|
+
|
61
|
+
def as_yaml
|
62
|
+
attrs = {
|
63
|
+
'name' => name,
|
64
|
+
'version' => version,
|
65
|
+
'license' => license,
|
66
|
+
'approved' => approved,
|
67
|
+
'source' => source,
|
68
|
+
'license_url' => license_url,
|
69
|
+
'notes' => notes,
|
70
|
+
'license_files' => nil,
|
71
|
+
'readme_files' => nil
|
72
|
+
}
|
73
|
+
|
74
|
+
unless license_files.empty?
|
75
|
+
attrs['license_files'] = license_files.map do |file|
|
76
|
+
{'path' => file}
|
29
77
|
end
|
30
78
|
end
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
79
|
+
|
80
|
+
unless readme_files.empty?
|
81
|
+
attrs['readme_files'] = readme_files.map do |file|
|
82
|
+
{'path' => file}
|
35
83
|
end
|
36
84
|
end
|
85
|
+
|
37
86
|
attrs
|
38
87
|
end
|
39
88
|
|
89
|
+
def to_yaml
|
90
|
+
as_yaml.to_yaml
|
91
|
+
end
|
92
|
+
|
40
93
|
def to_s
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
end
|
94
|
+
template = ERB.new <<-TEMPLATE
|
95
|
+
<%= attributes.join(", ") %>
|
96
|
+
<% if license == 'other' %>
|
97
|
+
<% unless license_files.empty? %>
|
98
|
+
license files:
|
99
|
+
<%= license_files.join("\n ") %>
|
100
|
+
<% end %>
|
101
|
+
<% unless readme_files.empty? %>
|
102
|
+
readme files:
|
103
|
+
<%= readme_files.join("\n ") %>
|
104
|
+
<% end %>
|
105
|
+
<% end%>
|
106
|
+
TEMPLATE
|
107
|
+
|
108
|
+
attributes = ["#{name} #{version}".strip, license, license_url, summary, description, bundler_groups].flatten.compact.reject {|a| a == ""}
|
57
109
|
|
58
|
-
|
110
|
+
template.result(binding).gsub(/(^|\n)\s*(\n|$)/, '\1')
|
59
111
|
end
|
60
112
|
end
|
61
113
|
end
|
@@ -4,14 +4,7 @@ module LicenseFinder
|
|
4
4
|
attr_reader :dependencies
|
5
5
|
|
6
6
|
def self.from_bundler
|
7
|
-
|
8
|
-
root = gemfile.dirname
|
9
|
-
lockfile = root.join('Gemfile.lock')
|
10
|
-
definition = Bundler::Definition.build(gemfile, lockfile, nil)
|
11
|
-
|
12
|
-
groups = definition.groups - LicenseFinder.config.ignore_groups
|
13
|
-
|
14
|
-
new(definition.specs_for(groups).map { |spec| GemSpecDetails.new(spec).dependency })
|
7
|
+
new(BundlerDependencyQuery.new.dependencies)
|
15
8
|
end
|
16
9
|
|
17
10
|
def initialize(dependencies)
|
@@ -25,48 +18,40 @@ module LicenseFinder
|
|
25
18
|
|
26
19
|
def merge(new_list)
|
27
20
|
deps = new_list.dependencies.map do |new_dep|
|
28
|
-
old_dep =
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
'version' => new_dep.version,
|
33
|
-
'license' => new_dep.license,
|
34
|
-
'approved' => (old_dep.approved || new_dep.approved),
|
35
|
-
'license_url' => old_dep.license_url,
|
36
|
-
'notes' => old_dep.notes,
|
37
|
-
'license_files' => new_dep.license_files,
|
38
|
-
'readme_files' => new_dep.readme_files
|
39
|
-
)
|
40
|
-
elsif old_dep && new_dep.license == 'other'
|
41
|
-
Dependency.new(
|
42
|
-
'name' => new_dep.name,
|
43
|
-
'version' => new_dep.version,
|
44
|
-
'license' => old_dep.license,
|
45
|
-
'approved' => old_dep.approved,
|
46
|
-
'license_url' => old_dep.license_url,
|
47
|
-
'notes' => old_dep.notes,
|
48
|
-
'license_files' => new_dep.license_files,
|
49
|
-
'readme_files' => new_dep.readme_files
|
50
|
-
)
|
21
|
+
old_dep = dependencies.detect { |d| d.name == new_dep.name }
|
22
|
+
|
23
|
+
if old_dep
|
24
|
+
old_dep.merge(new_dep)
|
51
25
|
else
|
52
26
|
new_dep
|
53
27
|
end
|
54
28
|
end
|
55
29
|
|
30
|
+
deps += dependencies.select { |d| d.source != "bundle" }
|
31
|
+
|
56
32
|
self.class.new(deps)
|
57
33
|
end
|
58
34
|
|
35
|
+
def as_yaml
|
36
|
+
sorted_dependencies.map(&:as_yaml)
|
37
|
+
end
|
38
|
+
|
59
39
|
def to_yaml
|
60
|
-
|
61
|
-
dependencies.sort_by(&:name).inject(result) { |r, d| r << d.to_yaml_entry; r }
|
40
|
+
as_yaml.to_yaml
|
62
41
|
end
|
63
42
|
|
64
43
|
def to_s
|
65
|
-
|
44
|
+
sorted_dependencies.map(&:to_s).join
|
66
45
|
end
|
67
46
|
|
68
47
|
def action_items
|
69
|
-
|
48
|
+
sorted_dependencies.reject(&:approved).map(&:to_s).join
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def sorted_dependencies
|
54
|
+
dependencies.sort_by(&:name)
|
70
55
|
end
|
71
56
|
end
|
72
57
|
end
|
@@ -2,7 +2,7 @@ module LicenseFinder
|
|
2
2
|
class Finder
|
3
3
|
def from_bundler
|
4
4
|
require 'bundler'
|
5
|
-
Bundler.load.specs.map { |spec|
|
5
|
+
Bundler.load.specs.map { |spec| BundledGem.new(spec) }.sort_by &:sort_order
|
6
6
|
end
|
7
7
|
|
8
8
|
def write_files
|
@@ -11,10 +11,10 @@ module LicenseFinder
|
|
11
11
|
File.open(LicenseFinder.config.dependencies_yaml, 'w+') do |f|
|
12
12
|
f.puts new_list.to_yaml
|
13
13
|
end
|
14
|
+
|
14
15
|
File.open(LicenseFinder.config.dependencies_text, 'w+') do |f|
|
15
16
|
f.puts new_list.to_s
|
16
17
|
end
|
17
|
-
|
18
18
|
end
|
19
19
|
|
20
20
|
def action_items
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module LicenseFinder::License
|
2
|
+
class << self
|
3
|
+
def all
|
4
|
+
@all ||= []
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
class Text
|
9
|
+
def initialize(text)
|
10
|
+
@text = normalized(text)
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_s
|
14
|
+
@text
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def normalized(text)
|
20
|
+
text.gsub(/\s+/, ' ').gsub(/['`"]{1,2}/, "\"")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class Base
|
25
|
+
class << self
|
26
|
+
def inherited(descendant)
|
27
|
+
LicenseFinder::License.all << descendant
|
28
|
+
end
|
29
|
+
|
30
|
+
def demodulized_name
|
31
|
+
name.gsub(/^.*::/, '')
|
32
|
+
end
|
33
|
+
|
34
|
+
def slug
|
35
|
+
demodulized_name.downcase
|
36
|
+
end
|
37
|
+
|
38
|
+
def pretty_name
|
39
|
+
demodulized_name
|
40
|
+
end
|
41
|
+
|
42
|
+
def license_text
|
43
|
+
unless defined?(@license_text)
|
44
|
+
template = File.join(LicenseFinder::ROOT_PATH, "templates", "#{demodulized_name}.txt").to_s
|
45
|
+
|
46
|
+
@license_text = Text.new(File.read(template)).to_s if File.exists?(template)
|
47
|
+
end
|
48
|
+
@license_text
|
49
|
+
end
|
50
|
+
|
51
|
+
def license_regex
|
52
|
+
/#{Regexp.escape(license_text).gsub(/<[^<>]+>/, '(.*)')}/ if license_text
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def initialize(text)
|
57
|
+
self.text = text
|
58
|
+
end
|
59
|
+
|
60
|
+
attr_reader :text
|
61
|
+
|
62
|
+
def text=(text)
|
63
|
+
@text = Text.new(text).to_s
|
64
|
+
end
|
65
|
+
|
66
|
+
def matches?
|
67
|
+
!!(text =~ self.class.license_regex if self.class.license_regex)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
Dir[File.join(File.dirname(__FILE__), 'license', '*.rb')].each do |license|
|
73
|
+
require license
|
74
|
+
end
|