license_finder 0.9.4-java → 0.9.5-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 (60) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +0 -7
  3. data/.travis.yml +1 -3
  4. data/CHANGELOG.rdoc +13 -0
  5. data/db/migrate/201307251004_data_fix_manual_licenses.rb +2 -2
  6. data/db/migrate/201307251107_reassociate_license.rb +18 -18
  7. data/db/migrate/201311192002_add_manually_approved_to_dependencies.rb +7 -0
  8. data/db/migrate/201311192003_reassociate_manual_approval.rb +14 -0
  9. data/db/migrate/201311192010_drop_approvals.rb +5 -0
  10. data/features/cli.feature +1 -1
  11. data/features/html_report.feature +1 -1
  12. data/features/{non_bundler_dependencies.feature → manually_managed_dependencies.feature} +6 -6
  13. data/features/step_definitions/html_report_steps.rb +2 -9
  14. data/features/step_definitions/{non_bundler_steps.rb → manually_managed_steps.rb} +0 -0
  15. data/features/step_definitions/shared_steps.rb +4 -8
  16. data/lib/license_finder.rb +21 -17
  17. data/lib/license_finder/bower.rb +3 -34
  18. data/lib/license_finder/bower_package.rb +63 -0
  19. data/lib/license_finder/bundler.rb +73 -0
  20. data/lib/license_finder/bundler_package.rb +33 -0
  21. data/lib/license_finder/cli.rb +33 -35
  22. data/lib/license_finder/dependency_manager.rb +14 -23
  23. data/lib/license_finder/license/apache2.rb +1 -1
  24. data/lib/license_finder/license/lgpl.rb +1 -0
  25. data/lib/license_finder/npm.rb +22 -39
  26. data/lib/license_finder/npm_package.rb +61 -0
  27. data/lib/license_finder/package.rb +14 -80
  28. data/lib/license_finder/package_saver.rb +13 -75
  29. data/lib/license_finder/pip.rb +21 -33
  30. data/lib/license_finder/pip_package.rb +51 -0
  31. data/lib/license_finder/platform.rb +3 -15
  32. data/lib/license_finder/possible_license_file.rb +0 -4
  33. data/lib/license_finder/possible_license_files.rb +4 -0
  34. data/lib/license_finder/tables.rb +2 -2
  35. data/lib/license_finder/tables/bundler_group.rb +3 -0
  36. data/lib/license_finder/tables/dependency.rb +43 -18
  37. data/lib/license_finder/tables/license_alias.rb +4 -0
  38. data/lib/license_finder/yml_to_sql.rb +22 -30
  39. data/license_finder.gemspec +3 -3
  40. data/readme.md +5 -5
  41. data/spec/lib/license_finder/bower_package_spec.rb +56 -0
  42. data/spec/lib/license_finder/bower_spec.rb +3 -24
  43. data/spec/lib/license_finder/bundler_package_spec.rb +62 -0
  44. data/spec/lib/license_finder/{bundle_spec.rb → bundler_spec.rb} +7 -7
  45. data/spec/lib/license_finder/cli_spec.rb +6 -6
  46. data/spec/lib/license_finder/dependency_manager_spec.rb +14 -15
  47. data/spec/lib/license_finder/html_report_spec.rb +2 -3
  48. data/spec/lib/license_finder/markdown_report_spec.rb +4 -4
  49. data/spec/lib/license_finder/npm_package_spec.rb +51 -0
  50. data/spec/lib/license_finder/npm_spec.rb +25 -25
  51. data/spec/lib/license_finder/package_saver_spec.rb +50 -190
  52. data/spec/lib/license_finder/pip_package_spec.rb +74 -0
  53. data/spec/lib/license_finder/pip_spec.rb +33 -55
  54. data/spec/lib/license_finder/tables/dependency_spec.rb +83 -32
  55. data/spec/lib/license_finder/yml_to_sql_spec.rb +5 -12
  56. data/spec/spec_helper.rb +22 -2
  57. metadata +30 -18
  58. data/lib/license_finder/bundle.rb +0 -74
  59. data/lib/license_finder/tables/approval.rb +0 -4
  60. data/spec/lib/license_finder/package_spec.rb +0 -98
@@ -0,0 +1,33 @@
1
+ module LicenseFinder
2
+ class BundlerPackage < Package
3
+ extend Forwardable
4
+ def_delegators :gem_def, :summary, :description, :name, :homepage
5
+
6
+ attr_reader :gem_def
7
+ attr_accessor :children
8
+
9
+ def initialize(gem_def, bundler_def)
10
+ @gem_def = gem_def
11
+ @bundler_def = bundler_def
12
+ @children = []
13
+ end
14
+
15
+ def groups
16
+ Array(@bundler_def && @bundler_def.groups)
17
+ end
18
+
19
+ def version
20
+ gem_def.version.to_s
21
+ end
22
+
23
+ private
24
+
25
+ def install_path
26
+ gem_def.full_gem_path
27
+ end
28
+
29
+ def license_from_spec
30
+ gem_def.license
31
+ end
32
+ end
33
+ end
@@ -40,10 +40,10 @@ module LicenseFinder
40
40
 
41
41
  class Dependencies < Subcommand
42
42
  method_option :approve, type: :boolean, desc: "Approve the added dependency"
43
- desc "add LICENSE DEPENDENCY_NAME [VERSION] [--approve]", "Add a dependency that is not managed by Bundler"
43
+ desc "Add LICENSE DEPENDENCY_NAME [VERSION] [--approve]", "Add a dependency that is not managed by Bundler, NPM, etc"
44
44
  def add(license, name, version = nil)
45
45
  die_on_error {
46
- DependencyManager.create_non_bundler(license, name, version)
46
+ DependencyManager.create_manually_managed(license, name, version)
47
47
  DependencyManager.approve!(name) if options[:approve]
48
48
  }
49
49
  if options[:approve]
@@ -53,17 +53,30 @@ module LicenseFinder
53
53
  end
54
54
  end
55
55
 
56
- desc "remove DEPENDENCY_NAME", "Remove a dependency that is not managed by Bundler"
56
+ desc "Remove DEPENDENCY_NAME", "Remove a dependency that is not managed by Bundler, NPM, etc"
57
57
  def remove(name)
58
58
  die_on_error {
59
- DependencyManager.destroy_non_bundler(name)
59
+ DependencyManager.destroy_manually_managed(name)
60
60
  }
61
61
 
62
62
  say "The #{name} dependency has been removed.", :green
63
63
  end
64
64
  end
65
65
 
66
- class Whitelist < Subcommand
66
+ class ConfigSubcommand < Subcommand
67
+ private
68
+
69
+ def modifying
70
+ die_on_error {
71
+ yield
72
+
73
+ LicenseFinder.config.save
74
+ Reporter.write_reports
75
+ }
76
+ end
77
+ end
78
+
79
+ class Whitelist < ConfigSubcommand
67
80
  desc "list", "List all the whitelisted licenses"
68
81
  def list
69
82
  whitelist = LicenseFinder.config.whitelist
@@ -76,45 +89,36 @@ module LicenseFinder
76
89
 
77
90
  desc "add LICENSE", "Add one ore more licenses to the whitelist"
78
91
  def add(*licenses)
79
- die_on_error {
92
+ modifying {
80
93
  licenses.each do |license|
81
94
  LicenseFinder.config.whitelist.push(license)
82
95
  end
83
- LicenseFinder.config.save
84
-
85
- Reporter.write_reports
86
96
  }
87
97
  say "Added #{licenses.join(", ")} to the license whitelist"
88
98
  end
89
99
 
90
100
  desc "remove LICENSE", "Remove one ore more licenses from the whitelist"
91
101
  def remove(*licenses)
92
- die_on_error {
102
+ modifying {
93
103
  licenses.each do |license|
94
104
  LicenseFinder.config.whitelist.delete(license)
95
105
  end
96
- LicenseFinder.config.save
97
-
98
- Reporter.write_reports
99
106
  }
100
107
  say "Removed #{licenses.join(", ")} from the license whitelist"
101
108
  end
102
109
  end
103
110
 
104
- class ProjectName < Subcommand
111
+ class ProjectName < ConfigSubcommand
105
112
  desc "set NAME", "Set the project name"
106
113
  def set(name)
107
- die_on_error {
114
+ modifying {
108
115
  LicenseFinder.config.project_name = name
109
- LicenseFinder.config.save
110
-
111
- Reporter.write_reports
112
116
  }
113
117
  say "Set the project name to #{name}", :green
114
118
  end
115
119
  end
116
120
 
117
- class IgnoredBundlerGroups < Subcommand
121
+ class IgnoredBundlerGroups < ConfigSubcommand
118
122
  desc "list", "List all the ignored bundler groups"
119
123
  def list
120
124
  ignored = LicenseFinder.config.ignore_groups
@@ -127,22 +131,16 @@ module LicenseFinder
127
131
 
128
132
  desc "add GROUP", "Add a bundler group to be ignored"
129
133
  def add(group)
130
- die_on_error {
134
+ modifying {
131
135
  LicenseFinder.config.ignore_groups.push(group)
132
- LicenseFinder.config.save
133
-
134
- Reporter.write_reports
135
136
  }
136
137
  say "Added #{group} to the ignored bundler groups"
137
138
  end
138
139
 
139
140
  desc "remove GROUP", "Remove a bundler group from the ignored bundler groups"
140
141
  def remove(group)
141
- die_on_error {
142
+ modifying {
142
143
  LicenseFinder.config.ignore_groups.delete(group)
143
- LicenseFinder.config.save
144
-
145
- Reporter.write_reports
146
144
  }
147
145
  say "Removed #{group} from the ignored bundler groups"
148
146
  end
@@ -154,7 +152,7 @@ module LicenseFinder
154
152
  def rescan
155
153
  die_on_error {
156
154
  spinner {
157
- DependencyManager.sync_with_bundler
155
+ DependencyManager.sync_with_package_managers
158
156
  }
159
157
  }
160
158
 
@@ -162,7 +160,7 @@ module LicenseFinder
162
160
  end
163
161
  default_task :rescan
164
162
 
165
- desc "approve DEPENDENCY_NAME", "Approve one ore more dependencies by name."
163
+ desc "approve DEPENDENCY_NAME", "Approve one ore more dependencies by name"
166
164
  def approve(*names)
167
165
  die_on_error {
168
166
  names.each { |name| DependencyManager.approve!(name) }
@@ -171,7 +169,7 @@ module LicenseFinder
171
169
  say "The #{names.join(", ")} dependency has been approved!", :green
172
170
  end
173
171
 
174
- desc "license LICENSE DEPENDENCY_NAME", "Update a dependency's license."
172
+ desc "license LICENSE DEPENDENCY_NAME", "Update a dependency's license"
175
173
  def license(license, name)
176
174
  die_on_error {
177
175
  DependencyManager.license!(name, license)
@@ -180,7 +178,7 @@ module LicenseFinder
180
178
  say "The #{name} dependency has been marked as using #{license} license!", :green
181
179
  end
182
180
 
183
- desc "move", "Move dependency.* files from root directory to doc/."
181
+ desc "move", "Move dependency.* files from root directory to doc/"
184
182
  def move
185
183
  Configuration.move!
186
184
  say "Congratulations, you have cleaned up your root directory!'", :green
@@ -199,10 +197,10 @@ module LicenseFinder
199
197
  end
200
198
  end
201
199
 
202
- subcommand "dependencies", Dependencies, "manage non-Bundler dependencies"
203
- subcommand "ignored_bundler_groups", IgnoredBundlerGroups, "manage ignored bundler groups"
204
- subcommand "whitelist", Whitelist, "manage whitelisted licenses"
205
- subcommand "project_name", ProjectName, "manage the project name"
200
+ subcommand "dependencies", Dependencies, "Manually manage dependencies outside of Bundler, NPM, pip, etc"
201
+ subcommand "ignored_bundler_groups", IgnoredBundlerGroups, "Manage ignored bundler groups"
202
+ subcommand "whitelist", Whitelist, "Manage whitelisted licenses"
203
+ subcommand "project_name", ProjectName, "Manage the project name"
206
204
 
207
205
  private
208
206
 
@@ -2,43 +2,26 @@ require 'digest'
2
2
 
3
3
  module LicenseFinder
4
4
  module DependencyManager
5
- def self.sync_with_bundler
5
+ def self.sync_with_package_managers
6
6
  modifying {
7
- current_dependencies = []
7
+ current_dependencies = PackageSaver.save_all(current_packages)
8
8
 
9
- if Bundle.has_gemfile?
10
- current_dependencies += PackageSaver.save_packages(Bundle.current_gems(LicenseFinder.config))
11
- end
12
-
13
- if Pip.has_requirements?
14
- current_dependencies += PackageSaver.save_packages(Pip.current_dists())
15
- end
16
-
17
- if NPM.has_package?
18
- current_dependencies += PackageSaver.save_packages(NPM.current_modules())
19
- end
20
-
21
- if Bower.has_package_file?
22
- current_dependencies += PackageSaver.save_packages(Bower.current_packages())
23
- end
24
-
25
- Dependency.bundler.obsolete(current_dependencies).each(&:destroy)
9
+ Dependency.managed.obsolete(current_dependencies).each(&:destroy)
26
10
  }
27
11
  end
28
12
 
29
- def self.create_non_bundler(license, name, version)
13
+ def self.create_manually_managed(license, name, version)
30
14
  raise Error.new("#{name} dependency already exists") unless Dependency.where(name: name).empty?
31
15
 
32
16
  modifying {
33
17
  dependency = Dependency.new(manual: true, name: name, version: version)
34
18
  dependency.license = LicenseAlias.create(name: license)
35
- dependency.approval = Approval.create
36
19
  dependency.save
37
20
  }
38
21
  end
39
22
 
40
- def self.destroy_non_bundler(name)
41
- modifying { find_by_name(name, Dependency.non_bundler).destroy }
23
+ def self.destroy_manually_managed(name)
24
+ modifying { find_by_name(name, Dependency.manually_managed).destroy }
42
25
  end
43
26
 
44
27
  def self.license!(name, license)
@@ -68,6 +51,14 @@ module LicenseFinder
68
51
 
69
52
  private # not really private, but it looks like it is!
70
53
 
54
+ def self.current_packages
55
+ package_managers.select(&:active?).map(&:current_packages).flatten
56
+ end
57
+
58
+ def self.package_managers
59
+ [Bundler, NPM, Pip, Bower]
60
+ end
61
+
71
62
  def self.find_by_name(name, scope = Dependency)
72
63
  dep = scope.first(name: name)
73
64
  raise Error.new("could not find dependency named #{name}") unless dep
@@ -1,5 +1,5 @@
1
1
  class LicenseFinder::License::Apache2 < LicenseFinder::License::Base
2
- self.alternative_names = ["Apache 2.0", "Apache2", "Apache-2.0", "Apache Software License", "Apache License 2.0", "Apache License Version 2.0"]
2
+ self.alternative_names = ["Apache 2.0", "Apache2", "Apache-2.0", "Apache Software License", "Apache License 2.0", "Apache License Version 2.0", "Apache Public License 2.0"]
3
3
  self.license_url = "http://www.apache.org/licenses/LICENSE-2.0.txt"
4
4
 
5
5
  def self.pretty_name
@@ -1,3 +1,4 @@
1
1
  class LicenseFinder::License::LGPL < LicenseFinder::License::Base
2
+ self.alternative_names = ["LGPL-3", "LGPLv3", "LGPL-3.0"]
2
3
  self.license_url = "http://www.gnu.org/licenses/lgpl.txt"
3
4
  end
@@ -1,39 +1,40 @@
1
1
  require 'json'
2
- require 'license_finder/package'
3
2
 
4
3
  module LicenseFinder
5
4
  class NPM
6
-
7
5
  DEPENDENCY_GROUPS = ["dependencies", "devDependencies", "bundleDependencies", "bundledDependencies"]
8
6
 
9
- def self.current_modules
10
- return @modules if @modules
7
+ def self.current_packages
8
+ json = npm_json
9
+ dependencies = DEPENDENCY_GROUPS.map { |g| (json[g] || {}).values }.flatten(1).reject{ |d| d.is_a?(String) }
11
10
 
12
- command = "npm list --json --long"
13
- output, success = capture(command)
14
- raise "Command #{command} failed to execute: #{output}" unless success
15
-
16
- json = JSON(output)
17
- dependencies = DEPENDENCY_GROUPS.map { |g| (json[g] || {}).values }.flatten(1)
18
-
19
- @modules = dependencies.map do |node_module|
20
- Package.new(OpenStruct.new(
21
- :name => node_module.fetch("name", nil),
22
- :version => node_module.fetch("version", nil),
23
- :full_gem_path => node_module.fetch("path", nil),
24
- :license => self.harvest_license(node_module),
25
- :summary => node_module.fetch("description", nil),
26
- :description => node_module.fetch("readme", nil)
27
- ))
11
+ dependencies.map do |node_module|
12
+ NpmPackage.new(node_module)
28
13
  end
29
14
  end
30
15
 
31
- def self.has_package?
16
+ def self.active?
32
17
  File.exists?(package_path)
33
18
  end
34
19
 
35
20
  private
36
21
 
22
+ def self.npm_json
23
+ command = "npm list --json --long"
24
+ output, success = capture(command)
25
+ if success
26
+ json = JSON(output)
27
+ else
28
+ json = JSON(output) rescue nil
29
+ if json
30
+ $stderr.puts "Command #{command} returned error but parsing succeeded." unless ENV['test_run']
31
+ else
32
+ raise "Command #{command} failed to execute: #{output}"
33
+ end
34
+ end
35
+ json
36
+ end
37
+
37
38
  def self.capture(command)
38
39
  [`#{command}`, $?.success?]
39
40
  end
@@ -41,23 +42,5 @@ module LicenseFinder
41
42
  def self.package_path
42
43
  Pathname.new('package.json').expand_path
43
44
  end
44
-
45
- def self.harvest_license(node_module)
46
- license = node_module.fetch("licenses", []).first
47
-
48
- if license.is_a? Hash
49
- license = license.fetch("type", nil)
50
- end
51
-
52
- if license.nil?
53
- license = node_module.fetch("license", nil)
54
-
55
- if license.is_a? Hash
56
- license = license.fetch("type", nil)
57
- end
58
- end
59
-
60
- license
61
- end
62
45
  end
63
46
  end
@@ -0,0 +1,61 @@
1
+ module LicenseFinder
2
+ class NpmPackage < Package
3
+ def initialize(node_module)
4
+ @node_module = node_module
5
+ end
6
+
7
+ def name
8
+ node_module["name"]
9
+ end
10
+
11
+ def version
12
+ node_module["version"]
13
+ end
14
+
15
+ def summary
16
+ node_module["description"]
17
+ end
18
+
19
+ def description
20
+ node_module["readme"]
21
+ end
22
+
23
+ def children
24
+ [] # no way to determine child deps from npm (maybe?)
25
+ end
26
+
27
+ def groups
28
+ [] # no concept of dev/test groups in npm (maybe?)
29
+ end
30
+
31
+ def homepage
32
+ nil # no way to extract homepage from npm (maybe?)
33
+ end
34
+
35
+ private
36
+
37
+ attr_reader :node_module
38
+
39
+ def install_path
40
+ node_module["path"]
41
+ end
42
+
43
+ def license_from_spec
44
+ license = node_module.fetch("licenses", []).first
45
+
46
+ if license
47
+ license = license.fetch("type", nil)
48
+ end
49
+
50
+ if license.nil?
51
+ license = node_module.fetch("license", nil)
52
+
53
+ if license.is_a? Hash
54
+ license = license.fetch("type", nil)
55
+ end
56
+ end
57
+
58
+ license
59
+ end
60
+ end
61
+ end
@@ -1,97 +1,31 @@
1
1
  module LicenseFinder
2
+ # Super-class that adapts data from different package management
3
+ # systems (gems, npm, pip, etc.) to a common interface.
4
+ #
5
+ # For guidance on adding a new system use the shared behavior
6
+ # it_behaves_like "it conforms to interface required by PackageSaver"
7
+ # and see BundlerPackage, PipPackage and NpmPackage
2
8
  class Package
3
- attr_reader :parents, :spec, :bundler_dependency, :children
4
-
5
- def initialize(spec, bundler_dependency = nil)
6
- @spec = spec
7
- @bundler_dependency = bundler_dependency
8
- @children = []
9
- end
10
-
11
- def name
12
- "#{dependency_name} #{dependency_version}"
13
- end
14
-
15
- def parents
16
- @parents ||= []
17
- end
18
-
19
- def dependency_name
20
- @spec.name
21
- end
22
-
23
- def dependency_version
24
- @spec.version.to_s
25
- end
26
-
27
- def summary
28
- @spec.summary
29
- end
30
-
31
- def description
32
- @spec.description
33
- end
34
-
35
- def groups
36
- @groups ||= bundler_dependency ? bundler_dependency.groups : []
37
- end
38
-
39
9
  def license
40
10
  @license ||= determine_license
41
11
  end
42
12
 
43
- def sort_order
44
- dependency_name.downcase
45
- end
46
-
47
- def license_files
48
- PossibleLicenseFiles.new(@spec.full_gem_path).find
49
- end
50
-
51
- def children=(childs)
52
- @children = childs
53
- end
54
-
55
13
  private
56
14
 
57
15
  def determine_license
58
- return @spec.license if @spec.license
59
-
60
- license = license_files.map(&:license).compact.first
61
- license || "other"
16
+ license_from_spec || license_from_files || default_license
62
17
  end
63
- end
64
18
 
65
- class PythonPackage < Package
66
- def determine_license
67
- return @spec.license if @spec.license
68
-
69
- license = super
70
-
71
- if !license || license == "other"
72
- license = Pip.license_for self
73
- end
74
-
75
- license
76
- end
77
-
78
- def summary
79
- json.fetch("summary", "")
19
+ def license_from_files
20
+ license_files.map(&:license).compact.first
80
21
  end
81
22
 
82
- def description
83
- json.fetch("description", "")
23
+ def license_files
24
+ PossibleLicenseFiles.find(install_path)
84
25
  end
85
26
 
86
- def json
87
- return @json if @json
88
-
89
- response = HTTParty.get("https://pypi.python.org/pypi/#{dependency_name}/#{dependency_version}/json")
90
- if response.code == 200
91
- @json = JSON.parse(response.body).fetch("info", {})
92
- end
93
-
94
- @json ||= {}
27
+ def default_license
28
+ "other"
95
29
  end
96
30
  end
97
- end
31
+ end