license_finder 1.1.1-java → 1.2-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.
- 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
|