gitlab-license_finder 6.14.2.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|