license_finder 0.8.0-java

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.
Files changed (128) hide show
  1. data/.gitignore +12 -0
  2. data/.rspec +1 -0
  3. data/.travis.yml +15 -0
  4. data/Gemfile +3 -0
  5. data/LICENSE +22 -0
  6. data/Rakefile +21 -0
  7. data/bin/license_finder +54 -0
  8. data/db/migrate/201303290935_create_dependencies.rb +14 -0
  9. data/db/migrate/201303291155_create_licenses.rb +13 -0
  10. data/db/migrate/201303291402_create_approvals.rb +13 -0
  11. data/db/migrate/201303291456_create_ancestries.rb +9 -0
  12. data/db/migrate/201303291519_create_bundler_groups.rb +13 -0
  13. data/db/migrate/201303291720_move_manual_from_approvals_to_licenses.rb +11 -0
  14. data/db/migrate/201303291753_allow_null_license_names.rb +7 -0
  15. data/db/migrate/201304011027_allow_null_dependency_version.rb +7 -0
  16. data/db/migrate/201304020947_change_table_name_licenses_to_license_aliases.rb +5 -0
  17. data/features/approve_dependencies.feature +14 -0
  18. data/features/html_report.feature +38 -0
  19. data/features/ignore_bundle_groups.feature +11 -0
  20. data/features/license_finder.feature +47 -0
  21. data/features/license_finder_rake_task.feature +37 -0
  22. data/features/rails_rake.feature +9 -0
  23. data/features/set_license.feature +12 -0
  24. data/features/step_definitions/license_finder_steps.rb +25 -0
  25. data/features/step_definitions/steps.rb +376 -0
  26. data/features/text_report.feature +27 -0
  27. data/features/whitelist.feature +24 -0
  28. data/files/license_finder.yml +8 -0
  29. data/lib/data/licenses/Apache2.txt +172 -0
  30. data/lib/data/licenses/BSD.txt +24 -0
  31. data/lib/data/licenses/GPLv2.txt +339 -0
  32. data/lib/data/licenses/ISC.txt +2 -0
  33. data/lib/data/licenses/LGPL.txt +165 -0
  34. data/lib/data/licenses/MIT.txt +9 -0
  35. data/lib/data/licenses/NewBSD.txt +21 -0
  36. data/lib/data/licenses/Ruby.txt +52 -0
  37. data/lib/data/licenses/SimplifiedBSD.txt +23 -0
  38. data/lib/license_finder.rb +47 -0
  39. data/lib/license_finder/bundle.rb +48 -0
  40. data/lib/license_finder/bundle_syncer.rb +11 -0
  41. data/lib/license_finder/bundled_gem.rb +48 -0
  42. data/lib/license_finder/cli.rb +49 -0
  43. data/lib/license_finder/configuration.rb +71 -0
  44. data/lib/license_finder/dependency_report.rb +30 -0
  45. data/lib/license_finder/gem_saver.rb +69 -0
  46. data/lib/license_finder/html_report.rb +14 -0
  47. data/lib/license_finder/license.rb +90 -0
  48. data/lib/license_finder/license/apache2.rb +8 -0
  49. data/lib/license_finder/license/bsd.rb +4 -0
  50. data/lib/license_finder/license/gplv2.rb +4 -0
  51. data/lib/license_finder/license/isc.rb +3 -0
  52. data/lib/license_finder/license/lgpl.rb +3 -0
  53. data/lib/license_finder/license/mit.rb +23 -0
  54. data/lib/license_finder/license/new_bsd.rb +8 -0
  55. data/lib/license_finder/license/ruby.rb +11 -0
  56. data/lib/license_finder/license/simplified_bsd.rb +8 -0
  57. data/lib/license_finder/license_files.rb +36 -0
  58. data/lib/license_finder/license_url.rb +12 -0
  59. data/lib/license_finder/platform.rb +32 -0
  60. data/lib/license_finder/possible_license_file.rb +32 -0
  61. data/lib/license_finder/railtie.rb +7 -0
  62. data/lib/license_finder/reporter.rb +20 -0
  63. data/lib/license_finder/tables.rb +7 -0
  64. data/lib/license_finder/tables/approval.rb +4 -0
  65. data/lib/license_finder/tables/bundler_group.rb +4 -0
  66. data/lib/license_finder/tables/dependency.rb +31 -0
  67. data/lib/license_finder/tables/license_alias.rb +22 -0
  68. data/lib/license_finder/text_report.rb +9 -0
  69. data/lib/license_finder/yml_to_sql.rb +127 -0
  70. data/lib/tasks/license_finder.rake +7 -0
  71. data/lib/templates/html_report.erb +111 -0
  72. data/lib/templates/text_report.erb +3 -0
  73. data/license_finder.gemspec +36 -0
  74. data/readme.md +115 -0
  75. data/spec/fixtures/APACHE-2-LICENSE +202 -0
  76. data/spec/fixtures/GPLv2 +339 -0
  77. data/spec/fixtures/ISC-LICENSE +10 -0
  78. data/spec/fixtures/MIT-LICENSE +22 -0
  79. data/spec/fixtures/MIT-LICENSE-with-varied-disclaimer +22 -0
  80. data/spec/fixtures/README-with-MIT-LICENSE +222 -0
  81. data/spec/fixtures/license_directory/COPYING +0 -0
  82. data/spec/fixtures/license_directory/LICENSE/BSD-2-Clause.txt +25 -0
  83. data/spec/fixtures/license_directory/LICENSE/GPL-2.0.txt +339 -0
  84. data/spec/fixtures/license_directory/LICENSE/LICENSE +191 -0
  85. data/spec/fixtures/license_directory/LICENSE/MIT.txt +21 -0
  86. data/spec/fixtures/license_directory/LICENSE/RUBY.txt +60 -0
  87. data/spec/fixtures/license_names/COPYING.txt +0 -0
  88. data/spec/fixtures/license_names/LICENSE +0 -0
  89. data/spec/fixtures/license_names/Licence.rdoc +0 -0
  90. data/spec/fixtures/license_names/Mit-License +0 -0
  91. data/spec/fixtures/license_names/README.rdoc +0 -0
  92. data/spec/fixtures/mit_licensed_gem/LICENSE +22 -0
  93. data/spec/fixtures/nested_gem/vendor/LICENSE +0 -0
  94. data/spec/fixtures/nested_readme/vendor/README +0 -0
  95. data/spec/fixtures/other_licensed_gem/LICENSE +3 -0
  96. data/spec/fixtures/readme/Project ReadMe b/data/spec/fixtures/readme/Project → ReadMe +0 -0
  97. data/spec/fixtures/readme/README +0 -0
  98. data/spec/fixtures/readme/Readme.markdown +0 -0
  99. data/spec/fixtures/utf8_gem/README +210 -0
  100. data/spec/lib/license_finder/bundle_spec.rb +61 -0
  101. data/spec/lib/license_finder/bundle_syncer_spec.rb +16 -0
  102. data/spec/lib/license_finder/bundled_gem_spec.rb +62 -0
  103. data/spec/lib/license_finder/cli_spec.rb +38 -0
  104. data/spec/lib/license_finder/configuration_spec.rb +70 -0
  105. data/spec/lib/license_finder/gem_saver_spec.rb +155 -0
  106. data/spec/lib/license_finder/html_report_spec.rb +84 -0
  107. data/spec/lib/license_finder/license/apache_spec.rb +7 -0
  108. data/spec/lib/license_finder/license/bsd_spec.rb +41 -0
  109. data/spec/lib/license_finder/license/gplv2_spec.rb +7 -0
  110. data/spec/lib/license_finder/license/isc_spec.rb +7 -0
  111. data/spec/lib/license_finder/license/lgpl_spec.rb +7 -0
  112. data/spec/lib/license_finder/license/mit_spec.rb +33 -0
  113. data/spec/lib/license_finder/license/new_bsd_spec.rb +35 -0
  114. data/spec/lib/license_finder/license/ruby_spec.rb +19 -0
  115. data/spec/lib/license_finder/license/simplified_bsd_spec.rb +7 -0
  116. data/spec/lib/license_finder/license_files_spec.rb +50 -0
  117. data/spec/lib/license_finder/license_spec.rb +45 -0
  118. data/spec/lib/license_finder/license_url_spec.rb +20 -0
  119. data/spec/lib/license_finder/possible_license_file_spec.rb +37 -0
  120. data/spec/lib/license_finder/reporter_spec.rb +4 -0
  121. data/spec/lib/license_finder/tables/dependency_spec.rb +102 -0
  122. data/spec/lib/license_finder/tables/license_alias_spec.rb +54 -0
  123. data/spec/lib/license_finder/text_report_spec.rb +31 -0
  124. data/spec/lib/license_finder/yml_to_sql_spec.rb +99 -0
  125. data/spec/lib/license_finder_spec.rb +82 -0
  126. data/spec/spec_helper.rb +31 -0
  127. data/spec/support/license_examples.rb +30 -0
  128. metadata +435 -0
@@ -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 {|dep| dep.license.name }.sort_by { |_, group| group.size }.reverse
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,90 @@
1
+ module LicenseFinder
2
+ module License
3
+ class << self
4
+ def all
5
+ @all ||= []
6
+ end
7
+
8
+ def find_by_name(license_name)
9
+ all.detect { |l| l.names.map(&:downcase).include? license_name.to_s.downcase }
10
+ end
11
+ end
12
+
13
+ class Text
14
+ def initialize(text)
15
+ @text = normalized(text)
16
+ end
17
+
18
+ def to_s
19
+ @text
20
+ end
21
+
22
+ private
23
+
24
+ def normalized(text)
25
+ text.gsub(/\s+/, ' ').gsub(/['`"]{1,2}/, "\"")
26
+ end
27
+ end
28
+
29
+ class Base
30
+ class << self
31
+ attr_accessor :license_url, :alternative_names
32
+
33
+ def inherited(descendant)
34
+ License.all << descendant
35
+ end
36
+
37
+ def names
38
+ ([demodulized_name, pretty_name] + self.alternative_names).uniq
39
+ end
40
+
41
+ def alternative_names
42
+ @alternative_names ||= []
43
+ end
44
+
45
+ def demodulized_name
46
+ name.gsub(/^.*::/, '')
47
+ end
48
+
49
+ def slug
50
+ demodulized_name.downcase
51
+ end
52
+
53
+ def pretty_name
54
+ demodulized_name
55
+ end
56
+
57
+ def license_text
58
+ unless defined?(@license_text)
59
+ template = File.join(ROOT_PATH, "data", "licenses", "#{demodulized_name}.txt").to_s
60
+
61
+ @license_text = Text.new(File.read(template)).to_s if File.exists?(template)
62
+ end
63
+ @license_text
64
+ end
65
+
66
+ def license_regex
67
+ /#{Regexp.escape(license_text).gsub(/<[^<>]+>/, '(.*)')}/ if license_text
68
+ end
69
+ end
70
+
71
+ def initialize(text)
72
+ self.text = text
73
+ end
74
+
75
+ attr_reader :text
76
+
77
+ def text=(text)
78
+ @text = Text.new(text).to_s
79
+ end
80
+
81
+ def matches?
82
+ !!(text =~ self.class.license_regex if self.class.license_regex)
83
+ end
84
+ end
85
+ end
86
+ end
87
+
88
+ Dir[File.join(File.dirname(__FILE__), 'license', '*.rb')].each do |license|
89
+ require license
90
+ end
@@ -0,0 +1,8 @@
1
+ class LicenseFinder::License::Apache2 < LicenseFinder::License::Base
2
+ self.alternative_names = ["Apache 2.0", "Apache2", "Apache-2.0"]
3
+ self.license_url = "http://www.apache.org/licenses/LICENSE-2.0.txt"
4
+
5
+ def self.pretty_name
6
+ 'Apache 2.0'
7
+ end
8
+ end
@@ -0,0 +1,4 @@
1
+ class LicenseFinder::License::BSD < LicenseFinder::License::Base
2
+ self.alternative_names = ["BSD4", "bsd-old", "4-clause BSD", "BSD-4-Clause"]
3
+ self.license_url = "http://en.wikipedia.org/wiki/BSD_licenses#4-clause_license_.28original_.22BSD_License.22.29"
4
+ end
@@ -0,0 +1,4 @@
1
+ class LicenseFinder::License::GPLv2 < LicenseFinder::License::Base
2
+ self.license_url = 'http://www.gnu.org/licenses/gpl-2.0.txt'
3
+ self.alternative_names = ["GPL V2", "gpl-v2", "GNU GENERAL PUBLIC LICENSE Version 2"]
4
+ end
@@ -0,0 +1,3 @@
1
+ class LicenseFinder::License::ISC < LicenseFinder::License::Base
2
+ self.license_url = "http://en.wikipedia.org/wiki/ISC_license"
3
+ end
@@ -0,0 +1,3 @@
1
+ class LicenseFinder::License::LGPL < LicenseFinder::License::Base
2
+ self.license_url = "http://www.gnu.org/licenses/lgpl.txt"
3
+ end
@@ -0,0 +1,23 @@
1
+ class LicenseFinder::License::MIT < LicenseFinder::License::Base
2
+ self.license_url = "http://opensource.org/licenses/mit-license"
3
+ self.alternative_names = ["Expat"]
4
+
5
+ HEADER_REGEX = /The MIT Licen[sc]e/
6
+ ONE_LINER_REGEX = /is released under the MIT licen[sc]e/
7
+ URL_REGEX = %r{MIT Licen[sc]e.*http://(?:www.)?opensource.org/licenses/mit-license}
8
+
9
+ def matches?
10
+ super || matches_url? || matches_header?
11
+ end
12
+
13
+ private
14
+
15
+ def matches_url?
16
+ !!(text =~ URL_REGEX)
17
+ end
18
+
19
+ def matches_header?
20
+ header = text.split("\n").first
21
+ header && ((header.strip =~ HEADER_REGEX) || !!(text =~ ONE_LINER_REGEX))
22
+ end
23
+ end
@@ -0,0 +1,8 @@
1
+ class LicenseFinder::License::NewBSD < LicenseFinder::License::Base
2
+ self.license_url = "http://opensource.org/licenses/BSD-3-Clause"
3
+ self.alternative_names = ["Modified BSD", "BSD3", "BSD-3", "3-clause BSD", "BSD-3-Clause"]
4
+
5
+ def self.pretty_name
6
+ 'New BSD'
7
+ end
8
+ end
@@ -0,0 +1,11 @@
1
+ class LicenseFinder::License::Ruby < LicenseFinder::License::Base
2
+ self.license_url = "http://www.ruby-lang.org/en/LICENSE.txt"
3
+
4
+ def self.pretty_name
5
+ 'ruby'
6
+ end
7
+
8
+ def matches?
9
+ super || !!(text =~ /#{self.class.license_url}/)
10
+ end
11
+ end
@@ -0,0 +1,8 @@
1
+ class LicenseFinder::License::SimplifiedBSD < LicenseFinder::License::Base
2
+ self.license_url = "http://opensource.org/licenses/bsd-license"
3
+ self.alternative_names = ["Simplified BSD", "FreeBSD", "2-clause BSD", "BSD-2-Clause"]
4
+
5
+ def self.pretty_name
6
+ 'Simplified BSD'
7
+ end
8
+ end
@@ -0,0 +1,36 @@
1
+ module LicenseFinder
2
+ class LicenseFiles
3
+ LICENSE_FILE_NAMES = %w(LICENSE License Licence COPYING README Readme ReadMe)
4
+
5
+ def initialize(install_path)
6
+ @install_path = install_path
7
+ end
8
+
9
+ attr_reader :install_path
10
+
11
+ def files
12
+ paths_for_license_files.map do |path|
13
+ get_file_for_path(path)
14
+ end
15
+ end
16
+
17
+ def paths_for_license_files
18
+ find_matching_files.map do |path|
19
+ File.directory?(path) ? paths_for_files_in_license_directory(path) : path
20
+ end.flatten.uniq
21
+ end
22
+
23
+ def find_matching_files
24
+ Dir.glob(File.join(install_path, '**', "*{#{LICENSE_FILE_NAMES.join(',')}}*"))
25
+ end
26
+
27
+ def paths_for_files_in_license_directory(path)
28
+ entries_in_directory = Dir::entries(path).reject { |p| p.match(/^(\.){1,2}$/) }
29
+ entries_in_directory.map { |entry_name| File.join(path, entry_name) }
30
+ end
31
+
32
+ def get_file_for_path(path)
33
+ PossibleLicenseFile.new(install_path, path)
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,12 @@
1
+ module LicenseFinder
2
+ module LicenseUrl
3
+ extend self
4
+
5
+ def find_by_name(name)
6
+ name = name.to_s
7
+
8
+ license = License.find_by_name(name)
9
+ license.license_url if license
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,32 @@
1
+ module LicenseFinder
2
+ module Platform
3
+ def self.sqlite_adapter
4
+ if java?
5
+ 'jdbc:sqlite'
6
+ else
7
+ 'sqlite'
8
+ end
9
+ end
10
+
11
+ def self.sqlite_gem
12
+ if java?
13
+ 'jdbc-sqlite3'
14
+ else
15
+ 'sqlite3'
16
+ end
17
+ end
18
+
19
+ def self.sqlite_load_path
20
+ if java?
21
+ 'jdbc/sqlite3'
22
+ else
23
+ 'sqlite3'
24
+ end
25
+ end
26
+
27
+ def self.java?
28
+ RUBY_PLATFORM =~ /java/
29
+ end
30
+ end
31
+ end
32
+
@@ -0,0 +1,32 @@
1
+ module LicenseFinder
2
+ class PossibleLicenseFile
3
+ def initialize(install_path, file_path)
4
+ @install_path = Pathname.new(install_path)
5
+ @file_path = Pathname.new(file_path)
6
+ end
7
+
8
+ def file_path
9
+ @file_path.relative_path_from(@install_path).to_s
10
+ end
11
+
12
+ def full_file_path
13
+ Pathname.new(@file_path).realpath.to_s
14
+ end
15
+
16
+ def file_name
17
+ @file_path.basename.to_s
18
+ end
19
+
20
+ def text
21
+ @text ||= @file_path.send(@file_path.respond_to?(:binread) ? :binread : :read)
22
+ end
23
+
24
+ def license
25
+ license = License.all.detect do |klass|
26
+ klass.new(text).matches?
27
+ end
28
+
29
+ license.pretty_name if license
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,7 @@
1
+ module LicenseFinder
2
+ class Railtie < Rails::Railtie
3
+ rake_tasks do
4
+ load "tasks/license_finder.rake"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,20 @@
1
+ module LicenseFinder
2
+ module Reporter
3
+ extend self
4
+
5
+ def write_reports
6
+ dependencies = Dependency.all
7
+
8
+ write_file LicenseFinder.config.dependencies_text, TextReport.new(dependencies).to_s
9
+ write_file LicenseFinder.config.dependencies_html, HtmlReport.new(dependencies).to_s
10
+ end
11
+
12
+ private
13
+ def write_file(file_path, content)
14
+ File.open(file_path, 'w+') do |f|
15
+ f.puts content
16
+ end
17
+ end
18
+ end
19
+ end
20
+
@@ -0,0 +1,7 @@
1
+ require 'rubygems'
2
+ require 'sequel'
3
+ require LicenseFinder::Platform.sqlite_load_path
4
+
5
+ DB = Sequel.connect("#{LicenseFinder::Platform.sqlite_adapter}://#{LicenseFinder.config.database_path}")
6
+ Sequel.extension :migration, :core_extensions
7
+ Sequel::Migrator.run(DB, LicenseFinder::ROOT_PATH.join('../db/migrate'))
@@ -0,0 +1,4 @@
1
+ module LicenseFinder
2
+ class Approval < Sequel::Model
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module LicenseFinder
2
+ class BundlerGroup < Sequel::Model
3
+ end
4
+ end
@@ -0,0 +1,31 @@
1
+ module LicenseFinder
2
+ class Dependency < Sequel::Model
3
+ many_to_one :license, class: LicenseAlias
4
+ many_to_one :approval
5
+ many_to_many :children, join_table: :ancestries, left_key: :parent_dependency_id, right_key: :child_dependency_id, class: self
6
+ many_to_many :parents, join_table: :ancestries, left_key: :child_dependency_id, right_key: :parent_dependency_id, class: self
7
+ many_to_many :bundler_groups
8
+
9
+ def self.destroy_obsolete(current_dependencies)
10
+ exclude(id: current_dependencies.map(&:id)).each(&:destroy)
11
+ end
12
+
13
+ def self.unapproved
14
+ all.reject(&:approved?)
15
+ end
16
+
17
+ def approve!
18
+ approval.state = true
19
+ approval.save
20
+ end
21
+
22
+ def approved?
23
+ (license && license.whitelisted?) || (approval && approval.state)
24
+ end
25
+
26
+ def set_license_manually(name)
27
+ license.set_manually(name)
28
+ end
29
+ end
30
+ end
31
+
@@ -0,0 +1,22 @@
1
+ module LicenseFinder
2
+ class LicenseAlias < Sequel::Model
3
+ def initialize(*args)
4
+ super
5
+ self.url = LicenseUrl.find_by_name name
6
+ end
7
+
8
+ def whitelisted?
9
+ !!(config.whitelisted?(name))
10
+ end
11
+
12
+ def set_manually(name)
13
+ update('name' => name, 'manual' => true)
14
+ end
15
+
16
+ private
17
+
18
+ def config
19
+ LicenseFinder.config
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,9 @@
1
+ # encoding: UTF-8
2
+
3
+ module LicenseFinder
4
+ class TextReport < DependencyReport
5
+ def to_s
6
+ super.strip
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,127 @@
1
+ module LicenseFinder
2
+ class YmlToSql
3
+ def self.convert_if_required
4
+ if needs_conversion?
5
+ convert_all(load_yml)
6
+ remove_yml
7
+ end
8
+ end
9
+
10
+ def self.load_yml
11
+ YAML.load File.read(yml_path)
12
+ end
13
+
14
+ def self.convert_all(all_legacy_attrs)
15
+ converters = all_legacy_attrs.map do |attrs|
16
+ new(attrs)
17
+ end
18
+ converters.each(&:convert)
19
+ converters.each(&:associate_children)
20
+ end
21
+
22
+ def self.needs_conversion?
23
+ File.exists?(yml_path)
24
+ end
25
+
26
+ def self.remove_yml
27
+ File.delete(yml_path)
28
+ end
29
+
30
+ def self.yml_path
31
+ LicenseFinder.config.dependencies_yaml
32
+ end
33
+
34
+ def initialize(attrs)
35
+ @legacy_attrs = attrs
36
+ end
37
+
38
+ attr_reader :legacy_attrs
39
+
40
+ def convert
41
+ @dep = create_dependency
42
+ @dep.license = create_license
43
+ @dep.approval = create_approval
44
+ associate_bundler_groups
45
+ @dep.save
46
+ end
47
+
48
+ def associate_children
49
+ find_children.each do |child|
50
+ @dep.add_child(child)
51
+ end
52
+ end
53
+
54
+ def associate_bundler_groups
55
+ find_bundler_groups.each do |group|
56
+ @dep.add_bundler_group(group)
57
+ end
58
+ end
59
+
60
+ def create_dependency
61
+ Sql::Dependency.convert(legacy_attrs)
62
+ end
63
+
64
+ def create_license
65
+ Sql::LicenseAlias.convert(legacy_attrs)
66
+ end
67
+
68
+ def create_approval
69
+ Sql::Approval.convert(legacy_attrs)
70
+ end
71
+
72
+ def find_children
73
+ Sql::Dependency.where(name: legacy_attrs['children'])
74
+ end
75
+
76
+ def find_bundler_groups
77
+ (legacy_attrs['bundler_groups'] || []).map do |name|
78
+ Sql::BundlerGroup.find_or_create(name: name.to_s)
79
+ end
80
+ end
81
+
82
+ module Sql
83
+ module Convertable
84
+ def convert(attrs)
85
+ create remap_attrs(attrs)
86
+ end
87
+
88
+ def remap_attrs(legacy_attrs)
89
+ self::VALID_ATTRIBUTES.each_with_object({}) do |(legacy_key, new_key), new_attrs|
90
+ new_attrs[new_key] = legacy_attrs[legacy_key]
91
+ end
92
+ end
93
+ end
94
+
95
+ class Dependency < Sequel::Model
96
+ extend Convertable
97
+ VALID_ATTRIBUTES = Hash[*%w[name version summary description homepage].map { |k| [k, k] }.flatten]
98
+
99
+ many_to_one :license, class: LicenseAlias
100
+ many_to_one :approval
101
+ many_to_many :children, join_table: :ancestries, left_key: :parent_dependency_id, right_key: :child_dependency_id, class: self
102
+ many_to_many :bundler_groups
103
+ end
104
+
105
+ class BundlerGroup < Sequel::Model
106
+ end
107
+
108
+ class LicenseAlias < Sequel::Model
109
+ extend Convertable
110
+
111
+ VALID_ATTRIBUTES = {
112
+ 'license' => 'name',
113
+ 'license_url' => 'url',
114
+ 'manual' => 'manual'
115
+ }
116
+ end
117
+
118
+ class Approval < Sequel::Model
119
+ extend Convertable
120
+
121
+ VALID_ATTRIBUTES = {
122
+ 'approved' => 'state'
123
+ }
124
+ end
125
+ end
126
+ end
127
+ end