gitlab-license_finder 6.14.2.1
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 +7 -0
- data/.force-build +0 -0
- data/.gitignore +13 -0
- data/.rspec +1 -0
- data/.rubocop.yml +70 -0
- data/CHANGELOG.md +981 -0
- data/CONTRIBUTING.md +121 -0
- data/Dockerfile +249 -0
- data/Gemfile +2 -0
- data/LICENSE +22 -0
- data/README.md +555 -0
- data/Rakefile +77 -0
- data/TODO.md +12 -0
- data/VERSION +1 -0
- data/appveyor.yml +21 -0
- data/bin/license_finder +6 -0
- data/bin/license_finder_pip.py +43 -0
- data/ci/pipelines/pull-request.yml.erb +141 -0
- data/ci/pipelines/release.yml.erb +200 -0
- data/ci/scripts/containerize-tests.sh +14 -0
- data/ci/scripts/pushscript.sh +32 -0
- data/ci/scripts/run-rubocop.sh +15 -0
- data/ci/scripts/run-tests.sh +24 -0
- data/ci/scripts/test.ps1 +81 -0
- data/ci/scripts/updateChangelog.sh +84 -0
- data/ci/tasks/build-and-push-gem.yml +10 -0
- data/ci/tasks/build-windows.yml +6 -0
- data/ci/tasks/build.yml +16 -0
- data/ci/tasks/rubocop.yml +15 -0
- data/ci/tasks/run-tests.yml +10 -0
- data/ci/tasks/update-changelog.yml +18 -0
- data/dlf +12 -0
- data/examples/Gemfile +4 -0
- data/examples/custom_erb_template.rb +24 -0
- data/examples/extract_license_data.rb +63 -0
- data/examples/sample_template.erb +7 -0
- data/lib/license_finder/cli/approvals.rb +28 -0
- data/lib/license_finder/cli/base.rb +107 -0
- data/lib/license_finder/cli/dependencies.rb +44 -0
- data/lib/license_finder/cli/ignored_dependencies.rb +32 -0
- data/lib/license_finder/cli/ignored_groups.rb +32 -0
- data/lib/license_finder/cli/inherited_decisions.rb +50 -0
- data/lib/license_finder/cli/licenses.rb +26 -0
- data/lib/license_finder/cli/main.rb +221 -0
- data/lib/license_finder/cli/makes_decisions.rb +38 -0
- data/lib/license_finder/cli/patched_thor.rb +33 -0
- data/lib/license_finder/cli/permitted_licenses.rb +32 -0
- data/lib/license_finder/cli/project_name.rb +32 -0
- data/lib/license_finder/cli/restricted_licenses.rb +32 -0
- data/lib/license_finder/cli.rb +20 -0
- data/lib/license_finder/configuration.rb +186 -0
- data/lib/license_finder/core.rb +118 -0
- data/lib/license_finder/decision_applier.rb +70 -0
- data/lib/license_finder/decisions.rb +312 -0
- data/lib/license_finder/decisions_factory.rb +13 -0
- data/lib/license_finder/diff.rb +51 -0
- data/lib/license_finder/license/any_matcher.rb +15 -0
- data/lib/license_finder/license/definitions.rb +366 -0
- data/lib/license_finder/license/header_matcher.rb +17 -0
- data/lib/license_finder/license/matcher.rb +24 -0
- data/lib/license_finder/license/none_matcher.rb +11 -0
- data/lib/license_finder/license/template.rb +19 -0
- data/lib/license_finder/license/templates/0BSD.txt +10 -0
- data/lib/license_finder/license/templates/Apache1_1.txt +16 -0
- data/lib/license_finder/license/templates/Apache2.txt +172 -0
- data/lib/license_finder/license/templates/BSD.txt +24 -0
- data/lib/license_finder/license/templates/CC01.txt +30 -0
- data/lib/license_finder/license/templates/CDDL1.txt +131 -0
- data/lib/license_finder/license/templates/EPL1.txt +86 -0
- data/lib/license_finder/license/templates/GPLv2.txt +339 -0
- data/lib/license_finder/license/templates/GPLv3.txt +674 -0
- data/lib/license_finder/license/templates/ISC.txt +2 -0
- data/lib/license_finder/license/templates/LGPL.txt +165 -0
- data/lib/license_finder/license/templates/LGPL2_1.txt +169 -0
- data/lib/license_finder/license/templates/MIT.txt +9 -0
- data/lib/license_finder/license/templates/MPL1_1.txt +469 -0
- data/lib/license_finder/license/templates/MPL2.txt +373 -0
- data/lib/license_finder/license/templates/NewBSD.txt +21 -0
- data/lib/license_finder/license/templates/OFL.txt +91 -0
- data/lib/license_finder/license/templates/Python.txt +47 -0
- data/lib/license_finder/license/templates/Ruby.txt +52 -0
- data/lib/license_finder/license/templates/SimplifiedBSD.txt +19 -0
- data/lib/license_finder/license/templates/WTFPL.txt +14 -0
- data/lib/license_finder/license/templates/Zlib.txt +17 -0
- data/lib/license_finder/license/text.rb +45 -0
- data/lib/license_finder/license.rb +117 -0
- data/lib/license_finder/license_aggregator.rb +59 -0
- data/lib/license_finder/logger.rb +69 -0
- data/lib/license_finder/package.rb +202 -0
- data/lib/license_finder/package_delta.rb +61 -0
- data/lib/license_finder/package_manager.rb +181 -0
- data/lib/license_finder/package_managers/bower.rb +37 -0
- data/lib/license_finder/package_managers/bundler.rb +110 -0
- data/lib/license_finder/package_managers/cargo.rb +38 -0
- data/lib/license_finder/package_managers/carthage.rb +68 -0
- data/lib/license_finder/package_managers/cocoa_pods.rb +61 -0
- data/lib/license_finder/package_managers/composer.rb +63 -0
- data/lib/license_finder/package_managers/conan.rb +28 -0
- data/lib/license_finder/package_managers/conda.rb +131 -0
- data/lib/license_finder/package_managers/dep.rb +43 -0
- data/lib/license_finder/package_managers/dotnet.rb +83 -0
- data/lib/license_finder/package_managers/erlangmk.rb +50 -0
- data/lib/license_finder/package_managers/glide.rb +36 -0
- data/lib/license_finder/package_managers/go_15vendorexperiment.rb +87 -0
- data/lib/license_finder/package_managers/go_dep.rb +80 -0
- data/lib/license_finder/package_managers/go_modules.rb +93 -0
- data/lib/license_finder/package_managers/go_workspace.rb +116 -0
- data/lib/license_finder/package_managers/govendor.rb +73 -0
- data/lib/license_finder/package_managers/gradle.rb +99 -0
- data/lib/license_finder/package_managers/gvt.rb +69 -0
- data/lib/license_finder/package_managers/maven.rb +65 -0
- data/lib/license_finder/package_managers/mix.rb +131 -0
- data/lib/license_finder/package_managers/npm.rb +57 -0
- data/lib/license_finder/package_managers/nuget.rb +154 -0
- data/lib/license_finder/package_managers/pip.rb +70 -0
- data/lib/license_finder/package_managers/pipenv.rb +63 -0
- data/lib/license_finder/package_managers/rebar.rb +65 -0
- data/lib/license_finder/package_managers/sbt.rb +50 -0
- data/lib/license_finder/package_managers/spm.rb +93 -0
- data/lib/license_finder/package_managers/trash.rb +43 -0
- data/lib/license_finder/package_managers/yarn.rb +107 -0
- data/lib/license_finder/package_utils/activation.rb +40 -0
- data/lib/license_finder/package_utils/conan_info_parser.rb +77 -0
- data/lib/license_finder/package_utils/gradle_dependency_finder.rb +15 -0
- data/lib/license_finder/package_utils/license_files.rb +41 -0
- data/lib/license_finder/package_utils/licensing.rb +39 -0
- data/lib/license_finder/package_utils/maven_dependency_finder.rb +15 -0
- data/lib/license_finder/package_utils/notice_files.rb +40 -0
- data/lib/license_finder/package_utils/possible_license_file.rb +27 -0
- data/lib/license_finder/package_utils/pypi.rb +41 -0
- data/lib/license_finder/package_utils/sbt_dependency_finder.rb +15 -0
- data/lib/license_finder/packages/bower_package.rb +42 -0
- data/lib/license_finder/packages/bundler_package.rb +33 -0
- data/lib/license_finder/packages/cargo_package.rb +28 -0
- data/lib/license_finder/packages/carthage_package.rb +18 -0
- data/lib/license_finder/packages/cocoa_pods_package.rb +22 -0
- data/lib/license_finder/packages/composer_package.rb +13 -0
- data/lib/license_finder/packages/conan_package.rb +23 -0
- data/lib/license_finder/packages/conda_package.rb +74 -0
- data/lib/license_finder/packages/erlangmk_package.rb +114 -0
- data/lib/license_finder/packages/go_package.rb +32 -0
- data/lib/license_finder/packages/gradle_package.rb +30 -0
- data/lib/license_finder/packages/manual_package.rb +27 -0
- data/lib/license_finder/packages/maven_package.rb +27 -0
- data/lib/license_finder/packages/merged_package.rb +44 -0
- data/lib/license_finder/packages/mix_package.rb +13 -0
- data/lib/license_finder/packages/npm_package.rb +171 -0
- data/lib/license_finder/packages/nuget_package.rb +13 -0
- data/lib/license_finder/packages/pip_package.rb +50 -0
- data/lib/license_finder/packages/rebar_package.rb +13 -0
- data/lib/license_finder/packages/sbt_package.rb +22 -0
- data/lib/license_finder/packages/spm_package.rb +18 -0
- data/lib/license_finder/packages/yarn_package.rb +13 -0
- data/lib/license_finder/platform.rb +15 -0
- data/lib/license_finder/project_finder.rb +62 -0
- data/lib/license_finder/report.rb +33 -0
- data/lib/license_finder/reports/csv_report.rb +99 -0
- data/lib/license_finder/reports/diff_report.rb +29 -0
- data/lib/license_finder/reports/erb_report.rb +58 -0
- data/lib/license_finder/reports/html_report.rb +13 -0
- data/lib/license_finder/reports/json_report.rb +30 -0
- data/lib/license_finder/reports/junit_report.rb +19 -0
- data/lib/license_finder/reports/markdown_report.rb +9 -0
- data/lib/license_finder/reports/merged_report.rb +16 -0
- data/lib/license_finder/reports/templates/bootstrap.css +9 -0
- data/lib/license_finder/reports/templates/html_report.erb +113 -0
- data/lib/license_finder/reports/templates/junit_report.erb +41 -0
- data/lib/license_finder/reports/templates/markdown_report.erb +49 -0
- data/lib/license_finder/reports/templates/xml_report.erb +19 -0
- data/lib/license_finder/reports/text_report.rb +12 -0
- data/lib/license_finder/reports/xml_report.rb +19 -0
- data/lib/license_finder/scanner.rb +83 -0
- data/lib/license_finder/shared_helpers/cmd.rb +13 -0
- data/lib/license_finder/shared_helpers/common_path.rb +29 -0
- data/lib/license_finder/version.rb +6 -0
- data/lib/license_finder.rb +14 -0
- data/license_finder.gemspec +72 -0
- data/release/instructions.md +8 -0
- data/swift-all-keys.asc +240 -0
- metadata +544 -0
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'json'
|
|
4
|
+
|
|
5
|
+
module LicenseFinder
|
|
6
|
+
class GoWorkspacePackageManagerError < ::StandardError
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
class GoWorkspace < PackageManager
|
|
10
|
+
Submodule = Struct.new :install_path, :revision
|
|
11
|
+
ENVRC_REGEXP = /GOPATH|GO15VENDOREXPERIMENT/.freeze
|
|
12
|
+
|
|
13
|
+
def initialize(options = {})
|
|
14
|
+
super
|
|
15
|
+
@full_version = options[:go_full_version]
|
|
16
|
+
@strict_matching = options[:strict_matching]
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def package_management_command
|
|
20
|
+
'go'
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def current_packages
|
|
24
|
+
go_list_packages = go_list
|
|
25
|
+
git_modules.map do |submodule|
|
|
26
|
+
# We are filtering the non-standard packages because the word "net"
|
|
27
|
+
# seems to be common that can give false positive when filtering the git submodules
|
|
28
|
+
import_path = go_list_packages.find do |gp|
|
|
29
|
+
submodule.install_path =~ /#{repo_name(gp)}$/
|
|
30
|
+
end
|
|
31
|
+
next unless import_path
|
|
32
|
+
|
|
33
|
+
dependency_info = {
|
|
34
|
+
'ImportPath' => repo_name(import_path),
|
|
35
|
+
'Homepage' => repo_name(import_path),
|
|
36
|
+
'InstallPath' => submodule.install_path,
|
|
37
|
+
'Rev' => submodule.revision
|
|
38
|
+
}
|
|
39
|
+
GoPackage.from_dependency(dependency_info, nil, @full_version)
|
|
40
|
+
end.compact
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def self.takes_priority_over
|
|
44
|
+
Go15VendorExperiment
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def possible_package_paths
|
|
48
|
+
[envrc_path.dirname]
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def active?
|
|
52
|
+
return false if @strict_matching
|
|
53
|
+
|
|
54
|
+
godep = LicenseFinder::GoDep.new(project_path: Pathname(project_path))
|
|
55
|
+
dep = LicenseFinder::Dep.new(project_path: Pathname(project_path))
|
|
56
|
+
# go workspace is only active if GoDep wasn't. There are some projects
|
|
57
|
+
# that will use the .envrc and have a Godep folder as well.
|
|
58
|
+
!!(!godep.active? && !dep.active? && envrc_path && ENVRC_REGEXP.match(IO.read(envrc_path)))
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
private
|
|
62
|
+
|
|
63
|
+
def repo_name(import_path)
|
|
64
|
+
import_path.split('/')[0..2].join('/')
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def project_src
|
|
68
|
+
project_path.join('src')
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def envrc_path
|
|
72
|
+
p = Pathname.new project_path
|
|
73
|
+
4.times.reduce([p]) { |memo, _| memo << memo.last.parent }.map { |path| path.join('.envrc') }.find(&:exist?)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def go_list
|
|
77
|
+
Dir.chdir(project_path) do
|
|
78
|
+
# avoid checking canonical import path. some projects uses
|
|
79
|
+
# non-canonical import path and rely on the fact that the deps are
|
|
80
|
+
# checked in. Canonical paths are only checked by `go get'. We
|
|
81
|
+
# discovered that `go list' will print a warning and unfortunately exit
|
|
82
|
+
# with status code 1. Setting GOPATH to nil removes those warnings.
|
|
83
|
+
orig_gopath = ENV['GOPATH']
|
|
84
|
+
ENV['GOPATH'] = nil
|
|
85
|
+
val, stderr, status = Cmd.run('go list -f "{{join .Deps \"\n\"}}" ./...')
|
|
86
|
+
ENV['GOPATH'] = project_path.to_s
|
|
87
|
+
val, stderr, status = Cmd.run('go list -f "{{join .Deps \"\n\"}}" ./...') unless status.success?
|
|
88
|
+
ENV['GOPATH'] = orig_gopath
|
|
89
|
+
raise GoWorkspacePackageManagerError, "go list failed:\n#{stderr}" unless status.success?
|
|
90
|
+
|
|
91
|
+
# Select non-standard packages. `go list std` returns the list of standard
|
|
92
|
+
# dependencies. We then filter those dependencies out of the full list of
|
|
93
|
+
# dependencies.
|
|
94
|
+
deps = val.split("\n")
|
|
95
|
+
Cmd.run('go list std').first.split("\n").each do |std|
|
|
96
|
+
deps.delete_if do |dep|
|
|
97
|
+
dep =~ %r{(\/|^)#{std}(\/|$)}
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
deps
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def git_modules
|
|
105
|
+
Dir.chdir(detected_package_path) do |_d|
|
|
106
|
+
result, _stderr, status = Cmd.run('git submodule status')
|
|
107
|
+
raise 'git submodule status failed' unless status.success?
|
|
108
|
+
|
|
109
|
+
result.lines.map do |l|
|
|
110
|
+
columns = l.split.map(&:strip)
|
|
111
|
+
Submodule.new File.join(detected_package_path, columns[1]), columns[0]
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'license_finder/shared_helpers/common_path'
|
|
4
|
+
require 'json'
|
|
5
|
+
|
|
6
|
+
module LicenseFinder
|
|
7
|
+
class Govendor < PackageManager
|
|
8
|
+
def possible_package_paths
|
|
9
|
+
[project_path.join('vendor', 'vendor.json')]
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def current_packages
|
|
13
|
+
file = File.read(detected_package_path)
|
|
14
|
+
packages = packages_from_json(file)
|
|
15
|
+
packages.map do |package|
|
|
16
|
+
GoPackage.from_dependency({
|
|
17
|
+
'ImportPath' => package[:path],
|
|
18
|
+
'InstallPath' => project_path.join('vendor', package[:path]),
|
|
19
|
+
'Rev' => package[:sha]
|
|
20
|
+
}, nil, true)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def self.takes_priority_over
|
|
25
|
+
Go15VendorExperiment
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def package_management_command
|
|
29
|
+
'govendor'
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def prepare_command
|
|
33
|
+
'govendor sync'
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
private
|
|
37
|
+
|
|
38
|
+
def packages_from_json(json_string)
|
|
39
|
+
data = JSON.parse(json_string)
|
|
40
|
+
packages = data['package']
|
|
41
|
+
|
|
42
|
+
packages_by_sha = {}
|
|
43
|
+
packages_with_no_sha = []
|
|
44
|
+
|
|
45
|
+
packages.each do |package|
|
|
46
|
+
package_path = package['origin'] || package['path']
|
|
47
|
+
package_revision = package['revision']
|
|
48
|
+
|
|
49
|
+
if !package_is_versioned?(package)
|
|
50
|
+
packages_with_no_sha << { sha: '', path: package_path }
|
|
51
|
+
elsif packages_by_sha[package_revision].nil?
|
|
52
|
+
packages_by_sha[package_revision] = [package_path]
|
|
53
|
+
else
|
|
54
|
+
packages_by_sha[package_revision] << package_path
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
result = packages_with_no_sha
|
|
59
|
+
packages_by_sha.each do |sha, paths|
|
|
60
|
+
common_paths = CommonPathHelper.longest_common_paths(paths)
|
|
61
|
+
common_paths.each { |cp| result << { sha: sha, path: cp } }
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
result
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def package_is_versioned?(package)
|
|
68
|
+
package_revision = package['revision']
|
|
69
|
+
|
|
70
|
+
!package_revision.nil? && !package_revision.empty?
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'xmlsimple'
|
|
4
|
+
require 'with_env'
|
|
5
|
+
require 'license_finder/package_utils/gradle_dependency_finder'
|
|
6
|
+
|
|
7
|
+
module LicenseFinder
|
|
8
|
+
class Gradle < PackageManager
|
|
9
|
+
def initialize(options = {})
|
|
10
|
+
super
|
|
11
|
+
@command = options[:gradle_command] || package_management_command
|
|
12
|
+
@include_groups = options[:gradle_include_groups]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def current_packages
|
|
16
|
+
WithEnv.with_env('TERM' => 'dumb') do
|
|
17
|
+
command = "#{@command} downloadLicenses"
|
|
18
|
+
_stdout, stderr, status = Dir.chdir(project_path) { Cmd.run(command) }
|
|
19
|
+
raise "Command '#{command}' failed to execute: #{stderr}" unless status.success?
|
|
20
|
+
|
|
21
|
+
dependencies = GradleDependencyFinder.new(project_path).dependencies
|
|
22
|
+
packages = dependencies.flat_map do |xml_file|
|
|
23
|
+
options = { 'GroupTags' => { 'dependencies' => 'dependency' } }
|
|
24
|
+
contents = XmlSimple.xml_in(xml_file, options).fetch('dependency', [])
|
|
25
|
+
contents.map do |dep|
|
|
26
|
+
GradlePackage.new(dep, logger: logger, include_groups: @include_groups)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
packages.uniq
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def package_management_command
|
|
34
|
+
if Platform.windows?
|
|
35
|
+
wrapper = 'gradlew.bat'
|
|
36
|
+
gradle = 'gradle.bat'
|
|
37
|
+
else
|
|
38
|
+
wrapper = './gradlew'
|
|
39
|
+
gradle = 'gradle'
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
File.exist?(File.join(project_path, wrapper)) ? wrapper : gradle
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def project_root?
|
|
46
|
+
active? && root_module?
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
private
|
|
50
|
+
|
|
51
|
+
def root_module?
|
|
52
|
+
return false if project_path.to_s.include?('buildSrc')
|
|
53
|
+
|
|
54
|
+
command = "#{package_management_command} -Dorg.gradle.jvmargs=-Xmx6144m properties | grep 'parent: '"
|
|
55
|
+
stdout, stderr, status = Dir.chdir(project_path) { Cmd.run(command) }
|
|
56
|
+
|
|
57
|
+
if stderr&.include?('not part of the build defined by settings file')
|
|
58
|
+
Dir.chdir(project_path) do
|
|
59
|
+
Cmd.run('touch settings.gradle')
|
|
60
|
+
stdout, stderr, status = Cmd.run(command)
|
|
61
|
+
Cmd.run('rm settings.gradle')
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
raise "Command '#{command}' failed to execute in #{project_path}: #{stderr}" unless status.success?
|
|
66
|
+
|
|
67
|
+
root_project_name = stdout.gsub(/\s|parent:|\n/, '')
|
|
68
|
+
root_project_name == 'null'
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def detected_package_path
|
|
72
|
+
alternate_build_file = build_file_from_settings(project_path)
|
|
73
|
+
return alternate_build_file if alternate_build_file
|
|
74
|
+
|
|
75
|
+
build_gradle_file
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def build_gradle_file
|
|
79
|
+
kotlin_gradle_path = project_path.join('build.gradle.kts')
|
|
80
|
+
return kotlin_gradle_path if File.exist? kotlin_gradle_path
|
|
81
|
+
|
|
82
|
+
project_path.join('build.gradle')
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def build_file_from_settings(project_path)
|
|
86
|
+
settings_gradle_path = project_path.join 'settings.gradle'
|
|
87
|
+
|
|
88
|
+
return nil unless File.exist? settings_gradle_path
|
|
89
|
+
|
|
90
|
+
settings_gradle = File.read settings_gradle_path
|
|
91
|
+
|
|
92
|
+
match = /rootProject.buildFileName = ['"](?<build_file>.*)['"]/.match settings_gradle
|
|
93
|
+
|
|
94
|
+
return nil unless match
|
|
95
|
+
|
|
96
|
+
project_path.join match[:build_file]
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'license_finder/shared_helpers/common_path'
|
|
4
|
+
|
|
5
|
+
module LicenseFinder
|
|
6
|
+
class Gvt < PackageManager
|
|
7
|
+
def possible_package_paths
|
|
8
|
+
potential_path = project_path.join('vendor', 'manifest')
|
|
9
|
+
[Pathname(potential_path)]
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def package_management_command
|
|
13
|
+
'gvt'
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def prepare_command
|
|
17
|
+
'gvt restore'
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def current_packages
|
|
21
|
+
shell_command = "cd #{project_path} && gvt list -f \"{{.Importpath}} {{.Revision}} {{.Repository}}\""
|
|
22
|
+
path = project_path.join(project_path, 'vendor')
|
|
23
|
+
|
|
24
|
+
stdout, _stderr, status = Cmd.run(shell_command)
|
|
25
|
+
return [] unless status.success?
|
|
26
|
+
|
|
27
|
+
packages_from_output(stdout, path)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def self.takes_priority_over
|
|
31
|
+
Go15VendorExperiment
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
def packages_from_output(output, path)
|
|
37
|
+
package_lines = output.split("\n")
|
|
38
|
+
packages_by_sha = {}
|
|
39
|
+
package_lines.each do |p|
|
|
40
|
+
package_path, sha, repo = p.split
|
|
41
|
+
if packages_by_sha[sha].nil?
|
|
42
|
+
packages_by_sha[sha] = {}
|
|
43
|
+
packages_by_sha[sha]['paths'] = [package_path]
|
|
44
|
+
packages_by_sha[sha]['repo'] = repo
|
|
45
|
+
else
|
|
46
|
+
packages_by_sha[sha]['paths'] << package_path
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
result = []
|
|
51
|
+
packages_by_sha.each do |sha, info|
|
|
52
|
+
paths = CommonPathHelper.longest_common_paths(info['paths'])
|
|
53
|
+
|
|
54
|
+
paths.each { |p| result << [sha, p, info['repo']] }
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
result.map do |package_info|
|
|
58
|
+
sha, import_path, repo = package_info
|
|
59
|
+
|
|
60
|
+
GoPackage.from_dependency({
|
|
61
|
+
'ImportPath' => import_path,
|
|
62
|
+
'InstallPath' => path.join(import_path),
|
|
63
|
+
'Rev' => sha,
|
|
64
|
+
'Homepage' => repo
|
|
65
|
+
}, nil, true)
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'xmlsimple'
|
|
4
|
+
require 'license_finder/package_utils/maven_dependency_finder'
|
|
5
|
+
|
|
6
|
+
module LicenseFinder
|
|
7
|
+
class Maven < PackageManager
|
|
8
|
+
def initialize(options = {})
|
|
9
|
+
super
|
|
10
|
+
@ignored_groups = options[:ignored_groups]
|
|
11
|
+
@include_groups = options[:maven_include_groups]
|
|
12
|
+
@maven_options = options[:maven_options]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def current_packages
|
|
16
|
+
command = "#{package_management_command} org.codehaus.mojo:license-maven-plugin:download-licenses"
|
|
17
|
+
command += " -Dlicense.excludedScopes=#{@ignored_groups.to_a.join(',')}" if @ignored_groups && !@ignored_groups.empty?
|
|
18
|
+
command += " #{@maven_options}" unless @maven_options.nil?
|
|
19
|
+
_stdout, stderr, status = Dir.chdir(project_path) { Cmd.run(command) }
|
|
20
|
+
raise "Command '#{command}' failed to execute: #{stderr}" unless status.success?
|
|
21
|
+
|
|
22
|
+
dependencies = MavenDependencyFinder.new(project_path).dependencies
|
|
23
|
+
packages = dependencies.flat_map do |xml|
|
|
24
|
+
options = {
|
|
25
|
+
'GroupTags' => { 'licenses' => 'license', 'dependencies' => 'dependency' },
|
|
26
|
+
'ForceArray' => %w[license dependency]
|
|
27
|
+
}
|
|
28
|
+
contents = XmlSimple.xml_in(xml, options)['dependencies']
|
|
29
|
+
contents.map do |dep|
|
|
30
|
+
MavenPackage.new(dep, logger: logger, include_groups: @include_groups)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
packages.uniq
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def package_management_command
|
|
37
|
+
wrapper = if Platform.windows?
|
|
38
|
+
'mvnw.cmd'
|
|
39
|
+
else
|
|
40
|
+
'./mvnw'
|
|
41
|
+
end
|
|
42
|
+
maven = 'mvn'
|
|
43
|
+
|
|
44
|
+
File.exist?(File.join(project_path, wrapper)) ? wrapper : maven
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def possible_package_paths
|
|
48
|
+
[project_path.join('pom.xml')]
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def project_root?
|
|
52
|
+
active? && root_module?
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
private
|
|
56
|
+
|
|
57
|
+
def root_module?
|
|
58
|
+
command = "#{package_management_command} help:evaluate -Dexpression=project.parent -q -DforceStdout"
|
|
59
|
+
stdout, _stderr, status = Dir.chdir(project_path) { Cmd.run(command) }
|
|
60
|
+
raise "Command '#{command}' failed to execute in #{project_path}: #{stdout}" unless status.success?
|
|
61
|
+
|
|
62
|
+
stdout.include?('null object or invalid expression')
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module LicenseFinder
|
|
4
|
+
class Mix < PackageManager
|
|
5
|
+
def initialize(options = {})
|
|
6
|
+
super
|
|
7
|
+
@command = options[:mix_command] || package_management_command
|
|
8
|
+
@elixir_command = options[:elixir_command] || 'elixir'
|
|
9
|
+
@deps_path = Pathname(options[:mix_deps_dir] || 'deps')
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def current_packages
|
|
13
|
+
mix_output.map do |name, version|
|
|
14
|
+
MixPackage.new(
|
|
15
|
+
name,
|
|
16
|
+
version,
|
|
17
|
+
install_path: @deps_path.join(name),
|
|
18
|
+
logger: logger,
|
|
19
|
+
spec_licenses: licenses(name)
|
|
20
|
+
)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def licenses(name)
|
|
25
|
+
licenses_by_package = load_all_licenses
|
|
26
|
+
licenses_by_package.fetch(name, ['license is not in deps'])
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def package_management_command
|
|
30
|
+
'mix'
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def self.package_lock_file
|
|
34
|
+
'mix.lock'
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def prepare_command
|
|
38
|
+
'mix deps.get'
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def possible_package_paths
|
|
42
|
+
[project_path.join('mix.exs')]
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def installed?(logger = Core.default_logger)
|
|
46
|
+
if package_management_command.nil?
|
|
47
|
+
logger.debug self.class, 'no command defined'
|
|
48
|
+
true
|
|
49
|
+
elsif command_exists?('elixir') && command_exists?('mix')
|
|
50
|
+
logger.debug self.class, 'is installed', color: :green
|
|
51
|
+
true
|
|
52
|
+
else
|
|
53
|
+
logger.info self.class, '(elixir) is not installed', color: :red
|
|
54
|
+
false
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
private
|
|
59
|
+
|
|
60
|
+
def load_all_licenses
|
|
61
|
+
elixir_code = <<-ELIXIR
|
|
62
|
+
deps_path = "#{@deps_path}"
|
|
63
|
+
|
|
64
|
+
case File.ls(deps_path) do
|
|
65
|
+
{:ok, dirs} ->
|
|
66
|
+
Enum.reduce(dirs, [], fn name, acc ->
|
|
67
|
+
with hexmetadata_file <- Path.join([deps_path, name, "hex_metadata.config"]),
|
|
68
|
+
{:ok, metadata} <- :file.consult(hexmetadata_file),
|
|
69
|
+
{"licenses", licenses} <- List.keyfind(metadata, "licenses", 0) do
|
|
70
|
+
[[name, licenses] | acc]
|
|
71
|
+
else
|
|
72
|
+
_ -> acc
|
|
73
|
+
end
|
|
74
|
+
end)
|
|
75
|
+
{:error, _} ->
|
|
76
|
+
[]
|
|
77
|
+
end
|
|
78
|
+
|> IO.inspect(limit: :infinity)
|
|
79
|
+
ELIXIR
|
|
80
|
+
command = "#{@elixir_command} -e '#{elixir_code}'"
|
|
81
|
+
return {} unless File.directory?(project_path)
|
|
82
|
+
|
|
83
|
+
stdout, stderr, status = Dir.chdir(project_path) { Cmd.run(command) }
|
|
84
|
+
raise "Command '#{command}' failed to execute: #{stderr}" unless status.success?
|
|
85
|
+
|
|
86
|
+
Hash[JSON.parse(stdout)]
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def end_of_package_lines?(line)
|
|
90
|
+
line == 'ok'
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def mix_output
|
|
94
|
+
command = "#{@command} deps"
|
|
95
|
+
stdout, stderr, status = Dir.chdir(project_path) { Cmd.run(command) }
|
|
96
|
+
raise "Command '#{command}' failed to execute: #{stderr}" unless status.success?
|
|
97
|
+
|
|
98
|
+
packages_lines(stdout)
|
|
99
|
+
.reject { |package_lines| package_lines.length == 1 || package_lines.empty? } # in_umbrella: true dependencies
|
|
100
|
+
.map { |package_lines| [package_lines[0].split(' ')[1], resolve_version(package_lines[1])] }
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def packages_lines(stdout)
|
|
104
|
+
packages_lines, last_package_lines =
|
|
105
|
+
stdout
|
|
106
|
+
.each_line
|
|
107
|
+
.map(&:strip)
|
|
108
|
+
.reject { |line| end_of_package_lines?(line) }
|
|
109
|
+
.reduce([[], []]) do |(packages_lines, package_lines), line|
|
|
110
|
+
if start_of_package_lines?(line)
|
|
111
|
+
packages_lines.push(package_lines) unless package_lines.empty?
|
|
112
|
+
|
|
113
|
+
[packages_lines, [line]]
|
|
114
|
+
else
|
|
115
|
+
package_lines.push(line)
|
|
116
|
+
[packages_lines, package_lines]
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
packages_lines.push(last_package_lines)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def resolve_version(line)
|
|
124
|
+
line =~ /locked at ([^\s]+)/ ? Regexp.last_match(1) : line
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def start_of_package_lines?(line)
|
|
128
|
+
line.start_with?('* ')
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'json'
|
|
4
|
+
require 'tempfile'
|
|
5
|
+
|
|
6
|
+
module LicenseFinder
|
|
7
|
+
class NPM < PackageManager
|
|
8
|
+
def initialize(options = {})
|
|
9
|
+
super
|
|
10
|
+
@npm_options = options[:npm_options]
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def current_packages
|
|
14
|
+
NpmPackage.packages_from_json(npm_json, detected_package_path)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def package_management_command
|
|
18
|
+
'npm'
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def prepare_command
|
|
22
|
+
'npm install --no-save --ignore-scripts'
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def possible_package_paths
|
|
26
|
+
[project_path.join('package.json')]
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def prepare
|
|
30
|
+
prep_cmd = "#{prepare_command}#{production_flag}"
|
|
31
|
+
_stdout, stderr, status = Dir.chdir(project_path) { Cmd.run(prep_cmd) }
|
|
32
|
+
|
|
33
|
+
return if status.success?
|
|
34
|
+
|
|
35
|
+
log_errors stderr
|
|
36
|
+
raise "Prepare command '#{prep_cmd}' failed" unless @prepare_no_fail
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
private
|
|
40
|
+
|
|
41
|
+
def npm_json
|
|
42
|
+
command = "#{package_management_command} list --json --long#{production_flag}"
|
|
43
|
+
command += " #{@npm_options}" unless @npm_options.nil?
|
|
44
|
+
stdout, stderr, status = Dir.chdir(project_path) { Cmd.run(command) }
|
|
45
|
+
# we can try and continue if we got an exit status 1 - unmet peer dependency
|
|
46
|
+
raise "Command '#{command}' failed to execute: #{stderr}" if !status.success? && status.exitstatus != 1
|
|
47
|
+
|
|
48
|
+
JSON.parse(stdout)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def production_flag
|
|
52
|
+
return '' if @ignored_groups.nil?
|
|
53
|
+
|
|
54
|
+
@ignored_groups.include?('devDependencies') ? ' --production' : ''
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|