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,221 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'license_finder/report'
|
|
4
|
+
require 'license_finder/version'
|
|
5
|
+
require 'license_finder/diff'
|
|
6
|
+
require 'license_finder/package_delta'
|
|
7
|
+
require 'license_finder/license_aggregator'
|
|
8
|
+
require 'license_finder/project_finder'
|
|
9
|
+
require 'license_finder/logger'
|
|
10
|
+
|
|
11
|
+
module LicenseFinder
|
|
12
|
+
module CLI
|
|
13
|
+
class Main < Base
|
|
14
|
+
extend Rootcommand
|
|
15
|
+
|
|
16
|
+
FORMATS = {
|
|
17
|
+
'text' => TextReport,
|
|
18
|
+
'html' => HtmlReport,
|
|
19
|
+
'markdown' => MarkdownReport,
|
|
20
|
+
'csv' => CsvReport,
|
|
21
|
+
'xml' => XmlReport,
|
|
22
|
+
'json' => JsonReport,
|
|
23
|
+
'junit' => JunitReport
|
|
24
|
+
}.freeze
|
|
25
|
+
|
|
26
|
+
class_option :go_full_version, desc: 'Whether dependency version should include full version. Only meaningful if used with a Go project. Defaults to false.'
|
|
27
|
+
class_option :gradle_include_groups, desc: 'Whether dependency name should include group id. Only meaningful if used with a Java/gradle project. Defaults to false.'
|
|
28
|
+
class_option :gradle_command,
|
|
29
|
+
desc: "Command to use when fetching gradle packages. Only meaningful if used with a Java/gradle project.
|
|
30
|
+
Defaults to 'gradlew' / 'gradlew.bat' if the wrapper is present, otherwise to 'gradle'."
|
|
31
|
+
class_option :maven_include_groups, desc: 'Whether dependency name should include group id. Only meaningful if used with a Java/maven project. Defaults to false.'
|
|
32
|
+
class_option :maven_options, desc: 'Maven options to append to command. Defaults to empty.'
|
|
33
|
+
class_option :npm_options, desc: 'npm options to append to command. Defaults to empty.'
|
|
34
|
+
class_option :pip_requirements_path, desc: 'Path to python requirements file. Defaults to requirements.txt.'
|
|
35
|
+
class_option :python_version, desc: 'Python version to invoke pip with. Valid versions: 2 or 3. Default: 2'
|
|
36
|
+
class_option :rebar_command, desc: "Command to use when fetching rebar packages. Only meaningful if used with a Erlang/rebar project. Defaults to 'rebar'."
|
|
37
|
+
class_option :rebar_deps_dir, desc: "Path to rebar dependencies directory. Only meaningful if used with a Erlang/rebar project. Defaults to 'deps'."
|
|
38
|
+
class_option :elixir_command, desc: "Command to use when parsing package metadata for Mix. Only meaningful if used with a Mix project (i.e., Elixir or Erlang). Defaults to 'elixir'."
|
|
39
|
+
class_option :mix_command, desc: "Command to use when fetching packages through Mix. Only meaningful if used with a Mix project (i.e., Elixir or Erlang). Defaults to 'mix'."
|
|
40
|
+
class_option :mix_deps_dir, desc: "Path to Mix dependencies directory. Only meaningful if used with a Mix project (i.e., Elixir or Erlang). Defaults to 'deps'."
|
|
41
|
+
class_option :sbt_include_groups, desc: 'Whether dependency name should include group id. Only meaningful if used with a Scala/sbt project. Defaults to false.'
|
|
42
|
+
class_option :conda_bash_setup_script, desc: "Path to conda.sh script. Only meaningful if used with a Conda project. Defaults to '~/miniconda3/etc/profile.d/conda.sh'."
|
|
43
|
+
class_option :composer_check_require_only,
|
|
44
|
+
desc: "Whether to only check for licenses from dependencies on the 'require' section. Only meaningful if used with a Composer project. Defaults to false."
|
|
45
|
+
|
|
46
|
+
# Method options which are shared between report and action_item
|
|
47
|
+
def self.format_option
|
|
48
|
+
method_option :format,
|
|
49
|
+
desc: 'Emit detailed info about what LicenseFinder is doing',
|
|
50
|
+
default: 'text',
|
|
51
|
+
enum: FORMATS.keys
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def self.shared_options
|
|
55
|
+
method_option :debug,
|
|
56
|
+
aliases: '-d',
|
|
57
|
+
type: :boolean,
|
|
58
|
+
desc: 'Emit detailed info about what LicenseFinder is doing'
|
|
59
|
+
|
|
60
|
+
method_option :prepare,
|
|
61
|
+
aliases: '-p',
|
|
62
|
+
type: :boolean,
|
|
63
|
+
desc: 'Prepares the project first for license_finder',
|
|
64
|
+
default: false,
|
|
65
|
+
required: false
|
|
66
|
+
|
|
67
|
+
method_option :prepare_no_fail,
|
|
68
|
+
type: :boolean,
|
|
69
|
+
desc: 'Prepares the project first for license_finder but carries on despite any potential failures',
|
|
70
|
+
default: false,
|
|
71
|
+
required: false
|
|
72
|
+
|
|
73
|
+
method_option :recursive,
|
|
74
|
+
aliases: '-r',
|
|
75
|
+
type: :boolean,
|
|
76
|
+
default: false,
|
|
77
|
+
desc: 'Recursively runs License Finder on all sub-projects'
|
|
78
|
+
|
|
79
|
+
method_option :aggregate_paths,
|
|
80
|
+
aliases: '-a',
|
|
81
|
+
type: :array,
|
|
82
|
+
desc: "Generate a single report for multiple projects. Ex: --aggregate_paths='path/to/project1' 'path/to/project2'"
|
|
83
|
+
|
|
84
|
+
method_option :quiet,
|
|
85
|
+
aliases: '-q',
|
|
86
|
+
type: :boolean,
|
|
87
|
+
desc: 'Silences progress report',
|
|
88
|
+
required: false
|
|
89
|
+
|
|
90
|
+
method_option :columns,
|
|
91
|
+
desc: "For text or CSV reports, which columns to print. Pick from: #{CsvReport::AVAILABLE_COLUMNS}",
|
|
92
|
+
type: :array
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
desc 'project_roots', 'List project directories to be scanned'
|
|
96
|
+
shared_options
|
|
97
|
+
def project_roots
|
|
98
|
+
config.strict_matching = true
|
|
99
|
+
project_path = config.project_path.to_s || Pathname.pwd.to_s
|
|
100
|
+
paths = aggregate_paths
|
|
101
|
+
filtered_project_roots = Scanner.remove_subprojects(paths)
|
|
102
|
+
|
|
103
|
+
filtered_project_roots << project_path if aggregate_paths.include?(project_path) && !filtered_project_roots.include?(project_path)
|
|
104
|
+
|
|
105
|
+
say(filtered_project_roots)
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
desc 'action_items', 'List unapproved dependencies (the default action for `license_finder`)'
|
|
109
|
+
shared_options
|
|
110
|
+
format_option
|
|
111
|
+
def action_items
|
|
112
|
+
finder = LicenseAggregator.new(config, aggregate_paths)
|
|
113
|
+
any_packages = finder.any_packages?
|
|
114
|
+
unapproved = finder.unapproved
|
|
115
|
+
restricted = finder.restricted
|
|
116
|
+
|
|
117
|
+
# Ensure to start output on a new line even with dot progress indicators.
|
|
118
|
+
say "\n"
|
|
119
|
+
|
|
120
|
+
unless any_packages
|
|
121
|
+
say 'No dependencies recognized!', :red
|
|
122
|
+
exit 0
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
if unapproved.empty?
|
|
126
|
+
say 'All dependencies are approved for use', :green
|
|
127
|
+
else
|
|
128
|
+
unless restricted.empty?
|
|
129
|
+
say 'Restricted dependencies:', :red
|
|
130
|
+
say report_of(restricted)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
other_unapproved = unapproved - restricted
|
|
134
|
+
unless other_unapproved.empty?
|
|
135
|
+
say 'Dependencies that need approval:', :yellow
|
|
136
|
+
say report_of(other_unapproved)
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
exit 1
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
default_task :action_items
|
|
144
|
+
|
|
145
|
+
desc 'report', "Print a report of the project's dependencies to stdout"
|
|
146
|
+
shared_options
|
|
147
|
+
format_option
|
|
148
|
+
method_option :write_headers, type: :boolean, desc: 'Write exported columns as header row (csv).', default: false, required: false
|
|
149
|
+
method_option :save, desc: "Save report to a file. Default: 'license_report.csv' in project root.", lazy_default: 'license_report'
|
|
150
|
+
|
|
151
|
+
def report
|
|
152
|
+
finder = LicenseAggregator.new(config, aggregate_paths)
|
|
153
|
+
report = report_of(finder.dependencies)
|
|
154
|
+
save? ? save_report(report, config.save_file) : say(report)
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
desc 'version', 'Print the version of LicenseFinder'
|
|
158
|
+
def version
|
|
159
|
+
puts LicenseFinder::VERSION
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
desc 'diff OLDFILE NEWFILE', 'Command to view the differences between two generated reports (csv).'
|
|
163
|
+
format_option
|
|
164
|
+
method_option :save, desc: "Save report to a file. Default: 'license_report.csv' in project root.", lazy_default: 'license_report'
|
|
165
|
+
def diff(file1, file2)
|
|
166
|
+
f1 = IO.read(file1)
|
|
167
|
+
f2 = IO.read(file2)
|
|
168
|
+
report = DiffReport.new(Diff.compare(f1, f2))
|
|
169
|
+
save? ? save_report(report, config.save_file) : say(report)
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
subcommand 'dependencies', Dependencies, 'Add or remove dependencies that your package managers are not aware of'
|
|
173
|
+
subcommand 'licenses', Licenses, "Set a dependency's licenses, if the licenses found by license_finder are missing or wrong"
|
|
174
|
+
subcommand 'approvals', Approvals, 'Manually approve dependencies, even if their licenses are not permitted'
|
|
175
|
+
subcommand 'ignored_groups', IgnoredGroups, 'Exclude test and development dependencies from action items and reports'
|
|
176
|
+
subcommand 'ignored_dependencies', IgnoredDependencies, 'Exclude individual dependencies from action items and reports'
|
|
177
|
+
subcommand 'permitted_licenses', PermittedLicenses, 'Automatically approve any dependency that has a permitted license'
|
|
178
|
+
subcommand 'restricted_licenses', RestrictedLicenses, 'Forbid approval of any dependency whose licenses are all restricted'
|
|
179
|
+
subcommand 'project_name', ProjectName, 'Set the project name, for display in reports'
|
|
180
|
+
subcommand 'inherited_decisions', InheritedDecisions, 'Add or remove decision files you want to inherit from'
|
|
181
|
+
|
|
182
|
+
private
|
|
183
|
+
|
|
184
|
+
def check_valid_project_path
|
|
185
|
+
raise "Project path '#{config.project_path}' does not exist!" unless config.valid_project_path?
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
def aggregate_paths
|
|
189
|
+
check_valid_project_path
|
|
190
|
+
aggregate_paths = config.aggregate_paths
|
|
191
|
+
project_path = config.project_path.to_s || Pathname.pwd.to_s
|
|
192
|
+
aggregate_paths = ProjectFinder.new(project_path, config.strict_matching).find_projects if config.recursive
|
|
193
|
+
|
|
194
|
+
if aggregate_paths.nil? || aggregate_paths.empty?
|
|
195
|
+
[project_path]
|
|
196
|
+
else
|
|
197
|
+
aggregate_paths
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
def save_report(content, file_name)
|
|
202
|
+
dir = File.dirname(file_name)
|
|
203
|
+
FileUtils.mkdir_p(dir) unless Dir.exist?(dir)
|
|
204
|
+
|
|
205
|
+
File.open(file_name, 'w') do |f|
|
|
206
|
+
f.write(content)
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
def report_of(content)
|
|
211
|
+
report = FORMATS[config.format] || FORMATS['text']
|
|
212
|
+
report = MergedReport if report == CsvReport && config.aggregate_paths
|
|
213
|
+
report.of(content, columns: config.columns, project_name: decisions.project_name || config.project_path.basename.to_s, write_headers: config.write_headers)
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
def save?
|
|
217
|
+
!!config.save_file
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module LicenseFinder
|
|
4
|
+
module CLI
|
|
5
|
+
module MakesDecisions
|
|
6
|
+
def self.included(mod)
|
|
7
|
+
mod.extend(ClassMethods)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
module ClassMethods
|
|
11
|
+
def auditable
|
|
12
|
+
method_option :who, desc: 'The person making this decision'
|
|
13
|
+
method_option :why, desc: 'The reason for making this decision'
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def approvable
|
|
17
|
+
method_option :version, desc: 'The version that will be approved'
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
def txn
|
|
24
|
+
@txn ||= {
|
|
25
|
+
who: options[:who],
|
|
26
|
+
why: options[:why],
|
|
27
|
+
versions: options[:version] ? [options[:version]] : [],
|
|
28
|
+
when: Time.now.getutc
|
|
29
|
+
}
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def modifying
|
|
33
|
+
yield
|
|
34
|
+
decisions.save!(config.decisions_file_path)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module LicenseFinder
|
|
4
|
+
module CLI
|
|
5
|
+
module Rootcommand
|
|
6
|
+
# Helper to auto-generate the documentation for a group of commands
|
|
7
|
+
def subcommand(namespace, klass, namespace_description)
|
|
8
|
+
description = "#{namespace} [#{(klass.tasks.keys - ['help']).join('|')}]"
|
|
9
|
+
desc description, "#{namespace_description} - see `license_finder #{namespace} help` for more information"
|
|
10
|
+
super namespace, klass
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Thor fix for `license_finder <subcommand> help <action>`
|
|
15
|
+
module Subcommand
|
|
16
|
+
# Hack to override the help message produced by Thor.
|
|
17
|
+
# https://github.com/wycats/thor/issues/261#issuecomment-16880836
|
|
18
|
+
def banner(command, _namespace = nil, _subcommand = nil)
|
|
19
|
+
"#{basename} #{underscore_name(name)} #{command.usage}"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
protected
|
|
23
|
+
|
|
24
|
+
def underscore_name(name)
|
|
25
|
+
underscored = name.split('::').last
|
|
26
|
+
underscored.gsub!(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
|
27
|
+
underscored.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
|
|
28
|
+
underscored.tr!('-', '_')
|
|
29
|
+
underscored.downcase
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module LicenseFinder
|
|
4
|
+
module CLI
|
|
5
|
+
class PermittedLicenses < Base
|
|
6
|
+
extend Subcommand
|
|
7
|
+
include MakesDecisions
|
|
8
|
+
|
|
9
|
+
desc 'list', 'List all the permitted licenses'
|
|
10
|
+
def list
|
|
11
|
+
say 'Permitted Licenses:', :blue
|
|
12
|
+
say_each(decisions.permitted, &:name)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
auditable
|
|
16
|
+
desc 'add LICENSE...', 'Add one or more licenses to the permitted licenses'
|
|
17
|
+
def add(*licenses)
|
|
18
|
+
assert_some licenses
|
|
19
|
+
modifying { licenses.each { |l| decisions.permit(l, txn) } }
|
|
20
|
+
say "Added #{licenses.join(', ')} to the permitted licenses"
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
auditable
|
|
24
|
+
desc 'remove LICENSE...', 'Remove one or more licenses from the permitted licenses'
|
|
25
|
+
def remove(*licenses)
|
|
26
|
+
assert_some licenses
|
|
27
|
+
modifying { licenses.each { |l| decisions.unpermit(l, txn) } }
|
|
28
|
+
say "Removed #{licenses.join(', ')} from the license permitted licenses"
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module LicenseFinder
|
|
4
|
+
module CLI
|
|
5
|
+
class ProjectName < Base
|
|
6
|
+
extend Subcommand
|
|
7
|
+
include MakesDecisions
|
|
8
|
+
|
|
9
|
+
desc 'show', 'Show the project name'
|
|
10
|
+
def show
|
|
11
|
+
say 'Project Name:', :blue
|
|
12
|
+
say decisions.project_name
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
auditable
|
|
16
|
+
desc 'add NAME', 'Set the project name'
|
|
17
|
+
def add(name)
|
|
18
|
+
modifying { decisions.name_project(name, txn) }
|
|
19
|
+
|
|
20
|
+
say "Set the project name to #{name}", :green
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
auditable
|
|
24
|
+
desc 'remove', 'Remove the project name'
|
|
25
|
+
def remove
|
|
26
|
+
modifying { decisions.unname_project(txn) }
|
|
27
|
+
|
|
28
|
+
say 'Removed the project name'
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module LicenseFinder
|
|
4
|
+
module CLI
|
|
5
|
+
class RestrictedLicenses < Base
|
|
6
|
+
extend Subcommand
|
|
7
|
+
include MakesDecisions
|
|
8
|
+
|
|
9
|
+
desc 'list', 'List all the restricted licenses'
|
|
10
|
+
def list
|
|
11
|
+
say 'Restricted Licenses:', :blue
|
|
12
|
+
say_each(decisions.restricted, &:name)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
auditable
|
|
16
|
+
desc 'add LICENSE...', 'Add one or more licenses to the restricted licenses'
|
|
17
|
+
def add(*licenses)
|
|
18
|
+
assert_some licenses
|
|
19
|
+
modifying { licenses.each { |l| decisions.restrict(l, txn) } }
|
|
20
|
+
say "Added #{licenses.join(', ')} to the restricted licenses"
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
auditable
|
|
24
|
+
desc 'remove LICENSE...', 'Remove one or more licenses from the restricted licenses'
|
|
25
|
+
def remove(*licenses)
|
|
26
|
+
assert_some licenses
|
|
27
|
+
modifying { licenses.each { |l| decisions.unrestrict(l, txn) } }
|
|
28
|
+
say "Removed #{licenses.join(', ')} from the restricted licenses"
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module LicenseFinder
|
|
4
|
+
module CLI
|
|
5
|
+
end
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
require 'license_finder/cli/patched_thor'
|
|
9
|
+
require 'license_finder/cli/base'
|
|
10
|
+
require 'license_finder/cli/makes_decisions'
|
|
11
|
+
require 'license_finder/cli/inherited_decisions'
|
|
12
|
+
require 'license_finder/cli/permitted_licenses'
|
|
13
|
+
require 'license_finder/cli/restricted_licenses'
|
|
14
|
+
require 'license_finder/cli/dependencies'
|
|
15
|
+
require 'license_finder/cli/licenses'
|
|
16
|
+
require 'license_finder/cli/approvals'
|
|
17
|
+
require 'license_finder/cli/ignored_groups'
|
|
18
|
+
require 'license_finder/cli/ignored_dependencies'
|
|
19
|
+
require 'license_finder/cli/project_name'
|
|
20
|
+
require 'license_finder/cli/main'
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'platform'
|
|
4
|
+
|
|
5
|
+
module LicenseFinder
|
|
6
|
+
class Configuration
|
|
7
|
+
def self.with_optional_saved_config(primary_config)
|
|
8
|
+
project_path = Pathname(primary_config.fetch(:project_path, Pathname.pwd)).expand_path
|
|
9
|
+
config_file = project_path.join('config', 'license_finder.yml')
|
|
10
|
+
saved_config = config_file.exist? ? YAML.safe_load(config_file.read) : {}
|
|
11
|
+
new(primary_config, saved_config)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def initialize(primary_config, saved_config)
|
|
15
|
+
@primary_config = primary_config
|
|
16
|
+
@saved_config = saved_config
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def valid_project_path?
|
|
20
|
+
return project_path.exist? if get(:project_path)
|
|
21
|
+
|
|
22
|
+
true
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def elixir_command
|
|
26
|
+
get(:elixir_command) || 'elixir'
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def mix_command
|
|
30
|
+
get(:mix_command) || 'mix'
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def merge(other_hash)
|
|
34
|
+
dup_with other_hash
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def rebar_deps_dir
|
|
38
|
+
path = get(:rebar_deps_dir) || '_build/default/lib'
|
|
39
|
+
project_path.join(path).expand_path
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def mix_deps_dir
|
|
43
|
+
path = get(:mix_deps_dir) || 'deps'
|
|
44
|
+
project_path.join(path).expand_path
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def decisions_file_path
|
|
48
|
+
path = File.join(project_path, 'doc/dependency_decisions.yml') unless project_path.nil?
|
|
49
|
+
path = get(:decisions_file) unless get(:decisions_file).nil?
|
|
50
|
+
path = 'doc/dependency_decisions.yml' if path.nil?
|
|
51
|
+
Pathname.new(path)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def log_directory
|
|
55
|
+
path = get(:log_directory) || 'lf_logs'
|
|
56
|
+
|
|
57
|
+
if (aggregate_paths || recursive) && project_path == ''
|
|
58
|
+
Pathname(path).expand_path
|
|
59
|
+
else
|
|
60
|
+
project_path.join(path).expand_path
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def project_path
|
|
65
|
+
Pathname(path_prefix).expand_path
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def enabled_package_manager_ids
|
|
69
|
+
get(:enabled_package_managers)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def logger_mode
|
|
73
|
+
get(:logger)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def gradle_command
|
|
77
|
+
get(:gradle_command)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def go_full_version
|
|
81
|
+
get(:go_full_version)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def gradle_include_groups
|
|
85
|
+
get(:gradle_include_groups)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def maven_include_groups
|
|
89
|
+
get(:maven_include_groups)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def maven_options
|
|
93
|
+
get(:maven_options)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def npm_options
|
|
97
|
+
get(:npm_options)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def pip_requirements_path
|
|
101
|
+
get(:pip_requirements_path)
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def conda_bash_setup_script
|
|
105
|
+
get(:conda_bash_setup_script)
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def python_version
|
|
109
|
+
get(:python_version)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def rebar_command
|
|
113
|
+
get(:rebar_command)
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def prepare
|
|
117
|
+
get(:prepare) || prepare_no_fail
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def prepare_no_fail
|
|
121
|
+
get(:prepare_no_fail)
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def write_headers
|
|
125
|
+
get(:write_headers)
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def save_file
|
|
129
|
+
get(:save)
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def aggregate_paths
|
|
133
|
+
get(:aggregate_paths)
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def recursive
|
|
137
|
+
get(:recursive)
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def format
|
|
141
|
+
get(:format)
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def columns
|
|
145
|
+
get(:columns)
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def sbt_include_groups
|
|
149
|
+
get(:sbt_include_groups)
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def composer_check_require_only
|
|
153
|
+
get(:composer_check_require_only)
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
attr_writer :strict_matching
|
|
157
|
+
|
|
158
|
+
attr_reader :strict_matching
|
|
159
|
+
|
|
160
|
+
protected
|
|
161
|
+
|
|
162
|
+
attr_accessor :primary_config
|
|
163
|
+
def dup_with(other_hash)
|
|
164
|
+
dup.tap do |dup|
|
|
165
|
+
dup.primary_config.merge!(other_hash)
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
private
|
|
170
|
+
|
|
171
|
+
attr_reader :saved_config
|
|
172
|
+
|
|
173
|
+
def get(key)
|
|
174
|
+
@primary_config[key.to_sym] || @saved_config[key.to_s]
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def initialize_copy(orig)
|
|
178
|
+
super
|
|
179
|
+
@primary_config = @primary_config.dup
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def path_prefix
|
|
183
|
+
get(:project_path) || ''
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
end
|