license_finder 1.1.1-java → 1.2-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +2 -2
- data/CHANGELOG.rdoc +10 -0
- data/Gemfile +1 -1
- data/README.md +363 -0
- data/Rakefile +30 -1
- data/TODO.md +28 -0
- data/bin/license_finder_pip.py +18 -0
- data/db/migrate/201410031451_rename_dependency_license_name.rb +6 -0
- data/features/multiple_licenses.feature +9 -0
- data/features/step_definitions/cli_steps.rb +9 -9
- data/features/step_definitions/cocoapod_steps.rb +1 -1
- data/features/step_definitions/configure_bundler_groups_steps.rb +3 -3
- data/features/step_definitions/configure_whitelist_steps.rb +4 -4
- data/features/step_definitions/gradle_steps.rb +1 -1
- data/features/step_definitions/manually_added_steps.rb +3 -3
- data/features/step_definitions/manually_approved_steps.rb +5 -5
- data/features/step_definitions/manually_assigned_license_steps.rb +4 -4
- data/features/step_definitions/maven_steps.rb +1 -1
- data/features/step_definitions/multiple_licenses_steps.rb +14 -0
- data/features/step_definitions/node_steps.rb +1 -1
- data/features/step_definitions/python_steps.rb +1 -1
- data/features/step_definitions/report_csv_steps.rb +3 -3
- data/features/step_definitions/report_html_steps.rb +5 -5
- data/features/step_definitions/shared_steps.rb +23 -6
- data/lib/license_finder.rb +3 -0
- data/lib/license_finder/cli.rb +13 -34
- data/lib/license_finder/configuration.rb +8 -4
- data/lib/license_finder/dependency_manager.rb +25 -15
- data/lib/license_finder/license.rb +8 -0
- data/lib/license_finder/logger.rb +59 -0
- data/lib/license_finder/package.rb +37 -30
- data/lib/license_finder/package_manager.rb +20 -0
- data/lib/license_finder/package_managers/bower.rb +4 -9
- data/lib/license_finder/package_managers/bower_package.rb +2 -1
- data/lib/license_finder/package_managers/bundler.rb +26 -41
- data/lib/license_finder/package_managers/bundler_package.rb +6 -3
- data/lib/license_finder/package_managers/cocoa_pods.rb +18 -10
- data/lib/license_finder/package_managers/cocoa_pods_package.rb +4 -3
- data/lib/license_finder/package_managers/gradle.rb +7 -11
- data/lib/license_finder/package_managers/gradle_package.rb +2 -7
- data/lib/license_finder/package_managers/maven.rb +5 -9
- data/lib/license_finder/package_managers/maven_package.rb +4 -8
- data/lib/license_finder/package_managers/npm.rb +6 -10
- data/lib/license_finder/package_managers/npm_package.rb +2 -1
- data/lib/license_finder/package_managers/pip.rb +11 -24
- data/lib/license_finder/package_managers/pip_package.rb +2 -1
- data/lib/license_finder/package_saver.rb +2 -2
- data/lib/license_finder/platform.rb +4 -0
- data/lib/license_finder/possible_license_file.rb +4 -0
- data/lib/license_finder/possible_license_files.rb +2 -1
- data/lib/license_finder/reports/detailed_text_report.rb +1 -1
- data/lib/license_finder/reports/formatted_report.rb +1 -1
- data/lib/license_finder/tables/dependency.rb +22 -12
- data/lib/license_finder/yml_to_sql.rb +1 -1
- data/lib/templates/html_report.erb +4 -4
- data/lib/templates/markdown_report.erb +4 -4
- data/lib/templates/text_report.erb +1 -1
- data/license_finder.gemspec +28 -12
- data/spec/lib/license_finder/cli_spec.rb +193 -185
- data/spec/lib/license_finder/configuration_spec.rb +46 -47
- data/spec/lib/license_finder/dependency_manager_spec.rb +48 -44
- data/spec/lib/license_finder/license/definitions_spec.rb +26 -26
- data/spec/lib/license_finder/license_spec.rb +25 -25
- data/spec/lib/license_finder/package_managers/bower_package_spec.rb +33 -17
- data/spec/lib/license_finder/package_managers/bower_spec.rb +35 -35
- data/spec/lib/license_finder/package_managers/bundler_package_spec.rb +20 -15
- data/spec/lib/license_finder/package_managers/bundler_spec.rb +12 -19
- data/spec/lib/license_finder/package_managers/cocoa_pods_package_spec.rb +8 -5
- data/spec/lib/license_finder/package_managers/cocoa_pods_spec.rb +20 -22
- data/spec/lib/license_finder/package_managers/gradle_package_spec.rb +8 -5
- data/spec/lib/license_finder/package_managers/gradle_spec.rb +20 -20
- data/spec/lib/license_finder/package_managers/maven_package_spec.rb +8 -5
- data/spec/lib/license_finder/package_managers/maven_spec.rb +18 -18
- data/spec/lib/license_finder/package_managers/npm_package_spec.rb +36 -17
- data/spec/lib/license_finder/package_managers/npm_spec.rb +17 -17
- data/spec/lib/license_finder/package_managers/pip_package_spec.rb +16 -10
- data/spec/lib/license_finder/package_managers/pip_spec.rb +21 -18
- data/spec/lib/license_finder/package_saver_spec.rb +15 -25
- data/spec/lib/license_finder/possible_license_file_spec.rb +5 -4
- data/spec/lib/license_finder/possible_license_files_spec.rb +11 -5
- data/spec/lib/license_finder/reports/detailed_text_report_spec.rb +3 -3
- data/spec/lib/license_finder/reports/html_report_spec.rb +23 -23
- data/spec/lib/license_finder/reports/markdown_report_spec.rb +12 -12
- data/spec/lib/license_finder/reports/reporter_spec.rb +11 -11
- data/spec/lib/license_finder/reports/text_report_spec.rb +3 -3
- data/spec/lib/license_finder/tables/dependency_spec.rb +59 -41
- data/spec/lib/license_finder/yml_to_sql_spec.rb +21 -21
- data/spec/lib/license_finder_spec.rb +1 -1
- data/spec/spec_helper.rb +0 -13
- data/spec/support/shared_examples_for_package.rb +46 -0
- data/spec/support/shared_examples_for_package_manager.rb +15 -0
- metadata +19 -100
- data/readme.md +0 -259
@@ -102,9 +102,13 @@ module LicenseFinder
|
|
102
102
|
end
|
103
103
|
|
104
104
|
def last_refreshed
|
105
|
-
[
|
106
|
-
|
107
|
-
|
105
|
+
[
|
106
|
+
database_file,
|
107
|
+
text_file,
|
108
|
+
detailed_text_file,
|
109
|
+
html_file,
|
110
|
+
markdown_file
|
111
|
+
].map(&:mtime).min
|
108
112
|
end
|
109
113
|
end
|
110
114
|
|
@@ -126,7 +130,7 @@ module LicenseFinder
|
|
126
130
|
end
|
127
131
|
|
128
132
|
def last_modified
|
129
|
-
|
133
|
+
file.mtime
|
130
134
|
end
|
131
135
|
|
132
136
|
private
|
@@ -1,8 +1,14 @@
|
|
1
1
|
require 'digest'
|
2
2
|
|
3
3
|
module LicenseFinder
|
4
|
-
|
5
|
-
|
4
|
+
class DependencyManager
|
5
|
+
attr_reader :logger
|
6
|
+
|
7
|
+
def initialize options={}
|
8
|
+
@logger = options[:logger] || LicenseFinder::Logger::Default.new
|
9
|
+
end
|
10
|
+
|
11
|
+
def sync_with_package_managers options={}
|
6
12
|
modifying {
|
7
13
|
current_dependencies = PackageSaver.save_all(current_packages)
|
8
14
|
|
@@ -10,30 +16,30 @@ module LicenseFinder
|
|
10
16
|
}
|
11
17
|
end
|
12
18
|
|
13
|
-
def
|
19
|
+
def manually_add(license, name, version)
|
14
20
|
raise Error.new("#{name} dependency already exists") unless Dependency.where(name: name).empty?
|
15
21
|
|
16
22
|
modifying {
|
17
23
|
dependency = Dependency.new(added_manually: true, name: name, version: version)
|
18
|
-
dependency.
|
24
|
+
dependency.licenses = [License.find_by_name(license)].to_set
|
19
25
|
dependency.save
|
20
26
|
}
|
21
27
|
end
|
22
28
|
|
23
|
-
def
|
29
|
+
def manually_remove(name)
|
24
30
|
modifying { find_by_name(name, Dependency.added_manually).destroy }
|
25
31
|
end
|
26
32
|
|
27
|
-
def
|
33
|
+
def license!(name, license_name)
|
28
34
|
license = License.find_by_name(license_name)
|
29
35
|
modifying { find_by_name(name).set_license_manually!(license) }
|
30
36
|
end
|
31
37
|
|
32
|
-
def
|
38
|
+
def approve!(name, approver = nil, notes = nil)
|
33
39
|
modifying { find_by_name(name).approve!(approver, notes) }
|
34
40
|
end
|
35
41
|
|
36
|
-
def
|
42
|
+
def modifying
|
37
43
|
checksum_before = checksum
|
38
44
|
result = DB.transaction { yield }
|
39
45
|
checksum_after = checksum
|
@@ -49,29 +55,33 @@ module LicenseFinder
|
|
49
55
|
|
50
56
|
private # not really private, but it looks like it is!
|
51
57
|
|
52
|
-
def
|
58
|
+
def reports_do_not_exist
|
53
59
|
!(LicenseFinder.config.artifacts.html_file.exist?)
|
54
60
|
end
|
55
61
|
|
56
|
-
def
|
62
|
+
def reports_are_stale
|
57
63
|
LicenseFinder.config.last_modified > LicenseFinder.config.artifacts.last_refreshed
|
58
64
|
end
|
59
65
|
|
60
|
-
def
|
61
|
-
package_managers.
|
66
|
+
def current_packages
|
67
|
+
package_managers.
|
68
|
+
map { |pm| pm.new(logger: logger) }.
|
69
|
+
select(&:active?).
|
70
|
+
map(&:current_packages).
|
71
|
+
flatten
|
62
72
|
end
|
63
73
|
|
64
|
-
def
|
74
|
+
def package_managers
|
65
75
|
[Bundler, NPM, Pip, Bower, Maven, Gradle, CocoaPods]
|
66
76
|
end
|
67
77
|
|
68
|
-
def
|
78
|
+
def find_by_name(name, scope = Dependency)
|
69
79
|
dep = scope.first(name: name)
|
70
80
|
raise Error.new("could not find dependency named #{name}") unless dep
|
71
81
|
dep
|
72
82
|
end
|
73
83
|
|
74
|
-
def
|
84
|
+
def checksum
|
75
85
|
database_file = LicenseFinder.config.artifacts.database_file
|
76
86
|
if database_file.exist?
|
77
87
|
Digest::SHA2.file(database_file).hexdigest
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module LicenseFinder
|
2
|
+
module Logger
|
3
|
+
def self.new options={}
|
4
|
+
klass = if options[:quiet]
|
5
|
+
Quiet
|
6
|
+
elsif options[:debug]
|
7
|
+
Verbose
|
8
|
+
else
|
9
|
+
Progress
|
10
|
+
end
|
11
|
+
klass.new
|
12
|
+
end
|
13
|
+
|
14
|
+
class Base
|
15
|
+
def active package_manager, is_active
|
16
|
+
log package_manager, sprintf("%s active", (is_active ? "is" : "not"))
|
17
|
+
end
|
18
|
+
|
19
|
+
def package package_manager, package
|
20
|
+
dependencies = package.children
|
21
|
+
if dependencies.empty?
|
22
|
+
log package_manager, sprintf("package '%s' has no dependencies", package.name)
|
23
|
+
else
|
24
|
+
log package_manager, sprintf("package '%s' has dependencies:", package.name)
|
25
|
+
dependencies.each do |dep|
|
26
|
+
log package_manager, sprintf("- %s", dep)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def license package, package_name, license, how
|
32
|
+
log package, sprintf("package %s: found license '%s' %s", package_name, license, how)
|
33
|
+
end
|
34
|
+
|
35
|
+
def log prefix, string
|
36
|
+
raise NotImplementedError, "#log must be implemented"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
class Quiet < Base
|
41
|
+
def log prefix, string
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class Progress < Base
|
46
|
+
def log prefix, string
|
47
|
+
STDOUT.print(".") && STDOUT.flush
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
class Verbose < Base
|
52
|
+
def log prefix, string
|
53
|
+
STDOUT.printf("%s: %s\n", prefix, string)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
Default = Quiet
|
58
|
+
end
|
59
|
+
end
|
@@ -3,9 +3,20 @@ module LicenseFinder
|
|
3
3
|
# systems (gems, npm, pip, etc.) to a common interface.
|
4
4
|
#
|
5
5
|
# For guidance on adding a new system use the shared behavior
|
6
|
-
#
|
7
|
-
#
|
6
|
+
#
|
7
|
+
# it_behaves_like "a Package"
|
8
|
+
#
|
9
|
+
# Additional guidelines are:
|
10
|
+
#
|
11
|
+
# - if you're going to use Package#licenses ...
|
12
|
+
# - implement #licenses_names_from_spec
|
13
|
+
# - implement #install_path
|
14
|
+
# - else
|
15
|
+
# - implement #licenses
|
16
|
+
#
|
8
17
|
class Package
|
18
|
+
attr_reader :logger
|
19
|
+
|
9
20
|
def self.license_names_from_standard_spec(spec)
|
10
21
|
licenses = spec["licenses"] || [spec["license"]].compact
|
11
22
|
licenses = [licenses] unless licenses.is_a?(Array)
|
@@ -18,54 +29,50 @@ module LicenseFinder
|
|
18
29
|
end
|
19
30
|
end
|
20
31
|
|
21
|
-
def
|
22
|
-
@
|
32
|
+
def initialize options={}
|
33
|
+
@logger = options[:logger] || LicenseFinder::Logger::Default.new
|
23
34
|
end
|
24
35
|
|
25
|
-
|
36
|
+
def licenses
|
37
|
+
@licenses ||= determine_license.to_set
|
38
|
+
end
|
26
39
|
|
27
40
|
def determine_license
|
28
|
-
|
29
|
-
|
30
|
-
elsif licenses_from_files.any?
|
31
|
-
choose_license_from licenses_from_files
|
32
|
-
else
|
33
|
-
default_license
|
34
|
-
end
|
35
|
-
end
|
41
|
+
lfs = licenses_from_spec
|
42
|
+
return lfs if lfs.any?
|
36
43
|
|
37
|
-
|
38
|
-
if
|
39
|
-
|
40
|
-
|
41
|
-
licenses.first
|
42
|
-
end
|
44
|
+
lff = licenses_from_files
|
45
|
+
return lff if lff.any?
|
46
|
+
|
47
|
+
[default_license].to_set
|
43
48
|
end
|
44
49
|
|
45
50
|
def licenses_from_spec
|
46
51
|
license_names_from_spec.map do |name|
|
47
|
-
License.find_by_name(name)
|
48
|
-
|
52
|
+
License.find_by_name(name).tap do |license|
|
53
|
+
logger.license self.class, self.name, license.name, "from spec" if license
|
54
|
+
end
|
55
|
+
end.compact.to_set
|
49
56
|
end
|
50
57
|
|
51
58
|
def licenses_from_files
|
52
|
-
license_files.map
|
59
|
+
license_files.map do |license_file|
|
60
|
+
license_file.license.tap do |license|
|
61
|
+
logger.license self.class, self.name, license.name, "from file '#{license_file.path}'" if license
|
62
|
+
end
|
63
|
+
end.compact.to_set
|
53
64
|
end
|
54
65
|
|
55
66
|
def license_files
|
56
67
|
PossibleLicenseFiles.find(install_path)
|
57
68
|
end
|
58
69
|
|
59
|
-
def multiple_licenses
|
60
|
-
if ( licenses_from_spec.uniq.size > 1 )
|
61
|
-
License.find_by_name "multiple licenses: #{(licenses_from_spec).map(&:name).uniq.join(', ')}"
|
62
|
-
else
|
63
|
-
License.find_by_name "multiple licenses: #{(licenses_from_files).map(&:name).uniq.join(', ')}"
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
70
|
def default_license
|
68
71
|
License.find_by_name nil
|
69
72
|
end
|
73
|
+
|
74
|
+
def install_path
|
75
|
+
nil
|
76
|
+
end
|
70
77
|
end
|
71
78
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module LicenseFinder
|
2
|
+
class PackageManager
|
3
|
+
attr_reader :logger
|
4
|
+
|
5
|
+
def initialize options={}
|
6
|
+
@logger = options[:logger] || LicenseFinder::Logger::Default.new
|
7
|
+
@package_path = options[:package_path] # dependency injection for tests
|
8
|
+
end
|
9
|
+
|
10
|
+
def active?
|
11
|
+
injected_package_path.exist?.tap { |is_active| logger.active self.class, is_active }
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def injected_package_path
|
17
|
+
@package_path || package_path
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -1,25 +1,20 @@
|
|
1
1
|
require 'json'
|
2
2
|
|
3
3
|
module LicenseFinder
|
4
|
-
class Bower
|
5
|
-
|
6
|
-
def self.current_packages
|
4
|
+
class Bower < PackageManager
|
5
|
+
def current_packages
|
7
6
|
output = `bower list --json`
|
8
7
|
|
9
8
|
json = JSON(output)
|
10
9
|
|
11
10
|
json.fetch("dependencies",[]).map do |package|
|
12
|
-
BowerPackage.new(package[1])
|
11
|
+
BowerPackage.new(package[1], logger: logger)
|
13
12
|
end
|
14
13
|
end
|
15
14
|
|
16
|
-
def self.active?
|
17
|
-
package_path.exist?
|
18
|
-
end
|
19
|
-
|
20
15
|
private
|
21
16
|
|
22
|
-
def
|
17
|
+
def package_path
|
23
18
|
Pathname.new('bower.json')
|
24
19
|
end
|
25
20
|
end
|
@@ -1,48 +1,41 @@
|
|
1
1
|
require "bundler"
|
2
2
|
|
3
3
|
module LicenseFinder
|
4
|
-
class Bundler
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
def active?
|
11
|
-
gemfile_path.exist?
|
12
|
-
end
|
13
|
-
|
14
|
-
def gemfile_path
|
15
|
-
Pathname.new("Gemfile").expand_path
|
16
|
-
end
|
4
|
+
class Bundler < PackageManager
|
5
|
+
def initialize options={}
|
6
|
+
super
|
7
|
+
@ignore_groups = options[:ignore_groups] # dependency injection for tests
|
8
|
+
@definition = options[:definition] # dependency injection for tests
|
17
9
|
end
|
18
10
|
|
19
|
-
def
|
20
|
-
|
21
|
-
|
22
|
-
end
|
23
|
-
|
24
|
-
def packages
|
25
|
-
top_level_gems = Set.new
|
26
|
-
|
27
|
-
packages = definition.specs_for(included_groups).map do |gem_def|
|
11
|
+
def current_packages
|
12
|
+
logger.log self.class, "including groups #{included_groups.inspect}"
|
13
|
+
definition.specs_for(included_groups).map do |gem_def|
|
28
14
|
bundler_def = bundler_defs.detect { |bundler_def| bundler_def.name == gem_def.name }
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
BundlerPackage.new(gem_def, bundler_def)
|
15
|
+
BundlerPackage.new(gem_def, bundler_def, logger: logger).tap do |package|
|
16
|
+
logger.package self.class, package
|
17
|
+
end
|
33
18
|
end
|
19
|
+
end
|
34
20
|
|
35
|
-
|
36
|
-
gem.children = children_for(gem, top_level_gems)
|
37
|
-
end
|
21
|
+
private
|
38
22
|
|
39
|
-
|
23
|
+
def definition
|
24
|
+
# DI
|
25
|
+
@definition ||= ::Bundler::Definition.build(package_path, lockfile_path, nil)
|
40
26
|
end
|
41
27
|
|
42
|
-
|
43
|
-
|
28
|
+
def ignore_groups
|
29
|
+
# DI
|
30
|
+
@ignore_groups ||= LicenseFinder.config.ignore_groups
|
31
|
+
end
|
32
|
+
|
33
|
+
def package_path
|
34
|
+
Pathname.new("Gemfile")
|
35
|
+
end
|
44
36
|
|
45
37
|
def bundler_defs
|
38
|
+
# memoized
|
46
39
|
@bundler_defs ||= definition.dependencies
|
47
40
|
end
|
48
41
|
|
@@ -51,15 +44,7 @@ module LicenseFinder
|
|
51
44
|
end
|
52
45
|
|
53
46
|
def lockfile_path
|
54
|
-
|
55
|
-
end
|
56
|
-
|
57
|
-
def children_for(gem, top_level_gems)
|
58
|
-
gem.gem_def.dependencies.map(&:name).select { |name| top_level_gems.include? name }
|
59
|
-
end
|
60
|
-
|
61
|
-
def format_name(gem)
|
62
|
-
gem.name.split(" ")[0]
|
47
|
+
package_path.dirname.join('Gemfile.lock')
|
63
48
|
end
|
64
49
|
end
|
65
50
|
end
|