metric_fu 4.4.4 → 4.5.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +14 -6
- checksums.yaml.gz.sig +3 -0
- data.tar.gz.sig +0 -0
- data/.gitignore +1 -0
- data/.metrics +0 -3
- data/.travis.yml +1 -1
- data/.yardopts +0 -1
- data/CONTRIBUTING.md +1 -0
- data/CONTRIBUTORS +61 -2
- data/Gemfile +14 -11
- data/Gemfile.devtools +40 -0
- data/Guardfile +30 -0
- data/HISTORY.md +54 -1
- data/README.md +86 -56
- data/bin/mf-cane +8 -6
- data/bin/mf-churn +8 -7
- data/bin/mf-flay +8 -7
- data/bin/mf-reek +8 -7
- data/bin/mf-roodi +8 -7
- data/bin/mf-saikuro +8 -6
- data/certs/bf4.pem +22 -0
- data/checksum/metric_fu-4.4.4.gem.sha512 +1 -0
- data/checksum/metric_fu-4.5.0.gem.sha512 +1 -0
- data/etc/README.md +16 -0
- data/etc/erd.dot +173 -0
- data/etc/erd.png +0 -0
- data/lib/metric_fu.rb +56 -12
- data/lib/metric_fu/cli/helper.rb +8 -2
- data/lib/metric_fu/cli/parser.rb +86 -50
- data/lib/metric_fu/configuration.rb +4 -31
- data/lib/metric_fu/environment.rb +1 -1
- data/lib/metric_fu/formatter/html.rb +5 -5
- data/lib/metric_fu/gem_run.rb +68 -0
- data/lib/metric_fu/gem_version.rb +57 -0
- data/lib/metric_fu/io.rb +1 -1
- data/lib/metric_fu/load_files.rb +3 -5
- data/lib/metric_fu/loader.rb +31 -2
- data/lib/metric_fu/logging/mf_debugger.rb +1 -0
- data/lib/metric_fu/metric.rb +23 -1
- data/lib/metric_fu/metrics/cane/cane.rb +7 -3
- data/lib/metric_fu/metrics/cane/cane_grapher.rb +19 -0
- data/lib/metric_fu/metrics/cane/template_awesome/cane.html.erb +0 -4
- data/lib/metric_fu/metrics/churn/churn.rb +6 -7
- data/lib/metric_fu/metrics/flay/flay.rb +2 -4
- data/lib/metric_fu/metrics/flay/flay_grapher.rb +19 -0
- data/lib/metric_fu/metrics/flay/template_awesome/flay.html.erb +0 -4
- data/lib/metric_fu/metrics/flog/flog.rb +0 -2
- data/lib/metric_fu/metrics/flog/flog_grapher.rb +19 -0
- data/lib/metric_fu/metrics/flog/template_awesome/flog.html.erb +0 -4
- data/lib/metric_fu/metrics/generator.rb +34 -24
- data/lib/metric_fu/metrics/graph.rb +8 -14
- data/lib/metric_fu/metrics/hotspots/hotspot.rb +7 -5
- data/lib/metric_fu/metrics/hotspots/template_awesome/hotspots.html.erb +4 -6
- data/lib/metric_fu/metrics/rails_best_practices/rails_best_practices.rb +0 -2
- data/lib/metric_fu/metrics/rails_best_practices/rails_best_practices_grapher.rb +19 -0
- data/lib/metric_fu/metrics/rails_best_practices/template_awesome/rails_best_practices.html.erb +0 -4
- data/lib/metric_fu/metrics/rcov/rcov_grapher.rb +19 -0
- data/lib/metric_fu/metrics/rcov/template_awesome/rcov.html.erb +0 -4
- data/lib/metric_fu/metrics/reek/init.rb +1 -1
- data/lib/metric_fu/metrics/reek/reek.rb +12 -8
- data/lib/metric_fu/metrics/reek/reek_grapher.rb +19 -0
- data/lib/metric_fu/metrics/reek/template_awesome/reek.html.erb +0 -4
- data/lib/metric_fu/metrics/roodi/roodi.rb +2 -3
- data/lib/metric_fu/metrics/roodi/roodi_grapher.rb +19 -0
- data/lib/metric_fu/metrics/roodi/template_awesome/roodi.html.erb +0 -4
- data/lib/metric_fu/metrics/saikuro/saikuro.rb +69 -33
- data/lib/metric_fu/metrics/saikuro/scratch_file.rb +8 -9
- data/lib/metric_fu/metrics/stats/stats_grapher.rb +20 -0
- data/lib/metric_fu/metrics/stats/template_awesome/stats.html.erb +0 -4
- data/lib/metric_fu/reporting/graphs/grapher.rb +69 -3
- data/lib/metric_fu/reporting/result.rb +5 -1
- data/lib/metric_fu/reporting/templates/awesome/awesome_template.rb +7 -3
- data/lib/metric_fu/run.rb +13 -7
- data/lib/metric_fu/tasks/metric_fu.rake +50 -3
- data/lib/metric_fu/utility.rb +10 -0
- data/lib/metric_fu/version.rb +1 -1
- data/metric_fu.gemspec +7 -4
- data/spec/dummy/.gitignore +1 -0
- data/spec/dummy/.gitkeep +0 -0
- data/spec/dummy/.metrics +4 -0
- data/spec/dummy/lib/.gitkeep +0 -0
- data/spec/dummy/spec/.gitkeep +0 -0
- data/spec/{resources/yml → fixtures}/20090630.yml +1 -1
- data/spec/{resources/yml → fixtures}/hotspots/flog.yml +0 -0
- data/spec/{resources/yml → fixtures}/hotspots/generator.yml +0 -0
- data/spec/{resources/yml → fixtures}/hotspots/generator_analysis.yml +0 -0
- data/spec/{resources/yml → fixtures}/hotspots/reek.yml +0 -0
- data/spec/{resources/yml → fixtures}/hotspots/roodi.yml +0 -0
- data/spec/{resources/yml → fixtures}/hotspots/saikuro.yml +0 -0
- data/spec/{resources/yml → fixtures}/hotspots/several_metrics.yml +0 -0
- data/spec/{resources/yml → fixtures}/hotspots/stats.yml +0 -0
- data/spec/{resources/yml → fixtures}/hotspots/three_metrics_on_same_file.yml +0 -0
- data/spec/{resources → fixtures}/line_numbers/foo.rb +0 -0
- data/spec/{resources → fixtures}/line_numbers/module.rb +0 -0
- data/spec/{resources → fixtures}/line_numbers/module_surrounds_class.rb +0 -0
- data/spec/{resources → fixtures}/line_numbers/two_classes.rb +0 -0
- data/spec/{resources/yml → fixtures}/metric_missing.yml +0 -0
- data/spec/{resources → fixtures}/saikuro/app/controllers/sessions_controller.rb_cyclo.html +0 -0
- data/spec/{resources → fixtures}/saikuro/app/controllers/users_controller.rb_cyclo.html +0 -0
- data/spec/{resources → fixtures}/saikuro/index_cyclo.html +0 -0
- data/spec/{resources → fixtures}/saikuro_sfiles/thing.rb_cyclo.html +0 -0
- data/spec/metric_fu/configuration_spec.rb +1 -1
- data/spec/metric_fu/data_structures/line_numbers_spec.rb +13 -11
- data/spec/metric_fu/formatter/html_spec.rb +2 -2
- data/spec/metric_fu/gem_version_spec.rb +14 -0
- data/spec/metric_fu/loader_spec.rb +12 -0
- data/spec/metric_fu/metrics/base_template_spec.rb +9 -7
- data/spec/metric_fu/metrics/cane/cane_spec.rb +7 -7
- data/spec/metric_fu/metrics/churn/churn_spec.rb +1 -1
- data/spec/metric_fu/metrics/flay/flay_grapher_spec.rb +2 -2
- data/spec/metric_fu/metrics/flay/flay_spec.rb +2 -2
- data/spec/metric_fu/metrics/flog/flog_grapher_spec.rb +3 -3
- data/spec/metric_fu/metrics/generator_spec.rb +1 -35
- data/spec/metric_fu/metrics/graph_spec.rb +7 -24
- data/spec/metric_fu/metrics/hotspots/analysis/analyzed_problems_spec.rb +2 -2
- data/spec/metric_fu/metrics/hotspots/analysis/analyzer_tables_spec.rb +2 -2
- data/spec/metric_fu/metrics/hotspots/analysis/rankings_spec.rb +5 -5
- data/spec/metric_fu/metrics/hotspots/hotspots_spec.rb +2 -3
- data/spec/metric_fu/metrics/rails_best_practices/rails_best_practices_grapher_spec.rb +2 -2
- data/spec/metric_fu/metrics/rails_best_practices/rails_best_practices_spec.rb +1 -1
- data/spec/metric_fu/metrics/rcov/rcov_grapher_spec.rb +2 -2
- data/spec/metric_fu/metrics/rcov/rcov_spec.rb +1 -4
- data/spec/metric_fu/metrics/reek/reek_grapher_spec.rb +2 -2
- data/spec/metric_fu/metrics/reek/reek_spec.rb +1 -1
- data/spec/metric_fu/metrics/roodi/roodi_grapher_spec.rb +2 -2
- data/spec/metric_fu/metrics/roodi/roodi_spec.rb +3 -3
- data/spec/metric_fu/metrics/saikuro/saikuro_spec.rb +14 -10
- data/spec/metric_fu/metrics/stats/stats_grapher_spec.rb +2 -2
- data/spec/metric_fu/reporting/graphs/{engines/bluff_spec.rb → grapher_spec.rb} +8 -2
- data/spec/{run_spec.rb → metric_fu/run_spec.rb} +8 -13
- data/spec/spec_helper.rb +30 -5
- data/spec/support/deferred_garbaged_collection.rb +34 -0
- data/spec/support/helper_methods.rb +1 -15
- data/spec/support/suite.rb +4 -24
- data/spec/support/test_fixtures.rb +39 -0
- data/spec/support/timeout.rb +7 -0
- metadata +129 -104
- metadata.gz.sig +1 -0
- data/lib/metric_fu/metrics/cane/cane_bluff_grapher.rb +0 -16
- data/lib/metric_fu/metrics/cane/cane_gchart_grapher.rb +0 -25
- data/lib/metric_fu/metrics/flay/flay_bluff_grapher.rb +0 -16
- data/lib/metric_fu/metrics/flay/flay_gchart_grapher.rb +0 -20
- data/lib/metric_fu/metrics/flog/flog_bluff_grapher.rb +0 -17
- data/lib/metric_fu/metrics/flog/flog_gchart_grapher.rb +0 -28
- data/lib/metric_fu/metrics/rails_best_practices/rails_best_practices_bluff_grapher.rb +0 -16
- data/lib/metric_fu/metrics/rails_best_practices/rails_best_practices_gchart_grapher.rb +0 -27
- data/lib/metric_fu/metrics/rcov/rcov_bluff_grapher.rb +0 -16
- data/lib/metric_fu/metrics/rcov/rcov_gchart_grapher.rb +0 -22
- data/lib/metric_fu/metrics/reek/reek_bluff_grapher.rb +0 -16
- data/lib/metric_fu/metrics/reek/reek_gchart_grapher.rb +0 -30
- data/lib/metric_fu/metrics/roodi/roodi_bluff_grapher.rb +0 -16
- data/lib/metric_fu/metrics/roodi/roodi_gchart_grapher.rb +0 -20
- data/lib/metric_fu/metrics/stats/stats_bluff_grapher.rb +0 -17
- data/lib/metric_fu/metrics/stats/stats_gchart_grapher.rb +0 -27
- data/lib/metric_fu/reporting/graphs/engines/bluff.rb +0 -33
- data/lib/metric_fu/reporting/graphs/engines/gchart.rb +0 -72
- data/lib/metric_fu/reporting/graphs/engines/init.rb +0 -19
- data/lib/metric_fu_requires.rb +0 -63
- data/spec/metric_fu/reporting/graphs/engines/gchart_spec.rb +0 -161
data/lib/metric_fu/cli/parser.rb
CHANGED
@@ -13,72 +13,102 @@ module MetricFu
|
|
13
13
|
yield self if block_given?
|
14
14
|
end
|
15
15
|
|
16
|
+
def process!(arguments = ARGV)
|
17
|
+
parser = build_option_parser
|
18
|
+
process_options(parser, arguments)
|
19
|
+
end
|
20
|
+
|
16
21
|
def option(name, desc, settings = {})
|
17
22
|
@options << [name, desc, settings]
|
18
23
|
end
|
19
24
|
|
20
|
-
def short_from(name)
|
21
|
-
name.to_s.chars.each do |c|
|
22
|
-
next if @used_short.include?(c) || c == "_"
|
23
|
-
return c # returns from short_from method
|
24
|
-
end
|
25
|
-
end
|
26
25
|
|
27
|
-
|
26
|
+
private
|
27
|
+
|
28
|
+
def build_option_parser
|
28
29
|
@result = (@default_values || {}).clone # reset or new
|
30
|
+
|
29
31
|
@optionparser ||= OptionParser.new do |p| # prepare only once
|
30
|
-
|
31
|
-
@used_short << short = o[2][:short] || short_from(o[0])
|
32
|
-
@result[o[0]] = o[2][:default] || false # set default
|
33
|
-
klass = o[2][:default].class == Fixnum ? Integer : o[2][:default].class
|
34
|
-
|
35
|
-
if [TrueClass, FalseClass, NilClass].include?(klass) # boolean switch
|
36
|
-
p.on("-" << short, "--[no-]" << o[0].to_s.gsub("_", "-"), o[1]) {|x| @result[o[0]] = x}
|
37
|
-
else # argument with parameter
|
38
|
-
p.on("-" << short, "--" << o[0].to_s.gsub("_", "-") << " " << o[2][:default].to_s, klass, o[1]) {|x| @result[o[0]] = x}
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
p.on("--format FORMAT",
|
43
|
-
"Specify the formatter to use for output.",
|
44
|
-
"This option can be specified multiple times.",
|
45
|
-
"Specify a built-in formatter from the list below,",
|
46
|
-
"or the fully-qualified class name of your own custom formatter.",
|
47
|
-
*format_descriptions) do |f|
|
48
|
-
@result[:format] ||= []
|
49
|
-
@result[:format] << [f]
|
50
|
-
end
|
51
|
-
|
52
|
-
p.on("--out FILE|DIR",
|
53
|
-
"Specify the file or directory to use for output",
|
54
|
-
"This option applies to the previously",
|
55
|
-
"specified --format, or the default format",
|
56
|
-
"if no format is specified. Paths are relative to",
|
57
|
-
"#{Pathname.pwd.join(MetricFu::Io::FileSystem.directory('base_directory'))}",
|
58
|
-
"Check the specific formatter\'s docs to see",
|
59
|
-
"whether to pass a file or a dir.") do |o|
|
60
|
-
@result[:format] ||= MetricFu::Formatter::DEFAULT
|
61
|
-
@result[:format].last << o
|
62
|
-
end
|
63
|
-
|
64
|
-
p.banner = @banner unless @banner.nil?
|
65
|
-
p.on_tail("-h", "--help", "Show this message") {puts p ; exit}
|
66
|
-
short = @used_short.include?("v") ? "-V" : "-v"
|
67
|
-
p.on_tail(short, "--version", "Print version") {puts @version ; exit} unless @version.nil?
|
68
|
-
p.on_tail("--debug-info", "Print debug info") { debug_info; exit }
|
69
|
-
@default_values = @result.clone # save default values to reset @result in subsequent calls
|
32
|
+
configure_options(p)
|
70
33
|
end
|
34
|
+
end
|
71
35
|
|
36
|
+
def process_options(parser, arguments)
|
72
37
|
begin
|
73
|
-
|
38
|
+
parser.parse!(arguments)
|
74
39
|
rescue OptionParser::ParseError => e
|
75
|
-
puts e.message
|
40
|
+
puts e.message
|
41
|
+
MetricFu::Cli.immediate_shutdown!
|
76
42
|
end
|
77
43
|
|
78
|
-
validate(@result) if self.respond_to?("validate")
|
79
44
|
@result
|
80
45
|
end
|
81
46
|
|
47
|
+
def configure_options(p)
|
48
|
+
add_general_options(@options, p)
|
49
|
+
|
50
|
+
add_format_option(p)
|
51
|
+
add_output_option(p)
|
52
|
+
|
53
|
+
p.banner = @banner unless @banner.nil?
|
54
|
+
p.on_tail("-h", "--help", "Show this message") {puts p ; success!}
|
55
|
+
short = @used_short.include?("v") ? "-V" : "-v"
|
56
|
+
p.on_tail(short, "--version", "Print version") {puts @version ; success!} unless @version.nil?
|
57
|
+
p.on_tail("--debug-info", "Print debug info") { debug_info; success! }
|
58
|
+
@default_values = @result.clone # save default values to reset @result in subsequent calls
|
59
|
+
end
|
60
|
+
|
61
|
+
def add_general_options(options, p)
|
62
|
+
options.each do |o|
|
63
|
+
add_general_option(p, o)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def add_general_option(p, o)
|
68
|
+
@used_short << short = o[2][:short] || short_from(o[0])
|
69
|
+
@result[o[0]] = o[2][:default] || false # set default
|
70
|
+
klass = o[2][:default].class == Fixnum ? Integer : o[2][:default].class
|
71
|
+
|
72
|
+
if [TrueClass, FalseClass, NilClass].include?(klass) # boolean switch
|
73
|
+
p.on("-" << short, "--[no-]" << o[0].to_s.gsub("_", "-"), o[1]) {|x| @result[o[0]] = x}
|
74
|
+
else # argument with parameter
|
75
|
+
p.on("-" << short, "--" << o[0].to_s.gsub("_", "-") << " " << o[2][:default].to_s, klass, o[1]) {|x| @result[o[0]] = x}
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def add_output_option(p)
|
80
|
+
p.on("--out FILE|DIR",
|
81
|
+
"Specify the file or directory to use for output",
|
82
|
+
"This option applies to the previously",
|
83
|
+
"specified --format, or the default format",
|
84
|
+
"if no format is specified. Paths are relative to",
|
85
|
+
"#{MetricFu.run_path.join(MetricFu::Io::FileSystem.directory('base_directory'))}",
|
86
|
+
"Check the specific formatter\'s docs to see",
|
87
|
+
"whether to pass a file or a dir.") do |o|
|
88
|
+
@result[:format] ||= MetricFu::Formatter::DEFAULT
|
89
|
+
@result[:format].last << o
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def add_format_option(p)
|
94
|
+
p.on("--format FORMAT",
|
95
|
+
"Specify the formatter to use for output.",
|
96
|
+
"This option can be specified multiple times.",
|
97
|
+
"Specify a built-in formatter from the list below,",
|
98
|
+
"or the fully-qualified class name of your own custom formatter.",
|
99
|
+
*format_descriptions) do |f|
|
100
|
+
@result[:format] ||= []
|
101
|
+
@result[:format] << [f]
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def short_from(name)
|
106
|
+
name.to_s.chars.each do |c|
|
107
|
+
next if @used_short.include?(c) || c == "_"
|
108
|
+
return c # returns from short_from method
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
82
112
|
def debug_info
|
83
113
|
extend(MetricFu::Environment)
|
84
114
|
require 'pp'
|
@@ -99,6 +129,12 @@ module MetricFu
|
|
99
129
|
" #{key}#{' ' * (max - key.length)} : #{formats[key][1]}"
|
100
130
|
end
|
101
131
|
end
|
132
|
+
|
133
|
+
def success!
|
134
|
+
MetricFu::Cli.complete!
|
135
|
+
end
|
136
|
+
|
137
|
+
|
102
138
|
end
|
103
139
|
end
|
104
140
|
|
@@ -52,12 +52,6 @@ module MetricFu
|
|
52
52
|
# config.configure_formatter(:yaml, "customreport.yml")
|
53
53
|
# config.configure_formatter(MyCustomFormatter)
|
54
54
|
#
|
55
|
-
# == Graph Configuration
|
56
|
-
#
|
57
|
-
# Graphing engine can be configured by e.g.
|
58
|
-
# config.configure_graph_engine(:bluff)
|
59
|
-
#
|
60
|
-
#
|
61
55
|
class Configuration
|
62
56
|
require_relative 'environment'
|
63
57
|
require_relative 'io'
|
@@ -83,17 +77,16 @@ module MetricFu
|
|
83
77
|
MetricFu::Io::FileSystem.set_directories
|
84
78
|
MetricFu::Formatter::Templates.configure_template(self)
|
85
79
|
@formatters = []
|
86
|
-
@graph_engine_config = MetricFu::GraphEngine.new
|
87
80
|
end
|
88
81
|
|
89
82
|
# This allows us to have a nice syntax like:
|
90
83
|
#
|
91
84
|
# MetricFu.run do |config|
|
92
|
-
#
|
85
|
+
# config.configure_metric(:churn) do
|
93
86
|
# ...
|
94
87
|
# end
|
95
88
|
#
|
96
|
-
# config.
|
89
|
+
# config.configure_formatter(MyCustomFormatter)
|
97
90
|
# end
|
98
91
|
#
|
99
92
|
# See the README for more information on configuration options.
|
@@ -133,33 +126,13 @@ module MetricFu
|
|
133
126
|
end
|
134
127
|
|
135
128
|
# @return [Array<Symbol>] names of enabled metrics with graphs
|
136
|
-
def
|
129
|
+
def graphed_metrics
|
137
130
|
# TODO: This is a common enough need to be pushed into MetricFu::Metric as :enabled_metrics_with_graphs
|
138
131
|
MetricFu::Metric.enabled_metrics.select{|metric|metric.has_graph?}.map(&:name)
|
139
132
|
end
|
140
133
|
|
141
|
-
# TODO: Consider if we need to delegate so much to graph_engine_config
|
142
|
-
# if we should use forwardable or change the api
|
143
|
-
|
144
|
-
# @return [Array<Symbol>] names of available graph engines
|
145
|
-
# @example [:bluff, :gchart]
|
146
|
-
def graph_engines
|
147
|
-
@graph_engine_config.graph_engines
|
148
|
-
end
|
149
|
-
|
150
|
-
# @return [Symbol] the selected graph engine
|
151
134
|
def graph_engine
|
152
|
-
|
153
|
-
end
|
154
|
-
|
155
|
-
# @param graph_engine [Symbol] the name of an available graph engine
|
156
|
-
def add_graph_engine(graph_engine)
|
157
|
-
@graph_engine_config.add_graph_engine(graph_engine)
|
158
|
-
end
|
159
|
-
|
160
|
-
# @param graph_engine [Symbol] sets the selected graph engine to use
|
161
|
-
def configure_graph_engine(graph_engine)
|
162
|
-
@graph_engine_config.configure_graph_engine(graph_engine)
|
135
|
+
:bluff
|
163
136
|
end
|
164
137
|
|
165
138
|
end
|
@@ -106,7 +106,7 @@ module MetricFu
|
|
106
106
|
'Version' => version,
|
107
107
|
'Verbose Mode' => verbose,
|
108
108
|
'Enabled Metrics' => MetricFu::Metric.enabled_metrics.map(&:name),
|
109
|
-
|
109
|
+
'Dependencies' => MetricFu::GemVersion.dependencies_summary,
|
110
110
|
}
|
111
111
|
end
|
112
112
|
|
@@ -15,7 +15,7 @@ module MetricFu
|
|
15
15
|
mf_debug "** SAVING REPORT DATA OUTPUT TO #{MetricFu::Io::FileSystem.directory('data_directory')}"
|
16
16
|
# TODO: Allow customizing output filenames
|
17
17
|
MetricFu::Formatter::YAML.new(
|
18
|
-
output:
|
18
|
+
output: MetricFu.run_path.join("#{MetricFu::Io::FileSystem.directory('data_directory')}/#{Time.now.strftime("%Y%m%d")}.yml")
|
19
19
|
).finish
|
20
20
|
|
21
21
|
mf_debug "** SAVING TEMPLATIZED REPORT"
|
@@ -37,7 +37,7 @@ module MetricFu
|
|
37
37
|
protected
|
38
38
|
|
39
39
|
def output_directory
|
40
|
-
@output ||= dir_for(@options[:output]) ||
|
40
|
+
@output ||= dir_for(@options[:output]) || MetricFu.run_path.join(MetricFu::Io::FileSystem.directory('output_directory'))
|
41
41
|
end
|
42
42
|
|
43
43
|
# Instantiates a new template class based on the configuration set
|
@@ -57,11 +57,11 @@ module MetricFu
|
|
57
57
|
def save_graphs
|
58
58
|
mf_log "** GENERATING GRAPHS"
|
59
59
|
mf_debug "** PREPARING TO GRAPH"
|
60
|
-
MetricFu.configuration.
|
61
|
-
mf_debug "** Graphing #{
|
60
|
+
MetricFu.configuration.graphed_metrics.each {|graphed_metric|
|
61
|
+
mf_debug "** Graphing #{graphed_metric} with #{MetricFu.configuration.graph_engine}"
|
62
62
|
# TODO: This should probably be defined on configuration
|
63
63
|
# rather than the module. See MetricFu::Graph
|
64
|
-
MetricFu.graph.add(
|
64
|
+
MetricFu.graph.add(graphed_metric, MetricFu.configuration.graph_engine, self.output_directory)
|
65
65
|
}
|
66
66
|
mf_debug "** GENERATING GRAPH"
|
67
67
|
MetricFu.graph.generate
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'open3'
|
3
|
+
require 'shellwords'
|
4
|
+
require 'metric_fu'
|
5
|
+
MetricFu.lib_require { 'logging/mf_debugger' }
|
6
|
+
MetricFu.lib_require { 'gem_version' }
|
7
|
+
module MetricFu
|
8
|
+
class GemRun
|
9
|
+
|
10
|
+
attr_reader :output, :gem_name, :library_name, :version, :arguments
|
11
|
+
def initialize(arguments={})
|
12
|
+
@gem_name = arguments.fetch(:gem_name)
|
13
|
+
@library_name = arguments.fetch(:metric_name)
|
14
|
+
@version = arguments.fetch(:version) { MetricFu::GemVersion.for(library_name) }
|
15
|
+
args = arguments.fetch(:args)
|
16
|
+
@arguments = args.respond_to?(:scan) ? Shellwords.shellwords(args) : args
|
17
|
+
@output = ''
|
18
|
+
@errors = []
|
19
|
+
end
|
20
|
+
|
21
|
+
def summary
|
22
|
+
"RubyGem #{gem_name}, library #{library_name}, version #{version}, arguments #{arguments}"
|
23
|
+
end
|
24
|
+
|
25
|
+
def run
|
26
|
+
@output = execute
|
27
|
+
end
|
28
|
+
|
29
|
+
def execute
|
30
|
+
mf_debug "Running #{summary}"
|
31
|
+
captured_output = ''
|
32
|
+
Open3.popen3("#{library_name}", *arguments) do |stdin, stdout, stderr, wait_thr|
|
33
|
+
captured_output << stdout.read.chomp
|
34
|
+
end
|
35
|
+
rescue StandardError => run_error
|
36
|
+
handle_run_error(run_error)
|
37
|
+
rescue SystemExit => system_exit
|
38
|
+
handle_system_exit(system_exit)
|
39
|
+
ensure
|
40
|
+
print_errors
|
41
|
+
return captured_output
|
42
|
+
end
|
43
|
+
|
44
|
+
def handle_run_error(run_error)
|
45
|
+
@errors << "ERROR: #{run_error.inspect}"
|
46
|
+
end
|
47
|
+
|
48
|
+
def handle_system_exit(system_exit)
|
49
|
+
status = system_exit.success? ? "SUCCESS" : "FAILURE"
|
50
|
+
message = "#{status} with code #{system_exit.status}: " <<
|
51
|
+
"#{system_exit.message}: #{system_exit.backtrace.inspect}"
|
52
|
+
if status == 'SUCCESS'
|
53
|
+
mf_debug message
|
54
|
+
else
|
55
|
+
@errors << message
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def print_errors
|
60
|
+
return if @errors.empty?
|
61
|
+
STDERR.puts "ERRORS running #{summary}"
|
62
|
+
@errors.each do |error|
|
63
|
+
STDERR.puts "\t" << error
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
module MetricFu
|
3
|
+
class GemVersion
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@gem_spec = Gem::Specification.load(gemspec)
|
7
|
+
end
|
8
|
+
|
9
|
+
def gemspec
|
10
|
+
gemspec = File.join(MetricFu.root_dir, 'metric_fu.gemspec')
|
11
|
+
end
|
12
|
+
|
13
|
+
def new_dependency(name, version)
|
14
|
+
Gem::Dependency.new(name, version, :runtime)
|
15
|
+
end
|
16
|
+
|
17
|
+
def gem_runtime_dependencies
|
18
|
+
@gem_runtime_dependencies ||= begin
|
19
|
+
@gem_spec.dependencies.select{|gem| gem.type == :runtime}.each do |gem_dep|
|
20
|
+
gem_dep.name = gem_dep.name.downcase.sub('metric_fu-','')
|
21
|
+
end << new_dependency('rcov', ['~> 0.8'])
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def for(name)
|
26
|
+
name.downcase!
|
27
|
+
dep = gem_runtime_dependencies.find(unknown_dependency(name)) do |gem_dep|
|
28
|
+
gem_dep.name == name
|
29
|
+
end
|
30
|
+
|
31
|
+
dep.requirements_list
|
32
|
+
end
|
33
|
+
|
34
|
+
def unknown_dependency(name)
|
35
|
+
->{ new_dependency(name, ['>= 0']) }
|
36
|
+
end
|
37
|
+
|
38
|
+
RESOLVER = new
|
39
|
+
def self.for(name)
|
40
|
+
RESOLVER.for(name).dup
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.dependencies
|
44
|
+
RESOLVER.gem_runtime_dependencies.dup
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.dependencies_summary
|
48
|
+
dependencies.map do |gem_dep|
|
49
|
+
{
|
50
|
+
'name' => gem_dep.name,
|
51
|
+
'version' => gem_dep.requirements_list,
|
52
|
+
}
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
data/lib/metric_fu/io.rb
CHANGED
@@ -127,7 +127,7 @@ module MetricFu
|
|
127
127
|
end
|
128
128
|
|
129
129
|
def path_relative_to_base(path)
|
130
|
-
pathname =
|
130
|
+
pathname = MetricFu.run_path.join(MetricFu::Io::FileSystem.directory('base_directory')) # make full path relative to base directory
|
131
131
|
pathname.join(path)
|
132
132
|
end
|
133
133
|
end
|
data/lib/metric_fu/load_files.rb
CHANGED
@@ -11,11 +11,9 @@ Dir.glob(File.join(MetricFu.lib_dir, '*.rb')).
|
|
11
11
|
each do |file|
|
12
12
|
require file
|
13
13
|
end
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
MetricFu.tasks_load 'metric_fu.rake'
|
18
|
-
end
|
14
|
+
|
15
|
+
MetricFu.load_tasks('metric_fu.rake', task_name: 'metrics:all')
|
16
|
+
|
19
17
|
Dir.glob(File.join(MetricFu.data_structures_dir, '**/*.rb')).each do |file|
|
20
18
|
require file
|
21
19
|
end
|
data/lib/metric_fu/loader.rb
CHANGED
@@ -24,6 +24,14 @@ module MetricFu
|
|
24
24
|
end
|
25
25
|
|
26
26
|
# TODO: Reduce duplication of directory logic
|
27
|
+
# Adds methods x_dir and _x_require for the directory x,
|
28
|
+
# relative to the metric_fu lib, to the given klass
|
29
|
+
# @param klass [Class] the klass to add methods for the specified directories
|
30
|
+
# @yieldreturn [Array<String>] Takes a list of directories and adds readers for each
|
31
|
+
# @example For the directory 'metrics', which is relative to the metric_fu lib directory,
|
32
|
+
# creates on the klass two methods:
|
33
|
+
# ::metrics_dir which returns the full path
|
34
|
+
# ::metrics_require which takes a block of files to require relative to the metrics_dir
|
27
35
|
def create_dirs(klass)
|
28
36
|
class << klass
|
29
37
|
Array(yield).each do |dir|
|
@@ -35,6 +43,12 @@ module MetricFu
|
|
35
43
|
end
|
36
44
|
end
|
37
45
|
|
46
|
+
# Adds method x_dir relative to the metric_fu artifact directory to the given klass
|
47
|
+
# And strips any leading non-alphanumerical character from the directory name
|
48
|
+
# @param klass [Class] the klass to add methods for the specified artifact sub-directories
|
49
|
+
# @yieldreturn [Array<String>] Takes a list of directories and adds readers for each
|
50
|
+
# @example For the artifact sub-directory '_scratch', creates on the klass one method:
|
51
|
+
# ::scratch_dir (which notably has the leading underscore removed)
|
38
52
|
def create_artifact_subdirs(klass)
|
39
53
|
class << klass
|
40
54
|
Array(yield).each do |dir|
|
@@ -45,8 +59,16 @@ module MetricFu
|
|
45
59
|
end
|
46
60
|
end
|
47
61
|
|
48
|
-
|
49
|
-
|
62
|
+
# Load specified task task only once
|
63
|
+
# if and only if rake is required and the task is not yet defined
|
64
|
+
# to prevent the task from being loaded multiple times
|
65
|
+
# @param tasks_relative_path [String] 'metric_fu.rake' by default
|
66
|
+
# @param options [Hash] optional task_name to check if loaded
|
67
|
+
# @option options [String] :task_name The task_name to load, if not yet loaded
|
68
|
+
def load_tasks(tasks_relative_path, options={task_name: ''})
|
69
|
+
if defined?(Rake::Task) and not Rake::Task.task_defined?(options[:task_name])
|
70
|
+
load File.join(@lib_root, 'tasks', *Array(tasks_relative_path))
|
71
|
+
end
|
50
72
|
end
|
51
73
|
|
52
74
|
def setup
|
@@ -56,7 +78,14 @@ module MetricFu
|
|
56
78
|
MetricFu.lib_require { 'initial_requires' }
|
57
79
|
# Load a few things to make our lives easier elsewhere.
|
58
80
|
MetricFu.lib_require { 'load_files' }
|
81
|
+
load_user_configuration
|
82
|
+
end
|
83
|
+
|
84
|
+
def load_user_configuration
|
85
|
+
file = File.join(MetricFu.run_dir, '.metrics')
|
86
|
+
load file if File.exist?(file)
|
59
87
|
end
|
88
|
+
|
60
89
|
end
|
61
90
|
end
|
62
91
|
|