license_finder 6.14.1 → 7.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/dependabot.yml +9 -0
- data/.rubocop.yml +12 -2
- data/CHANGELOG.md +45 -0
- data/Dockerfile +26 -5
- data/README.md +6 -6
- data/Rakefile +2 -2
- data/VERSION +1 -1
- data/bin/license_finder_pip.py +9 -7
- data/ci/pipelines/release.yml.erb +1 -1
- data/ci/scripts/pushscript.sh +2 -3
- data/ci/scripts/run-tests.sh +4 -3
- data/ci/tasks/rubocop.yml +1 -1
- data/dlf +9 -5
- data/lib/license_finder/cli/approvals.rb +2 -2
- data/lib/license_finder/cli/base.rb +9 -5
- data/lib/license_finder/cli/dependencies.rb +4 -4
- data/lib/license_finder/cli/ignored_dependencies.rb +3 -3
- data/lib/license_finder/cli/ignored_groups.rb +3 -3
- data/lib/license_finder/cli/inherited_decisions.rb +5 -5
- data/lib/license_finder/cli/licenses.rb +2 -2
- data/lib/license_finder/cli/main.rb +17 -11
- data/lib/license_finder/cli/permitted_licenses.rb +3 -3
- data/lib/license_finder/cli/project_name.rb +4 -4
- data/lib/license_finder/cli/restricted_licenses.rb +3 -3
- data/lib/license_finder/configuration.rb +6 -3
- data/lib/license_finder/core.rb +2 -1
- data/lib/license_finder/decisions.rb +9 -5
- data/lib/license_finder/license/definitions.rb +35 -1
- data/lib/license_finder/license/templates/Zlib.txt +17 -0
- data/lib/license_finder/license/text.rb +5 -3
- data/lib/license_finder/license.rb +8 -2
- data/lib/license_finder/logger.rb +1 -1
- data/lib/license_finder/package.rb +3 -11
- data/lib/license_finder/package_delta.rb +1 -1
- data/lib/license_finder/package_manager.rb +1 -0
- data/lib/license_finder/package_managers/cocoa_pods.rb +14 -7
- data/lib/license_finder/package_managers/conan.rb +2 -2
- data/lib/license_finder/package_managers/conda.rb +1 -1
- data/lib/license_finder/package_managers/glide.rb +7 -1
- data/lib/license_finder/package_managers/go_15vendorexperiment.rb +2 -2
- data/lib/license_finder/package_managers/go_dep.rb +1 -1
- data/lib/license_finder/package_managers/go_workspace.rb +1 -1
- data/lib/license_finder/package_managers/nuget.rb +1 -1
- data/lib/license_finder/package_managers/pub.rb +86 -0
- data/lib/license_finder/package_managers/sbt.rb +1 -5
- data/lib/license_finder/package_managers/yarn.rb +34 -6
- data/lib/license_finder/package_utils/license_files.rb +2 -2
- data/lib/license_finder/packages/bower_package.rb +5 -2
- data/lib/license_finder/packages/erlangmk_package.rb +2 -4
- data/lib/license_finder/packages/npm_package.rb +1 -0
- data/lib/license_finder/packages/pubspec_package.rb +18 -0
- data/lib/license_finder/printer.rb +39 -0
- data/lib/license_finder/report.rb +2 -1
- data/lib/license_finder/reports/csv_report.rb +1 -1
- data/lib/license_finder/reports/erb_report.rb +7 -3
- data/lib/license_finder/reports/json_report.rb +2 -1
- data/lib/license_finder/reports/junit_report.rb +5 -1
- data/lib/license_finder/reports/xml_report.rb +5 -1
- data/lib/license_finder/scanner.rb +1 -1
- data/license_finder.gemspec +16 -14
- metadata +61 -28
@@ -0,0 +1,86 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
require 'yaml'
|
5
|
+
|
6
|
+
module LicenseFinder
|
7
|
+
class Pub < PackageManager
|
8
|
+
class PubError < RuntimeError; end
|
9
|
+
|
10
|
+
def current_packages
|
11
|
+
unless File.exist?('pubspec.lock')
|
12
|
+
raise PubError, "No checked-out Pub packages found.
|
13
|
+
Please install your dependencies first."
|
14
|
+
end
|
15
|
+
|
16
|
+
if ENV['PUB_CACHE'].nil? || ENV['PUB_CACHE'].eql?('')
|
17
|
+
raise PubError, 'While PUB_CACHE environment variable is empty, retrieving package licenses is impossible. Please set the PUB_CACHE env variable (default: ~/.pub)'
|
18
|
+
end
|
19
|
+
|
20
|
+
stdout, _stderr, _status = Cmd.run('flutter pub deps --json')
|
21
|
+
yaml_deps = JSON.parse(stdout)
|
22
|
+
yaml_deps['packages'].map do |dependency|
|
23
|
+
package_name = dependency['name']
|
24
|
+
subpath = "#{dependency['name']}-#{dependency['version']}"
|
25
|
+
package_version = dependency['version']
|
26
|
+
|
27
|
+
project_repo = dependency['source'] == 'git' ? Pathname("#{ENV['PUB_CACHE']}/git/#{dependency['name']}-*/") : Pathname("#{ENV['PUB_CACHE']}/hosted/pub.dartlang.org/#{subpath}")
|
28
|
+
|
29
|
+
homepage = read_repository_home(project_repo)
|
30
|
+
homepage = "https://pub.dev/packages/#{package_name}" if homepage.nil? || homepage.empty?
|
31
|
+
PubPackage.new(
|
32
|
+
package_name,
|
33
|
+
package_version,
|
34
|
+
license_text(project_repo),
|
35
|
+
logger: logger,
|
36
|
+
install_path: project_repo,
|
37
|
+
homepage: homepage
|
38
|
+
)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def possible_package_paths
|
43
|
+
[project_path.join('pubspec.lock')]
|
44
|
+
end
|
45
|
+
|
46
|
+
def package_management_command
|
47
|
+
'flutter'
|
48
|
+
end
|
49
|
+
|
50
|
+
def prepare_command
|
51
|
+
'flutter pub get'
|
52
|
+
end
|
53
|
+
|
54
|
+
def prepare
|
55
|
+
prep_cmd = "#{prepare_command} #{production_flag}"
|
56
|
+
_stdout, stderr, status = Dir.chdir(project_path) { Cmd.run(prep_cmd) }
|
57
|
+
|
58
|
+
return if status.success?
|
59
|
+
|
60
|
+
log_errors stderr
|
61
|
+
raise "Prepare command '#{prep_cmd}' failed" unless @prepare_no_fail
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def license_text(subpath)
|
67
|
+
license_path = license_pattern(subpath).find { |f| File.exist?(f) }
|
68
|
+
license_path.nil? ? nil : IO.read(license_path)
|
69
|
+
end
|
70
|
+
|
71
|
+
def license_pattern(subpath)
|
72
|
+
Dir.glob(subpath.join('LICENSE*'), File::FNM_CASEFOLD)
|
73
|
+
end
|
74
|
+
|
75
|
+
def production_flag
|
76
|
+
return '' if @ignored_groups.nil?
|
77
|
+
|
78
|
+
@ignored_groups.include?('devDependencies') ? '' : 'no-'
|
79
|
+
end
|
80
|
+
|
81
|
+
def read_repository_home(project_repo)
|
82
|
+
package_yaml = project_repo.join('pubspec.yaml')
|
83
|
+
YAML.load(IO.read(package_yaml))['repository'] if Dir.exist?(project_repo) && File.exist?(package_yaml)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -17,11 +17,7 @@ module LicenseFinder
|
|
17
17
|
|
18
18
|
dependencies = SbtDependencyFinder.new(project_path).dependencies
|
19
19
|
packages = dependencies.flat_map do |text|
|
20
|
-
|
21
|
-
headers: true
|
22
|
-
}
|
23
|
-
|
24
|
-
contents = CSV.parse(text, options)
|
20
|
+
contents = CSV.parse(text, headers: true)
|
25
21
|
contents.map do |row|
|
26
22
|
group_id, name, version = row['Dependency'].split('#').map(&:strip)
|
27
23
|
spec = {
|
@@ -9,12 +9,12 @@ module LicenseFinder
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def current_packages
|
12
|
-
cmd = "#{Yarn::SHELL_COMMAND}#{
|
12
|
+
cmd = "#{Yarn::SHELL_COMMAND}#{yarn1_production_flag}"
|
13
13
|
suffix = " --cwd #{project_path}" unless project_path.nil?
|
14
14
|
cmd += suffix unless suffix.nil?
|
15
15
|
|
16
|
-
stdout,
|
17
|
-
|
16
|
+
stdout, stderr, status = Cmd.run(cmd)
|
17
|
+
raise "Command '#{cmd}' failed to execute: #{stderr}" unless status.success?
|
18
18
|
|
19
19
|
packages = []
|
20
20
|
incompatible_packages = []
|
@@ -39,7 +39,7 @@ module LicenseFinder
|
|
39
39
|
end
|
40
40
|
|
41
41
|
def prepare
|
42
|
-
prep_cmd =
|
42
|
+
prep_cmd = prepare_command.to_s
|
43
43
|
_stdout, stderr, status = Dir.chdir(project_path) { Cmd.run(prep_cmd) }
|
44
44
|
return if status.success?
|
45
45
|
|
@@ -56,11 +56,33 @@ module LicenseFinder
|
|
56
56
|
end
|
57
57
|
|
58
58
|
def prepare_command
|
59
|
-
|
59
|
+
if yarn2_project?
|
60
|
+
yarn2_prepare_command
|
61
|
+
else
|
62
|
+
yarn1_prepare_command
|
63
|
+
end
|
60
64
|
end
|
61
65
|
|
62
66
|
private
|
63
67
|
|
68
|
+
def yarn2_prepare_command
|
69
|
+
"#{yarn2_production_flag}yarn install"
|
70
|
+
end
|
71
|
+
|
72
|
+
def yarn1_prepare_command
|
73
|
+
"yarn install --ignore-engines --ignore-scripts#{yarn1_production_flag}"
|
74
|
+
end
|
75
|
+
|
76
|
+
def yarn2_project?
|
77
|
+
Dir.chdir(project_path) do
|
78
|
+
version_string, stderr_str, status = Cmd.run('yarn -v')
|
79
|
+
raise "Command 'yarn -v' failed to execute: #{stderr_str}" unless status.success?
|
80
|
+
|
81
|
+
version = version_string.split('.').map(&:to_i)
|
82
|
+
return version[0] >= 2
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
64
86
|
def packages_from_json(json_data)
|
65
87
|
body = json_data['body']
|
66
88
|
head = json_data['head']
|
@@ -98,10 +120,16 @@ module LicenseFinder
|
|
98
120
|
all_packages - [yarn_internal_package]
|
99
121
|
end
|
100
122
|
|
101
|
-
def
|
123
|
+
def yarn1_production_flag
|
102
124
|
return '' if @ignored_groups.nil?
|
103
125
|
|
104
126
|
@ignored_groups.include?('devDependencies') ? ' --production' : ''
|
105
127
|
end
|
128
|
+
|
129
|
+
def yarn2_production_flag
|
130
|
+
return '' if @ignored_groups.nil?
|
131
|
+
|
132
|
+
@ignored_groups.include?('devDependencies') ? 'yarn plugin import workspace-tools && yarn workspaces focus --all --production && ' : ''
|
133
|
+
end
|
106
134
|
end
|
107
135
|
end
|
@@ -4,7 +4,7 @@ require 'license_finder/package_utils/possible_license_file'
|
|
4
4
|
|
5
5
|
module LicenseFinder
|
6
6
|
class LicenseFiles
|
7
|
-
CANDIDATE_FILE_NAMES = %w[License Licence COPYING README].freeze
|
7
|
+
CANDIDATE_FILE_NAMES = %w[LICENSE License license LICENCE Licence licence COPYING copying README readme].freeze
|
8
8
|
CANDIDATE_PATH_WILDCARD = "*{#{CANDIDATE_FILE_NAMES.join(',')}}*"
|
9
9
|
|
10
10
|
def self.find(install_path, options = {})
|
@@ -35,7 +35,7 @@ module LicenseFinder
|
|
35
35
|
def candidate_files_and_dirs
|
36
36
|
return [] if install_path.nil?
|
37
37
|
|
38
|
-
Pathname.glob(install_path.join('**', CANDIDATE_PATH_WILDCARD)
|
38
|
+
Pathname.glob(install_path.join('**', CANDIDATE_PATH_WILDCARD))
|
39
39
|
end
|
40
40
|
end
|
41
41
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'open-uri'
|
4
|
-
|
5
4
|
module LicenseFinder
|
6
5
|
class BowerPackage < Package
|
7
6
|
def initialize(bower_module, options = {})
|
@@ -35,7 +34,11 @@ module LicenseFinder
|
|
35
34
|
end
|
36
35
|
|
37
36
|
def package_url
|
38
|
-
meta =
|
37
|
+
meta = if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.5.0')
|
38
|
+
JSON.parse(open("https://registry.bower.io/packages/#{CGI.escape(name)}").read)
|
39
|
+
else
|
40
|
+
JSON.parse(URI.open("https://registry.bower.io/packages/#{CGI.escape(name)}").read)
|
41
|
+
end
|
39
42
|
meta['url']
|
40
43
|
end
|
41
44
|
end
|
@@ -37,9 +37,7 @@ module LicenseFinder
|
|
37
37
|
end
|
38
38
|
|
39
39
|
def dep_version
|
40
|
-
@dep_version ||=
|
41
|
-
dep_version_unformatted.sub(version_prefix_re, '')
|
42
|
-
end
|
40
|
+
@dep_version ||= dep_version_unformatted.sub(version_prefix_re, '')
|
43
41
|
end
|
44
42
|
|
45
43
|
def dep_repo
|
@@ -88,7 +86,7 @@ module LicenseFinder
|
|
88
86
|
def dep_version_valid?
|
89
87
|
return false unless set?(dep_version_unformatted)
|
90
88
|
|
91
|
-
if dep_version
|
89
|
+
if dep_version&.match?(version_re)
|
92
90
|
Gem::Version.correct?(dep_version)
|
93
91
|
else
|
94
92
|
dep_version =~ word_dot_re
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module LicenseFinder
|
4
|
+
class PubPackage < Package
|
5
|
+
def initialize(name, version, license_text, options = {})
|
6
|
+
super(name, version, options)
|
7
|
+
@license = License.find_by_text(license_text.to_s)
|
8
|
+
end
|
9
|
+
|
10
|
+
def licenses_from_spec
|
11
|
+
[@license].compact
|
12
|
+
end
|
13
|
+
|
14
|
+
def package_manager
|
15
|
+
'Pub'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module LicenseFinder
|
4
|
+
class Printer
|
5
|
+
attr_reader :padding
|
6
|
+
|
7
|
+
def initialize #:nodoc:
|
8
|
+
@base = nil
|
9
|
+
@mute = false
|
10
|
+
@padding = 0
|
11
|
+
@always_force = false
|
12
|
+
end
|
13
|
+
|
14
|
+
def say(message = '', color = nil, force_new_line = (message.to_s !~ /( |\t)\Z/))
|
15
|
+
buffer = prepare_message(message, *color)
|
16
|
+
buffer << "\n" if force_new_line && !message.to_s.end_with?("\n")
|
17
|
+
|
18
|
+
stdout.print(buffer)
|
19
|
+
stdout.flush
|
20
|
+
end
|
21
|
+
|
22
|
+
def prepare_message(message, *color)
|
23
|
+
spaces = ' ' * padding
|
24
|
+
spaces + set_color(message.to_s, *color)
|
25
|
+
end
|
26
|
+
|
27
|
+
def set_color(string, *) #:nodoc:
|
28
|
+
string
|
29
|
+
end
|
30
|
+
|
31
|
+
def padding=(value)
|
32
|
+
@padding = [0, value].max
|
33
|
+
end
|
34
|
+
|
35
|
+
def stdout
|
36
|
+
$stdout
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -9,11 +9,12 @@ module LicenseFinder
|
|
9
9
|
def initialize(dependencies, options)
|
10
10
|
@dependencies = dependencies
|
11
11
|
@project_name = options[:project_name]
|
12
|
+
@use_spdx_id = options[:use_spdx_id]
|
12
13
|
end
|
13
14
|
|
14
15
|
private
|
15
16
|
|
16
|
-
attr_reader :dependencies, :project_name
|
17
|
+
attr_reader :dependencies, :project_name, :use_spdx_id
|
17
18
|
|
18
19
|
def sorted_dependencies
|
19
20
|
dependencies.sort
|
@@ -5,7 +5,11 @@ module LicenseFinder
|
|
5
5
|
TEMPLATE_PATH = ROOT_PATH.join('reports', 'templates')
|
6
6
|
|
7
7
|
def to_s(filename = TEMPLATE_PATH.join("#{template_name}.erb"))
|
8
|
-
|
8
|
+
if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.6.0')
|
9
|
+
template = ERB.new(filename.read, nil, '-')
|
10
|
+
else
|
11
|
+
template = ERB.new(filename.read, trim_mode: '-')
|
12
|
+
end
|
9
13
|
template.result(binding)
|
10
14
|
end
|
11
15
|
|
@@ -22,7 +26,7 @@ module LicenseFinder
|
|
22
26
|
end
|
23
27
|
|
24
28
|
def link_to_license(license)
|
25
|
-
link_to_maybe license.name, license.url
|
29
|
+
link_to_maybe (@use_spdx_id ? license.standard_id : license.name), license.url
|
26
30
|
end
|
27
31
|
|
28
32
|
def link_to_dependency(dependency)
|
@@ -42,7 +46,7 @@ module LicenseFinder
|
|
42
46
|
end
|
43
47
|
|
44
48
|
def license_names(dependency)
|
45
|
-
dependency.licenses.map(
|
49
|
+
dependency.licenses.map(&@use_spdx_id? :standard_id : :name).sort.join ', '
|
46
50
|
end
|
47
51
|
|
48
52
|
def license_links(dependency)
|
@@ -6,7 +6,11 @@ module LicenseFinder
|
|
6
6
|
TEMPLATE_PATH = ROOT_PATH.join('templates')
|
7
7
|
|
8
8
|
def to_s(filename = TEMPLATE_PATH.join("#{template_name}.erb"))
|
9
|
-
|
9
|
+
if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.6.0')
|
10
|
+
template = ERB.new(filename.read, nil, '-')
|
11
|
+
else
|
12
|
+
template = ERB.new(filename.read, trim_mode: '-')
|
13
|
+
end
|
10
14
|
template.result(binding)
|
11
15
|
end
|
12
16
|
|
@@ -6,7 +6,11 @@ module LicenseFinder
|
|
6
6
|
TEMPLATE_PATH = ROOT_PATH.join('templates')
|
7
7
|
|
8
8
|
def to_s(filename = TEMPLATE_PATH.join("#{template_name}.erb"))
|
9
|
-
|
9
|
+
if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.6.0')
|
10
|
+
template = ERB.new(filename.read, nil, '-')
|
11
|
+
else
|
12
|
+
template = ERB.new(filename.read, trim_mode: '-')
|
13
|
+
end
|
10
14
|
template.result(binding)
|
11
15
|
end
|
12
16
|
|
@@ -5,7 +5,7 @@ module LicenseFinder
|
|
5
5
|
PACKAGE_MANAGERS = [
|
6
6
|
GoModules, GoDep, GoWorkspace, Go15VendorExperiment, Glide, Gvt, Govendor, Trash, Dep, Bundler, NPM, Pip,
|
7
7
|
Yarn, Bower, Maven, Gradle, CocoaPods, Rebar, Erlangmk, Nuget, Carthage, Mix, Conan, Sbt, Cargo, Dotnet, Composer, Pipenv,
|
8
|
-
Conda, Spm
|
8
|
+
Conda, Spm, Pub
|
9
9
|
].freeze
|
10
10
|
|
11
11
|
class << self
|
data/license_finder.gemspec
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
version = File.read(File.expand_path('VERSION', __dir__)).strip
|
4
4
|
|
5
5
|
Gem::Specification.new do |s|
|
6
|
-
s.required_ruby_version = '>= 2.
|
6
|
+
s.required_ruby_version = '>= 2.4.0'
|
7
7
|
s.name = 'license_finder'
|
8
8
|
s.version = version
|
9
9
|
|
@@ -45,26 +45,28 @@ Gem::Specification.new do |s|
|
|
45
45
|
|
46
46
|
s.add_dependency 'bundler'
|
47
47
|
s.add_dependency 'rubyzip', '>=1', '<3'
|
48
|
-
s.add_dependency 'thor', '~> 1.
|
48
|
+
s.add_dependency 'thor', '~> 1.2'
|
49
49
|
s.add_dependency 'tomlrb', '>= 1.3', '< 2.1'
|
50
50
|
s.add_dependency 'with_env', '1.1.0'
|
51
|
-
s.add_dependency 'xml-simple', '~> 1.1.
|
51
|
+
s.add_dependency 'xml-simple', '~> 1.1.9'
|
52
52
|
|
53
|
-
s.add_development_dependency 'addressable', '2.
|
54
|
-
s.add_development_dependency 'capybara', '~> 3.
|
55
|
-
s.add_development_dependency 'cocoapods', '>= 1.0.0' if RUBY_PLATFORM
|
56
|
-
s.add_development_dependency '
|
57
|
-
s.add_development_dependency '
|
58
|
-
s.add_development_dependency '
|
59
|
-
s.add_development_dependency '
|
53
|
+
s.add_development_dependency 'addressable', '2.8.0'
|
54
|
+
s.add_development_dependency 'capybara', '~> 3.32.2'
|
55
|
+
s.add_development_dependency 'cocoapods', '>= 1.0.0' if RUBY_PLATFORM.match?(/darwin/)
|
56
|
+
s.add_development_dependency 'e2mmap', '~> 0.1.0'
|
57
|
+
s.add_development_dependency 'fakefs', '~> 1.4.1'
|
58
|
+
s.add_development_dependency 'matrix', '~> 0.1.0'
|
59
|
+
s.add_development_dependency 'mime-types', '3.4.1'
|
60
|
+
s.add_development_dependency 'pry', '~> 0.14.1'
|
61
|
+
s.add_development_dependency 'rake', '~> 13.0.6'
|
60
62
|
s.add_development_dependency 'rspec', '~> 3'
|
61
63
|
s.add_development_dependency 'rspec-its', '~> 1.3.0'
|
62
|
-
s.add_development_dependency 'rubocop', '~>
|
63
|
-
s.add_development_dependency 'rubocop-performance', '~> 1.
|
64
|
-
s.add_development_dependency 'webmock', '~> 3.
|
64
|
+
s.add_development_dependency 'rubocop', '~> 1.12.1'
|
65
|
+
s.add_development_dependency 'rubocop-performance', '~> 1.10.2'
|
66
|
+
s.add_development_dependency 'webmock', '~> 3.14'
|
65
67
|
|
66
68
|
s.add_development_dependency 'nokogiri', '~>1.10'
|
67
|
-
s.add_development_dependency 'rack', '~> 2.2.
|
69
|
+
s.add_development_dependency 'rack', '~> 2.2.3'
|
68
70
|
s.add_development_dependency 'rack-test', '~> 1.1.0', '> 0.7'
|
69
71
|
|
70
72
|
s.files = `git ls-files`.split("\n").reject { |f| f.start_with?('spec', 'features') }
|