forked from rubocop/rubocop
/
formatter_set.rb
105 lines (88 loc) · 3.21 KB
/
formatter_set.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# frozen_string_literal: true
require 'fileutils'
module RuboCop
module Formatter
# This is a collection of formatters. A FormatterSet can hold multiple
# formatter instances and provides transparent formatter API methods
# which invoke same method of each formatters.
class FormatterSet < Array
BUILTIN_FORMATTERS_FOR_KEYS = {
'[a]utogenconf' => AutoGenConfigFormatter,
'[c]lang' => ClangStyleFormatter,
'[e]macs' => EmacsStyleFormatter,
'[fi]les' => FileListFormatter,
'[fu]ubar' => FuubarStyleFormatter,
'[h]tml' => HTMLFormatter,
'[j]son' => JSONFormatter,
'[ju]nit' => JUnitFormatter,
'[o]ffenses' => OffenseCountFormatter,
'[pa]cman' => PacmanFormatter,
'[p]rogress' => ProgressFormatter,
'[q]uiet' => QuietFormatter,
'[s]imple' => SimpleTextFormatter,
'[t]ap' => TapFormatter,
'[w]orst' => WorstOffendersFormatter
}.freeze
FORMATTER_APIS = %i[started finished].freeze
FORMATTER_APIS.each do |method_name|
define_method(method_name) do |*args|
each { |f| f.send(method_name, *args) }
end
end
def initialize(options = {})
super()
@options = options # CLI options
end
def file_started(file, options)
@options = options[:cli_options]
@config_store = options[:config_store]
each { |f| f.file_started(file, options) }
end
def file_finished(file, offenses)
each { |f| f.file_finished(file, offenses) }
offenses
end
def add_formatter(formatter_type, output_path = nil)
if output_path
dir_path = File.dirname(output_path)
FileUtils.mkdir_p(dir_path) unless File.exist?(dir_path)
output = File.open(output_path, 'w')
else
output = $stdout
end
self << formatter_class(formatter_type).new(output, @options)
end
def close_output_files
each do |formatter|
formatter.output.close if formatter.output.is_a?(File)
end
end
private
def formatter_class(formatter_type)
case formatter_type
when Class
formatter_type
when /\A[A-Z]/
custom_formatter_class(formatter_type)
else
builtin_formatter_class(formatter_type)
end
end
def builtin_formatter_class(specified_key)
matching_keys = BUILTIN_FORMATTERS_FOR_KEYS.keys.select do |key|
/^\[#{specified_key}\]/.match?(key) || specified_key == key.delete('[]')
end
raise %(No formatter for "#{specified_key}") if matching_keys.empty?
raise %(Cannot determine formatter for "#{specified_key}") if matching_keys.size > 1
BUILTIN_FORMATTERS_FOR_KEYS[matching_keys.first]
end
def custom_formatter_class(specified_class_name)
constant_names = specified_class_name.split('::')
constant_names.shift if constant_names.first.empty?
constant_names.reduce(Object) do |namespace, constant_name|
namespace.const_get(constant_name, false)
end
end
end
end
end