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,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module LicenseFinder
|
4
|
+
class License
|
5
|
+
module Text
|
6
|
+
SPACES = /\s+/.freeze
|
7
|
+
QUOTES = /['`"]{1,2}/.freeze
|
8
|
+
YEAR_PLACEHOLDERS = /<year>/.freeze
|
9
|
+
PLACEHOLDERS = /<[^<>]+>/.freeze
|
10
|
+
SPECIAL_SINGLE_QUOTES = /[‘’]/.freeze
|
11
|
+
SPECIAL_DOUBLE_QUOTES = /[“”„«»]/.freeze
|
12
|
+
ALPHABET_ORDERED_LIST = /\\\([a-z]\\\)\\\s/.freeze
|
13
|
+
ALPHABET_ORDERED_LIST_OPTIONAL = '(\([a-z]\)\s)?'
|
14
|
+
LIST_BULLETS = /(\d{1,2}\\\.|\\\*|\\\-)\\\s/.freeze
|
15
|
+
LIST_BULLETS_OPTIONAL = '(\d{1,2}.|\*|\-)?\s*'
|
16
|
+
NEWLINE_CHARACTER = /\n+/.freeze
|
17
|
+
QUOTE_COMMENT_CHARACTER = /^\s*\>+/.freeze
|
18
|
+
ESCAPED_QUOTES = /\\\"/.freeze
|
19
|
+
|
20
|
+
def self.normalize_punctuation(text)
|
21
|
+
text.dup.force_encoding('UTF-8')
|
22
|
+
.gsub(SPECIAL_DOUBLE_QUOTES, '"')
|
23
|
+
.gsub(SPECIAL_SINGLE_QUOTES, "'")
|
24
|
+
.gsub(QUOTE_COMMENT_CHARACTER, '')
|
25
|
+
.gsub(SPACES, ' ')
|
26
|
+
.gsub(NEWLINE_CHARACTER, ' ')
|
27
|
+
.gsub(ESCAPED_QUOTES, '"')
|
28
|
+
.gsub(QUOTES, '"')
|
29
|
+
.strip
|
30
|
+
rescue ArgumentError => _e
|
31
|
+
text
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.compile_to_regex(text)
|
35
|
+
Regexp.new(Regexp.escape(normalize_punctuation(text))
|
36
|
+
.gsub(YEAR_PLACEHOLDERS, '(\S*)')
|
37
|
+
.gsub(PLACEHOLDERS, '(.*)')
|
38
|
+
.gsub(',', '(,)?')
|
39
|
+
.gsub('HOLDER', '(HOLDER|OWNER)')
|
40
|
+
.gsub(ALPHABET_ORDERED_LIST, ALPHABET_ORDERED_LIST_OPTIONAL)
|
41
|
+
.gsub(LIST_BULLETS, LIST_BULLETS_OPTIONAL))
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'license_finder/license/text'
|
4
|
+
require 'license_finder/license/template'
|
5
|
+
|
6
|
+
require 'license_finder/license/matcher'
|
7
|
+
require 'license_finder/license/header_matcher'
|
8
|
+
require 'license_finder/license/any_matcher'
|
9
|
+
require 'license_finder/license/none_matcher'
|
10
|
+
|
11
|
+
require 'license_finder/license/definitions'
|
12
|
+
|
13
|
+
module LicenseFinder
|
14
|
+
class License
|
15
|
+
class << self
|
16
|
+
def all
|
17
|
+
@all ||= Definitions.all
|
18
|
+
end
|
19
|
+
|
20
|
+
def find_by_name(name)
|
21
|
+
name ||= 'unknown'
|
22
|
+
license = all.detect { |l| l.matches_name? l.stripped_name(name) }
|
23
|
+
|
24
|
+
if license
|
25
|
+
license
|
26
|
+
elsif name.include?(OrLicense.operator)
|
27
|
+
OrLicense.new(name)
|
28
|
+
elsif name.include?(AndLicense.operator)
|
29
|
+
AndLicense.new(name)
|
30
|
+
else
|
31
|
+
Definitions.build_unrecognized(name)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def find_by_text(text)
|
36
|
+
all.detect { |l| l.matches_text? text }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def initialize(settings)
|
41
|
+
@short_name = settings.fetch(:short_name)
|
42
|
+
@pretty_name = settings.fetch(:pretty_name, short_name)
|
43
|
+
@other_names = settings.fetch(:other_names, [])
|
44
|
+
@url = settings.fetch(:url)
|
45
|
+
@matcher = settings.fetch(:matcher) { Matcher.from_template(Template.named(short_name)) }
|
46
|
+
end
|
47
|
+
|
48
|
+
attr_reader :url
|
49
|
+
|
50
|
+
def name
|
51
|
+
pretty_name
|
52
|
+
end
|
53
|
+
|
54
|
+
def stripped_name(name)
|
55
|
+
name.sub(/^The /i, '')
|
56
|
+
end
|
57
|
+
|
58
|
+
def matches_name?(name)
|
59
|
+
names.map(&:downcase).include? name.to_s.downcase
|
60
|
+
end
|
61
|
+
|
62
|
+
def matches_text?(text)
|
63
|
+
matcher.matches_text?(text)
|
64
|
+
end
|
65
|
+
|
66
|
+
def eql?(other)
|
67
|
+
name == other.name
|
68
|
+
end
|
69
|
+
|
70
|
+
def hash
|
71
|
+
name.hash
|
72
|
+
end
|
73
|
+
|
74
|
+
def unrecognized_matcher?
|
75
|
+
matcher.is_a?(NoneMatcher)
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
attr_reader :short_name, :pretty_name, :other_names
|
81
|
+
attr_reader :matcher
|
82
|
+
|
83
|
+
def names
|
84
|
+
([short_name, pretty_name] + other_names).uniq
|
85
|
+
end
|
86
|
+
end
|
87
|
+
class AndLicense < License
|
88
|
+
def self.operator
|
89
|
+
' AND '
|
90
|
+
end
|
91
|
+
|
92
|
+
def initialize(name, operator = AndLicense.operator)
|
93
|
+
@short_name = name
|
94
|
+
@pretty_name = name
|
95
|
+
@url = nil
|
96
|
+
@matcher = NoneMatcher.new
|
97
|
+
# removes heading and trailing parentesis and splits
|
98
|
+
name = name[1..-2] if name.start_with?('(')
|
99
|
+
names = name.split(operator)
|
100
|
+
@sub_licenses = names.map do |sub_name|
|
101
|
+
License.find_by_name(sub_name)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
attr_reader :sub_licenses
|
106
|
+
end
|
107
|
+
|
108
|
+
class OrLicense < AndLicense
|
109
|
+
def self.operator
|
110
|
+
' OR '
|
111
|
+
end
|
112
|
+
|
113
|
+
def initialize(name)
|
114
|
+
super(name, OrLicense.operator)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module LicenseFinder
|
4
|
+
class LicenseAggregator
|
5
|
+
def initialize(config, aggregate_paths)
|
6
|
+
@config = config
|
7
|
+
@aggregate_paths = aggregate_paths
|
8
|
+
end
|
9
|
+
|
10
|
+
def dependencies
|
11
|
+
aggregate_packages
|
12
|
+
end
|
13
|
+
|
14
|
+
def any_packages?
|
15
|
+
finders.map do |finder|
|
16
|
+
finder.prepare_projects if @config.prepare
|
17
|
+
finder.any_packages?
|
18
|
+
end.reduce(:|)
|
19
|
+
end
|
20
|
+
|
21
|
+
def unapproved
|
22
|
+
aggregate_packages.reject(&:approved?)
|
23
|
+
end
|
24
|
+
|
25
|
+
def restricted
|
26
|
+
aggregate_packages.select(&:restricted?)
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def finders
|
32
|
+
return @finders unless @finders.nil?
|
33
|
+
|
34
|
+
@finders = if @aggregate_paths.nil?
|
35
|
+
[LicenseFinder::Core.new(@config)]
|
36
|
+
else
|
37
|
+
@aggregate_paths.map do |path|
|
38
|
+
# Passing file paths as values instead of allowing them to evaluate in config
|
39
|
+
LicenseFinder::Core.new(@config.merge(project_path: path,
|
40
|
+
log_directory: @config.log_directory || @config.project_path,
|
41
|
+
decisions_file: @config.decisions_file_path))
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def aggregate_packages
|
47
|
+
return @packages unless @packages.nil?
|
48
|
+
|
49
|
+
all_packages = finders.flat_map do |finder|
|
50
|
+
finder.prepare_projects if @config.prepare
|
51
|
+
finder.acknowledged.map { |dep| MergedPackage.new(dep, [finder.project_path]) }
|
52
|
+
end
|
53
|
+
@packages = all_packages.group_by { |package| [package.name, package.version] }
|
54
|
+
.map do |_, packages|
|
55
|
+
MergedPackage.new(packages[0].dependency, packages.flat_map(&:aggregate_paths))
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'logger'
|
4
|
+
|
5
|
+
module LicenseFinder
|
6
|
+
class Logger
|
7
|
+
MODE_QUIET = :quiet
|
8
|
+
MODE_INFO = :info
|
9
|
+
MODE_DEBUG = :debug
|
10
|
+
|
11
|
+
attr_reader :mode
|
12
|
+
|
13
|
+
def initialize(mode = nil)
|
14
|
+
@system_logger = ::Logger.new(STDOUT)
|
15
|
+
@system_logger.formatter = proc do |_, _, _, msg|
|
16
|
+
"#{msg}\n"
|
17
|
+
end
|
18
|
+
|
19
|
+
self.mode = mode || MODE_INFO
|
20
|
+
end
|
21
|
+
|
22
|
+
[MODE_INFO, MODE_DEBUG].each do |level|
|
23
|
+
define_method level do |prefix, string, options = {}|
|
24
|
+
msg = format('%s: %s', prefix, colorize(string, options[:color]))
|
25
|
+
log(msg, level)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
attr_reader :system_logger
|
32
|
+
|
33
|
+
def colorize(string, color)
|
34
|
+
case color
|
35
|
+
when :red
|
36
|
+
"\e[31m#{string}\e[0m"
|
37
|
+
when :green
|
38
|
+
"\e[32m#{string}\e[0m"
|
39
|
+
when :magenta
|
40
|
+
"\e[35m#{string}\e[0m"
|
41
|
+
else
|
42
|
+
string
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def mode=(verbose)
|
47
|
+
@mode = verbose
|
48
|
+
|
49
|
+
return if quiet?
|
50
|
+
|
51
|
+
level = @mode.equal?(MODE_DEBUG) ? ::Logger::DEBUG : ::Logger::INFO
|
52
|
+
system_logger.level = level
|
53
|
+
end
|
54
|
+
|
55
|
+
def log(msg, method)
|
56
|
+
return if quiet?
|
57
|
+
|
58
|
+
system_logger.send(method, msg)
|
59
|
+
end
|
60
|
+
|
61
|
+
def debug?
|
62
|
+
@mode.equal?(MODE_DEBUG)
|
63
|
+
end
|
64
|
+
|
65
|
+
def quiet?
|
66
|
+
@mode.equal?(MODE_QUIET)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,202 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'license_finder/package_utils/licensing'
|
4
|
+
require 'license_finder/package_utils/license_files'
|
5
|
+
require 'license_finder/package_utils/notice_files'
|
6
|
+
|
7
|
+
module LicenseFinder
|
8
|
+
# Super-class that adapts data from different package management
|
9
|
+
# systems (gems, npm, pip, etc.) to a common interface.
|
10
|
+
#
|
11
|
+
# Guidance on adding a new system
|
12
|
+
#
|
13
|
+
# - subclass Package, and initialize based on the data you receive from the
|
14
|
+
# package manager
|
15
|
+
# - if the package specs will report license names, pass :spec_licenses in the
|
16
|
+
# constructor options
|
17
|
+
# - if the package's files can be searched for licenses pass :install_path in
|
18
|
+
# the constructor options
|
19
|
+
# - otherwise, override #licenses_from_spec or #license_files
|
20
|
+
class Package
|
21
|
+
attr_reader :logger
|
22
|
+
|
23
|
+
def self.license_names_from_standard_spec(spec)
|
24
|
+
licenses = spec['licenses'] || [spec['license']].compact
|
25
|
+
licenses = [licenses] unless licenses.is_a?(Array)
|
26
|
+
licenses = licenses.flatten
|
27
|
+
licenses.map do |license|
|
28
|
+
if license.is_a? Hash
|
29
|
+
license['type']
|
30
|
+
else
|
31
|
+
license
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def initialize(name, version = nil, options = {})
|
37
|
+
@logger = options[:logger] || Core.default_logger
|
38
|
+
|
39
|
+
## DESCRIPTION
|
40
|
+
@name = name
|
41
|
+
@version = version || ''
|
42
|
+
@authors = options[:authors] || ''
|
43
|
+
@summary = options[:summary] || ''
|
44
|
+
@description = options[:description] || ''
|
45
|
+
@homepage = options[:homepage] || ''
|
46
|
+
@package_url = options[:package_url].to_s
|
47
|
+
@children = options[:children] || []
|
48
|
+
@parents = Set.new # will be figured out later by package manager
|
49
|
+
@groups = options[:groups] || []
|
50
|
+
|
51
|
+
## APPROVAL
|
52
|
+
@permitted = false
|
53
|
+
@restricted = false
|
54
|
+
@manual_approval = nil
|
55
|
+
|
56
|
+
## LICENSING
|
57
|
+
@license_names_from_spec = options[:spec_licenses] || []
|
58
|
+
@install_path = options[:install_path]
|
59
|
+
@missing = options[:missing] || false
|
60
|
+
@decided_licenses = Set.new
|
61
|
+
end
|
62
|
+
|
63
|
+
## DESCRIPTION
|
64
|
+
|
65
|
+
attr_accessor :homepage, :package_url
|
66
|
+
|
67
|
+
attr_reader :name, :version, :authors,
|
68
|
+
:summary, :description,
|
69
|
+
:children, :parents, :groups
|
70
|
+
|
71
|
+
## APPROVAL
|
72
|
+
|
73
|
+
def approved_manually!(approval)
|
74
|
+
@manual_approval = approval
|
75
|
+
end
|
76
|
+
|
77
|
+
def approved_manually?
|
78
|
+
!@manual_approval.nil?
|
79
|
+
end
|
80
|
+
|
81
|
+
def approved?
|
82
|
+
# Question: is `!restricted?` redundant?
|
83
|
+
# DecisionApplier does not call `permitted!` or `approved_manually!`
|
84
|
+
# if a Package has been restricted.
|
85
|
+
(approved_manually? || permitted?) && !restricted?
|
86
|
+
end
|
87
|
+
|
88
|
+
def permitted!
|
89
|
+
@permitted = true
|
90
|
+
end
|
91
|
+
|
92
|
+
def permitted?
|
93
|
+
@permitted
|
94
|
+
end
|
95
|
+
|
96
|
+
def restricted!
|
97
|
+
@restricted = true
|
98
|
+
end
|
99
|
+
|
100
|
+
def restricted?
|
101
|
+
@restricted
|
102
|
+
end
|
103
|
+
|
104
|
+
attr_reader :manual_approval
|
105
|
+
|
106
|
+
## EQUALITY
|
107
|
+
|
108
|
+
def <=>(other)
|
109
|
+
eq_name = name <=> other.name
|
110
|
+
return eq_name unless eq_name.zero?
|
111
|
+
|
112
|
+
version <=> other.version
|
113
|
+
end
|
114
|
+
|
115
|
+
def eql?(other)
|
116
|
+
name == other.name && version == other.version
|
117
|
+
end
|
118
|
+
|
119
|
+
def hash
|
120
|
+
[name, version].hash
|
121
|
+
end
|
122
|
+
|
123
|
+
## LICENSING
|
124
|
+
|
125
|
+
attr_reader :license_names_from_spec # stubbed in tests, otherwise private
|
126
|
+
attr_reader :install_path # checked in tests, otherwise private
|
127
|
+
|
128
|
+
def licenses
|
129
|
+
@licenses ||= activations.map(&:license).sort_by(&:name).to_set
|
130
|
+
end
|
131
|
+
|
132
|
+
def activations
|
133
|
+
licensing.activations.tap do |activations|
|
134
|
+
activations.each { |activation| log_activation activation }
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def licensing
|
139
|
+
Licensing.new(self, @decided_licenses, licenses_from_spec, license_files)
|
140
|
+
end
|
141
|
+
|
142
|
+
def decide_on_license(license)
|
143
|
+
@decided_licenses << license
|
144
|
+
end
|
145
|
+
|
146
|
+
def licenses_from_spec
|
147
|
+
license_names_from_spec
|
148
|
+
.map { |name| License.find_by_name(name) }
|
149
|
+
.to_set
|
150
|
+
end
|
151
|
+
|
152
|
+
def license_files
|
153
|
+
LicenseFiles.find(install_path, logger: logger)
|
154
|
+
end
|
155
|
+
|
156
|
+
def notice_files
|
157
|
+
NoticeFiles.find(install_path, logger: logger)
|
158
|
+
end
|
159
|
+
|
160
|
+
def package_manager
|
161
|
+
'unknown'
|
162
|
+
end
|
163
|
+
|
164
|
+
def missing?
|
165
|
+
@missing
|
166
|
+
end
|
167
|
+
|
168
|
+
def log_activation(activation)
|
169
|
+
preamble = format('package %s:', activation.package.name)
|
170
|
+
if activation.sources.empty?
|
171
|
+
logger.debug activation.package.class, format('%s no licenses found', preamble)
|
172
|
+
else
|
173
|
+
activation.sources.each do |source|
|
174
|
+
logger.debug activation.package.class, format("%s found license '%s' %s", preamble, activation.license.name, source)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
require 'license_finder/packages/manual_package'
|
182
|
+
require 'license_finder/packages/bower_package'
|
183
|
+
require 'license_finder/packages/go_package'
|
184
|
+
require 'license_finder/packages/bundler_package'
|
185
|
+
require 'license_finder/packages/pip_package'
|
186
|
+
require 'license_finder/packages/npm_package'
|
187
|
+
require 'license_finder/packages/maven_package'
|
188
|
+
require 'license_finder/packages/gradle_package'
|
189
|
+
require 'license_finder/packages/cocoa_pods_package'
|
190
|
+
require 'license_finder/packages/carthage_package'
|
191
|
+
require 'license_finder/packages/spm_package'
|
192
|
+
require 'license_finder/packages/rebar_package'
|
193
|
+
require 'license_finder/packages/erlangmk_package'
|
194
|
+
require 'license_finder/packages/mix_package'
|
195
|
+
require 'license_finder/packages/merged_package'
|
196
|
+
require 'license_finder/packages/nuget_package'
|
197
|
+
require 'license_finder/packages/conan_package'
|
198
|
+
require 'license_finder/packages/yarn_package'
|
199
|
+
require 'license_finder/packages/sbt_package'
|
200
|
+
require 'license_finder/packages/cargo_package'
|
201
|
+
require 'license_finder/packages/composer_package'
|
202
|
+
require 'license_finder/packages/conda_package'
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module LicenseFinder
|
4
|
+
class PackageDelta
|
5
|
+
STATUSES = %i[added removed unchanged].freeze
|
6
|
+
|
7
|
+
def initialize(status, current_package, previous_package)
|
8
|
+
@status = status
|
9
|
+
@current_package = current_package
|
10
|
+
@previous_package = previous_package
|
11
|
+
end
|
12
|
+
|
13
|
+
def name
|
14
|
+
pick_package.name
|
15
|
+
end
|
16
|
+
|
17
|
+
def version
|
18
|
+
pick_package.version
|
19
|
+
end
|
20
|
+
|
21
|
+
def aggregate_paths
|
22
|
+
pick_package.aggregate_paths
|
23
|
+
end
|
24
|
+
|
25
|
+
attr_reader :status
|
26
|
+
|
27
|
+
def licenses
|
28
|
+
pick_package.licenses
|
29
|
+
end
|
30
|
+
|
31
|
+
def merged_package?
|
32
|
+
pick_package.class == MergedPackage
|
33
|
+
end
|
34
|
+
|
35
|
+
def method_missing(_method_name)
|
36
|
+
nil
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.added(package)
|
40
|
+
new(:added, package, nil)
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.removed(package)
|
44
|
+
new(:removed, nil, package)
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.unchanged(current_package, previous_package)
|
48
|
+
new(:unchanged, current_package, previous_package)
|
49
|
+
end
|
50
|
+
|
51
|
+
def <=>(other)
|
52
|
+
STATUSES.index(status) <=> STATUSES.index(other.status)
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def pick_package
|
58
|
+
@current_package || @previous_package
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|