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.
Files changed (73) hide show
  1. data/.gitignore +4 -3
  2. data/.travis.yml +1 -8
  3. data/bin/license_finder +31 -1
  4. data/db/migrate/201303290935_create_dependencies.rb +14 -0
  5. data/db/migrate/201303291155_create_licenses.rb +13 -0
  6. data/db/migrate/201303291402_create_approvals.rb +13 -0
  7. data/db/migrate/201303291456_create_ancestries.rb +9 -0
  8. data/db/migrate/201303291519_create_bundler_groups.rb +13 -0
  9. data/db/migrate/201303291720_move_manual_from_approvals_to_licenses.rb +11 -0
  10. data/db/migrate/201303291753_allow_null_license_names.rb +7 -0
  11. data/db/migrate/201304011027_allow_null_dependency_version.rb +7 -0
  12. data/db/migrate/201304020947_change_table_name_licenses_to_license_aliases.rb +5 -0
  13. data/features/approve_dependencies.feature +0 -45
  14. data/features/html_report.feature +1 -11
  15. data/features/license_finder.feature +13 -27
  16. data/features/license_finder_rake_task.feature +2 -1
  17. data/features/set_license.feature +2 -4
  18. data/features/step_definitions/license_finder_steps.rb +25 -0
  19. data/features/step_definitions/steps.rb +40 -26
  20. data/features/text_report.feature +2 -2
  21. data/files/license_finder.yml +1 -1
  22. data/lib/license_finder.rb +14 -6
  23. data/lib/license_finder/bundle.rb +4 -17
  24. data/lib/license_finder/bundle_syncer.rb +2 -3
  25. data/lib/license_finder/bundled_gem.rb +4 -47
  26. data/lib/license_finder/cli.rb +9 -16
  27. data/lib/license_finder/configuration.rb +55 -3
  28. data/lib/license_finder/dependency_report.rb +1 -1
  29. data/lib/license_finder/gem_saver.rb +69 -0
  30. data/lib/license_finder/html_report.rb +2 -2
  31. data/lib/license_finder/license.rb +60 -58
  32. data/lib/license_finder/license_files.rb +36 -0
  33. data/lib/license_finder/license_url.rb +8 -6
  34. data/lib/license_finder/platform.rb +32 -0
  35. data/lib/license_finder/possible_license_file.rb +1 -1
  36. data/lib/license_finder/tables.rb +7 -0
  37. data/lib/license_finder/tables/approval.rb +4 -0
  38. data/lib/license_finder/tables/bundler_group.rb +4 -0
  39. data/lib/license_finder/tables/dependency.rb +31 -0
  40. data/lib/license_finder/tables/license_alias.rb +22 -0
  41. data/lib/license_finder/yml_to_sql.rb +127 -0
  42. data/lib/tasks/license_finder.rake +3 -0
  43. data/lib/templates/html_report.erb +50 -32
  44. data/lib/templates/text_report.erb +3 -2
  45. data/license_finder.gemspec +14 -5
  46. data/readme.md +10 -50
  47. data/spec/lib/license_finder/bundle_spec.rb +22 -19
  48. data/spec/lib/license_finder/bundle_syncer_spec.rb +4 -10
  49. data/spec/lib/license_finder/bundled_gem_spec.rb +40 -108
  50. data/spec/lib/license_finder/cli_spec.rb +3 -3
  51. data/spec/lib/license_finder/configuration_spec.rb +53 -21
  52. data/spec/lib/license_finder/gem_saver_spec.rb +155 -0
  53. data/spec/lib/license_finder/html_report_spec.rb +32 -15
  54. data/spec/lib/license_finder/license_files_spec.rb +50 -0
  55. data/spec/lib/license_finder/tables/dependency_spec.rb +102 -0
  56. data/spec/lib/license_finder/tables/license_alias_spec.rb +54 -0
  57. data/spec/lib/license_finder/text_report_spec.rb +6 -4
  58. data/spec/lib/license_finder/yml_to_sql_spec.rb +99 -0
  59. data/spec/lib/license_finder_spec.rb +5 -5
  60. data/spec/spec_helper.rb +17 -1
  61. metadata +79 -32
  62. data/lib/license_finder/dependency.rb +0 -50
  63. data/lib/license_finder/persistence.rb +0 -1
  64. data/lib/license_finder/persistence/yaml.rb +0 -7
  65. data/lib/license_finder/persistence/yaml/configuration.rb +0 -34
  66. data/lib/license_finder/persistence/yaml/dependency.rb +0 -127
  67. data/lib/license_finder/source_syncer.rb +0 -40
  68. data/lib/templates/dependency.html.erb +0 -54
  69. data/spec/lib/license_finder/dependency_spec.rb +0 -188
  70. data/spec/lib/license_finder/persistence/yaml/dependency_spec.rb +0 -5
  71. data/spec/lib/license_finder/source_syncer_spec.rb +0 -37
  72. data/spec/support/shared_examples/persistence/configuration.rb +0 -28
  73. data/spec/support/shared_examples/persistence/dependency.rb +0 -138
@@ -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
@@ -1,10 +1,12 @@
1
- module LicenseFinder::LicenseUrl
2
- extend self
1
+ module LicenseFinder
2
+ module LicenseUrl
3
+ extend self
3
4
 
4
- def find_by_name(name)
5
- name = name.to_s
5
+ def find_by_name(name)
6
+ name = name.to_s
6
7
 
7
- license = LicenseFinder::License.find_by_name(name)
8
- license.license_url if license
8
+ license = License.find_by_name(name)
9
+ license.license_url if license
10
+ end
9
11
  end
10
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
+
@@ -22,7 +22,7 @@ module LicenseFinder
22
22
  end
23
23
 
24
24
  def license
25
- license = LicenseFinder::License.all.detect do |klass|
25
+ license = License.all.detect do |klass|
26
26
  klass.new(text).matches?
27
27
  end
28
28
 
@@ -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,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
@@ -1,4 +1,7 @@
1
1
  desc 'Audit your Gemfile for software licenses. This is the same as running `license_finder` in the terminal.'
2
2
  task :license_finder do
3
+ puts "DEPRECATION WARNING: 'rake license_finder' is going to be removed
4
+ for the 1.0.0 release. Please instead use the command line utility 'license_finder'
5
+ or refer to the README for avalible command line utilities"
3
6
  LicenseFinder::CLI.check_for_action_items
4
7
  end
@@ -9,6 +9,9 @@
9
9
  .unapproved h2, .unapproved h2 a {
10
10
  color: red;
11
11
  }
12
+ .unapproved h2:after {
13
+ content: " (unapproved)"
14
+ }
12
15
  </style>
13
16
  </head>
14
17
  <body>
@@ -16,33 +19,51 @@
16
19
  <div class="summary hero-unit">
17
20
  <h1>Dependencies</h1>
18
21
 
22
+ <p>As of <%= Time.now.strftime("%B %e, %Y %l:%M%P") %></p>
23
+
19
24
  <h4>
20
25
  <%= dependencies.size %> total
21
26
 
22
- <% if unapproved_dependencies.any? %>
27
+ <% if unapproved_dependencies.any? -%>
23
28
  <span class="badge badge-important"><%= unapproved_dependencies.size %> unapproved</span>
24
- <% end %>
29
+ <% end -%>
25
30
  </h4>
26
31
 
27
32
  <ul>
28
- <% grouped_dependencies.each do |license, group| %>
29
- <li><%= group.size %> <%= license %></li>
30
- <% end %>
33
+ <% grouped_dependencies.each do |license_name, group| -%>
34
+ <li><%= group.size %> <%= license_name %></li>
35
+ <% end -%>
31
36
  </ul>
32
37
  </div>
38
+ <% if unapproved_dependencies.any? -%>
39
+ <div class="action-items hero-unit">
40
+ <h1>Action Items</h1>
41
+ <h4><%= unapproved_dependencies.size %> unapproved dependencies</h4>
42
+ <ul>
43
+ <% unapproved_dependencies.each do |dependency| -%>
44
+ <li>
45
+ <a href='#<%= dependency.name %>'>
46
+ <%= dependency.name %>
47
+ </a>
48
+ (<%= dependency.license.name %>)
49
+ </li>
50
+ <% end -%>
51
+ </ul>
52
+ </div>
53
+ <% end -%>
33
54
  <div class="dependencies">
34
- <% sorted_dependencies.each do |dependency| %>
35
- <div id="<%= dependency.name %>" class="<%= dependency.approved ? "approved" : "unapproved" %>">
55
+ <% sorted_dependencies.each do |dependency| -%>
56
+ <div id="<%= dependency.name %>" class="<%= dependency.approved? ? "approved" : "unapproved" %>">
36
57
  <h2>
37
- <% if dependency.homepage && !dependency.homepage.empty? %>
58
+ <% if dependency.homepage && !dependency.homepage.empty? -%>
38
59
  <a href="<%= dependency.homepage %>"><%= dependency.name %></a>
39
- <% else %>
60
+ <% else -%>
40
61
  <%= dependency.name %>
41
- <% end %>
62
+ <% end -%>
42
63
  v<%= dependency.version %>
43
- <% if dependency.bundler_groups.any? %>
44
- (<%= dependency.bundler_groups.join(", ") %>)
45
- <% end %>
64
+ <% if dependency.bundler_groups.any? -%>
65
+ (<%= dependency.bundler_groups.map(&:name).join(", ") %>)
66
+ <% end -%>
46
67
  </h2>
47
68
  <table class="table table-striped table-bordered">
48
69
  <thead>
@@ -57,36 +78,33 @@
57
78
  <td><%= dependency.summary %></td>
58
79
  <td><%= dependency.description %></td>
59
80
  <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>
81
+ <% if dependency.license.url && !dependency.license.url.empty? -%>
82
+ <a href="<%= dependency.license.url %>"><%= dependency.license.name %></a>
83
+ <% else -%>
84
+ <%= dependency.license.name %>
85
+ <% end -%>
66
86
  </td>
67
87
  </tr>
68
88
  </tbody>
69
89
  </table>
70
-
71
- <% if dependency.parents.any? %>
90
+ <% if dependency.parents.any? -%>
72
91
  <dl>
73
92
  <dt>Parents</dt>
74
- <% dependency.parents.each do |parent| %>
75
- <dd><%= parent %></dd>
76
- <% end %>
93
+ <% dependency.parents.each do |parent| -%>
94
+ <dd><%= parent.name %></dd>
95
+ <% end -%>
77
96
  </dl>
78
- <% end %>
79
-
80
- <% if dependency.children.any? %>
97
+ <% end -%>
98
+ <% if dependency.children.any? -%>
81
99
  <dl>
82
100
  <dt>Children</dt>
83
- <% dependency.children.each do |child| %>
84
- <dd><%= child %></dd>
85
- <% end %>
101
+ <% dependency.children.each do |child| -%>
102
+ <dd><%= child.name %></dd>
103
+ <% end -%>
86
104
  </dl>
87
- <% end %>
105
+ <% end -%>
88
106
  </div>
89
- <% end %>
107
+ <% end -%>
90
108
  </div>
91
109
  </div>
92
110
  </body>
@@ -1,2 +1,3 @@
1
- <% sorted_dependencies.each do |s| %><%=s.name %>, <%=s.version %>, <%=s.license%>
2
- <% end %>
1
+ <% sorted_dependencies.each do |s| -%>
2
+ <%=s.name %>, <%=s.version %>, <%=s.license.name%>
3
+ <% end -%>
@@ -1,7 +1,9 @@
1
+ require './lib/license_finder/platform'
2
+
1
3
  Gem::Specification.new do |s|
2
4
  s.name = "license_finder"
3
- s.version = "0.7.3"
4
- s.authors = ["Jacob Maine", "Matthew Kane Parker", "Ian Lesperance", "David Edwards", "Paul Meskers"]
5
+ s.version = "0.8.0"
6
+ s.authors = ["Jacob Maine", "Matthew Kane Parker", "Ian Lesperance", "David Edwards", "Paul Meskers", "Brent Wheeldon", "David Tengdin"]
5
7
  s.email = ["licensefinder@pivotalabs.com"]
6
8
  s.homepage = "https://github.com/pivotal/LicenseFinder"
7
9
  s.summary = "Audit the OSS licenses of your application's dependencies."
@@ -9,19 +11,26 @@ Gem::Specification.new do |s|
9
11
  s.description = <<-DESCRIPTION
10
12
  Do you know the licenses of all your application's dependencies? What open source software licenses will your business accept?
11
13
 
12
- LicenseFinder culls your Gemfile, detects the licenses of the gems in it, and gives you a report that you can act on. If you already know
13
- what licenses your business is comfortable with, you can whitelist them, leaving you with an action report of only those dependencies that have
14
+ LicenseFinder culls your Gemfile, detects the licenses of the gems in it, and gives you a report that you can act on. If you already know
15
+ what licenses your business is comfortable with, you can whitelist them, leaving you with an action report of only those dependencies that have
14
16
  licenses that fall outside of the whitelist.
15
17
  DESCRIPTION
16
18
 
17
19
  s.license = "MIT"
18
20
 
19
21
  s.add_dependency "bundler"
20
- %w(rspec rake cucumber rails pry xpath capybara).each do |gem|
22
+ s.add_dependency "sequel"
23
+ s.add_dependency LicenseFinder::Platform.sqlite_gem
24
+
25
+ %w(rspec rake xpath capybara cucumber database_cleaner).each do |gem|
21
26
  s.add_development_dependency gem
22
27
  end
23
28
 
29
+ s.add_development_dependency "rails", "~> 3.2.0"
30
+
24
31
  s.files = `git ls-files`.split("\n")
25
32
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
26
33
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
34
+
35
+ s.platform = "java" if LicenseFinder::Platform.java?
27
36
  end