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,77 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module LicenseFinder
|
4
|
+
class ConanInfoParser
|
5
|
+
def parse(info)
|
6
|
+
@lines = info.lines.map(&:chomp)
|
7
|
+
@state = :project_level # state of the state machine
|
8
|
+
@projects = [] # list of projects
|
9
|
+
@current_project = nil # current project being populated in the SM
|
10
|
+
@current_vals = [] # current val list being populate in the SM
|
11
|
+
@current_key = nil # current key to be associated with the current val
|
12
|
+
while (line = @lines.shift)
|
13
|
+
next if line == ''
|
14
|
+
|
15
|
+
case @state
|
16
|
+
when :project_level
|
17
|
+
@current_project = {}
|
18
|
+
@current_project['name'] = line.strip
|
19
|
+
@state = :key_val
|
20
|
+
when :key_val
|
21
|
+
parse_key_val(line)
|
22
|
+
when :val_list
|
23
|
+
parse_val_list(line)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
wrap_up
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def parse_key_val(line)
|
32
|
+
key, val = key_val(line)
|
33
|
+
if val
|
34
|
+
@current_project[key] = val
|
35
|
+
elsif line.start_with?(' ')
|
36
|
+
@current_key = key
|
37
|
+
@current_vals = []
|
38
|
+
@state = :val_list
|
39
|
+
else
|
40
|
+
change_to_new_project_state line
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def parse_val_list(line)
|
45
|
+
if val_list_level(line)
|
46
|
+
@current_vals << line.strip
|
47
|
+
else
|
48
|
+
@current_project[@current_key] = @current_vals
|
49
|
+
if line.start_with?(' ')
|
50
|
+
@state = :key_val
|
51
|
+
@lines.unshift(line)
|
52
|
+
else
|
53
|
+
change_to_new_project_state line
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def wrap_up
|
59
|
+
@current_project[@current_key] = @current_vals if @current_vals.count && @current_key
|
60
|
+
@projects << @current_project
|
61
|
+
end
|
62
|
+
|
63
|
+
def val_list_level(line)
|
64
|
+
line.start_with?(' ')
|
65
|
+
end
|
66
|
+
|
67
|
+
def change_to_new_project_state(line)
|
68
|
+
@state = :project_level
|
69
|
+
@projects << @current_project
|
70
|
+
@lines.unshift(line)
|
71
|
+
end
|
72
|
+
|
73
|
+
def key_val(info)
|
74
|
+
info.split(':', 2).map(&:strip!)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module LicenseFinder
|
4
|
+
class GradleDependencyFinder
|
5
|
+
def initialize(project_path)
|
6
|
+
@project_path = project_path
|
7
|
+
end
|
8
|
+
|
9
|
+
def dependencies
|
10
|
+
Pathname
|
11
|
+
.glob(@project_path.join('**', 'dependency-license.xml'))
|
12
|
+
.map(&:read)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'license_finder/package_utils/possible_license_file'
|
4
|
+
|
5
|
+
module LicenseFinder
|
6
|
+
class LicenseFiles
|
7
|
+
CANDIDATE_FILE_NAMES = %w[License Licence COPYING README].freeze
|
8
|
+
CANDIDATE_PATH_WILDCARD = "*{#{CANDIDATE_FILE_NAMES.join(',')}}*"
|
9
|
+
|
10
|
+
def self.find(install_path, options = {})
|
11
|
+
new(install_path).find(options)
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize(install_path)
|
15
|
+
@install_path = install_path ? Pathname(install_path) : nil
|
16
|
+
end
|
17
|
+
|
18
|
+
def find(options = {})
|
19
|
+
paths_of_candidate_files
|
20
|
+
.map { |path| PossibleLicenseFile.new(path, options) }
|
21
|
+
.reject { |file| file.license.nil? }
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
attr_reader :install_path
|
27
|
+
|
28
|
+
def paths_of_candidate_files
|
29
|
+
candidate_files_and_dirs
|
30
|
+
.flat_map { |path| path.directory? ? path.children : path }
|
31
|
+
.reject(&:directory?)
|
32
|
+
.uniq
|
33
|
+
end
|
34
|
+
|
35
|
+
def candidate_files_and_dirs
|
36
|
+
return [] if install_path.nil?
|
37
|
+
|
38
|
+
Pathname.glob(install_path.join('**', CANDIDATE_PATH_WILDCARD), File::FNM_CASEFOLD)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'license_finder/package_utils/activation'
|
4
|
+
|
5
|
+
module LicenseFinder
|
6
|
+
Licensing = Struct.new(:package, :decided_licenses, :licenses_from_spec, :license_files) do
|
7
|
+
# Implements the algorithm for choosing the right set of licenses from
|
8
|
+
# among the various sources of licenses we know about. In order of
|
9
|
+
# priority, licenses come from decisions, package specs, or package files.
|
10
|
+
def activations
|
11
|
+
if activations_from_decisions.any? then activations_from_decisions
|
12
|
+
elsif activations_from_spec.any? then activations_from_spec
|
13
|
+
elsif activations_from_files.any? then activations_from_files
|
14
|
+
else [default_activation]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def activations_from_decisions
|
19
|
+
@activations_from_decisions ||= decided_licenses
|
20
|
+
.map { |license| Activation::FromDecision.new(package, license) }
|
21
|
+
end
|
22
|
+
|
23
|
+
def activations_from_spec
|
24
|
+
@activations_from_spec ||= licenses_from_spec
|
25
|
+
.map { |license| Activation::FromSpec.new(package, license) }
|
26
|
+
end
|
27
|
+
|
28
|
+
def activations_from_files
|
29
|
+
@activations_from_files ||= license_files
|
30
|
+
.group_by(&:license)
|
31
|
+
.map { |license, files| Activation::FromFiles.new(package, license, files) }
|
32
|
+
end
|
33
|
+
|
34
|
+
def default_activation
|
35
|
+
default_license = License.find_by_name nil
|
36
|
+
Activation::None.new(package, default_license)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module LicenseFinder
|
4
|
+
class MavenDependencyFinder
|
5
|
+
def initialize(project_path)
|
6
|
+
@project_path = project_path
|
7
|
+
end
|
8
|
+
|
9
|
+
def dependencies
|
10
|
+
Pathname
|
11
|
+
.glob(@project_path.join('**', 'target', 'generated-resources', 'licenses.xml'))
|
12
|
+
.map(&:read)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'license_finder/package_utils/possible_license_file'
|
4
|
+
|
5
|
+
module LicenseFinder
|
6
|
+
class NoticeFiles
|
7
|
+
CANDIDATE_FILE_NAMES = %w[NOTICE Notice].freeze
|
8
|
+
CANDIDATE_PATH_WILDCARD = "*{#{CANDIDATE_FILE_NAMES.join(',')}}*"
|
9
|
+
|
10
|
+
def self.find(install_path, options = {})
|
11
|
+
new(install_path).find(options)
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize(install_path)
|
15
|
+
@install_path = install_path ? Pathname(install_path) : nil
|
16
|
+
end
|
17
|
+
|
18
|
+
def find(options = {})
|
19
|
+
paths_of_candidate_files
|
20
|
+
.map { |path| PossibleLicenseFile.new(path, options) } # Not really possible license files, but that class has all we need.
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
attr_reader :install_path
|
26
|
+
|
27
|
+
def paths_of_candidate_files
|
28
|
+
candidate_files_and_dirs
|
29
|
+
.flat_map { |path| path.directory? ? path.children : path }
|
30
|
+
.reject(&:directory?)
|
31
|
+
.uniq
|
32
|
+
end
|
33
|
+
|
34
|
+
def candidate_files_and_dirs
|
35
|
+
return [] if install_path.nil?
|
36
|
+
|
37
|
+
Pathname.glob(install_path.join('**', CANDIDATE_PATH_WILDCARD))
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module LicenseFinder
|
4
|
+
class PossibleLicenseFile
|
5
|
+
def initialize(path, options = {})
|
6
|
+
@path = Pathname(path)
|
7
|
+
@logger = options[:logger]
|
8
|
+
end
|
9
|
+
|
10
|
+
def path
|
11
|
+
@path.to_s
|
12
|
+
end
|
13
|
+
|
14
|
+
def license
|
15
|
+
License.find_by_text(text)
|
16
|
+
end
|
17
|
+
|
18
|
+
def text
|
19
|
+
if @path.exist?
|
20
|
+
@text ||= (@path.respond_to?(:binread) ? @path.binread : @path.read)
|
21
|
+
else
|
22
|
+
@logger.info('ERROR', "#{@path} does not exists", color: :red)
|
23
|
+
''
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'net/http'
|
4
|
+
require 'openssl'
|
5
|
+
|
6
|
+
module LicenseFinder
|
7
|
+
class PyPI
|
8
|
+
CONNECTION_ERRORS = [
|
9
|
+
EOFError,
|
10
|
+
Errno::ECONNREFUSED,
|
11
|
+
Errno::ECONNRESET,
|
12
|
+
Errno::ECONNRESET,
|
13
|
+
Errno::EHOSTUNREACH,
|
14
|
+
Errno::EINVAL,
|
15
|
+
Net::OpenTimeout,
|
16
|
+
Net::ProtocolError,
|
17
|
+
Net::ReadTimeout,
|
18
|
+
OpenSSL::OpenSSLError,
|
19
|
+
OpenSSL::SSL::SSLError,
|
20
|
+
SocketError,
|
21
|
+
Timeout::Error
|
22
|
+
].freeze
|
23
|
+
|
24
|
+
class << self
|
25
|
+
def definition(name, version)
|
26
|
+
response = request("https://pypi.org/pypi/#{name}/#{version}/json")
|
27
|
+
response.is_a?(Net::HTTPSuccess) ? JSON.parse(response.body).fetch('info', {}) : {}
|
28
|
+
rescue *CONNECTION_ERRORS
|
29
|
+
{}
|
30
|
+
end
|
31
|
+
|
32
|
+
def request(location, limit = 10)
|
33
|
+
uri = URI(location)
|
34
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
35
|
+
http.use_ssl = true
|
36
|
+
response = http.get(uri.request_uri).response
|
37
|
+
response.is_a?(Net::HTTPRedirection) && limit.positive? ? request(response['location'], limit - 1) : response
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module LicenseFinder
|
4
|
+
class SbtDependencyFinder
|
5
|
+
def initialize(project_path)
|
6
|
+
@project_path = project_path
|
7
|
+
end
|
8
|
+
|
9
|
+
def dependencies
|
10
|
+
Pathname
|
11
|
+
.glob(@project_path.join('**', 'target', 'license-reports', '*.csv'))
|
12
|
+
.map(&:read)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'open-uri'
|
4
|
+
|
5
|
+
module LicenseFinder
|
6
|
+
class BowerPackage < Package
|
7
|
+
def initialize(bower_module, options = {})
|
8
|
+
spec = bower_module.fetch('pkgMeta', {})
|
9
|
+
|
10
|
+
if spec.empty?
|
11
|
+
endpoint = bower_module.fetch('endpoint', {})
|
12
|
+
name = endpoint['name']
|
13
|
+
version = endpoint['target']
|
14
|
+
else
|
15
|
+
name = spec['name']
|
16
|
+
version = spec['version']
|
17
|
+
end
|
18
|
+
|
19
|
+
super(
|
20
|
+
name,
|
21
|
+
version,
|
22
|
+
options.merge(
|
23
|
+
summary: spec['description'],
|
24
|
+
description: spec['readme'],
|
25
|
+
homepage: spec['homepage'],
|
26
|
+
spec_licenses: Package.license_names_from_standard_spec(spec),
|
27
|
+
install_path: bower_module['canonicalDir'],
|
28
|
+
missing: bower_module['missing']
|
29
|
+
)
|
30
|
+
)
|
31
|
+
end
|
32
|
+
|
33
|
+
def package_manager
|
34
|
+
'Bower'
|
35
|
+
end
|
36
|
+
|
37
|
+
def package_url
|
38
|
+
meta = JSON.parse(open("https://registry.bower.io/packages/#{CGI.escape(name)}").read)
|
39
|
+
meta['url']
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module LicenseFinder
|
4
|
+
class BundlerPackage < Package
|
5
|
+
def initialize(spec, bundler_def, options = {})
|
6
|
+
children = spec.dependencies.map(&:name)
|
7
|
+
groups = Array(bundler_def && bundler_def.groups).map(&:to_s)
|
8
|
+
|
9
|
+
super(
|
10
|
+
spec.name,
|
11
|
+
spec.version.to_s,
|
12
|
+
options.merge(
|
13
|
+
authors: Array(spec.authors).join(', '),
|
14
|
+
summary: spec.summary,
|
15
|
+
description: spec.description,
|
16
|
+
homepage: spec.homepage,
|
17
|
+
children: children,
|
18
|
+
groups: groups,
|
19
|
+
spec_licenses: spec.licenses,
|
20
|
+
install_path: spec.full_gem_path
|
21
|
+
)
|
22
|
+
)
|
23
|
+
end
|
24
|
+
|
25
|
+
def package_manager
|
26
|
+
'Bundler'
|
27
|
+
end
|
28
|
+
|
29
|
+
def package_url
|
30
|
+
"https://rubygems.org/gems/#{CGI.escape(name)}/versions/#{CGI.escape(version)}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module LicenseFinder
|
4
|
+
class CargoPackage < Package
|
5
|
+
def initialize(crate, options = {})
|
6
|
+
crate = crate.reject { |_, v| v.nil? || v == '' }
|
7
|
+
children = crate.fetch('dependencies', []).map { |p| p['name'] }
|
8
|
+
licenses = crate.fetch('license', '').split('/')
|
9
|
+
super(
|
10
|
+
crate['name'],
|
11
|
+
crate['version'],
|
12
|
+
options.merge(
|
13
|
+
summary: crate.fetch('description', '').strip,
|
14
|
+
spec_licenses: licenses.compact,
|
15
|
+
children: children
|
16
|
+
)
|
17
|
+
)
|
18
|
+
end
|
19
|
+
|
20
|
+
def package_manager
|
21
|
+
'Cargo'
|
22
|
+
end
|
23
|
+
|
24
|
+
def package_url
|
25
|
+
"https://crates.io/crates/#{CGI.escape(name)}/#{CGI.escape(version)}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module LicenseFinder
|
4
|
+
class CarthagePackage < Package
|
5
|
+
def initialize(name, version, license_text, options = {})
|
6
|
+
super(name, version, options)
|
7
|
+
@license = License.find_by_text(license_text.to_s)
|
8
|
+
end
|
9
|
+
|
10
|
+
def licenses_from_spec
|
11
|
+
[@license].compact
|
12
|
+
end
|
13
|
+
|
14
|
+
def package_manager
|
15
|
+
'Carthage'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module LicenseFinder
|
4
|
+
class CocoaPodsPackage < Package
|
5
|
+
def initialize(name, version, license_text, options = {})
|
6
|
+
super(name, version, options)
|
7
|
+
@license = License.find_by_text(license_text.to_s)
|
8
|
+
end
|
9
|
+
|
10
|
+
def licenses_from_spec
|
11
|
+
[@license].compact
|
12
|
+
end
|
13
|
+
|
14
|
+
def package_manager
|
15
|
+
'CocoaPods'
|
16
|
+
end
|
17
|
+
|
18
|
+
def package_url
|
19
|
+
"https://cocoapods.org/pods/#{CGI.escape(name)}"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module LicenseFinder
|
4
|
+
class ConanPackage < Package
|
5
|
+
def initialize(name, version, license_text, url, options = {})
|
6
|
+
super(name, version, options)
|
7
|
+
@license = License.find_by_text(license_text.to_s)
|
8
|
+
@homepage = url
|
9
|
+
end
|
10
|
+
|
11
|
+
def licenses_from_spec
|
12
|
+
[@license].compact
|
13
|
+
end
|
14
|
+
|
15
|
+
def package_manager
|
16
|
+
'Conan'
|
17
|
+
end
|
18
|
+
|
19
|
+
def package_url
|
20
|
+
"https://conan.io/center/#{CGI.escape(name)}/#{CGI.escape(version)}"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module LicenseFinder
|
4
|
+
class CondaPackage < Package
|
5
|
+
attr_accessor :identifier, :json
|
6
|
+
|
7
|
+
def initialize(conda_json)
|
8
|
+
@json = conda_json
|
9
|
+
@identifier = Identifier.from_hash(conda_json)
|
10
|
+
super(@identifier.name,
|
11
|
+
@identifier.version,
|
12
|
+
spec_licenses: Package.license_names_from_standard_spec(conda_json),
|
13
|
+
children: children)
|
14
|
+
end
|
15
|
+
|
16
|
+
def ==(other)
|
17
|
+
other.is_a?(CondaPackage) && @identifier == other.identifier
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_s
|
21
|
+
@identifier.to_s
|
22
|
+
end
|
23
|
+
|
24
|
+
def package_manager
|
25
|
+
'Conda'
|
26
|
+
end
|
27
|
+
|
28
|
+
def package_url
|
29
|
+
@json['url']
|
30
|
+
end
|
31
|
+
|
32
|
+
def children
|
33
|
+
@json.fetch('depends', []).map { |constraint| constraint.split.first }
|
34
|
+
end
|
35
|
+
|
36
|
+
class Identifier
|
37
|
+
attr_accessor :name, :version
|
38
|
+
|
39
|
+
def initialize(name, version)
|
40
|
+
@name = name
|
41
|
+
@version = version
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.from_hash(hash)
|
45
|
+
name = hash['name']
|
46
|
+
version = hash['version']
|
47
|
+
return nil if name.nil? || version.nil?
|
48
|
+
|
49
|
+
Identifier.new(name, version)
|
50
|
+
end
|
51
|
+
|
52
|
+
def ==(other)
|
53
|
+
other.is_a?(Identifier) && @name == other.name && @version == other.version
|
54
|
+
end
|
55
|
+
|
56
|
+
def eql?(other)
|
57
|
+
self == other
|
58
|
+
end
|
59
|
+
|
60
|
+
def hash
|
61
|
+
[@name, @version].hash
|
62
|
+
end
|
63
|
+
|
64
|
+
def <=>(other)
|
65
|
+
sort_name = @name <=> other.name
|
66
|
+
sort_name.zero? ? @version <=> other.version : sort_name
|
67
|
+
end
|
68
|
+
|
69
|
+
def to_s
|
70
|
+
"#{@name} - #{@version}"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
|
5
|
+
class InvalidErlangmkPackageError < ArgumentError
|
6
|
+
end
|
7
|
+
|
8
|
+
module LicenseFinder
|
9
|
+
class ErlangmkPackage < Package
|
10
|
+
attr_reader :dep_parent,
|
11
|
+
:dep_name,
|
12
|
+
:dep_fetch_method,
|
13
|
+
:dep_repo_unformatted,
|
14
|
+
:dep_version_unformatted,
|
15
|
+
:dep_absolute_path
|
16
|
+
|
17
|
+
def initialize(dep_string_from_query_deps)
|
18
|
+
@dep_parent,
|
19
|
+
@dep_name,
|
20
|
+
@dep_fetch_method,
|
21
|
+
@dep_repo_unformatted,
|
22
|
+
@dep_version_unformatted,
|
23
|
+
@dep_absolute_path = dep_string_from_query_deps.split
|
24
|
+
|
25
|
+
raise_invalid(dep_string_from_query_deps) unless all_parts_valid?
|
26
|
+
|
27
|
+
super(
|
28
|
+
dep_name,
|
29
|
+
dep_version,
|
30
|
+
homepage: dep_repo,
|
31
|
+
install_path: dep_absolute_path
|
32
|
+
)
|
33
|
+
end
|
34
|
+
|
35
|
+
def package_manager
|
36
|
+
'Erlangmk'
|
37
|
+
end
|
38
|
+
|
39
|
+
def dep_version
|
40
|
+
@dep_version ||= begin
|
41
|
+
dep_version_unformatted.sub(version_prefix_re, '')
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def dep_repo
|
46
|
+
@dep_repo ||= dep_repo_unformatted
|
47
|
+
.chomp('.git')
|
48
|
+
.sub('git@github.com:', 'https://github.com/')
|
49
|
+
end
|
50
|
+
|
51
|
+
def raise_invalid(dep_string)
|
52
|
+
invalid_dep_message = "'#{dep_string}' does not look like a valid Erlank.mk dependency"
|
53
|
+
valid_dep_example = "A valid dependency example: 'lager: goldrush git https://github.com/DeadZen/goldrush.git 0.1.9 /absolute/path/to/dep'"
|
54
|
+
raise(InvalidErlangmkPackageError, "#{invalid_dep_message}. #{valid_dep_example}")
|
55
|
+
end
|
56
|
+
|
57
|
+
def all_parts_valid?
|
58
|
+
dep_part_valid?(dep_parent) &&
|
59
|
+
dep_part_valid?(dep_name) &&
|
60
|
+
set?(dep_fetch_method) &&
|
61
|
+
dep_repo_valid? &&
|
62
|
+
dep_version_valid? &&
|
63
|
+
set?(dep_absolute_path)
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
def dep_part_valid?(dep_part)
|
69
|
+
set?(dep_part) &&
|
70
|
+
word?(dep_part)
|
71
|
+
end
|
72
|
+
|
73
|
+
def set?(dep_part)
|
74
|
+
!dep_part.nil? &&
|
75
|
+
!dep_part.empty?
|
76
|
+
end
|
77
|
+
|
78
|
+
def word?(dep_part)
|
79
|
+
dep = dep_part.chomp(':')
|
80
|
+
dep =~ word_re
|
81
|
+
end
|
82
|
+
|
83
|
+
def dep_repo_valid?
|
84
|
+
set?(dep_repo_unformatted) &&
|
85
|
+
URI.parse(dep_repo)
|
86
|
+
end
|
87
|
+
|
88
|
+
def dep_version_valid?
|
89
|
+
return false unless set?(dep_version_unformatted)
|
90
|
+
|
91
|
+
if dep_version =~ version_re
|
92
|
+
Gem::Version.correct?(dep_version)
|
93
|
+
else
|
94
|
+
dep_version =~ word_dot_re
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def version_re
|
99
|
+
@version_re ||= Regexp.new('\d+\.\d+\.\d+')
|
100
|
+
end
|
101
|
+
|
102
|
+
def version_prefix_re
|
103
|
+
@version_prefix_re ||= Regexp.new('^v')
|
104
|
+
end
|
105
|
+
|
106
|
+
def word_re
|
107
|
+
@word_re ||= Regexp.new('^\w+$')
|
108
|
+
end
|
109
|
+
|
110
|
+
def word_dot_re
|
111
|
+
@word_dot_re ||= Regexp.new('^[.\w]+$')
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|