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,11 @@
|
|
1
1
|
module MetricFu
|
2
|
-
class
|
2
|
+
class CaneGenerator < Generator
|
3
3
|
attr_reader :violations, :total_violations
|
4
4
|
|
5
|
+
def self.metric
|
6
|
+
:cane
|
7
|
+
end
|
8
|
+
|
5
9
|
def emit
|
6
10
|
command = %Q{mf-cane#{abc_max_param}#{style_measure_param}#{no_doc_param}#{no_readme_param}}
|
7
11
|
mf_debug "** #{command}"
|
@@ -19,19 +23,19 @@ module MetricFu
|
|
19
23
|
private
|
20
24
|
|
21
25
|
def abc_max_param
|
22
|
-
|
26
|
+
options[:abc_max] ? " --abc-max #{options[:abc_max]}" : ""
|
23
27
|
end
|
24
28
|
|
25
29
|
def style_measure_param
|
26
|
-
|
30
|
+
options[:line_length] ? " --style-measure #{options[:line_length]}" : ""
|
27
31
|
end
|
28
32
|
|
29
33
|
def no_doc_param
|
30
|
-
|
34
|
+
options[:no_doc] == 'y' ? " --no-doc" : ""
|
31
35
|
end
|
32
36
|
|
33
37
|
def no_readme_param
|
34
|
-
|
38
|
+
options[:no_readme] == 'y' ? " --no-readme" : ""
|
35
39
|
end
|
36
40
|
|
37
41
|
def violations_by_category
|
@@ -1,14 +1,36 @@
|
|
1
|
-
MetricFu
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
1
|
+
module MetricFu
|
2
|
+
class MetricCane < Metric
|
3
|
+
|
4
|
+
def name
|
5
|
+
:cane
|
6
|
+
end
|
7
|
+
|
8
|
+
def default_run_options
|
9
|
+
{
|
10
|
+
:dirs_to_cane => MetricFu::Io::FileSystem.directory('code_dirs'),
|
11
|
+
:abc_max => 15,
|
12
|
+
:line_length => 80,
|
13
|
+
:no_doc => 'n',
|
14
|
+
:no_readme => 'n',
|
15
|
+
:filetypes => ['rb']
|
16
|
+
}
|
17
|
+
end
|
18
|
+
|
19
|
+
def has_graph?
|
20
|
+
true
|
21
|
+
end
|
14
22
|
|
23
|
+
def enable
|
24
|
+
if MetricFu.configuration.supports_ripper? && !MetricFu.configuration.ruby18?
|
25
|
+
super
|
26
|
+
else
|
27
|
+
MetricFu.configuration.mf_debug("Cane is only available in MRI. It requires ripper and 1.9 hash syntax support")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def activate
|
32
|
+
super
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
@@ -1,5 +1,25 @@
|
|
1
|
-
MetricFu
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
module MetricFu
|
2
|
+
class MetricChurn < Metric
|
3
|
+
|
4
|
+
def name
|
5
|
+
:churn
|
6
|
+
end
|
7
|
+
|
8
|
+
def default_run_options
|
9
|
+
{ :start_date => %q("1 year ago"), :minimum_churn_count => 10}
|
10
|
+
end
|
11
|
+
|
12
|
+
def has_graph?
|
13
|
+
false
|
14
|
+
end
|
15
|
+
|
16
|
+
def enable
|
17
|
+
super
|
18
|
+
end
|
19
|
+
|
20
|
+
def activate
|
21
|
+
super
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
5
25
|
end
|
@@ -1,11 +1,15 @@
|
|
1
1
|
module MetricFu
|
2
2
|
|
3
|
-
class
|
3
|
+
class FlayGenerator < Generator
|
4
|
+
|
5
|
+
def self.metric
|
6
|
+
:flay
|
7
|
+
end
|
4
8
|
|
5
9
|
def emit
|
6
|
-
minimum_score_parameter =
|
10
|
+
minimum_score_parameter = options[:minimum_score] ? "--mass #{options[:minimum_score]} " : ""
|
7
11
|
|
8
|
-
command = %Q(mf-flay #{minimum_score_parameter} #{
|
12
|
+
command = %Q(mf-flay #{minimum_score_parameter} #{options[:dirs_to_flay].join(" ")})
|
9
13
|
mf_debug "** #{command}"
|
10
14
|
@output = `#{command}`
|
11
15
|
end
|
@@ -1,14 +1,30 @@
|
|
1
|
-
MetricFu
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
1
|
+
module MetricFu
|
2
|
+
class MetricFlay < Metric
|
3
|
+
|
4
|
+
def name
|
5
|
+
:flay
|
6
|
+
end
|
7
|
+
|
8
|
+
def default_run_options
|
9
|
+
{ :dirs_to_flay => MetricFu::Io::FileSystem.directory('code_dirs'),
|
10
|
+
# MetricFu has been setting the minimum score as 100 for
|
11
|
+
# a long time. This is a really big number, considering
|
12
|
+
# the default is 16. Setting it to nil to use the Flay default.
|
13
|
+
:minimum_score => nil,
|
14
|
+
:filetypes => ['rb'] }
|
15
|
+
end
|
16
|
+
|
17
|
+
def has_graph?
|
18
|
+
true
|
19
|
+
end
|
20
|
+
|
21
|
+
def enable
|
22
|
+
super
|
23
|
+
end
|
24
|
+
|
25
|
+
def activate
|
26
|
+
super
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
14
30
|
end
|
@@ -11,7 +11,7 @@
|
|
11
11
|
<% end %>
|
12
12
|
|
13
13
|
<h4>Total Score (lower is better): <%= @flay[:total_score] %></h4>
|
14
|
-
<h5>Scores less than <%= MetricFu.flay[:minimum_score] %> are not shown or part of the total</h5>
|
14
|
+
<h5>Scores less than <%= MetricFu::Metric.get_metric('flay').run_options[:minimum_score] %> are not shown or part of the total</h5>
|
15
15
|
|
16
16
|
<table>
|
17
17
|
<tr>
|
@@ -1,58 +1,34 @@
|
|
1
1
|
require 'pathname'
|
2
2
|
require 'optparse'
|
3
|
-
|
4
|
-
class RubyParser
|
5
|
-
alias_method :original_process, :process
|
6
|
-
def process(s,f,t)
|
7
|
-
original_process(s,f,t)
|
8
|
-
rescue => e
|
9
|
-
if e.message =~ /wrong number of arguments/
|
10
|
-
original_process(s,f)
|
11
|
-
else
|
12
|
-
raise
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
3
|
+
|
16
4
|
module MetricFu
|
5
|
+
class FlogGenerator < Generator
|
17
6
|
|
18
|
-
|
7
|
+
def self.metric
|
8
|
+
:flog
|
9
|
+
end
|
19
10
|
|
20
11
|
def emit
|
21
|
-
|
22
|
-
MetricFu.flog[:dirs_to_flog].each do |directory|
|
23
|
-
directory = "." if directory=='./'
|
24
|
-
dir_files = Dir.glob("#{directory}/**/*.rb")
|
25
|
-
dir_files = remove_excluded_files(dir_files)
|
26
|
-
files += dir_files
|
27
|
-
end
|
28
|
-
options = ::Flog.parse_options [
|
12
|
+
parse_options = FlogCLI.parse_options [
|
29
13
|
"--all",
|
30
|
-
|
14
|
+
options[:continue] ? "--continue" : nil,
|
31
15
|
].compact
|
32
|
-
|
33
|
-
@flogger
|
34
|
-
@flogger.flog files
|
35
|
-
|
36
|
-
rescue LoadError => e
|
37
|
-
message = "#{e.class}\t#{e.message}\n\t#{e.backtrace.join('\n\t')}"
|
38
|
-
if MetricFu.configuration.mri?
|
39
|
-
mf_log "Flog Error: #{message}"
|
40
|
-
else
|
41
|
-
mf_log "Flog tasks only available in MRI: #{message}"
|
42
|
-
end
|
16
|
+
@flogger = FlogCLI.new parse_options
|
17
|
+
@flogger.flog *options[:dirs_to_flog]
|
43
18
|
end
|
44
19
|
|
45
20
|
def analyze
|
46
21
|
@method_containers = {}
|
47
|
-
@flogger.
|
22
|
+
@flogger.calculate
|
23
|
+
@flogger.each_by_score do |full_method_name, score, operators|
|
48
24
|
container_name = full_method_name.split('#').first
|
49
25
|
path = @flogger.method_locations[full_method_name]
|
50
26
|
if @method_containers[container_name]
|
51
|
-
@method_containers[container_name].add_method(full_method_name, operators,
|
27
|
+
@method_containers[container_name].add_method(full_method_name, operators, score, path)
|
52
28
|
@method_containers[container_name].add_path(path)
|
53
29
|
else
|
54
30
|
mc = MethodContainer.new(container_name, path)
|
55
|
-
mc.add_method(full_method_name, operators,
|
31
|
+
mc.add_method(full_method_name, operators, score, path)
|
56
32
|
@method_containers[container_name] = mc
|
57
33
|
end
|
58
34
|
end
|
@@ -60,7 +36,7 @@ module MetricFu
|
|
60
36
|
|
61
37
|
def to_h
|
62
38
|
sorted_containers = @method_containers.values.sort_by {|c| c.highest_score}.reverse
|
63
|
-
{:flog => { :total => @flogger.
|
39
|
+
{:flog => { :total => @flogger.total_score,
|
64
40
|
:average => @flogger.average,
|
65
41
|
:method_containers => sorted_containers.map {|method_container| method_container.to_h}}}
|
66
42
|
end
|
@@ -1,8 +1,31 @@
|
|
1
|
-
MetricFu
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
1
|
+
module MetricFu
|
2
|
+
class MetricFlog < Metric
|
3
|
+
|
4
|
+
def name
|
5
|
+
:flog
|
6
|
+
end
|
7
|
+
|
8
|
+
def default_run_options
|
9
|
+
{ :dirs_to_flog => MetricFu::Io::FileSystem.directory('code_dirs'), :continue => true, :all => true, :quiet => true }
|
10
|
+
end
|
11
|
+
|
12
|
+
def has_graph?
|
13
|
+
true
|
14
|
+
end
|
15
|
+
|
16
|
+
def enable
|
17
|
+
if MetricFu.configuration.mri?
|
18
|
+
super
|
19
|
+
else
|
20
|
+
MetricFu.configuration.mf_debug("Flog is only available in MRI due to flog tasks")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def activate
|
25
|
+
activate_library 'flog'
|
26
|
+
activate_library 'flog_cli'
|
27
|
+
super
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
8
31
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'fileutils'
|
1
2
|
module MetricFu
|
2
3
|
|
3
4
|
# = Generator
|
@@ -39,6 +40,20 @@ module MetricFu
|
|
39
40
|
create_data_dir_if_missing
|
40
41
|
end
|
41
42
|
|
43
|
+
@generators = []
|
44
|
+
# @return all subclassed generators [Array<MetricFu::Generator>]
|
45
|
+
def self.generators
|
46
|
+
@generators
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.get_generator(metric)
|
50
|
+
generators.find{|generator|generator.metric.to_s == metric.to_s.downcase}
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.inherited(subclass)
|
54
|
+
@generators << subclass
|
55
|
+
end
|
56
|
+
|
42
57
|
# Creates a new generator and returns the output of the
|
43
58
|
# #generate_result method. This is the typical way to
|
44
59
|
# generate a new MetricFu result. For more information see
|
@@ -70,7 +85,7 @@ module MetricFu
|
|
70
85
|
|
71
86
|
# Returns the directory where the Generator will write any output
|
72
87
|
def self.metric_directory
|
73
|
-
File.join(MetricFu.scratch_directory, class_name)
|
88
|
+
File.join(MetricFu::Io::FileSystem.directory('scratch_directory'), class_name)
|
74
89
|
end
|
75
90
|
|
76
91
|
def create_metric_dir_if_missing #:nodoc:
|
@@ -80,14 +95,14 @@ module MetricFu
|
|
80
95
|
end
|
81
96
|
|
82
97
|
def create_output_dir_if_missing #:nodoc:
|
83
|
-
unless File.directory?(MetricFu.output_directory)
|
84
|
-
FileUtils.mkdir_p(MetricFu.output_directory, :verbose => false)
|
98
|
+
unless File.directory?(MetricFu::Io::FileSystem.directory('output_directory'))
|
99
|
+
FileUtils.mkdir_p(MetricFu::Io::FileSystem.directory('output_directory'), :verbose => false)
|
85
100
|
end
|
86
101
|
end
|
87
102
|
|
88
103
|
def create_data_dir_if_missing #:nodoc:
|
89
|
-
unless File.directory?(MetricFu.data_directory)
|
90
|
-
FileUtils.mkdir_p(MetricFu.data_directory, :verbose => false)
|
104
|
+
unless File.directory?(MetricFu::Io::FileSystem.directory('data_directory'))
|
105
|
+
FileUtils.mkdir_p(MetricFu::Io::FileSystem.directory('data_directory'), :verbose => false)
|
91
106
|
end
|
92
107
|
end
|
93
108
|
|
@@ -97,7 +112,7 @@ module MetricFu
|
|
97
112
|
self.class.metric_directory
|
98
113
|
end
|
99
114
|
|
100
|
-
def remove_excluded_files(paths, globs_to_remove = MetricFu.file_globs_to_ignore)
|
115
|
+
def remove_excluded_files(paths, globs_to_remove = MetricFu::Io::FileSystem.file_globs_to_ignore)
|
101
116
|
files_to_remove = []
|
102
117
|
globs_to_remove.each do |glob|
|
103
118
|
files_to_remove.concat(Dir[glob])
|
@@ -12,7 +12,7 @@ module MetricFu
|
|
12
12
|
self.clazz = []
|
13
13
|
end
|
14
14
|
|
15
|
-
def add(graph_type, graph_engine, output_directory = MetricFu.output_directory)
|
15
|
+
def add(graph_type, graph_engine, output_directory = MetricFu::Io::FileSystem.directory('output_directory'))
|
16
16
|
grapher_name = graph_type.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase } + graph_engine.to_s.capitalize + "Grapher"
|
17
17
|
self.clazz.push MetricFu.const_get(grapher_name).new.tap{|g| g.output_directory = output_directory }
|
18
18
|
end
|
@@ -21,7 +21,7 @@ module MetricFu
|
|
21
21
|
def generate
|
22
22
|
return if self.clazz.empty?
|
23
23
|
mf_log "Generating graphs"
|
24
|
-
Dir[File.join(MetricFu.data_directory, '*.yml')].sort.each do |metric_file|
|
24
|
+
Dir[File.join(MetricFu::Io::FileSystem.directory('data_directory'), '*.yml')].sort.each do |metric_file|
|
25
25
|
mf_log "Generating graphs for #{metric_file}"
|
26
26
|
date_parts = year_month_day_from_filename(metric_file)
|
27
27
|
metrics = YAML::load(File.open(metric_file))
|
@@ -1,6 +1,22 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
1
|
+
module MetricFu
|
2
|
+
class MetricHotspots < Metric
|
3
|
+
|
4
|
+
def name
|
5
|
+
:hotspots
|
6
|
+
end
|
7
|
+
|
8
|
+
# TODO remove explicit Churn dependency
|
9
|
+
def default_run_options
|
10
|
+
{ :start_date => "1 year ago", :minimum_churn_count => 10}
|
11
|
+
end
|
12
|
+
|
13
|
+
def has_graph?
|
14
|
+
false
|
15
|
+
end
|
16
|
+
|
17
|
+
def enable
|
18
|
+
super
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
6
22
|
end
|