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,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
|