license_finder 1.2 → 2.0.0.rc2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +2 -1
- data/CHANGELOG.rdoc +27 -0
- data/CONTRIBUTING.md +38 -0
- data/README.md +139 -159
- data/Rakefile +17 -13
- data/features/features/cli_spec.rb +43 -0
- data/features/features/configure/add_dependencies_spec.rb +37 -0
- data/features/features/configure/approve_dependencies_spec.rb +30 -0
- data/features/features/configure/assign_licenses_spec.rb +20 -0
- data/features/features/configure/ignore_dependencies_spec.rb +35 -0
- data/features/features/configure/ignore_groups_spec.rb +31 -0
- data/features/features/configure/name_project_spec.rb +32 -0
- data/features/features/configure/whitelist_licenses_spec.rb +40 -0
- data/features/features/package_managers/bower_spec.rb +14 -0
- data/features/features/package_managers/cocoapods_spec.rb +14 -0
- data/features/features/package_managers/gradle_spec.rb +14 -0
- data/features/features/package_managers/maven_spec.rb +14 -0
- data/features/features/package_managers/npm_spec.rb +14 -0
- data/features/features/package_managers/pip_spec.rb +14 -0
- data/features/features/report/csv_spec.rb +17 -0
- data/features/features/report/html_spec.rb +50 -0
- data/{spec → features}/fixtures/Podfile +0 -0
- data/{spec → features}/fixtures/build.gradle +0 -0
- data/{spec → features}/fixtures/pom.xml +0 -0
- data/features/support/testing_dsl.rb +295 -0
- data/lib/license_finder.rb +16 -50
- data/lib/license_finder/cli.rb +13 -253
- data/lib/license_finder/cli/approvals.rb +26 -0
- data/lib/license_finder/cli/base.rb +20 -0
- data/lib/license_finder/cli/dependencies.rb +39 -0
- data/lib/license_finder/cli/ignored_dependencies.rb +30 -0
- data/lib/license_finder/cli/ignored_groups.rb +30 -0
- data/lib/license_finder/cli/licenses.rb +24 -0
- data/lib/license_finder/cli/main.rb +82 -0
- data/lib/license_finder/cli/makes_decisions.rb +48 -0
- data/lib/license_finder/cli/patched_thor.rb +34 -0
- data/lib/license_finder/cli/project_name.rb +31 -0
- data/lib/license_finder/cli/whitelist.rb +32 -0
- data/lib/license_finder/configuration.rb +14 -145
- data/lib/license_finder/decision_applier.rb +46 -0
- data/lib/license_finder/decisions.rb +174 -0
- data/lib/license_finder/license.rb +13 -32
- data/lib/license_finder/license/definitions.rb +15 -13
- data/lib/license_finder/license/template.rb +1 -1
- data/lib/{data/licenses → license_finder/license/templates}/Apache2.txt +0 -0
- data/lib/{data/licenses → license_finder/license/templates}/BSD.txt +0 -0
- data/lib/{data/licenses → license_finder/license/templates}/GPLv2.txt +0 -0
- data/lib/{data/licenses → license_finder/license/templates}/ISC.txt +0 -0
- data/lib/{data/licenses → license_finder/license/templates}/LGPL.txt +0 -0
- data/lib/{data/licenses → license_finder/license/templates}/MIT.txt +0 -0
- data/lib/{data/licenses → license_finder/license/templates}/NewBSD.txt +0 -0
- data/lib/{data/licenses → license_finder/license/templates}/Python.txt +0 -0
- data/lib/{data/licenses → license_finder/license/templates}/Ruby.txt +0 -0
- data/lib/{data/licenses → license_finder/license/templates}/SimplifiedBSD.txt +0 -0
- data/lib/license_finder/package.rb +77 -7
- data/lib/license_finder/package_manager.rb +43 -0
- data/lib/license_finder/package_managers/bower.rb +1 -1
- data/lib/license_finder/package_managers/bower_package.rb +23 -44
- data/lib/license_finder/package_managers/bundler.rb +4 -7
- data/lib/license_finder/package_managers/bundler_package.rb +14 -31
- data/lib/license_finder/package_managers/cocoa_pods.rb +1 -1
- data/lib/license_finder/package_managers/cocoa_pods_package.rb +2 -10
- data/lib/license_finder/package_managers/gradle.rb +6 -2
- data/lib/license_finder/package_managers/gradle_package.rb +6 -30
- data/lib/license_finder/package_managers/manual_package.rb +25 -0
- data/lib/license_finder/package_managers/maven_package.rb +8 -37
- data/lib/license_finder/package_managers/npm.rb +16 -4
- data/lib/license_finder/package_managers/npm_package.rb +12 -43
- data/lib/license_finder/package_managers/pip_package.rb +17 -37
- data/lib/license_finder/platform.rb +0 -16
- data/lib/license_finder/possible_license_file.rb +9 -14
- data/lib/license_finder/possible_license_files.rb +1 -5
- data/lib/license_finder/report.rb +26 -0
- data/lib/license_finder/reports/csv_report.rb +58 -0
- data/lib/license_finder/reports/erb_report.rb +61 -0
- data/lib/license_finder/reports/html_report.rb +10 -1
- data/lib/license_finder/reports/markdown_report.rb +7 -1
- data/lib/license_finder/reports/templates/bootstrap.css +9 -0
- data/lib/license_finder/reports/templates/html_report.erb +105 -0
- data/lib/{templates → license_finder/reports/templates}/markdown_report.erb +7 -7
- data/lib/license_finder/reports/text_report.rb +5 -3
- data/lib/license_finder/version.rb +3 -0
- data/license_finder.gemspec +2 -6
- data/release/instructions.md +8 -0
- data/spec/feature_helper.rb +11 -0
- data/spec/fixtures/config/license_finder.yml +3 -0
- data/spec/fixtures/{nested_readme/vendor/README → license_directory/LICENSE/Apache.txt} +0 -0
- data/spec/lib/license_finder/cli/approvals_spec.rb +63 -0
- data/spec/lib/license_finder/cli/dependencies_spec.rb +59 -0
- data/spec/lib/license_finder/cli/ignored_dependencies_spec.rb +47 -0
- data/spec/lib/license_finder/cli/ignored_groups_spec.rb +40 -0
- data/spec/lib/license_finder/cli/licenses_spec.rb +60 -0
- data/spec/lib/license_finder/cli/main_spec.rb +110 -0
- data/spec/lib/license_finder/cli/project_name_spec.rb +40 -0
- data/spec/lib/license_finder/cli/whitelist_spec.rb +58 -0
- data/spec/lib/license_finder/configuration_spec.rb +46 -191
- data/spec/lib/license_finder/decision_applier_spec.rb +65 -0
- data/spec/lib/license_finder/decisions_spec.rb +347 -0
- data/spec/lib/license_finder/license/definitions_spec.rb +1 -7
- data/spec/lib/license_finder/license_spec.rb +2 -30
- data/spec/lib/license_finder/package_manager_spec.rb +22 -0
- data/spec/lib/license_finder/package_managers/bower_package_spec.rb +33 -66
- data/spec/lib/license_finder/package_managers/bundler_package_spec.rb +7 -71
- data/spec/lib/license_finder/package_managers/cocoa_pods_package_spec.rb +8 -11
- data/spec/lib/license_finder/package_managers/gradle_package_spec.rb +28 -32
- data/spec/lib/license_finder/package_managers/gradle_spec.rb +18 -23
- data/spec/lib/license_finder/package_managers/maven_package_spec.rb +20 -43
- data/spec/lib/license_finder/package_managers/npm_package_spec.rb +22 -73
- data/spec/lib/license_finder/package_managers/npm_spec.rb +18 -21
- data/spec/lib/license_finder/package_managers/pip_package_spec.rb +24 -63
- data/spec/lib/license_finder/package_spec.rb +121 -0
- data/spec/lib/license_finder/possible_license_file_spec.rb +2 -3
- data/spec/lib/license_finder/possible_license_files_spec.rb +18 -22
- data/spec/lib/license_finder/reports/csv_report_spec.rb +26 -0
- data/spec/lib/license_finder/reports/html_report_spec.rb +39 -22
- data/spec/lib/license_finder/reports/markdown_report_spec.rb +8 -16
- data/spec/lib/license_finder/reports/text_report_spec.rb +21 -12
- data/spec/spec_helper.rb +1 -4
- data/spec/support/shared_examples_for_package.rb +0 -11
- data/spec/support/shared_examples_for_package_manager.rb +1 -0
- data/spec/support/stdout_helpers.rb +4 -11
- metadata +73 -158
- data/db/migrate/201303290935_create_dependencies.rb +0 -14
- data/db/migrate/201303291155_create_licenses.rb +0 -13
- data/db/migrate/201303291402_create_approvals.rb +0 -13
- data/db/migrate/201303291456_create_ancestries.rb +0 -9
- data/db/migrate/201303291519_create_bundler_groups.rb +0 -13
- data/db/migrate/201303291720_move_manual_from_approvals_to_licenses.rb +0 -11
- data/db/migrate/201303291753_allow_null_license_names.rb +0 -7
- data/db/migrate/201304011027_allow_null_dependency_version.rb +0 -7
- data/db/migrate/201304020947_change_table_name_licenses_to_license_aliases.rb +0 -5
- data/db/migrate/201304181524_add_manual_to_dependencies.rb +0 -7
- data/db/migrate/201307250917_add_license_manual_to_dependencies.rb +0 -7
- data/db/migrate/201307251004_data_fix_manual_licenses.rb +0 -15
- data/db/migrate/201307251107_reassociate_license.rb +0 -23
- data/db/migrate/201307251340_remove_manual_from_license_aliases.rb +0 -7
- data/db/migrate/201311192002_add_manually_approved_to_dependencies.rb +0 -7
- data/db/migrate/201311192003_reassociate_manual_approval.rb +0 -13
- data/db/migrate/201311192010_drop_approvals.rb +0 -5
- data/db/migrate/201401302113_re_reassociate_license.rb +0 -23
- data/db/migrate/201403181732_rename_manual_fields.rb +0 -10
- data/db/migrate/201403190028_add_manual_approvals.rb +0 -22
- data/db/migrate/201403191419_add_timestamps_to_manual_approvals.rb +0 -15
- data/db/migrate/201403191645_remove_license_aliases.rb +0 -23
- data/db/migrate/201410031451_rename_dependency_license_name.rb +0 -6
- data/features/cli.feature +0 -37
- data/features/cocoapods_dependencies.feature +0 -10
- data/features/configure_bundler_groups.feature +0 -23
- data/features/configure_ignore_dependencies.feature +0 -16
- data/features/configure_project_name.feature +0 -10
- data/features/configure_whitelist.feature +0 -27
- data/features/gradle_dependencies.feature +0 -9
- data/features/manually_added.feature +0 -19
- data/features/manually_approved.feature +0 -10
- data/features/manually_assigned_license.feature +0 -16
- data/features/maven_dependencies.feature +0 -9
- data/features/multiple_licenses.feature +0 -9
- data/features/node_dependencies.feature +0 -9
- data/features/python_dependencies.feature +0 -9
- data/features/report_csv.feature +0 -15
- data/features/report_html.feature +0 -24
- data/features/step_definitions/cli_steps.rb +0 -51
- data/features/step_definitions/cocoapod_steps.rb +0 -8
- data/features/step_definitions/configure_bundler_groups_steps.rb +0 -30
- data/features/step_definitions/configure_ignore_dependencies.rb +0 -35
- data/features/step_definitions/configure_project_name_steps.rb +0 -3
- data/features/step_definitions/configure_whitelist_steps.rb +0 -45
- data/features/step_definitions/gradle_steps.rb +0 -8
- data/features/step_definitions/manually_added_steps.rb +0 -28
- data/features/step_definitions/manually_approved_steps.rb +0 -24
- data/features/step_definitions/manually_assigned_license_steps.rb +0 -34
- data/features/step_definitions/maven_steps.rb +0 -8
- data/features/step_definitions/multiple_licenses_steps.rb +0 -14
- data/features/step_definitions/node_steps.rb +0 -8
- data/features/step_definitions/python_steps.rb +0 -8
- data/features/step_definitions/report_csv_steps.rb +0 -20
- data/features/step_definitions/report_html_steps.rb +0 -60
- data/features/step_definitions/shared_steps.rb +0 -307
- data/lib/data/license_finder.example.yml +0 -12
- data/lib/license_finder/dependency_manager.rb +0 -92
- data/lib/license_finder/package_saver.rb +0 -44
- data/lib/license_finder/reports/dependency_report.rb +0 -34
- data/lib/license_finder/reports/detailed_text_report.rb +0 -19
- data/lib/license_finder/reports/formatted_report.rb +0 -40
- data/lib/license_finder/reports/reporter.rb +0 -27
- data/lib/license_finder/tables.rb +0 -9
- data/lib/license_finder/tables/bundler_group.rb +0 -7
- data/lib/license_finder/tables/dependency.rb +0 -113
- data/lib/license_finder/tables/manual_approval.rb +0 -13
- data/lib/license_finder/yml_to_sql.rb +0 -117
- data/lib/templates/html_report.erb +0 -117
- data/lib/templates/text_report.erb +0 -3
- data/release/gem_version.rb +0 -3
- data/release/manual_instructions.md +0 -29
- data/release/publish.sh +0 -32
- data/spec/fixtures/APACHE-2-LICENSE +0 -202
- data/spec/fixtures/GPLv2 +0 -339
- data/spec/fixtures/ISC-LICENSE +0 -10
- data/spec/fixtures/MIT-LICENSE +0 -22
- data/spec/fixtures/MIT-LICENSE-with-varied-disclaimer +0 -22
- data/spec/fixtures/README-with-MIT-LICENSE +0 -222
- data/spec/fixtures/license_directory/LICENSE/BSD-2-Clause.txt +0 -25
- data/spec/fixtures/license_directory/LICENSE/GPL-2.0.txt +0 -339
- data/spec/fixtures/license_directory/LICENSE/LICENSE +0 -191
- data/spec/fixtures/license_directory/LICENSE/MIT.txt +0 -21
- data/spec/fixtures/license_directory/LICENSE/RUBY.txt +0 -60
- data/spec/fixtures/mit_licensed_gem/LICENSE +0 -22
- data/spec/fixtures/other_licensed_gem/LICENSE +0 -3
- data/spec/fixtures/readme/Project ReadMe b/data/spec/fixtures/readme/Project → ReadMe +0 -0
- data/spec/fixtures/readme/README +0 -0
- data/spec/fixtures/readme/Readme.markdown +0 -0
- data/spec/lib/license_finder/cli_spec.rb +0 -298
- data/spec/lib/license_finder/dependency_manager_spec.rb +0 -198
- data/spec/lib/license_finder/package_saver_spec.rb +0 -82
- data/spec/lib/license_finder/reports/detailed_text_report_spec.rb +0 -33
- data/spec/lib/license_finder/reports/reporter_spec.rb +0 -33
- data/spec/lib/license_finder/tables/dependency_spec.rb +0 -196
- data/spec/lib/license_finder/yml_to_sql_spec.rb +0 -123
- data/spec/lib/license_finder_spec.rb +0 -16
@@ -0,0 +1,26 @@
|
|
1
|
+
module LicenseFinder
|
2
|
+
module CLI
|
3
|
+
class Approvals < Base
|
4
|
+
extend Subcommand
|
5
|
+
include MakesDecisions
|
6
|
+
|
7
|
+
auditable
|
8
|
+
desc "add DEPENDENCY...", "Approve one or more dependencies by name"
|
9
|
+
def add(name, *other_names)
|
10
|
+
names = modify_each(name, *other_names) do |name|
|
11
|
+
decisions.approve(name, txn)
|
12
|
+
end
|
13
|
+
|
14
|
+
say "The #{names.join(", ")} dependency has been approved!", :green
|
15
|
+
end
|
16
|
+
|
17
|
+
auditable
|
18
|
+
desc "remove DEPENDENCY", "Unapprove a dependency"
|
19
|
+
def remove(dep)
|
20
|
+
modifying { decisions.unapprove(dep, txn) }
|
21
|
+
|
22
|
+
say "The dependency #{dep} no longer has a manual approval"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module LicenseFinder
|
2
|
+
module CLI
|
3
|
+
class Base < Thor
|
4
|
+
class_option :decisions_file, desc: "Where decisions are saved. Defaults to doc/dependency_decisions.yml."
|
5
|
+
|
6
|
+
no_commands do
|
7
|
+
def decisions
|
8
|
+
@decisions ||= Decisions.saved!(config.decisions_file)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def config
|
15
|
+
@config ||= Configuration.with_optional_saved_config(options)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module LicenseFinder
|
2
|
+
module CLI
|
3
|
+
class Dependencies < Base
|
4
|
+
extend Subcommand
|
5
|
+
include MakesDecisions
|
6
|
+
|
7
|
+
method_option :approve, type: :boolean, desc: "Approve the added dependency"
|
8
|
+
auditable
|
9
|
+
desc "add DEPENDENCY LICENSE [VERSION] [--approve]", "Add a dependency that is not managed by a package manager, optionally approving it at the same time"
|
10
|
+
def add(name, license, version = nil)
|
11
|
+
modifying {
|
12
|
+
decisions.
|
13
|
+
add_package(name, version, txn).
|
14
|
+
license(name, license, txn)
|
15
|
+
decisions.approve(name, txn) if options[:approve]
|
16
|
+
}
|
17
|
+
if options[:approve]
|
18
|
+
say "The #{name} dependency has been added and approved!", :green
|
19
|
+
else
|
20
|
+
say "The #{name} dependency has been added!", :green
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
auditable
|
25
|
+
desc "remove DEPENDENCY", "Remove a dependency that is not managed by a package manager"
|
26
|
+
def remove(name)
|
27
|
+
modifying { decisions.remove_package(name, txn) }
|
28
|
+
|
29
|
+
say "The #{name} dependency has been removed.", :green
|
30
|
+
end
|
31
|
+
|
32
|
+
desc "list", "List manually added dependencies"
|
33
|
+
def list
|
34
|
+
say "Manually Added Dependencies:", :blue
|
35
|
+
say_each(decisions.packages) { |package| package.name }
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module LicenseFinder
|
2
|
+
module CLI
|
3
|
+
class IgnoredDependencies < Base
|
4
|
+
extend Subcommand
|
5
|
+
include MakesDecisions
|
6
|
+
|
7
|
+
desc "list", "List all the ignored dependencies"
|
8
|
+
def list
|
9
|
+
say "Ignored Dependencies:", :blue
|
10
|
+
say_each(decisions.ignored)
|
11
|
+
end
|
12
|
+
|
13
|
+
auditable
|
14
|
+
desc "add DEPENDENCY", "Add a dependency to be ignored"
|
15
|
+
def add(dep)
|
16
|
+
modifying { decisions.ignore(dep, txn) }
|
17
|
+
|
18
|
+
say "Added #{dep} to the ignored dependencies"
|
19
|
+
end
|
20
|
+
|
21
|
+
auditable
|
22
|
+
desc "remove DEPENDENCY", "Remove a dependency from the ignored dependencies"
|
23
|
+
def remove(dep)
|
24
|
+
modifying { decisions.heed(dep, txn) }
|
25
|
+
|
26
|
+
say "Removed #{dep} from the ignored dependencies"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module LicenseFinder
|
2
|
+
module CLI
|
3
|
+
class IgnoredGroups < Base
|
4
|
+
extend Subcommand
|
5
|
+
include MakesDecisions
|
6
|
+
|
7
|
+
desc "list", "List all the ignored groups"
|
8
|
+
def list
|
9
|
+
say "Ignored Groups:", :blue
|
10
|
+
say_each(decisions.ignored_groups)
|
11
|
+
end
|
12
|
+
|
13
|
+
auditable
|
14
|
+
desc "add GROUP", "Add a group to be ignored"
|
15
|
+
def add(group)
|
16
|
+
modifying { decisions.ignore_group(group, txn) }
|
17
|
+
|
18
|
+
say "Added #{group} to the ignored groups"
|
19
|
+
end
|
20
|
+
|
21
|
+
auditable
|
22
|
+
desc "remove GROUP", "Remove a group from the ignored groups"
|
23
|
+
def remove(group)
|
24
|
+
modifying { decisions.heed_group(group, txn) }
|
25
|
+
|
26
|
+
say "Removed #{group} from the ignored groups"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module LicenseFinder
|
2
|
+
module CLI
|
3
|
+
class Licenses < Base
|
4
|
+
extend Subcommand
|
5
|
+
include MakesDecisions
|
6
|
+
|
7
|
+
auditable
|
8
|
+
desc "add DEPENDENCY LICENSE", "Set a dependency's licenses, overwriting any license_finder has found"
|
9
|
+
def add(name, license)
|
10
|
+
modifying { decisions.license(name, license, txn) }
|
11
|
+
|
12
|
+
say "The #{name} dependency has been marked as using #{license} license!", :green
|
13
|
+
end
|
14
|
+
|
15
|
+
auditable
|
16
|
+
desc "remove DEPENDENCY LICENSE", "Remove a manually set license"
|
17
|
+
def remove(dep, lic)
|
18
|
+
modifying { decisions.unlicense(dep, lic, txn) }
|
19
|
+
|
20
|
+
say "The dependency #{dep} no longer has a manual license"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
module LicenseFinder
|
2
|
+
module CLI
|
3
|
+
class Main < Base
|
4
|
+
extend Rootcommand
|
5
|
+
|
6
|
+
FORMATS = {
|
7
|
+
'text' => TextReport,
|
8
|
+
'html' => HtmlReport,
|
9
|
+
'markdown' => MarkdownReport,
|
10
|
+
'csv' => CsvReport
|
11
|
+
}
|
12
|
+
|
13
|
+
class_option :format, desc: "The desired output format.", default: 'text', enum: FORMATS.keys
|
14
|
+
class_option :columns, type: :array, desc: "For CSV reports, which columns to print. Pick from: #{CsvReport::AVAILABLE_COLUMNS}", default: %w[name version licenses]
|
15
|
+
class_option :gradle_command, desc: "Command to use when fetching gradle packages. Only meaningful if used with a Java/gradle project. Defaults to 'gradle'."
|
16
|
+
|
17
|
+
method_option :quiet, type: :boolean, desc: "silences progress report"
|
18
|
+
method_option :debug, type: :boolean, desc: "emit detailed info about what LicenseFinder is doing"
|
19
|
+
desc "action_items", "List unapproved dependencies (the default action for `license_finder`)"
|
20
|
+
def action_items
|
21
|
+
unapproved = decision_applier.unapproved
|
22
|
+
|
23
|
+
if unapproved.empty?
|
24
|
+
say "All dependencies are approved for use", :green
|
25
|
+
else
|
26
|
+
say "Dependencies that need approval:", :red
|
27
|
+
say report_of(unapproved)
|
28
|
+
exit 1
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
default_task :action_items
|
33
|
+
|
34
|
+
desc "report", "Print a report of the project's dependencies to stdout"
|
35
|
+
def report
|
36
|
+
dependencies = decision_applier(Logger.new(quiet: true))
|
37
|
+
say report_of(dependencies.acknowledged)
|
38
|
+
end
|
39
|
+
|
40
|
+
desc "version", "Print the version of LicenseFinder"
|
41
|
+
def version
|
42
|
+
puts LicenseFinder::VERSION
|
43
|
+
end
|
44
|
+
|
45
|
+
subcommand "dependencies", Dependencies, "Add or remove dependencies that your package managers are not aware of"
|
46
|
+
subcommand "licenses", Licenses, "Set a dependency's licenses, if the licenses found by license_finder are missing or wrong"
|
47
|
+
subcommand "approvals", Approvals, "Manually approve dependencies, even if their licenses are not whitelisted"
|
48
|
+
subcommand "ignored_groups", IgnoredGroups, "Exclude test and development dependencies from action items and reports"
|
49
|
+
subcommand "ignored_dependencies", IgnoredDependencies, "Exclude individual dependencies from action items and reports"
|
50
|
+
subcommand "whitelist", Whitelist, "Automatically approve any dependency that has a whitelisted license"
|
51
|
+
subcommand "project_name", ProjectName, "Set the project name, for display in reports"
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
# The core of the system. The saved decisions are applied to the current
|
56
|
+
# packages.
|
57
|
+
def decision_applier(logger = Logger.new(options))
|
58
|
+
DecisionApplier.new(
|
59
|
+
decisions: decisions,
|
60
|
+
packages: current_packages(logger)
|
61
|
+
)
|
62
|
+
end
|
63
|
+
|
64
|
+
def current_packages(logger)
|
65
|
+
PackageManager.current_packages(
|
66
|
+
logger: logger,
|
67
|
+
gradle_command: config.gradle_command,
|
68
|
+
ignore_groups: decisions.ignored_groups
|
69
|
+
)
|
70
|
+
end
|
71
|
+
|
72
|
+
def report_of(content)
|
73
|
+
report = FORMATS[options[:format]]
|
74
|
+
report.of(content, columns: options[:columns], project_name: fetch_project_name)
|
75
|
+
end
|
76
|
+
|
77
|
+
def fetch_project_name
|
78
|
+
decisions.project_name || Pathname.pwd.basename.to_s
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module LicenseFinder
|
2
|
+
module CLI
|
3
|
+
module MakesDecisions
|
4
|
+
def self.included(mod)
|
5
|
+
mod.extend(ClassMethods)
|
6
|
+
end
|
7
|
+
|
8
|
+
module ClassMethods
|
9
|
+
def auditable
|
10
|
+
method_option :who, desc: "The person making this decision"
|
11
|
+
method_option :why, desc: "The reason for making this decision"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def say_each(coll)
|
18
|
+
if coll.any?
|
19
|
+
coll.each do |item|
|
20
|
+
say(block_given? ? yield(item) : item)
|
21
|
+
end
|
22
|
+
else
|
23
|
+
say '(none)'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def txn
|
28
|
+
@txn ||= {
|
29
|
+
who: options[:who],
|
30
|
+
why: options[:why],
|
31
|
+
when: Time.now.getutc
|
32
|
+
}
|
33
|
+
end
|
34
|
+
|
35
|
+
def modifying
|
36
|
+
# decisions = Decisions.saved! # is part of Base
|
37
|
+
yield
|
38
|
+
decisions.save!(config.decisions_file)
|
39
|
+
end
|
40
|
+
|
41
|
+
def modify_each(*things)
|
42
|
+
modifying { things.each { |thing| yield thing } }
|
43
|
+
things
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'thor'
|
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
|
34
|
+
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module LicenseFinder
|
2
|
+
module CLI
|
3
|
+
class ProjectName < Base
|
4
|
+
extend Subcommand
|
5
|
+
include MakesDecisions
|
6
|
+
|
7
|
+
desc "show", "Show the project name"
|
8
|
+
def show
|
9
|
+
say "Project Name:", :blue
|
10
|
+
say decisions.project_name
|
11
|
+
end
|
12
|
+
|
13
|
+
auditable
|
14
|
+
desc "add NAME", "Set the project name"
|
15
|
+
def add(name)
|
16
|
+
modifying { decisions.name_project(name, txn) }
|
17
|
+
|
18
|
+
say "Set the project name to #{name}", :green
|
19
|
+
end
|
20
|
+
|
21
|
+
auditable
|
22
|
+
desc "remove", "Remove the project name"
|
23
|
+
def remove
|
24
|
+
modifying { decisions.unname_project(txn) }
|
25
|
+
|
26
|
+
say "Removed the project name"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module LicenseFinder
|
2
|
+
module CLI
|
3
|
+
class Whitelist < Base
|
4
|
+
extend Subcommand
|
5
|
+
include MakesDecisions
|
6
|
+
|
7
|
+
desc "list", "List all the whitelisted licenses"
|
8
|
+
def list
|
9
|
+
say "Whitelisted Licenses:", :blue
|
10
|
+
say_each(decisions.whitelisted) { |license| license.name }
|
11
|
+
end
|
12
|
+
|
13
|
+
auditable
|
14
|
+
desc "add LICENSE...", "Add one or more licenses to the whitelist"
|
15
|
+
def add(license, *other_licenses)
|
16
|
+
licenses = modify_each(license, *other_licenses) do |l|
|
17
|
+
decisions.whitelist(l, txn)
|
18
|
+
end
|
19
|
+
say "Added #{licenses.join(", ")} to the license whitelist"
|
20
|
+
end
|
21
|
+
|
22
|
+
auditable
|
23
|
+
desc "remove LICENSE...", "Remove one or more licenses from the whitelist"
|
24
|
+
def remove(license, *other_licenses)
|
25
|
+
licenses = modify_each(license, *other_licenses) do |l|
|
26
|
+
decisions.unwhitelist(l, txn)
|
27
|
+
end
|
28
|
+
say "Removed #{licenses.join(", ")} from the license whitelist"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -1,160 +1,29 @@
|
|
1
|
-
require "delegate"
|
2
|
-
|
3
1
|
module LicenseFinder
|
4
2
|
class Configuration
|
5
|
-
def self.
|
6
|
-
|
7
|
-
|
3
|
+
def self.with_optional_saved_config(primary_config, project_path = Pathname.new('.'))
|
4
|
+
config_file = project_path.join('config', 'license_finder.yml')
|
5
|
+
saved_config = config_file.exist? ? YAML.load(config_file.read) : {}
|
6
|
+
new(primary_config, saved_config)
|
8
7
|
end
|
9
8
|
|
10
|
-
def
|
11
|
-
|
9
|
+
def initialize(primary_config, saved_config)
|
10
|
+
@primary_config = primary_config
|
11
|
+
@saved_config = saved_config
|
12
12
|
end
|
13
13
|
|
14
|
-
def
|
15
|
-
|
16
|
-
config.save
|
17
|
-
|
18
|
-
FileUtils.mv(Dir["dependencies*"], config.artifacts.dir)
|
14
|
+
def gradle_command
|
15
|
+
get(:gradle_command) || "gradle"
|
19
16
|
end
|
20
17
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
# which need a working artifacts directory. This helper is a compromise.
|
25
|
-
def self.prepare(config)
|
26
|
-
result = new(config)
|
27
|
-
result.artifacts.init
|
28
|
-
result
|
29
|
-
end
|
30
|
-
|
31
|
-
attr_accessor :whitelist, :ignore_groups, :ignore_dependencies, :artifacts, :project_name, :gradle_command
|
32
|
-
|
33
|
-
def initialize(config)
|
34
|
-
@whitelist = Array(config['whitelist'])
|
35
|
-
@ignore_groups = Array(config["ignore_groups"])
|
36
|
-
@ignore_dependencies = Array(config["ignore_dependencies"])
|
37
|
-
@artifacts = Artifacts.new(Pathname(config['dependencies_file_dir'] || './doc/'))
|
38
|
-
@project_name = config['project_name'] || determine_project_name
|
39
|
-
@gradle_command = config['gradle_command'] || 'gradle'
|
40
|
-
end
|
41
|
-
|
42
|
-
def save
|
43
|
-
Persistence.set(to_hash)
|
18
|
+
def decisions_file
|
19
|
+
file_name = get(:decisions_file) || "doc/dependency_decisions.yml"
|
20
|
+
Pathname(file_name)
|
44
21
|
end
|
45
22
|
|
46
23
|
private
|
47
24
|
|
48
|
-
def
|
49
|
-
|
50
|
-
'whitelist' => whitelist.uniq,
|
51
|
-
'ignore_groups' => ignore_groups.uniq,
|
52
|
-
'ignore_dependencies' => ignore_dependencies.uniq,
|
53
|
-
'dependencies_file_dir' => artifacts.dir.to_s,
|
54
|
-
'project_name' => project_name,
|
55
|
-
'gradle_command' => gradle_command
|
56
|
-
}
|
57
|
-
end
|
58
|
-
|
59
|
-
def determine_project_name
|
60
|
-
Pathname.pwd.basename.to_s
|
61
|
-
end
|
62
|
-
|
63
|
-
class Artifacts < SimpleDelegator
|
64
|
-
def init
|
65
|
-
mkpath
|
66
|
-
end
|
67
|
-
|
68
|
-
def dir
|
69
|
-
__getobj__
|
70
|
-
end
|
71
|
-
|
72
|
-
def database_uri
|
73
|
-
URI.escape(database_file.expand_path.to_s)
|
74
|
-
end
|
75
|
-
|
76
|
-
def database_file
|
77
|
-
join("dependencies.db")
|
78
|
-
end
|
79
|
-
|
80
|
-
def text_file
|
81
|
-
join("dependencies.csv")
|
82
|
-
end
|
83
|
-
|
84
|
-
def detailed_text_file
|
85
|
-
join("dependencies_detailed.csv")
|
86
|
-
end
|
87
|
-
|
88
|
-
def html_file
|
89
|
-
join("dependencies.html")
|
90
|
-
end
|
91
|
-
|
92
|
-
def markdown_file
|
93
|
-
join("dependencies.md")
|
94
|
-
end
|
95
|
-
|
96
|
-
def legacy_yaml_file
|
97
|
-
join("dependencies.yml")
|
98
|
-
end
|
99
|
-
|
100
|
-
def legacy_text_file
|
101
|
-
join("dependencies.txt")
|
102
|
-
end
|
103
|
-
|
104
|
-
def last_refreshed
|
105
|
-
[
|
106
|
-
database_file,
|
107
|
-
text_file,
|
108
|
-
detailed_text_file,
|
109
|
-
html_file,
|
110
|
-
markdown_file
|
111
|
-
].map(&:mtime).min
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
module Persistence
|
116
|
-
extend self
|
117
|
-
|
118
|
-
def init
|
119
|
-
init! unless inited?
|
120
|
-
end
|
121
|
-
|
122
|
-
def get
|
123
|
-
return {} unless inited?
|
124
|
-
|
125
|
-
YAML.load(file.read)
|
126
|
-
end
|
127
|
-
|
128
|
-
def set(hash)
|
129
|
-
file.open('w') { |f| f.write(YAML.dump(hash)) }
|
130
|
-
end
|
131
|
-
|
132
|
-
def last_modified
|
133
|
-
file.mtime
|
134
|
-
end
|
135
|
-
|
136
|
-
private
|
137
|
-
|
138
|
-
def inited?
|
139
|
-
file.exist?
|
140
|
-
end
|
141
|
-
|
142
|
-
def init!
|
143
|
-
file_dir.mkpath
|
144
|
-
FileUtils.cp(file_template, file)
|
145
|
-
end
|
146
|
-
|
147
|
-
def file_dir
|
148
|
-
Pathname.new('.').join('config')
|
149
|
-
end
|
150
|
-
|
151
|
-
def file
|
152
|
-
file_dir.join('license_finder.yml')
|
153
|
-
end
|
154
|
-
|
155
|
-
def file_template
|
156
|
-
ROOT_PATH.join('data', 'license_finder.example.yml')
|
157
|
-
end
|
25
|
+
def get(key)
|
26
|
+
@primary_config[key.to_sym] || @saved_config[key.to_s]
|
158
27
|
end
|
159
28
|
end
|
160
29
|
end
|