metric_fu 4.3.1 → 4.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.metrics +55 -26
- data/.travis.yml +4 -1
- data/AUTHORS +12 -0
- data/Gemfile +1 -0
- data/HISTORY.md +24 -0
- data/README.md +27 -22
- data/checksum/metric_fu-4.3.1.gem.sha512 +1 -0
- data/checksum/metric_fu-4.4.0.gem.sha512 +1 -0
- data/lib/metric_fu.rb +28 -79
- data/lib/metric_fu/cli/helper.rb +1 -1
- data/lib/metric_fu/cli/parser.rb +1 -1
- data/lib/metric_fu/configuration.rb +104 -150
- data/lib/metric_fu/environment.rb +88 -0
- data/lib/metric_fu/formatter.rb +23 -0
- data/lib/metric_fu/formatter/html.rb +12 -9
- data/lib/metric_fu/initial_requires.rb +1 -0
- data/lib/metric_fu/io.rb +60 -1
- data/lib/metric_fu/load_files.rb +4 -2
- data/lib/metric_fu/loader.rb +62 -0
- data/lib/metric_fu/metric.rb +102 -0
- data/lib/metric_fu/metrics/base_template.rb +15 -9
- data/lib/metric_fu/metrics/cane/cane.rb +9 -5
- data/lib/metric_fu/metrics/cane/init.rb +35 -13
- data/lib/metric_fu/metrics/churn/churn.rb +5 -1
- data/lib/metric_fu/metrics/churn/init.rb +24 -4
- data/lib/metric_fu/metrics/flay/flay.rb +7 -3
- data/lib/metric_fu/metrics/flay/init.rb +29 -13
- data/lib/metric_fu/metrics/flay/template_awesome/flay.html.erb +1 -1
- data/lib/metric_fu/metrics/flog/flog.rb +14 -38
- data/lib/metric_fu/metrics/flog/init.rb +30 -7
- data/lib/metric_fu/metrics/generator.rb +21 -6
- data/lib/metric_fu/metrics/graph.rb +2 -2
- data/lib/metric_fu/metrics/hotspots/hotspots.rb +5 -1
- data/lib/metric_fu/metrics/hotspots/init.rb +21 -5
- data/lib/metric_fu/metrics/rails_best_practices/init.rb +29 -5
- data/lib/metric_fu/metrics/rails_best_practices/rails_best_practices.rb +20 -27
- data/lib/metric_fu/metrics/rails_best_practices/template_awesome/rails_best_practices.html.erb +1 -1
- data/lib/metric_fu/metrics/rcov/init.rb +40 -15
- data/lib/metric_fu/metrics/rcov/rcov.rb +15 -10
- data/lib/metric_fu/metrics/reek/init.rb +25 -6
- data/lib/metric_fu/metrics/reek/reek.rb +52 -31
- data/lib/metric_fu/metrics/reek/template_awesome/reek.html.erb +1 -1
- data/lib/metric_fu/metrics/roodi/init.rb +25 -6
- data/lib/metric_fu/metrics/roodi/roodi.rb +7 -3
- data/lib/metric_fu/metrics/saikuro/init.rb +22 -6
- data/lib/metric_fu/metrics/saikuro/saikuro.rb +8 -3
- data/lib/metric_fu/metrics/stats/init.rb +28 -5
- data/lib/metric_fu/metrics/stats/stats.rb +24 -6
- data/lib/metric_fu/metrics/stats/template_awesome/stats.html.erb +2 -2
- data/lib/metric_fu/parser_ext.rb +15 -0
- data/lib/metric_fu/reporting/graphs/engines/gchart.rb +1 -1
- data/lib/metric_fu/reporting/graphs/engines/init.rb +18 -4
- data/lib/metric_fu/reporting/graphs/grapher.rb +1 -1
- data/lib/metric_fu/reporting/result.rb +13 -6
- data/lib/metric_fu/reporting/templates/awesome/awesome_template.rb +1 -1
- data/lib/metric_fu/run.rb +7 -10
- data/lib/metric_fu/sexp_ext.rb +11 -0
- data/lib/metric_fu/version.rb +1 -1
- data/metric_fu.gemspec +23 -20
- data/spec/cli/helper_spec.rb +5 -16
- data/spec/metric_fu/configuration_spec.rb +62 -88
- data/spec/metric_fu/formatter/html_spec.rb +26 -16
- data/spec/metric_fu/formatter/yaml_spec.rb +2 -2
- data/spec/metric_fu/metric_spec.rb +50 -0
- data/spec/metric_fu/metrics/base_template_spec.rb +9 -7
- data/spec/metric_fu/metrics/cane/cane_spec.rb +19 -24
- data/spec/metric_fu/metrics/churn/churn_spec.rb +8 -8
- data/spec/metric_fu/metrics/flay/flay_spec.rb +7 -13
- data/spec/metric_fu/metrics/flog/flog_spec.rb +63 -58
- data/spec/metric_fu/metrics/generator_spec.rb +4 -0
- data/spec/metric_fu/metrics/hotspots/hotspots_spec.rb +7 -7
- data/spec/metric_fu/metrics/rails_best_practices/rails_best_practices_spec.rb +14 -33
- data/spec/metric_fu/metrics/rcov/rcov_spec.rb +17 -18
- data/spec/metric_fu/metrics/reek/reek_spec.rb +9 -10
- data/spec/metric_fu/metrics/roodi/roodi_spec.rb +5 -11
- data/spec/metric_fu/metrics/saikuro/saikuro_spec.rb +15 -14
- data/spec/metric_fu/metrics/stats/stats_spec.rb +5 -6
- data/spec/metric_fu/reporting/graphs/engines/bluff_spec.rb +2 -3
- data/spec/metric_fu/reporting/graphs/engines/gchart_spec.rb +12 -9
- data/spec/metric_fu/reporting/result_spec.rb +3 -3
- data/spec/run_spec.rb +45 -29
- data/spec/spec_helper.rb +7 -0
- data/spec/support/helper_methods.rb +9 -0
- data/spec/support/suite.rb +17 -11
- metadata +59 -56
- data/bin/mf-rails_best_practices +0 -9
- data/bin/mf-stats +0 -7
@@ -1,7 +1,31 @@
|
|
1
|
-
MetricFu
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
1
|
+
module MetricFu
|
2
|
+
class MetricRailsBestPractices < Metric
|
3
|
+
|
4
|
+
def name
|
5
|
+
:rails_best_practices
|
6
|
+
end
|
7
|
+
|
8
|
+
def default_run_options
|
9
|
+
{}
|
10
|
+
end
|
11
|
+
|
12
|
+
def has_graph?
|
13
|
+
true
|
14
|
+
end
|
15
|
+
|
16
|
+
def enable
|
17
|
+
if MetricFu.configuration.supports_ripper?
|
18
|
+
super if MetricFu.configuration.rails?
|
19
|
+
else
|
20
|
+
MetricFu.configuration.mf_debug("Rails Best Practices is only available in MRI 1.9. It requires ripper")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def activate
|
25
|
+
activate_library('rails_best_practices')
|
26
|
+
activate_library('metric_fu/sexp_ext')
|
27
|
+
super
|
28
|
+
end
|
29
|
+
|
6
30
|
end
|
7
31
|
end
|
@@ -1,36 +1,29 @@
|
|
1
1
|
module MetricFu
|
2
|
-
class
|
2
|
+
class RailsBestPracticesGenerator < Generator
|
3
|
+
|
4
|
+
def self.metric
|
5
|
+
:rails_best_practices
|
6
|
+
end
|
7
|
+
|
3
8
|
def emit
|
4
|
-
|
5
|
-
|
6
|
-
|
9
|
+
mf_debug "** Rails Best Practices"
|
10
|
+
path = '.'
|
11
|
+
analyzer = ::RailsBestPractices::Analyzer.new(path, { 'silent' => true })
|
12
|
+
analyzer.analyze
|
13
|
+
@output = analyzer.errors
|
7
14
|
end
|
8
15
|
|
9
16
|
def analyze
|
10
|
-
@
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
file, line = match[0].split(':')
|
18
|
-
problem = match[1]
|
19
|
-
|
20
|
-
cleanup_color_switches(file)
|
21
|
-
cleanup_color_switches(problem)
|
22
|
-
|
23
|
-
file.gsub!(/^\.\//, '')
|
24
|
-
|
25
|
-
{:file => file, :line => line, :problem => problem}
|
17
|
+
@problems = @output.collect do |problem|
|
18
|
+
{
|
19
|
+
:file => problem.filename,
|
20
|
+
:line => problem.line_number,
|
21
|
+
:problem => problem.message,
|
22
|
+
:url => problem.url
|
23
|
+
}
|
26
24
|
end
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
def cleanup_color_switches(str)
|
31
|
-
return if str.nil?
|
32
|
-
str.gsub!(%r{^\e\[3[1|2]m}, '')
|
33
|
-
str.gsub!(%r{\e\[0m$}, '')
|
25
|
+
total = ["Found #{@problems.count} errors."]
|
26
|
+
@rails_best_practices_results = {:total => total, :problems => @problems}
|
34
27
|
end
|
35
28
|
|
36
29
|
def to_h
|
data/lib/metric_fu/metrics/rails_best_practices/template_awesome/rails_best_practices.html.erb
CHANGED
@@ -19,7 +19,7 @@
|
|
19
19
|
<% @rails_best_practices[:problems].each do |problem| %>
|
20
20
|
<tr class='<%= cycle("light", "dark", count) %>'>
|
21
21
|
<td><%= link_to_filename(problem[:file], problem[:line]) %></td>
|
22
|
-
<td
|
22
|
+
<td><a href =<%= problem[:url] %>><%= problem[:problem] %></a></td>
|
23
23
|
</tr>
|
24
24
|
<% count += 1 %>
|
25
25
|
<% end %>
|
@@ -1,20 +1,45 @@
|
|
1
|
-
MetricFu
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
"--profile",
|
10
|
-
"--exclude-only '.*'",
|
11
|
-
'--include-file "\Aapp,\Alib"'
|
12
|
-
]
|
13
|
-
rcov_opts << "-Ispec" if File.exist?("spec")
|
14
|
-
config.configure_metric(:rcov,
|
1
|
+
module MetricFu
|
2
|
+
class MetricRcov < Metric
|
3
|
+
|
4
|
+
def name
|
5
|
+
:rcov
|
6
|
+
end
|
7
|
+
|
8
|
+
def default_run_options
|
15
9
|
{ :environment => 'test',
|
16
10
|
:test_files => Dir['{spec,test}/**/*_{spec,test}.rb'],
|
17
11
|
:rcov_opts => rcov_opts,
|
18
12
|
:external => nil
|
19
|
-
}
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
def has_graph?
|
17
|
+
true
|
18
|
+
end
|
19
|
+
|
20
|
+
def enable
|
21
|
+
MetricFu.configuration.mf_debug("rcov is not available. See README")
|
22
|
+
end
|
23
|
+
|
24
|
+
def activate
|
25
|
+
super
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def rcov_opts
|
31
|
+
rcov_opts = [
|
32
|
+
"--sort coverage",
|
33
|
+
"--no-html",
|
34
|
+
"--text-coverage",
|
35
|
+
"--no-color",
|
36
|
+
"--profile",
|
37
|
+
"--exclude-only '.*'",
|
38
|
+
'--include-file "\Aapp,\Alib"'
|
39
|
+
]
|
40
|
+
rcov_opts << "-Ispec" if File.exist?("spec")
|
41
|
+
rcov_opts
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
20
45
|
end
|
@@ -1,10 +1,15 @@
|
|
1
1
|
require 'enumerator'
|
2
|
+
require 'fileutils'
|
2
3
|
|
3
4
|
module MetricFu
|
4
5
|
|
5
|
-
class
|
6
|
+
class RcovGenerator < Generator
|
6
7
|
NEW_FILE_MARKER = /^={80}$/.freeze
|
7
8
|
|
9
|
+
def self.metric
|
10
|
+
:rcov
|
11
|
+
end
|
12
|
+
|
8
13
|
class Line
|
9
14
|
attr_accessor :content, :was_run
|
10
15
|
|
@@ -20,7 +25,7 @@ module MetricFu
|
|
20
25
|
|
21
26
|
def emit
|
22
27
|
if run_rcov?
|
23
|
-
mf_debug "** Running the specs/tests in the [#{
|
28
|
+
mf_debug "** Running the specs/tests in the [#{options[:environment]}] environment"
|
24
29
|
mf_debug "** #{command}"
|
25
30
|
`#{command}`
|
26
31
|
end
|
@@ -35,17 +40,17 @@ module MetricFu
|
|
35
40
|
end
|
36
41
|
|
37
42
|
def default_command
|
38
|
-
FileUtils.rm_rf(MetricFu::
|
39
|
-
Dir.mkdir(MetricFu::
|
40
|
-
output = ">> #{MetricFu::
|
41
|
-
test_files = FileList[*
|
42
|
-
rcov_opts =
|
43
|
-
%Q(RAILS_ENV=#{
|
43
|
+
FileUtils.rm_rf(MetricFu::RcovGenerator.metric_directory, :verbose => false)
|
44
|
+
Dir.mkdir(MetricFu::RcovGenerator.metric_directory)
|
45
|
+
output = ">> #{MetricFu::RcovGenerator.metric_directory}/rcov.txt"
|
46
|
+
test_files = FileList[*options[:test_files]].join(' ')
|
47
|
+
rcov_opts = options[:rcov_opts].join(' ')
|
48
|
+
%Q(RAILS_ENV=#{options[:environment]} rcov #{test_files} #{rcov_opts} #{output})
|
44
49
|
end
|
45
50
|
|
46
51
|
|
47
52
|
def analyze
|
48
|
-
output_file =
|
53
|
+
output_file = options[:external] ? options[:external] : MetricFu::RcovGenerator.metric_directory + '/rcov.txt'
|
49
54
|
output = File.open(output_file).read
|
50
55
|
output = output.split(NEW_FILE_MARKER)
|
51
56
|
|
@@ -132,7 +137,7 @@ module MetricFu
|
|
132
137
|
end
|
133
138
|
|
134
139
|
def run_rcov?
|
135
|
-
!(
|
140
|
+
!(options[:external])
|
136
141
|
end
|
137
142
|
|
138
143
|
end
|
@@ -1,7 +1,26 @@
|
|
1
|
-
MetricFu
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
1
|
+
module MetricFu
|
2
|
+
class MetricReek < Metric
|
3
|
+
|
4
|
+
def name
|
5
|
+
:reek
|
6
|
+
end
|
7
|
+
|
8
|
+
def default_run_options
|
9
|
+
{ :dirs_to_reek => MetricFu::Io::FileSystem.directory('code_dirs'),
|
10
|
+
:config_file_pattern => nil}
|
11
|
+
end
|
12
|
+
|
13
|
+
def has_graph?
|
14
|
+
true
|
15
|
+
end
|
16
|
+
|
17
|
+
def enable
|
18
|
+
super
|
19
|
+
end
|
20
|
+
|
21
|
+
def activate
|
22
|
+
super
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
7
26
|
end
|
@@ -1,42 +1,25 @@
|
|
1
1
|
module MetricFu
|
2
2
|
|
3
|
-
class
|
3
|
+
class ReekGenerator < Generator
|
4
4
|
REEK_REGEX = /^(\S+) (.*) \((.*)\)$/
|
5
5
|
|
6
|
-
def
|
7
|
-
|
8
|
-
files = remove_excluded_files(files_to_reek.flatten)
|
9
|
-
config_file_param = MetricFu.reek[:config_file_pattern] ? "--config #{MetricFu.reek[:config_file_pattern]}" : ''
|
10
|
-
command = %Q(mf-reek #{config_file_param} #{files.join(" ")})
|
11
|
-
mf_debug "** #{command}"
|
12
|
-
@output = `#{command}`
|
13
|
-
@output = massage_for_reek_12 if reek_12?
|
6
|
+
def self.metric
|
7
|
+
:reek
|
14
8
|
end
|
15
9
|
|
16
|
-
def
|
17
|
-
|
18
|
-
|
10
|
+
def emit
|
11
|
+
files = files_to_analyze
|
12
|
+
if files.empty?
|
13
|
+
mf_log "Skipping Reek, no files found to analyze"
|
14
|
+
@output = ""
|
15
|
+
else
|
16
|
+
command = %Q(mf-reek #{cli_options(files)})
|
17
|
+
mf_debug "** #{command}"
|
18
|
+
@output = `#{command}`
|
19
|
+
@output = massage_for_reek_12 if reek_12?
|
20
|
+
end
|
19
21
|
end
|
20
22
|
|
21
|
-
def massage_for_reek_12
|
22
|
-
section_break = ''
|
23
|
-
@output.split("\n").map do |line|
|
24
|
-
case line
|
25
|
-
when /^ /
|
26
|
-
"#{line.gsub(/^ /, '')}\n"
|
27
|
-
else
|
28
|
-
parts = line.split(" -- ")
|
29
|
-
if parts[1].nil?
|
30
|
-
"#{line}\n"
|
31
|
-
else
|
32
|
-
warnings = parts[1].gsub(/ \(.*\):/, ':')
|
33
|
-
result = "#{section_break}\"#{parts[0]}\" -- #{warnings}\n"
|
34
|
-
section_break = "\n"
|
35
|
-
result
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end.join
|
39
|
-
end
|
40
23
|
|
41
24
|
def analyze
|
42
25
|
@matches = @output.chomp.split("\n\n").map{|m| m.split("\n") }
|
@@ -80,5 +63,43 @@ module MetricFu
|
|
80
63
|
end
|
81
64
|
end
|
82
65
|
|
66
|
+
def reek_12?
|
67
|
+
return false if @output.length == 0
|
68
|
+
(@output =~ /^"/) != 0
|
69
|
+
end
|
70
|
+
|
71
|
+
def massage_for_reek_12
|
72
|
+
section_break = ''
|
73
|
+
@output.split("\n").map do |line|
|
74
|
+
case line
|
75
|
+
when /^ /
|
76
|
+
"#{line.gsub(/^ /, '')}\n"
|
77
|
+
else
|
78
|
+
parts = line.split(" -- ")
|
79
|
+
if parts[1].nil?
|
80
|
+
"#{line}\n"
|
81
|
+
else
|
82
|
+
warnings = parts[1].gsub(/ \(.*\):/, ':')
|
83
|
+
result = "#{section_break}\"#{parts[0]}\" -- #{warnings}\n"
|
84
|
+
section_break = "\n"
|
85
|
+
result
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end.join
|
89
|
+
end
|
90
|
+
|
91
|
+
private
|
92
|
+
|
93
|
+
def files_to_analyze
|
94
|
+
dirs_to_reek = options[:dirs_to_reek]
|
95
|
+
files_to_reek = dirs_to_reek.map{|dir| Dir[File.join(dir, "**","*.rb")] }.flatten
|
96
|
+
remove_excluded_files(files_to_reek)
|
97
|
+
end
|
98
|
+
|
99
|
+
def cli_options(files)
|
100
|
+
config_file_param = options[:config_file_pattern] ? "--config #{options[:config_file_pattern]}" : ''
|
101
|
+
cli_options = "#{config_file_param} #{files.join(' ')}"
|
102
|
+
end
|
103
|
+
|
83
104
|
end
|
84
105
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
<h3>Reek Results</h3>
|
2
2
|
|
3
|
-
<p><a href="http://
|
3
|
+
<p><a href="http://github.com/troessner/reek">Reek</a> detects common code smells in ruby code.</p>
|
4
4
|
|
5
5
|
<% graph_name = 'reek' %>
|
6
6
|
<% if MetricFu.configuration.graph_engine == :gchart %>
|
@@ -1,7 +1,26 @@
|
|
1
|
-
MetricFu
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
1
|
+
module MetricFu
|
2
|
+
class MetricRoodi < Metric
|
3
|
+
|
4
|
+
def name
|
5
|
+
:roodi
|
6
|
+
end
|
7
|
+
|
8
|
+
def default_run_options
|
9
|
+
{ :dirs_to_roodi => MetricFu::Io::FileSystem.directory('code_dirs'),
|
10
|
+
:roodi_config => "#{MetricFu::Io::FileSystem.directory('root_directory')}/config/roodi_config.yml"}
|
11
|
+
end
|
12
|
+
|
13
|
+
def has_graph?
|
14
|
+
true
|
15
|
+
end
|
16
|
+
|
17
|
+
def enable
|
18
|
+
super
|
19
|
+
end
|
20
|
+
|
21
|
+
def activate
|
22
|
+
super
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
7
26
|
end
|
@@ -1,10 +1,14 @@
|
|
1
1
|
module MetricFu
|
2
|
-
class
|
2
|
+
class RoodiGenerator < Generator
|
3
|
+
|
4
|
+
def self.metric
|
5
|
+
:roodi
|
6
|
+
end
|
3
7
|
|
4
8
|
def emit
|
5
|
-
files_to_analyze =
|
9
|
+
files_to_analyze = options[:dirs_to_roodi].map{|dir| Dir[File.join(dir, "**/*.rb")] }
|
6
10
|
files = remove_excluded_files(files_to_analyze.flatten)
|
7
|
-
config =
|
11
|
+
config = options[:roodi_config] ? "-config=#{options[:roodi_config]}" : ""
|
8
12
|
command = %Q(mf-roodi #{config} #{files.join(" ")})
|
9
13
|
mf_debug "** #{command}"
|
10
14
|
@output = `#{command}`
|
@@ -1,11 +1,27 @@
|
|
1
|
-
MetricFu
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
1
|
+
module MetricFu
|
2
|
+
class MetricSaikuro < Metric
|
3
|
+
|
4
|
+
def name
|
5
|
+
:saikuro
|
6
|
+
end
|
7
|
+
|
8
|
+
def default_run_options
|
9
|
+
{ :output_directory => "#{MetricFu::Io::FileSystem.directory('scratch_directory')}/saikuro",
|
10
|
+
:input_directory =>MetricFu::Io::FileSystem.directory('code_dirs'),
|
6
11
|
:cyclo => "",
|
7
12
|
:filter_cyclo => "0",
|
8
13
|
:warn_cyclo => "5",
|
9
14
|
:error_cyclo => "7",
|
10
|
-
:formater => "text"}
|
15
|
+
:formater => "text"}
|
16
|
+
end
|
17
|
+
|
18
|
+
def has_graph?
|
19
|
+
false
|
20
|
+
end
|
21
|
+
|
22
|
+
def enable
|
23
|
+
super
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
11
27
|
end
|