license_finder-rubyzip3 7.2.1.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/.github/dependabot.yml +16 -0
- data/.gitignore +13 -0
- data/.pre-commit-hooks.yaml +10 -0
- data/.rspec +1 -0
- data/.rubocop.yml +84 -0
- data/CHANGELOG.md +1066 -0
- data/CONTRIBUTING.md +122 -0
- data/Dockerfile +275 -0
- data/Gemfile +2 -0
- data/LICENSE +22 -0
- data/README.md +597 -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 +138 -0
- data/ci/pipelines/release.yml.erb +176 -0
- data/ci/scripts/containerize-tests.sh +14 -0
- data/ci/scripts/pushscript.sh +31 -0
- data/ci/scripts/run-rubocop.sh +15 -0
- data/ci/scripts/run-tests.sh +41 -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 +21 -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 +113 -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 +31 -0
- data/lib/license_finder/cli/main.rb +229 -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 +197 -0
- data/lib/license_finder/core.rb +121 -0
- data/lib/license_finder/decision_applier.rb +70 -0
- data/lib/license_finder/decisions.rb +334 -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 +498 -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/AGPL3.txt +661 -0
- data/lib/license_finder/license/templates/Apache1_1.txt +16 -0
- data/lib/license_finder/license/templates/Apache2.txt +170 -0
- data/lib/license_finder/license/templates/Artistic.txt +128 -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/CC01_alt.txt +31 -0
- data/lib/license_finder/license/templates/CDDL1.txt +131 -0
- data/lib/license_finder/license/templates/CDDL1_1.txt +123 -0
- data/lib/license_finder/license/templates/CPL1.txt +217 -0
- data/lib/license_finder/license/templates/EPL1.txt +86 -0
- data/lib/license_finder/license/templates/EPL2.txt +80 -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/Unlicense.txt +24 -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 +49 -0
- data/lib/license_finder/license.rb +123 -0
- data/lib/license_finder/license_aggregator.rb +59 -0
- data/lib/license_finder/logger.rb +69 -0
- data/lib/license_finder/manual_licenses.rb +79 -0
- data/lib/license_finder/package.rb +195 -0
- data/lib/license_finder/package_delta.rb +61 -0
- data/lib/license_finder/package_manager.rb +183 -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 +66 -0
- data/lib/license_finder/package_managers/composer.rb +63 -0
- data/lib/license_finder/package_managers/conan.rb +70 -0
- data/lib/license_finder/package_managers/conda.rb +131 -0
- data/lib/license_finder/package_managers/dep.rb +45 -0
- data/lib/license_finder/package_managers/dotnet.rb +86 -0
- data/lib/license_finder/package_managers/erlangmk.rb +50 -0
- data/lib/license_finder/package_managers/glide.rb +42 -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 +117 -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 +69 -0
- data/lib/license_finder/package_managers/mix.rb +131 -0
- data/lib/license_finder/package_managers/npm.rb +70 -0
- data/lib/license_finder/package_managers/nuget.rb +159 -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/pnpm.rb +126 -0
- data/lib/license_finder/package_managers/pub.rb +86 -0
- data/lib/license_finder/package_managers/rebar.rb +65 -0
- data/lib/license_finder/package_managers/sbt.rb +46 -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 +195 -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/conan_info_parser_v2.rb +82 -0
- data/lib/license_finder/package_utils/gradle_dependency_finder.rb +15 -0
- data/lib/license_finder/package_utils/license_files.rb +51 -0
- data/lib/license_finder/package_utils/licensing.rb +40 -0
- data/lib/license_finder/package_utils/maven_dependency_finder.rb +57 -0
- data/lib/license_finder/package_utils/notice_files.rb +51 -0
- data/lib/license_finder/package_utils/possible_license_file.rb +33 -0
- data/lib/license_finder/package_utils/pypi.rb +43 -0
- data/lib/license_finder/package_utils/sbt_dependency_finder.rb +15 -0
- data/lib/license_finder/packages/bower_package.rb +45 -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 +112 -0
- data/lib/license_finder/packages/go_package.rb +30 -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 +39 -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 +219 -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/pnpm_package.rb +13 -0
- data/lib/license_finder/packages/pubspec_package.rb +18 -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/printer.rb +39 -0
- data/lib/license_finder/project_finder.rb +62 -0
- data/lib/license_finder/report.rb +34 -0
- data/lib/license_finder/reports/csv_report.rb +108 -0
- data/lib/license_finder/reports/diff_report.rb +29 -0
- data/lib/license_finder/reports/erb_report.rb +62 -0
- data/lib/license_finder/reports/html_report.rb +13 -0
- data/lib/license_finder/reports/json_report.rb +31 -0
- data/lib/license_finder/reports/junit_report.rb +23 -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 +23 -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 +79 -0
- data/release/instructions.md +8 -0
- data/swift-all-keys.asc +240 -0
- metadata +604 -0
|
@@ -0,0 +1,49 @@
|
|
|
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
|
+
SPECIAL_CHARACTERS = /§/.freeze
|
|
20
|
+
SPECIAL_DASHES = /–/.freeze
|
|
21
|
+
|
|
22
|
+
def self.normalize_punctuation(text)
|
|
23
|
+
text.dup.force_encoding('UTF-8')
|
|
24
|
+
.gsub(SPECIAL_DOUBLE_QUOTES, '"')
|
|
25
|
+
.gsub(SPECIAL_SINGLE_QUOTES, "'")
|
|
26
|
+
.gsub(QUOTE_COMMENT_CHARACTER, '')
|
|
27
|
+
.gsub(SPACES, ' ')
|
|
28
|
+
.gsub(NEWLINE_CHARACTER, ' ')
|
|
29
|
+
.gsub(ESCAPED_QUOTES, '"')
|
|
30
|
+
.gsub(QUOTES, '"')
|
|
31
|
+
.gsub(SPECIAL_CHARACTERS, '?')
|
|
32
|
+
.gsub(SPECIAL_DASHES, '-')
|
|
33
|
+
.strip
|
|
34
|
+
rescue ArgumentError => _e
|
|
35
|
+
text
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def self.compile_to_regex(text)
|
|
39
|
+
Regexp.new(Regexp.escape(normalize_punctuation(text))
|
|
40
|
+
.gsub(YEAR_PLACEHOLDERS, '(\S*)')
|
|
41
|
+
.gsub(PLACEHOLDERS, '(.*)')
|
|
42
|
+
.gsub(',', '(,)?')
|
|
43
|
+
.gsub('HOLDER', '(HOLDER|OWNER)')
|
|
44
|
+
.gsub(ALPHABET_ORDERED_LIST, ALPHABET_ORDERED_LIST_OPTIONAL)
|
|
45
|
+
.gsub(LIST_BULLETS, LIST_BULLETS_OPTIONAL))
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,123 @@
|
|
|
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
|
+
@spdx_id = settings.fetch(:spdx_id, '')
|
|
44
|
+
@other_names = settings.fetch(:other_names, [])
|
|
45
|
+
@url = settings.fetch(:url)
|
|
46
|
+
@matcher = settings.fetch(:matcher) { Matcher.from_template(Template.named(short_name)) }
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
attr_reader :url
|
|
50
|
+
|
|
51
|
+
def name
|
|
52
|
+
pretty_name
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def standard_id
|
|
56
|
+
spdx_id
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def stripped_name(name)
|
|
60
|
+
name.sub(/^The /i, '')
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def matches_name?(name)
|
|
64
|
+
names.map(&:downcase).include? name.to_s.downcase
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def matches_text?(text)
|
|
68
|
+
matcher.matches_text?(text)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def eql?(other)
|
|
72
|
+
name == other.name
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def hash
|
|
76
|
+
name.hash
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def unrecognized_matcher?
|
|
80
|
+
matcher.is_a?(NoneMatcher)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
private
|
|
84
|
+
|
|
85
|
+
attr_reader :short_name, :pretty_name, :other_names, :spdx_id, :matcher
|
|
86
|
+
|
|
87
|
+
def names
|
|
88
|
+
([short_name, pretty_name, spdx_id] + other_names).uniq
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
class AndLicense < License
|
|
93
|
+
def self.operator
|
|
94
|
+
' AND '
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def initialize(name, operator = AndLicense.operator)
|
|
98
|
+
@short_name = name
|
|
99
|
+
@pretty_name = name
|
|
100
|
+
@url = nil
|
|
101
|
+
@spdx_id = nil
|
|
102
|
+
@matcher = NoneMatcher.new
|
|
103
|
+
# removes heading and trailing parentesis and splits
|
|
104
|
+
name = name[1..-2] if name.start_with?('(')
|
|
105
|
+
names = name.split(operator)
|
|
106
|
+
@sub_licenses = names.map do |sub_name|
|
|
107
|
+
License.find_by_name(sub_name)
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
attr_reader :sub_licenses
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
class OrLicense < AndLicense
|
|
115
|
+
def self.operator
|
|
116
|
+
' OR '
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def initialize(name)
|
|
120
|
+
super(name, OrLicense.operator)
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
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,79 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module LicenseFinder
|
|
4
|
+
class ManualLicenses
|
|
5
|
+
def initialize
|
|
6
|
+
@all_versions = {}
|
|
7
|
+
@specific_versions = {}
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def licenses_of(name, version = nil)
|
|
11
|
+
return @all_versions[name] if @all_versions[name]
|
|
12
|
+
|
|
13
|
+
if version && @specific_versions[name] && @specific_versions[name][version]
|
|
14
|
+
@specific_versions[name][version]
|
|
15
|
+
else
|
|
16
|
+
Set.new
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def assign_to_all_versions(name, lic)
|
|
21
|
+
# Ex: licenses add foo_gem MIT => Adds MIT at "all" versions for this gem
|
|
22
|
+
|
|
23
|
+
@all_versions[name] ||= Set.new
|
|
24
|
+
@all_versions[name] << to_license(lic)
|
|
25
|
+
|
|
26
|
+
@specific_versions.delete(name)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def assign_to_specific_versions(name, lic, versions)
|
|
30
|
+
# Ex: licenses add foo_gem MIT --version=1.0 => Adds MIT at only 1.0 for this gem
|
|
31
|
+
|
|
32
|
+
@specific_versions[name] ||= {}
|
|
33
|
+
versions.each do |version|
|
|
34
|
+
@specific_versions[name][version] ||= Set.new
|
|
35
|
+
@specific_versions[name][version] << to_license(lic)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
@all_versions.delete(name)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def unassign_from_all_versions(name, lic = nil)
|
|
42
|
+
if lic
|
|
43
|
+
# Ex: licenses remove foo_gem MIT => Removes MIT at all versions for this gem
|
|
44
|
+
@all_versions[name]&.delete(to_license(lic))
|
|
45
|
+
|
|
46
|
+
@specific_versions[name]&.each_value do |licenses|
|
|
47
|
+
licenses.delete(to_license(lic))
|
|
48
|
+
end
|
|
49
|
+
else
|
|
50
|
+
# Ex: licenses remove foo_gem => Removes all licenses for all versions of the gem
|
|
51
|
+
@all_versions.delete(name)
|
|
52
|
+
@specific_versions.delete(name)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def unassign_from_specific_versions(name, lic, versions)
|
|
57
|
+
return unless @specific_versions[name]
|
|
58
|
+
|
|
59
|
+
versions.each do |version|
|
|
60
|
+
if @specific_versions[name][version]
|
|
61
|
+
if lic
|
|
62
|
+
# Ex: licenses remove foo_gem MIT --version=1.0 => Removes MIT at only 1.0 for this gem
|
|
63
|
+
@specific_versions[name][version].delete(to_license(lic))
|
|
64
|
+
@specific_versions[name].delete(version) if @specific_versions[name][version].empty?
|
|
65
|
+
else
|
|
66
|
+
# Ex: licenses remove foo_gem --version=1.0 => Removes all licenses at only 1.0 for the gem
|
|
67
|
+
@specific_versions[name].delete(version)
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
private
|
|
74
|
+
|
|
75
|
+
def to_license(lic)
|
|
76
|
+
License.find_by_name(lic)
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
@@ -0,0 +1,195 @@
|
|
|
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, :name, :version, :authors, :summary, :description, :children, :parents, :groups, :manual_approval, :license_names_from_spec, :install_path
|
|
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
|
+
## APPROVAL
|
|
68
|
+
|
|
69
|
+
def approved_manually!(approval)
|
|
70
|
+
@manual_approval = approval
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def approved_manually?
|
|
74
|
+
!@manual_approval.nil?
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def approved?
|
|
78
|
+
# Question: is `!restricted?` redundant?
|
|
79
|
+
# DecisionApplier does not call `permitted!` or `approved_manually!`
|
|
80
|
+
# if a Package has been restricted.
|
|
81
|
+
(approved_manually? || permitted?) && !restricted?
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def permitted!
|
|
85
|
+
@permitted = true
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def permitted?
|
|
89
|
+
@permitted
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def restricted!
|
|
93
|
+
@restricted = true
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def restricted?
|
|
97
|
+
@restricted
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
## EQUALITY
|
|
101
|
+
|
|
102
|
+
def <=>(other)
|
|
103
|
+
eq_name = name <=> other.name
|
|
104
|
+
return eq_name unless eq_name.zero?
|
|
105
|
+
|
|
106
|
+
version <=> other.version
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def eql?(other)
|
|
110
|
+
name == other.name && version == other.version
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def hash
|
|
114
|
+
[name, version].hash
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
## LICENSING # stubbed in tests, otherwise private # checked in tests, otherwise private
|
|
118
|
+
|
|
119
|
+
def licenses
|
|
120
|
+
@licenses ||= activations.map(&:license).sort_by(&:name).to_set
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def activations
|
|
124
|
+
licensing.activations.tap do |activations|
|
|
125
|
+
activations.each { |activation| log_activation activation }
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def licensing
|
|
130
|
+
Licensing.new(self, @decided_licenses, licenses_from_spec, license_files)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def decide_on_license(license)
|
|
134
|
+
@decided_licenses << license
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def licenses_from_spec
|
|
138
|
+
license_names_from_spec
|
|
139
|
+
.map { |name| License.find_by_name(name) }
|
|
140
|
+
.to_set
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def license_files
|
|
144
|
+
LicenseFiles.find(install_path, logger: logger)
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def notice_files
|
|
148
|
+
NoticeFiles.find(install_path, logger: logger)
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def package_manager
|
|
152
|
+
'unknown'
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def missing?
|
|
156
|
+
@missing
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def log_activation(activation)
|
|
160
|
+
preamble = format('package %s:', activation.package.name)
|
|
161
|
+
if activation.sources.empty?
|
|
162
|
+
logger.debug activation.package.class, format('%s no licenses found', preamble)
|
|
163
|
+
else
|
|
164
|
+
activation.sources.each do |source|
|
|
165
|
+
logger.debug activation.package.class, format("%s found license '%s' %s", preamble, activation.license.name, source)
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
require 'license_finder/packages/manual_package'
|
|
173
|
+
require 'license_finder/packages/bower_package'
|
|
174
|
+
require 'license_finder/packages/go_package'
|
|
175
|
+
require 'license_finder/packages/bundler_package'
|
|
176
|
+
require 'license_finder/packages/pip_package'
|
|
177
|
+
require 'license_finder/packages/npm_package'
|
|
178
|
+
require 'license_finder/packages/maven_package'
|
|
179
|
+
require 'license_finder/packages/gradle_package'
|
|
180
|
+
require 'license_finder/packages/cocoa_pods_package'
|
|
181
|
+
require 'license_finder/packages/carthage_package'
|
|
182
|
+
require 'license_finder/packages/spm_package'
|
|
183
|
+
require 'license_finder/packages/rebar_package'
|
|
184
|
+
require 'license_finder/packages/erlangmk_package'
|
|
185
|
+
require 'license_finder/packages/mix_package'
|
|
186
|
+
require 'license_finder/packages/merged_package'
|
|
187
|
+
require 'license_finder/packages/nuget_package'
|
|
188
|
+
require 'license_finder/packages/conan_package'
|
|
189
|
+
require 'license_finder/packages/yarn_package'
|
|
190
|
+
require 'license_finder/packages/pnpm_package'
|
|
191
|
+
require 'license_finder/packages/sbt_package'
|
|
192
|
+
require 'license_finder/packages/cargo_package'
|
|
193
|
+
require 'license_finder/packages/composer_package'
|
|
194
|
+
require 'license_finder/packages/conda_package'
|
|
195
|
+
require 'license_finder/packages/pubspec_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.instance_of?(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
|