Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'rubocop/formatter/graceful_formatter.rb')
-rw-r--r--rubocop/formatter/graceful_formatter.rb109
1 files changed, 109 insertions, 0 deletions
diff --git a/rubocop/formatter/graceful_formatter.rb b/rubocop/formatter/graceful_formatter.rb
new file mode 100644
index 00000000000..b5db7c6c192
--- /dev/null
+++ b/rubocop/formatter/graceful_formatter.rb
@@ -0,0 +1,109 @@
+# frozen_string_literal: true
+
+require 'rubocop'
+
+module RuboCop
+ module Formatter
+ class GracefulFormatter < ::RuboCop::Formatter::ProgressFormatter
+ CONFIG_DETAILS_KEY = 'Details'
+ CONFIG_DETAILS_VALUE = 'grace period'
+
+ class << self
+ attr_accessor :active_offenses
+ end
+
+ def started(...)
+ super
+
+ self.class.active_offenses = 0
+
+ @silenced_offenses_for_files = {}
+ @config = RuboCop::ConfigStore.new.for_pwd
+ end
+
+ def file_finished(file, offenses)
+ silenced_offenses, active_offenses = offenses.partition { silenced?(_1) }
+
+ @silenced_offenses_for_files[file] = silenced_offenses if silenced_offenses.any?
+
+ super(file, active_offenses)
+ end
+
+ def finished(inspected_files)
+ # See the note below why are using this ivar in the first place.
+ unless defined?(@total_offense_count)
+ raise <<~MESSAGE
+ RuboCop has changed its internals and the instance variable
+ `@total_offense_count` is no longer defined but we were relying on it.
+
+ Please change the implementation.
+
+ See https://github.com/rubocop/rubocop/blob/65a757b0f/lib/rubocop/formatter/simple_text_formatter.rb#L24
+ MESSAGE
+ end
+
+ super
+
+ # Internally, RuboCop has no notion of "silenced offenses". We cannot
+ # override this meaning in a formatter that's why we track what we
+ # consider to be an active offense.
+ # This is needed for `adjusted_exit_status` method below.
+ self.class.active_offenses = @total_offense_count
+
+ report_silenced_offenses(inspected_files)
+ end
+
+ # We consider this run a success without any active offenses.
+ def self.adjusted_exit_status(status)
+ return status unless status == RuboCop::CLI::STATUS_OFFENSES
+ return RuboCop::CLI::STATUS_SUCCESS if active_offenses == 0
+
+ status
+ end
+
+ def self.grace_period?(cop_name, config)
+ details = config[CONFIG_DETAILS_KEY]
+ return false unless details
+ return true if details == CONFIG_DETAILS_VALUE
+
+ warn "#{cop_name}: Unhandled value #{details.inspect} for `Details` key."
+
+ false
+ end
+
+ def self.grace_period_key_value
+ "#{CONFIG_DETAILS_KEY}: #{CONFIG_DETAILS_VALUE}"
+ end
+
+ private
+
+ def silenced?(offense)
+ cop_config = @config.for_cop(offense.cop_name)
+
+ self.class.grace_period?(offense.cop_name, cop_config)
+ end
+
+ def report_silenced_offenses(inspected_files)
+ return if @silenced_offenses_for_files.empty?
+
+ output.puts
+ output.puts 'Silenced offenses:'
+ output.puts
+
+ @silenced_offenses_for_files.each do |file, offenses|
+ report_file(file, offenses)
+ end
+
+ silenced_offense_count = @silenced_offenses_for_files.values.sum(&:size)
+ silenced_text = colorize("#{silenced_offense_count} offenses", :yellow)
+
+ output.puts
+ output.puts "#{inspected_files.size} files inspected, #{silenced_text} silenced"
+ end
+
+ def report_file_as_mark(_offenses)
+ # Skip progress bar. No dots. No C/Ws.
+ end
+ end
+ end
+end