1
1
module MetricFu
2
2
class ReekGenerator < Generator
3
- REEK_REGEX = /^(\S +) (.*) \( (.*)\) $/
4
-
5
3
def self . metric
6
4
:reek
7
5
end
@@ -12,34 +10,25 @@ def emit
12
10
mf_log "Skipping Reek, no files found to analyze"
13
11
@output = ""
14
12
else
15
- args = cli_options ( files )
16
- @output = run! ( args )
17
- @output = massage_for_reek_12 if reek_12?
13
+ @output = run! ( files , config_files )
18
14
end
19
15
end
20
16
21
- def run! ( args )
17
+ def run! ( files , config_files )
18
+ require "reek"
19
+ # To load any changing dependencies such as "reek/configuration/app_configuration"
20
+ # Added in 1.6.0 https://github.com/troessner/reek/commit/7f4ed2be442ca926e08ccc41945e909e8f710947
21
+ # But not always loaded
22
22
require "reek/cli/application"
23
23
24
- MetricFu ::Utility . capture_output do
25
- Reek ::Cli ::Application . new ( args ) . execute
26
- end
24
+ examiner = Reek . const_defined? ( :Examiner ) ? Reek . const_get ( :Examiner ) : Reek . const_get ( :Core ) . const_get ( :Examiner )
25
+ examiner . new ( files , config_files )
27
26
end
28
27
29
28
def analyze
30
- @matches = @output . chomp . split ( "\n \n " ) . map { |m | m . split ( "\n " ) }
31
- @matches = @matches . map do |match |
32
- break { } if zero_warnings? ( match )
33
- file_path = match . shift . split ( " -- " ) . first
34
- file_path = file_path . gsub ( '"' , " " ) . strip
35
- code_smells = match . map do |smell |
36
- match_object = smell . match ( REEK_REGEX )
37
- next unless match_object
38
- { method : match_object [ 1 ] . strip ,
39
- message : match_object [ 2 ] . strip ,
40
- type : match_object [ 3 ] . strip }
41
- end . compact
42
- { file_path : file_path , code_smells : code_smells }
29
+ @matches = @output . smells . group_by ( &:source ) . collect do |file_path , smells |
30
+ { file_path : file_path ,
31
+ code_smells : analyze_smells ( smells ) }
43
32
end
44
33
end
45
34
@@ -67,31 +56,6 @@ def per_file_info(out)
67
56
end
68
57
end
69
58
70
- def reek_12?
71
- return false if @output . length == 0
72
- ( @output =~ /^"/ ) != 0
73
- end
74
-
75
- def massage_for_reek_12
76
- section_break = ""
77
- @output . split ( "\n " ) . map do |line |
78
- case line
79
- when /^ /
80
- "#{ line . gsub ( /^ / , '' ) } \n "
81
- else
82
- parts = line . split ( " -- " )
83
- if parts [ 1 ] . nil?
84
- "#{ line } \n "
85
- else
86
- warnings = parts [ 1 ] . gsub ( / \( .*\) :/ , ":" )
87
- result = "#{ section_break } \" #{ parts [ 0 ] } \" -- #{ warnings } \n "
88
- section_break = "\n "
89
- result
90
- end
91
- end
92
- end . join
93
- end
94
-
95
59
private
96
60
97
61
def files_to_analyze
@@ -100,47 +64,26 @@ def files_to_analyze
100
64
remove_excluded_files ( files_to_reek )
101
65
end
102
66
103
- def cli_options ( files )
104
- [
105
- disable_line_number_option ,
106
- turn_off_color ,
107
- *config_option ,
108
- *files
109
- ] . reject ( &:empty? )
110
- end
111
-
112
67
# TODO: Check that specified line config file exists
113
- def config_option
114
- config_file_pattern = options [ :config_file_pattern ]
115
- if config_file_pattern . to_s . empty?
116
- [ "" ]
117
- else
118
- [ "--config" , config_file_pattern ]
119
- end
68
+ def config_files
69
+ Array ( options [ :config_file_pattern ] )
120
70
end
121
71
122
- # Work around "Error: invalid option: --no-color" in reek < 1.3.7
123
- def turn_off_color
124
- if reek_version >= "1.3.7"
125
- "--no-color"
126
- else
127
- ""
128
- end
72
+ def analyze_smells ( smells )
73
+ smells . collect ( &method ( :smell_data ) )
129
74
end
130
75
131
- def reek_version
132
- @reek_version ||= `reek --version` . chomp . sub ( / \s *reek \s */ , "" )
133
- # use the above, as the below may activate a version not available in
134
- # a Bundler context
135
- # MetricFu::GemVersion.activated_version('reek').to_s
76
+ def smell_data ( smell )
77
+ { method : smell . context ,
78
+ message : smell . message ,
79
+ type : smell_type ( smell ) ,
80
+ lines : smell . lines }
136
81
end
137
82
138
- def disable_line_number_option
139
- "--no-line-numbers"
140
- end
83
+ def smell_type ( smell )
84
+ return smell . subclass if smell . respond_to? ( :subclass )
141
85
142
- def zero_warnings? ( match )
143
- match . last == "0 total warnings"
86
+ smell . smell_type
144
87
end
145
88
end
146
89
end
0 commit comments