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,131 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module LicenseFinder
|
6
|
+
class Conda < PackageManager
|
7
|
+
attr_reader :conda_bash_setup_script
|
8
|
+
|
9
|
+
def initialize(options = {})
|
10
|
+
@conda_bash_setup_script = options[:conda_bash_setup_script] || Pathname("#{ENV['HOME']}/miniconda3/etc/profile.d/conda.sh")
|
11
|
+
super
|
12
|
+
end
|
13
|
+
|
14
|
+
# This command is *not* directly executable. See .conda() below.
|
15
|
+
def prepare_command
|
16
|
+
"conda env create -f #{detected_package_path}"
|
17
|
+
end
|
18
|
+
|
19
|
+
def prepare
|
20
|
+
return if environment_exists?
|
21
|
+
|
22
|
+
prep_cmd = prepare_command
|
23
|
+
_stdout, stderr, status = Dir.chdir(project_path) { conda(prep_cmd) }
|
24
|
+
return if status.success?
|
25
|
+
|
26
|
+
log_errors stderr
|
27
|
+
raise "Prepare command '#{prep_cmd}' failed" unless @prepare_no_fail
|
28
|
+
end
|
29
|
+
|
30
|
+
def current_packages
|
31
|
+
conda_list.map do |entry|
|
32
|
+
case entry['channel']
|
33
|
+
when 'pypi'
|
34
|
+
# PyPI is much faster than `conda search`, use it when we can.
|
35
|
+
PipPackage.new(entry['name'], entry['version'], PyPI.definition(entry['name'], entry['version']))
|
36
|
+
else
|
37
|
+
CondaPackage.new(conda_search_info(entry))
|
38
|
+
end
|
39
|
+
end.compact
|
40
|
+
end
|
41
|
+
|
42
|
+
def possible_package_paths
|
43
|
+
[project_path.join('environment.yaml'), project_path.join('environment.yml')]
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def environment_exists?
|
49
|
+
environments.grep(environment_name).any?
|
50
|
+
end
|
51
|
+
|
52
|
+
def environments
|
53
|
+
command = 'conda env list'
|
54
|
+
stdout, stderr, status = conda command
|
55
|
+
|
56
|
+
environments = []
|
57
|
+
if status.success?
|
58
|
+
environments = stdout.split("\n").grep_v(/^#/).map { |line| line.split.first }
|
59
|
+
else
|
60
|
+
log_errors_with_cmd command, stderr
|
61
|
+
end
|
62
|
+
environments
|
63
|
+
end
|
64
|
+
|
65
|
+
def environment_file
|
66
|
+
detected_package_path
|
67
|
+
end
|
68
|
+
|
69
|
+
def environment_name
|
70
|
+
@environment_name ||= YAML.load_file(environment_file).fetch('name')
|
71
|
+
end
|
72
|
+
|
73
|
+
def conda(command)
|
74
|
+
Open3.capture3('bash', '-c', "source #{conda_bash_setup_script} && #{command}")
|
75
|
+
end
|
76
|
+
|
77
|
+
def activated_conda(command)
|
78
|
+
Open3.capture3('bash', '-c', "source #{conda_bash_setup_script} && conda activate #{environment_name} && #{command}")
|
79
|
+
end
|
80
|
+
|
81
|
+
# Algorithm is based on
|
82
|
+
# https://bioinformatics.stackexchange.com/a/11226
|
83
|
+
# but completely recoded in Ruby. Like the poster, if the package is
|
84
|
+
# actually managed by conda, we assume that all the potential infos (for
|
85
|
+
# various architectures, versions of python, etc) have the same license.
|
86
|
+
def conda_list
|
87
|
+
command = 'conda list'
|
88
|
+
stdout, stderr, status = activated_conda(command)
|
89
|
+
|
90
|
+
if status.success?
|
91
|
+
conda_list = []
|
92
|
+
stdout.each_line do |line|
|
93
|
+
next if line =~ /^\s*#/
|
94
|
+
|
95
|
+
name, version, build, channel = line.split
|
96
|
+
conda_list << {
|
97
|
+
'name' => name,
|
98
|
+
'version' => version,
|
99
|
+
'build' => build,
|
100
|
+
'channel' => channel
|
101
|
+
}
|
102
|
+
end
|
103
|
+
conda_list
|
104
|
+
else
|
105
|
+
log_errors_with_cmd command, stderr
|
106
|
+
[]
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def conda_search_info(list_entry)
|
111
|
+
command = 'conda search --info --json '
|
112
|
+
command += "--channel #{list_entry['channel']} " if list_entry['channel'] && !list_entry['channel'].empty?
|
113
|
+
command += "'#{list_entry['name']} #{list_entry['version']}'"
|
114
|
+
|
115
|
+
# Errors from conda (in --json mode, at least) show up in stdout, not stderr
|
116
|
+
stdout, _stderr, status = activated_conda(command)
|
117
|
+
|
118
|
+
name = list_entry['name']
|
119
|
+
|
120
|
+
if status.success?
|
121
|
+
JSON(stdout).fetch(name).first
|
122
|
+
else
|
123
|
+
log_errors_with_cmd command, stdout
|
124
|
+
list_entry
|
125
|
+
end
|
126
|
+
rescue KeyError
|
127
|
+
logger.info('Conda', "Key error trying to find #{name} in\n#{JSON(stdout)}")
|
128
|
+
list_entry
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'tomlrb'
|
4
|
+
|
5
|
+
module LicenseFinder
|
6
|
+
class Dep < PackageManager
|
7
|
+
def possible_package_paths
|
8
|
+
[project_path.join('Gopkg.lock')]
|
9
|
+
end
|
10
|
+
|
11
|
+
def current_packages
|
12
|
+
toml = Tomlrb.load_file(detected_package_path)
|
13
|
+
projects = toml['projects']
|
14
|
+
|
15
|
+
return [] if projects.nil?
|
16
|
+
|
17
|
+
projects.map do |project|
|
18
|
+
GoPackage.from_dependency({
|
19
|
+
'ImportPath' => project['name'],
|
20
|
+
'InstallPath' => project_path.join('vendor', project['name']),
|
21
|
+
'Rev' => project['revision'],
|
22
|
+
'Homepage' => repo_name(project['name'])
|
23
|
+
}, nil, true)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def repo_name(name)
|
28
|
+
name.split('/')[0..2].join('/')
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.takes_priority_over
|
32
|
+
Go15VendorExperiment
|
33
|
+
end
|
34
|
+
|
35
|
+
def prepare_command
|
36
|
+
'dep ensure -vendor-only'
|
37
|
+
end
|
38
|
+
|
39
|
+
def package_management_command
|
40
|
+
'dep'
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'pathname'
|
4
|
+
require 'json'
|
5
|
+
|
6
|
+
module LicenseFinder
|
7
|
+
class Dotnet < PackageManager
|
8
|
+
class AssetFile
|
9
|
+
def initialize(path)
|
10
|
+
@manifest = JSON.parse(File.read(path))
|
11
|
+
end
|
12
|
+
|
13
|
+
def dependencies
|
14
|
+
libs = @manifest.fetch('libraries').reject do |_, v|
|
15
|
+
v.fetch('type') == 'project'
|
16
|
+
end
|
17
|
+
|
18
|
+
libs.keys.map do |name|
|
19
|
+
parts = name.split('/')
|
20
|
+
PackageMetadata.new(parts[0], parts[1], possible_spec_paths(name))
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def possible_spec_paths(package_key)
|
25
|
+
lib = @manifest.fetch('libraries').fetch(package_key)
|
26
|
+
spec_filename = lib.fetch('files').find { |f| f.end_with?('.nuspec') }
|
27
|
+
return [] if spec_filename.nil?
|
28
|
+
|
29
|
+
@manifest.fetch('packageFolders').keys.map do |root|
|
30
|
+
Pathname(root).join(lib.fetch('path'), spec_filename).to_s
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
class PackageMetadata
|
36
|
+
attr_reader :name, :version, :possible_spec_paths
|
37
|
+
|
38
|
+
def initialize(name, version, possible_spec_paths)
|
39
|
+
@name = name
|
40
|
+
@version = version
|
41
|
+
@possible_spec_paths = possible_spec_paths
|
42
|
+
end
|
43
|
+
|
44
|
+
def read_license_urls
|
45
|
+
possible_spec_paths.flat_map do |path|
|
46
|
+
Nuget.nuspec_license_urls(File.read(path)) if File.exist? path
|
47
|
+
end.compact
|
48
|
+
end
|
49
|
+
|
50
|
+
def ==(other)
|
51
|
+
other.name == name && other.version == version && other.possible_spec_paths == possible_spec_paths
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def possible_package_paths
|
56
|
+
paths = Dir[project_path.join('*.csproj')]
|
57
|
+
paths.map { |p| Pathname(p) }
|
58
|
+
end
|
59
|
+
|
60
|
+
def current_packages
|
61
|
+
package_metadatas = asset_files
|
62
|
+
.flat_map { |path| AssetFile.new(path).dependencies }
|
63
|
+
.uniq { |d| [d.name, d.version] }
|
64
|
+
|
65
|
+
package_metadatas.map do |d|
|
66
|
+
path = Dir.glob("#{Dir.home}/.nuget/packages/#{d.name.downcase}/#{d.version}").first
|
67
|
+
NugetPackage.new(d.name, d.version, spec_licenses: d.read_license_urls, install_path: path)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def asset_files
|
72
|
+
Dir[project_path.join('**/project.assets.json')]
|
73
|
+
end
|
74
|
+
|
75
|
+
def package_management_command
|
76
|
+
'dotnet'
|
77
|
+
end
|
78
|
+
|
79
|
+
def prepare_command
|
80
|
+
"#{package_management_command} restore"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module LicenseFinder
|
4
|
+
class Erlangmk < PackageManager
|
5
|
+
def package_management_command
|
6
|
+
'make'
|
7
|
+
end
|
8
|
+
|
9
|
+
def package_management_command_with_path
|
10
|
+
"#{package_management_command} --directory=#{project_path} --no-print-directory"
|
11
|
+
end
|
12
|
+
|
13
|
+
# The IS_DEP=1 is added because not all erlang.mk-based projects are
|
14
|
+
# updated to a version that is compatible with LicenseFinder
|
15
|
+
def prepare_command
|
16
|
+
"#{package_management_command_with_path} IS_DEP=1 fetch-deps"
|
17
|
+
end
|
18
|
+
|
19
|
+
def possible_package_paths
|
20
|
+
[
|
21
|
+
project_path.join('Erlang.mk'),
|
22
|
+
project_path.join('erlang.mk')
|
23
|
+
]
|
24
|
+
end
|
25
|
+
|
26
|
+
def current_packages
|
27
|
+
deps.map do |dep|
|
28
|
+
ErlangmkPackage.new(dep)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def deps
|
35
|
+
command = "#{package_management_command_with_path} QUERY='name fetch_method repo version absolute_path' query-deps"
|
36
|
+
stdout, stderr, status = Cmd.run(command)
|
37
|
+
if status.success?
|
38
|
+
dep_re = Regexp.new('^\s*DEP')
|
39
|
+
line_re = Regexp.new('^[_a-z0-9]+:')
|
40
|
+
stdout.each_line.map(&:strip).select { |line| !(line.start_with?('make') || line =~ dep_re) && line =~ line_re }
|
41
|
+
elsif stderr.include? "No rule to make target 'query-deps'"
|
42
|
+
# The stderr check happens because not all erlang.mk-based projects are
|
43
|
+
# updated to a version that is compatible with LicenseFinder
|
44
|
+
[]
|
45
|
+
else
|
46
|
+
raise "Command '#{command}' failed to execute: #{stderr}"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module LicenseFinder
|
4
|
+
class Glide < PackageManager
|
5
|
+
def possible_package_paths
|
6
|
+
[project_path.join('glide.lock')]
|
7
|
+
end
|
8
|
+
|
9
|
+
def current_packages
|
10
|
+
detected_path = detected_package_path
|
11
|
+
|
12
|
+
YAML.load_file(detected_path).fetch('imports').map do |package_hash|
|
13
|
+
import_path = package_hash.fetch('name')
|
14
|
+
license_path = project_path.join('vendor', import_path)
|
15
|
+
|
16
|
+
GoPackage.from_dependency({
|
17
|
+
'ImportPath' => import_path,
|
18
|
+
'InstallPath' => license_path,
|
19
|
+
'Rev' => package_hash.fetch('version')
|
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
|
+
'glide'
|
30
|
+
end
|
31
|
+
|
32
|
+
def prepare_command
|
33
|
+
'glide install'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module LicenseFinder
|
6
|
+
class Go15VendorExperiment < PackageManager
|
7
|
+
def initialize(options = {})
|
8
|
+
super
|
9
|
+
@full_version = options[:go_full_version]
|
10
|
+
end
|
11
|
+
|
12
|
+
def active?
|
13
|
+
super && go_files_exist?
|
14
|
+
end
|
15
|
+
|
16
|
+
def go_files_exist?
|
17
|
+
!Dir[project_path.join('**/*.go')].empty? && !Dir[project_path.join('vendor/**/*.go')].empty?
|
18
|
+
end
|
19
|
+
|
20
|
+
def possible_package_paths
|
21
|
+
[project_path.join('vendor')]
|
22
|
+
end
|
23
|
+
|
24
|
+
def project_sha(path)
|
25
|
+
Dir.chdir(path) do
|
26
|
+
stdout, _stderr, status = Cmd.run('git rev-list --max-count 1 HEAD')
|
27
|
+
raise 'git rev-list failed' unless status.success?
|
28
|
+
|
29
|
+
stdout.strip
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def current_packages
|
34
|
+
deps = go_list
|
35
|
+
vendored_deps = deps.select { |dep| detected_package_path.join(dep).exist? }
|
36
|
+
vendored_deps.map do |dep|
|
37
|
+
GoPackage.from_dependency({
|
38
|
+
'ImportPath' => dep,
|
39
|
+
'InstallPath' => detected_package_path.join(dep),
|
40
|
+
'Rev' => 'vendored-' + project_sha(detected_package_path.join(dep)),
|
41
|
+
'Homepage' => repo_name(dep)
|
42
|
+
}, nil, true)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def repo_name(name)
|
47
|
+
name.split('/')[0..2].join('/')
|
48
|
+
end
|
49
|
+
|
50
|
+
def package_management_command
|
51
|
+
'go'
|
52
|
+
end
|
53
|
+
|
54
|
+
def go_list
|
55
|
+
Dir.chdir(project_path) do
|
56
|
+
# avoid checking canonical import path. some projects uses
|
57
|
+
# non-canonical import path and rely on the fact that the deps are
|
58
|
+
# checked in. Canonical paths are only checked by `go get'. We
|
59
|
+
# discovered that `go list' will print a warning and unfortunately exit
|
60
|
+
# with status code 1. Setting GOPATH to nil removes those warnings.
|
61
|
+
orig_gopath = ENV['GOPATH']
|
62
|
+
ENV['GOPATH'] = nil
|
63
|
+
val, _stderr, status = Cmd.run('go list -f "{{join .Deps \"\n\"}}" ./...')
|
64
|
+
ENV['GOPATH'] = orig_gopath
|
65
|
+
return [] unless status.success?
|
66
|
+
|
67
|
+
# Select non-standard packages. `go list std` returns the list of standard
|
68
|
+
# dependencies. We then filter those dependencies out of the full list of
|
69
|
+
# dependencies.
|
70
|
+
deps = val.split("\n")
|
71
|
+
Cmd.run('go list std').first.split("\n").each do |std|
|
72
|
+
deps.delete_if do |dep|
|
73
|
+
dep =~ %r{(\/|^)#{std}(\/|$)}
|
74
|
+
end
|
75
|
+
end
|
76
|
+
deps.map do |d|
|
77
|
+
dep_parts = d.split('/')
|
78
|
+
if dep_parts.length > 2
|
79
|
+
dep_parts[0..2].join('/')
|
80
|
+
else
|
81
|
+
d
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module LicenseFinder
|
6
|
+
class GoDep < PackageManager
|
7
|
+
OLD_GODEP_VENDOR_PATH = 'Godeps/_workspace/src'
|
8
|
+
GODEP_VENDOR_PATH = 'vendor'
|
9
|
+
|
10
|
+
def initialize(options = {})
|
11
|
+
super
|
12
|
+
@full_version = options[:go_full_version]
|
13
|
+
end
|
14
|
+
|
15
|
+
def current_packages
|
16
|
+
packages_from_json(detected_package_path.read)
|
17
|
+
# godep includes subpackages as a seperate dependency, we can de-dup that
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.takes_priority_over
|
21
|
+
Go15VendorExperiment
|
22
|
+
end
|
23
|
+
|
24
|
+
def possible_package_paths
|
25
|
+
[project_path.join('Godeps/Godeps.json')]
|
26
|
+
end
|
27
|
+
|
28
|
+
def package_management_command
|
29
|
+
'godep'
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def install_prefix
|
35
|
+
@install_prefix ||= if project_path.join(OLD_GODEP_VENDOR_PATH).directory?
|
36
|
+
project_path.join(OLD_GODEP_VENDOR_PATH)
|
37
|
+
elsif project_path.join(GODEP_VENDOR_PATH).directory?
|
38
|
+
project_path.join(GODEP_VENDOR_PATH)
|
39
|
+
else
|
40
|
+
download_dependencies
|
41
|
+
Pathname(ENV['GOPATH'] ? ENV['GOPATH'] + '/src' : ENV['HOME'] + '/go/src')
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def download_dependencies
|
46
|
+
command = "#{package_management_command} restore"
|
47
|
+
_, stderr, status = Dir.chdir(project_path) { Cmd.run(command) }
|
48
|
+
raise "Command '#{command}' failed to execute: #{stderr}" if !status.success? && status.exitstatus != 1
|
49
|
+
end
|
50
|
+
|
51
|
+
def packages_from_json(json_string)
|
52
|
+
all_packages = JSON.parse(json_string)['Deps']
|
53
|
+
|
54
|
+
return [] unless all_packages
|
55
|
+
|
56
|
+
packages_grouped_by_revision = all_packages.group_by { |package| package['Rev'] }
|
57
|
+
result = []
|
58
|
+
|
59
|
+
packages_grouped_by_revision.each do |_sha, packages_in_group|
|
60
|
+
all_paths_in_group = packages_in_group.map { |p| p['ImportPath'] }
|
61
|
+
common_paths = CommonPathHelper.longest_common_paths(all_paths_in_group)
|
62
|
+
package_info = packages_in_group.first
|
63
|
+
|
64
|
+
common_paths.each do |common_path|
|
65
|
+
dependency_info_hash = {
|
66
|
+
'Homepage' => common_path,
|
67
|
+
'ImportPath' => common_path,
|
68
|
+
'InstallPath' => package_info['InstallPath'],
|
69
|
+
'Rev' => package_info['Rev']
|
70
|
+
}
|
71
|
+
|
72
|
+
result << GoPackage.from_dependency(dependency_info_hash,
|
73
|
+
install_prefix,
|
74
|
+
@full_version)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
result
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'license_finder/packages/go_package'
|
4
|
+
|
5
|
+
module LicenseFinder
|
6
|
+
class GoModules < PackageManager
|
7
|
+
PACKAGES_FILE = 'go.mod'
|
8
|
+
|
9
|
+
class << self
|
10
|
+
def takes_priority_over
|
11
|
+
Go15VendorExperiment
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def active?
|
16
|
+
mod_files?
|
17
|
+
end
|
18
|
+
|
19
|
+
def current_packages
|
20
|
+
packages = packages_info.map do |package|
|
21
|
+
name, version, install_path = package.split(',')
|
22
|
+
read_package(install_path, name, version) if install_path.to_s != ''
|
23
|
+
end.compact
|
24
|
+
packages.reject do |package|
|
25
|
+
Pathname(package.install_path).cleanpath == Pathname(project_path).cleanpath
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def packages_info
|
32
|
+
Dir.chdir(project_path) do
|
33
|
+
# Explanations:
|
34
|
+
# * Only list dependencies (packages not listed in the project directory)
|
35
|
+
# (.DepOnly)
|
36
|
+
# * Ignore packages that have nil modules
|
37
|
+
# (.Module)
|
38
|
+
# * Ignore standard library packages
|
39
|
+
# (not .Standard)
|
40
|
+
# * Replacement modules are respected
|
41
|
+
# (or .Module.Replace .Module)
|
42
|
+
# * Module cache directory or (vendored) package directory
|
43
|
+
# (or $mod.Dir .Dir)
|
44
|
+
format_str = \
|
45
|
+
'{{ if and (.DepOnly) (.Module) (not .Standard) }}'\
|
46
|
+
'{{ $mod := (or .Module.Replace .Module) }}'\
|
47
|
+
'{{ $mod.Path }},{{ $mod.Version }},{{ or $mod.Dir .Dir }}'\
|
48
|
+
'{{ end }}'
|
49
|
+
|
50
|
+
# The module list flag (`-m`) is intentionally not used here. If the module
|
51
|
+
# dependency tree were followed, transitive dependencies that are never imported
|
52
|
+
# may be included.
|
53
|
+
#
|
54
|
+
# Instead, the owning module is listed for each imported package. This better
|
55
|
+
# matches the implementation of other Go package managers.
|
56
|
+
#
|
57
|
+
# TODO: Figure out a way to make the vendor directory work (i.e. remove the
|
58
|
+
# -mod=readonly flag). Each of the imported packages gets listed separatly,
|
59
|
+
# confusing the issue as to which package is the root of the module.
|
60
|
+
go_list_cmd = "GO111MODULE=on go list -mod=readonly -deps -f '#{format_str}' ./..."
|
61
|
+
info_output, stderr, status = Cmd.run(go_list_cmd)
|
62
|
+
log_errors_with_cmd(go_list_cmd, "Getting the dependencies from go list failed \n\t#{stderr}") unless status.success?
|
63
|
+
raise "Command '#{go_list_cmd}' failed to execute" unless status.success?
|
64
|
+
|
65
|
+
# Since many packages may belong to a single module, #uniq is used to deduplicate
|
66
|
+
info_output.split("\n").uniq
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def mod_files?
|
71
|
+
mod_file_paths.any?
|
72
|
+
end
|
73
|
+
|
74
|
+
def mod_file_paths
|
75
|
+
Dir[project_path.join(PACKAGES_FILE)]
|
76
|
+
end
|
77
|
+
|
78
|
+
def read_package(install_path, name, version)
|
79
|
+
info = {
|
80
|
+
'ImportPath' => name,
|
81
|
+
'InstallPath' => install_path,
|
82
|
+
'Rev' => version,
|
83
|
+
'Homepage' => repo_name(name)
|
84
|
+
}
|
85
|
+
|
86
|
+
GoPackage.from_dependency(info, nil, true)
|
87
|
+
end
|
88
|
+
|
89
|
+
def repo_name(name)
|
90
|
+
name.split('/')[0..2].join('/')
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|