license_finder 2.0.4 → 2.1.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (135) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +6 -4
  3. data/.travis/install_godep.sh +6 -0
  4. data/.travis/install_gradle.sh +1 -1
  5. data/.travis/install_rebar.sh +7 -5
  6. data/CHANGELOG.rdoc +13 -0
  7. data/CONTRIBUTING.md +16 -2
  8. data/README.md +41 -4
  9. data/Rakefile +8 -2
  10. data/features/features/{cli_spec.rb → cli/cli_spec.rb} +24 -18
  11. data/features/features/configure/add_dependencies_spec.rb +18 -1
  12. data/features/features/configure/approve_dependencies_spec.rb +31 -1
  13. data/features/features/configure/assign_licenses_spec.rb +18 -3
  14. data/features/features/configure/blacklist_licenses_spec.rb +30 -0
  15. data/features/features/configure/ignore_dependencies_spec.rb +1 -1
  16. data/features/features/configure/ignore_groups_spec.rb +16 -1
  17. data/features/features/configure/name_project_spec.rb +1 -1
  18. data/features/features/configure/set_project_path_spec.rb +1 -1
  19. data/features/features/configure/whitelist_licenses_spec.rb +1 -3
  20. data/features/features/package_managers/bower_spec.rb +1 -1
  21. data/features/features/package_managers/cocoapods_spec.rb +1 -1
  22. data/features/features/package_managers/godep_spec.rb +17 -0
  23. data/features/features/package_managers/gradle_spec.rb +18 -4
  24. data/features/features/package_managers/maven_spec.rb +1 -1
  25. data/features/features/package_managers/npm_spec.rb +1 -1
  26. data/features/features/package_managers/nuget_spec.rb +14 -0
  27. data/features/features/package_managers/pip_spec.rb +1 -1
  28. data/features/features/package_managers/rebar_spec.rb +1 -1
  29. data/features/features/report/composite_spec.rb +15 -0
  30. data/features/features/report/csv_spec.rb +1 -1
  31. data/features/features/report/diff_spec.rb +190 -0
  32. data/features/features/report/html_spec.rb +1 -1
  33. data/features/features/report/subproject_spec.rb +52 -0
  34. data/features/fixtures/file-based-libs-gradle/build.gradle +18 -0
  35. data/features/fixtures/file-based-libs-gradle/libs/data.json-0.2.3.jar +0 -0
  36. data/features/fixtures/gopath/src/github.com/pivotal/foo/Godeps/Godeps.json +16 -0
  37. data/features/fixtures/gopath/src/github.com/pivotal/foo/Godeps/Readme +5 -0
  38. data/features/fixtures/gopath/src/github.com/pivotal/foo/foo.go +6 -0
  39. data/features/fixtures/multi-module-gradle/build.gradle +18 -0
  40. data/features/fixtures/multi-module-gradle/module1/build.gradle +3 -0
  41. data/features/fixtures/multi-module-gradle/module2/build.gradle +3 -0
  42. data/features/fixtures/multi-module-gradle/settings.gradle +1 -0
  43. data/features/fixtures/nuget/Fun.Test/packages.config +4 -0
  44. data/features/fixtures/nuget/Fun/packages.config +5 -0
  45. data/features/fixtures/nuget/packages/Microsoft.AspNet.Mvc.4.0.30506.0/.keep +0 -0
  46. data/features/fixtures/nuget/packages/NUnit.2.6.4/.keep +0 -0
  47. data/features/fixtures/nuget/packages/Ninject.MVC4.3.2.1.0/.keep +0 -0
  48. data/features/fixtures/nuget/packages/repositories.config +6 -0
  49. data/features/fixtures/{build.gradle → single-module-gradle/build.gradle} +0 -0
  50. data/{spec → features/support}/feature_helper.rb +5 -1
  51. data/features/support/testing_dsl.rb +297 -212
  52. data/lib/license_finder/cli.rb +1 -0
  53. data/lib/license_finder/cli/base.rb +16 -3
  54. data/lib/license_finder/cli/blacklist.rb +30 -0
  55. data/lib/license_finder/cli/main.rb +62 -4
  56. data/lib/license_finder/configuration.rb +39 -8
  57. data/lib/license_finder/core.rb +13 -10
  58. data/lib/license_finder/decision_applier.rb +14 -9
  59. data/lib/license_finder/decisions.rb +24 -6
  60. data/lib/license_finder/diff.rb +47 -0
  61. data/lib/license_finder/license_aggregator.rb +25 -0
  62. data/lib/license_finder/package.rb +39 -6
  63. data/lib/license_finder/package_delta.rb +65 -0
  64. data/lib/license_finder/package_manager.rb +10 -3
  65. data/lib/license_finder/package_managers/bower.rb +3 -1
  66. data/lib/license_finder/package_managers/bundler.rb +18 -9
  67. data/lib/license_finder/package_managers/bundler_package.rb +6 -2
  68. data/lib/license_finder/package_managers/go_dep.rb +25 -0
  69. data/lib/license_finder/package_managers/go_package.rb +19 -0
  70. data/lib/license_finder/package_managers/go_workspace.rb +35 -0
  71. data/lib/license_finder/package_managers/gradle.rb +16 -17
  72. data/lib/license_finder/package_managers/gradle_dependency_finder.rb +13 -0
  73. data/lib/license_finder/package_managers/gradle_package.rb +6 -1
  74. data/lib/license_finder/package_managers/maven.rb +3 -1
  75. data/lib/license_finder/package_managers/merged_package.rb +43 -0
  76. data/lib/license_finder/package_managers/npm.rb +42 -24
  77. data/lib/license_finder/package_managers/nuget.rb +50 -0
  78. data/lib/license_finder/package_managers/nuget_package.rb +4 -0
  79. data/lib/license_finder/package_managers/pip_package.rb +1 -0
  80. data/lib/license_finder/package_managers/rebar.rb +2 -6
  81. data/lib/license_finder/platform.rb +4 -1
  82. data/lib/license_finder/project_finder.rb +56 -0
  83. data/lib/license_finder/report.rb +3 -2
  84. data/lib/license_finder/reports/csv_report.rb +6 -2
  85. data/lib/license_finder/reports/diff_report.rb +33 -0
  86. data/lib/license_finder/reports/merged_report.rb +13 -0
  87. data/lib/license_finder/version.rb +1 -1
  88. data/license_finder.gemspec +6 -2
  89. data/spec/dummy_app/Gemfile +6 -0
  90. data/spec/fixtures/all_pms/.envrc +0 -0
  91. data/spec/fixtures/all_pms/Godeps/Godeps.json +0 -0
  92. data/spec/fixtures/all_pms/packages/.keep +0 -0
  93. data/spec/fixtures/composite/Gemfile +0 -0
  94. data/spec/fixtures/composite/nested_project/.envrc +8 -0
  95. data/spec/fixtures/composite/nested_project/src/github.com/pivotal/foo/Godeps/Godeps.json +16 -0
  96. data/spec/fixtures/composite/nested_project/src/github.com/pivotal/foo/Godeps/Readme +5 -0
  97. data/spec/fixtures/composite/nested_project/src/github.com/pivotal/foo/foo.go +6 -0
  98. data/spec/fixtures/composite/not_a_project/DONTREADME.md +0 -0
  99. data/spec/fixtures/composite/project1/Gemfile +0 -0
  100. data/spec/fixtures/composite/project2/package.json +0 -0
  101. data/spec/lib/license_finder/cli/approvals_spec.rb +1 -1
  102. data/spec/lib/license_finder/cli/blacklist_spec.rb +58 -0
  103. data/spec/lib/license_finder/cli/dependencies_spec.rb +1 -1
  104. data/spec/lib/license_finder/cli/ignored_dependencies_spec.rb +1 -1
  105. data/spec/lib/license_finder/cli/ignored_groups_spec.rb +1 -1
  106. data/spec/lib/license_finder/cli/licenses_spec.rb +1 -1
  107. data/spec/lib/license_finder/cli/main_spec.rb +113 -7
  108. data/spec/lib/license_finder/cli/project_name_spec.rb +1 -1
  109. data/spec/lib/license_finder/cli/whitelist_spec.rb +1 -1
  110. data/spec/lib/license_finder/configuration_spec.rb +63 -4
  111. data/spec/lib/license_finder/core_spec.rb +49 -0
  112. data/spec/lib/license_finder/decision_applier_spec.rb +101 -1
  113. data/spec/lib/license_finder/decisions_spec.rb +62 -0
  114. data/spec/lib/license_finder/diff_spec.rb +106 -0
  115. data/spec/lib/license_finder/license_aggregator_spec.rb +61 -0
  116. data/spec/lib/license_finder/package_delta_spec.rb +18 -0
  117. data/spec/lib/license_finder/package_managers/bower_spec.rb +8 -6
  118. data/spec/lib/license_finder/package_managers/bundler_package_spec.rb +4 -2
  119. data/spec/lib/license_finder/package_managers/go_dep_spec.rb +72 -0
  120. data/spec/lib/license_finder/package_managers/go_workspace_spec.rb +69 -0
  121. data/spec/lib/license_finder/package_managers/gradle_package_spec.rb +9 -0
  122. data/spec/lib/license_finder/package_managers/gradle_spec.rb +94 -44
  123. data/spec/lib/license_finder/package_managers/maven_spec.rb +8 -6
  124. data/spec/lib/license_finder/package_managers/merged_package_spec.rb +52 -0
  125. data/spec/lib/license_finder/package_managers/npm_spec.rb +59 -20
  126. data/spec/lib/license_finder/package_managers/nuget_spec.rb +82 -0
  127. data/spec/lib/license_finder/package_managers/pip_package_spec.rb +1 -0
  128. data/spec/lib/license_finder/package_managers/rebar_spec.rb +12 -12
  129. data/spec/lib/license_finder/package_spec.rb +59 -2
  130. data/spec/lib/license_finder/project_finder_spec.rb +33 -0
  131. data/spec/lib/license_finder/reports/csv_report_spec.rb +9 -3
  132. data/spec/lib/license_finder/reports/diff_report_spec.rb +56 -0
  133. data/spec/lib/license_finder/reports/merged_report_spec.rb +21 -0
  134. metadata +82 -9
  135. data/.travis/install_virtualenv.sh +0 -9
@@ -9,6 +9,7 @@ require 'license_finder/cli/base'
9
9
  require 'license_finder/cli/makes_decisions'
10
10
 
11
11
  require 'license_finder/cli/whitelist'
12
+ require 'license_finder/cli/blacklist'
12
13
  require 'license_finder/cli/dependencies'
13
14
  require 'license_finder/cli/licenses'
14
15
  require 'license_finder/cli/approvals'
@@ -16,12 +16,25 @@ module LicenseFinder
16
16
 
17
17
  def license_finder
18
18
  @lf ||= LicenseFinder::Core.new(license_finder_config)
19
+ fail "Project path '#{@lf.config.project_path}' does not exist!" unless @lf.config.valid_project_path?
20
+ @lf
21
+ end
22
+
23
+ def fail(message)
24
+ say message and exit 1
19
25
  end
20
26
 
21
27
  def license_finder_config
22
- result = extract_options(:project_path, :decisions_file, :gradle_command, :rebar_command, :rebar_deps_dir)
23
- result[:logger] = logger_config
24
- result
28
+ extract_options(
29
+ :project_path,
30
+ :decisions_file,
31
+ :gradle_command,
32
+ :rebar_command,
33
+ :rebar_deps_dir,
34
+ :save
35
+ ).merge(
36
+ logger: logger_config
37
+ )
25
38
  end
26
39
 
27
40
  def logger_config
@@ -0,0 +1,30 @@
1
+ module LicenseFinder
2
+ module CLI
3
+ class Blacklist < Base
4
+ extend Subcommand
5
+ include MakesDecisions
6
+
7
+ desc "list", "List all the blacklisted licenses"
8
+ def list
9
+ say "Blacklisted Licenses:", :blue
10
+ say_each(decisions.blacklisted) { |license| license.name }
11
+ end
12
+
13
+ auditable
14
+ desc "add LICENSE...", "Add one or more licenses to the blacklist"
15
+ def add(*licenses)
16
+ assert_some licenses
17
+ modifying { licenses.each { |l| decisions.blacklist(l, txn) } }
18
+ say "Added #{licenses.join(", ")} to the license blacklist"
19
+ end
20
+
21
+ auditable
22
+ desc "remove LICENSE...", "Remove one or more licenses from the blacklist"
23
+ def remove(*licenses)
24
+ assert_some licenses
25
+ modifying { licenses.each { |l| decisions.unblacklist(l, txn) } }
26
+ say "Removed #{licenses.join(", ")} from the license blacklist"
27
+ end
28
+ end
29
+ end
30
+ end
@@ -1,5 +1,9 @@
1
1
  require 'license_finder/report'
2
2
  require 'license_finder/version'
3
+ require 'license_finder/diff'
4
+ require 'license_finder/package_delta'
5
+ require 'license_finder/license_aggregator'
6
+ require 'license_finder/project_finder'
3
7
 
4
8
  module LicenseFinder
5
9
  module CLI
@@ -15,21 +19,35 @@ module LicenseFinder
15
19
 
16
20
  class_option :format, desc: "The desired output format.", default: 'text', enum: FORMATS.keys
17
21
  class_option :columns, type: :array, desc: "For CSV reports, which columns to print. Pick from: #{CsvReport::AVAILABLE_COLUMNS}", default: %w[name version licenses]
18
- class_option :gradle_command, desc: "Command to use when fetching gradle packages. Only meaningful if used with a Java/gradle project. Defaults to 'gradle'."
22
+ class_option :save, desc: "Save report to a file. Default: 'license_report.csv' in project root.", lazy_default: "license_report"
23
+ class_option :gradle_command, desc: "Command to use when fetching gradle packages. Only meaningful if used with a Java/gradle project. Defaults to 'gradlew' / 'gradlew.bat' if the wrapper is present, otherwise to 'gradle'."
19
24
  class_option :rebar_command, desc: "Command to use when fetching rebar packages. Only meaningful if used with a Erlang/rebar project. Defaults to 'rebar'."
20
25
  class_option :rebar_deps_dir, desc: "Path to rebar dependencies directory. Only meaningful if used with a Erlang/rebar project. Defaults to 'deps'."
26
+ class_option :subprojects, type: :array, desc: "Generate a single report for multiple sub-projects. Ex: --subprojects='path/to/project1', 'path/to/project2'"
27
+ class_option :recursive, desc: "Recursively runs License Finder on all sub-projects."
21
28
 
22
29
  method_option :quiet, type: :boolean, desc: "silences progress report"
23
30
  method_option :debug, type: :boolean, desc: "emit detailed info about what LicenseFinder is doing"
24
31
  desc "action_items", "List unapproved dependencies (the default action for `license_finder`)"
32
+
25
33
  def action_items
26
34
  unapproved = license_finder.unapproved
35
+ blacklisted = license_finder.blacklisted
27
36
 
28
37
  if unapproved.empty?
29
38
  say "All dependencies are approved for use", :green
30
39
  else
31
- say "Dependencies that need approval:", :red
32
- say report_of(unapproved)
40
+ unless blacklisted.empty?
41
+ say "Blacklisted dependencies:", :red
42
+ say report_of(blacklisted)
43
+ end
44
+
45
+ other_unapproved = unapproved - blacklisted
46
+ unless other_unapproved.empty?
47
+ say "Dependencies that need approval:", :yellow
48
+ say report_of(other_unapproved)
49
+ end
50
+
33
51
  exit 1
34
52
  end
35
53
  end
@@ -37,30 +55,70 @@ module LicenseFinder
37
55
  default_task :action_items
38
56
 
39
57
  desc "report", "Print a report of the project's dependencies to stdout"
58
+
40
59
  def report
41
60
  logger_config[:quiet] = true
42
- say report_of(license_finder.acknowledged)
61
+
62
+ subproject_paths = options[:subprojects] if subprojects?
63
+ subproject_paths = ProjectFinder.new(license_finder.config.project_path).find_projects if recursive?
64
+
65
+ if subproject_paths && !subproject_paths.empty?
66
+ finder = LicenseAggregator.new(license_finder_config, subproject_paths)
67
+ report = MergedReport.new(finder.dependencies)
68
+ else
69
+ report = report_of(license_finder.acknowledged)
70
+ end
71
+ save? ? save_report(report, options[:save]) : say(report)
43
72
  end
44
73
 
45
74
  desc "version", "Print the version of LicenseFinder"
75
+
46
76
  def version
47
77
  puts LicenseFinder::VERSION
48
78
  end
49
79
 
80
+ desc "diff OLDFILE NEWFILE", "Command to view the differences between two generated reports (csv)."
81
+
82
+ def diff(file1, file2)
83
+ f1 = IO.read(file1)
84
+ f2 = IO.read(file2)
85
+ report = DiffReport.new(Diff.compare(f1, f2))
86
+ save? ? save_report(report, options[:save]) : say(report)
87
+ end
88
+
50
89
  subcommand "dependencies", Dependencies, "Add or remove dependencies that your package managers are not aware of"
51
90
  subcommand "licenses", Licenses, "Set a dependency's licenses, if the licenses found by license_finder are missing or wrong"
52
91
  subcommand "approvals", Approvals, "Manually approve dependencies, even if their licenses are not whitelisted"
53
92
  subcommand "ignored_groups", IgnoredGroups, "Exclude test and development dependencies from action items and reports"
54
93
  subcommand "ignored_dependencies", IgnoredDependencies, "Exclude individual dependencies from action items and reports"
55
94
  subcommand "whitelist", Whitelist, "Automatically approve any dependency that has a whitelisted license"
95
+ subcommand "blacklist", Blacklist, "Forbid approval of any dependency whose licenses are all blacklisted"
56
96
  subcommand "project_name", ProjectName, "Set the project name, for display in reports"
57
97
 
58
98
  private
59
99
 
100
+ def save_report(content, file_name)
101
+ File.open(file_name, 'w') do |f|
102
+ f.write(content)
103
+ end
104
+ end
105
+
60
106
  def report_of(content)
61
107
  report = FORMATS[options[:format]]
62
108
  report.of(content, columns: options[:columns], project_name: license_finder.project_name)
63
109
  end
110
+
111
+ def save?
112
+ !!options[:save]
113
+ end
114
+
115
+ def recursive?
116
+ !!options[:recursive]
117
+ end
118
+
119
+ def subprojects?
120
+ !!options[:subprojects]
121
+ end
64
122
  end
65
123
  end
66
124
  end
@@ -1,7 +1,10 @@
1
+ require_relative 'platform'
2
+
1
3
  module LicenseFinder
2
4
  class Configuration
3
- def self.with_optional_saved_config(primary_config, project_path)
4
- config_file = project_path.join('config', 'license_finder.yml')
5
+ def self.with_optional_saved_config(primary_config)
6
+ project_path = Pathname(primary_config.fetch(:project_path, Pathname.pwd)).expand_path
7
+ config_file = project_path.join('config', 'license_finder.yml')
5
8
  saved_config = config_file.exist? ? YAML.load(config_file.read) : {}
6
9
  new(primary_config, saved_config)
7
10
  end
@@ -11,27 +14,55 @@ module LicenseFinder
11
14
  @saved_config = saved_config
12
15
  end
13
16
 
17
+ def valid_project_path?
18
+ if get(:project_path)
19
+ return project_path.exist?
20
+ end
21
+ true
22
+ end
23
+
14
24
  def gradle_command
15
- get(:gradle_command) || "gradle"
25
+ get(:gradle_command) || (
26
+ if Platform.windows?
27
+ wrapper = 'gradlew.bat'
28
+ gradle = 'gradle.bat'
29
+ else
30
+ wrapper = 'gradlew'
31
+ gradle = 'gradle'
32
+ end
33
+
34
+ File.exist?(wrapper) ? wrapper : gradle
35
+ )
16
36
  end
17
37
 
18
38
  def rebar_command
19
- get(:rebar_command) || "rebar"
39
+ get(:rebar_command) || 'rebar'
20
40
  end
21
41
 
22
42
  def rebar_deps_dir
23
- get(:rebar_deps_dir) || "deps"
43
+ path = get(:rebar_deps_dir) || 'deps'
44
+ project_path.join(path).expand_path
24
45
  end
25
46
 
26
- def decisions_file
27
- file_name = get(:decisions_file) || "doc/dependency_decisions.yml"
28
- Pathname(file_name)
47
+ def decisions_file_path
48
+ path = get(:decisions_file) || 'doc/dependency_decisions.yml'
49
+ project_path.join(path).expand_path
50
+ end
51
+
52
+ def project_path
53
+ Pathname(path_prefix).expand_path
29
54
  end
30
55
 
31
56
  private
32
57
 
58
+ attr_reader :saved_config
59
+
33
60
  def get(key)
34
61
  @primary_config[key.to_sym] || @saved_config[key.to_s]
35
62
  end
63
+
64
+ def path_prefix
65
+ get(:project_path) || ''
66
+ end
36
67
  end
37
68
  end
@@ -11,6 +11,8 @@ require 'forwardable'
11
11
  module LicenseFinder
12
12
  # Coordinates setup
13
13
  class Core
14
+ attr_reader :config
15
+
14
16
  def self.default_logger
15
17
  Logger::Default.new
16
18
  end
@@ -26,40 +28,41 @@ module LicenseFinder
26
28
  # }
27
29
  def initialize(options = {})
28
30
  @logger = Logger.new(options.fetch(:logger, {}))
29
- @project_path = Pathname(options.fetch(:project_path, Pathname.pwd))
30
- @config = Configuration.with_optional_saved_config(options, project_path)
31
- @decisions = Decisions.saved!(config.decisions_file)
31
+ @config = Configuration.with_optional_saved_config(options)
32
32
  end
33
33
 
34
34
  def modifying
35
35
  yield
36
- decisions.save!(config.decisions_file)
36
+ decisions.save!(config.decisions_file_path)
37
37
  end
38
38
 
39
39
  extend Forwardable
40
- def_delegators :decision_applier, :acknowledged, :unapproved
41
- attr_reader :decisions
40
+ def_delegators :decision_applier, :acknowledged, :unapproved, :blacklisted
42
41
 
43
42
  def project_name
44
- decisions.project_name || project_path.basename.to_s
43
+ decisions.project_name || config.project_path.basename.to_s
44
+ end
45
+
46
+ def decisions
47
+ @decisions ||= Decisions.fetch_saved(config.decisions_file_path)
45
48
  end
46
49
 
47
50
  private
48
51
 
49
- attr_reader :config, :logger, :project_path
52
+ attr_reader :logger
50
53
 
51
54
  # The core of the system. The saved decisions are applied to the current
52
55
  # packages.
53
56
  def decision_applier
54
57
  # lazy, do not move to `initialize`
55
- DecisionApplier.new(decisions: decisions, packages: current_packages)
58
+ @applier ||= DecisionApplier.new(decisions: decisions, packages: current_packages)
56
59
  end
57
60
 
58
61
  def current_packages
59
62
  # lazy, do not move to `initialize`
60
63
  PackageManager.current_packages(
61
64
  logger: logger,
62
- project_path: project_path,
65
+ project_path: config.project_path,
63
66
  ignore_groups: decisions.ignored_groups,
64
67
  gradle_command: config.gradle_command,
65
68
  rebar_command: config.rebar_command,
@@ -2,31 +2,34 @@ module LicenseFinder
2
2
  class DecisionApplier
3
3
  def initialize(options)
4
4
  @decisions = options.fetch(:decisions)
5
- @system_packages = options.fetch(:packages)
5
+ @acknowledged = apply_decisions(options.fetch(:packages))
6
6
  end
7
7
 
8
+ attr_reader :acknowledged
9
+
8
10
  def unapproved
9
11
  acknowledged.reject(&:approved?)
10
12
  end
11
13
 
12
- def acknowledged
13
- packages.reject { |package| ignored?(package) }
14
+ def blacklisted
15
+ acknowledged.select(&:blacklisted?)
14
16
  end
15
17
 
16
18
  private
17
19
 
18
- attr_reader :system_packages, :decisions
20
+ attr_reader :decisions
19
21
 
20
- def packages
21
- result = decisions.packages + system_packages
22
- result
22
+ def apply_decisions(system_packages)
23
+ all_packages = decisions.packages + system_packages
24
+ all_packages
23
25
  .map { |package| with_decided_licenses(package) }
24
26
  .map { |package| with_approval(package) }
27
+ .reject { |package| ignored?(package) }
25
28
  end
26
29
 
27
30
  def ignored?(package)
28
31
  decisions.ignored?(package.name) ||
29
- package.groups.any? { |group| decisions.ignored_group?(group) }
32
+ (package.groups.any? && package.groups.all? { |group| decisions.ignored_group?(group) })
30
33
  end
31
34
 
32
35
  def with_decided_licenses(package)
@@ -37,7 +40,9 @@ module LicenseFinder
37
40
  end
38
41
 
39
42
  def with_approval(package)
40
- if decisions.approved?(package.name)
43
+ if package.licenses.all? { |license| decisions.blacklisted?(license) }
44
+ package.blacklisted!
45
+ elsif decisions.approved?(package.name)
41
46
  package.approved_manually!(decisions.approval_of(package.name))
42
47
  elsif package.licenses.any? { |license| decisions.whitelisted?(license) }
43
48
  package.whitelisted!
@@ -4,7 +4,7 @@ module LicenseFinder
4
4
  # READ
5
5
  ######
6
6
 
7
- attr_reader :packages, :whitelisted, :ignored, :ignored_groups, :project_name
7
+ attr_reader :packages, :whitelisted, :blacklisted, :ignored, :ignored_groups, :project_name
8
8
 
9
9
  def licenses_of(name)
10
10
  @licenses[name]
@@ -22,6 +22,10 @@ module LicenseFinder
22
22
  @whitelisted.include?(lic)
23
23
  end
24
24
 
25
+ def blacklisted?(lic)
26
+ @blacklisted.include?(lic)
27
+ end
28
+
25
29
  def ignored?(name)
26
30
  @ignored.include?(name)
27
31
  end
@@ -46,6 +50,7 @@ module LicenseFinder
46
50
  @licenses = Hash.new { |h, k| h[k] = Set.new }
47
51
  @approvals = {}
48
52
  @whitelisted = Set.new
53
+ @blacklisted = Set.new
49
54
  @ignored = Set.new
50
55
  @ignored_groups = Set.new
51
56
  end
@@ -98,6 +103,18 @@ module LicenseFinder
98
103
  self
99
104
  end
100
105
 
106
+ def blacklist(lic, txn = {})
107
+ @decisions << [:blacklist, lic, txn]
108
+ @blacklisted << License.find_by_name(lic)
109
+ self
110
+ end
111
+
112
+ def unblacklist(lic, txn = {})
113
+ @decisions << [:unblacklist, lic, txn]
114
+ @blacklisted.delete(License.find_by_name(lic))
115
+ self
116
+ end
117
+
101
118
  def ignore(name, txn = {})
102
119
  @decisions << [:ignore, name, txn]
103
120
  @ignored << name
@@ -138,7 +155,7 @@ module LicenseFinder
138
155
  # PERSIST
139
156
  #########
140
157
 
141
- def self.saved!(file)
158
+ def self.fetch_saved(file)
142
159
  restore(read!(file))
143
160
  end
144
161
 
@@ -148,10 +165,11 @@ module LicenseFinder
148
165
 
149
166
  def self.restore(persisted)
150
167
  result = new
151
- if persisted
152
- YAML.load(persisted).each do |action, *args|
153
- result.send(action, *args)
154
- end
168
+ return result unless persisted
169
+
170
+ actions = YAML.load(persisted)
171
+ (actions || []).each do |action, *args|
172
+ result.send(action, *args)
155
173
  end
156
174
  result
157
175
  end