fastruby-metric_fu 5.0.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/.gitignore +28 -0
- data/.metrics +3 -0
- data/.rspec +2 -0
- data/.rubocop.yml +15 -0
- data/.rubocop_todo.yml +69 -0
- data/.simplecov +74 -0
- data/.travis.yml +18 -0
- data/.yardopts +4 -0
- data/AUTHORS +12 -0
- data/CONTRIBUTING.md +47 -0
- data/CONTRIBUTORS +76 -0
- data/DEV.md +76 -0
- data/Gemfile +58 -0
- data/Guardfile +30 -0
- data/HISTORY.md +705 -0
- data/MIT-LICENSE +22 -0
- data/README.md +299 -0
- data/Rakefile +27 -0
- data/TODO.md +118 -0
- data/appveyor.yml +29 -0
- data/bin/metric_fu +9 -0
- data/bin/mf-cane +10 -0
- data/bin/mf-churn +10 -0
- data/bin/mf-flay +10 -0
- data/bin/mf-reek +10 -0
- data/bin/mf-roodi +10 -0
- data/bin/mf-saikuro +10 -0
- data/certs/bf4.pem +22 -0
- data/checksum/.gitkeep +0 -0
- data/checksum/metric_fu-4.10.0.gem.sha512 +1 -0
- data/checksum/metric_fu-4.11.0.gem.sha512 +1 -0
- data/checksum/metric_fu-4.11.1.gem.sha512 +1 -0
- data/checksum/metric_fu-4.11.2.gem.sha512 +1 -0
- data/checksum/metric_fu-4.11.3.gem.sha512 +1 -0
- data/checksum/metric_fu-4.11.4.gem.sha512 +1 -0
- data/checksum/metric_fu-4.12.0.gem.sha512 +1 -0
- data/checksum/metric_fu-4.2.0.gem.sha512 +1 -0
- data/checksum/metric_fu-4.2.1.gem.sha512 +1 -0
- data/checksum/metric_fu-4.3.0.gem.sha512 +1 -0
- data/checksum/metric_fu-4.3.1.gem.sha512 +1 -0
- data/checksum/metric_fu-4.4.0.gem.sha512 +1 -0
- data/checksum/metric_fu-4.4.1.gem.sha512 +1 -0
- data/checksum/metric_fu-4.4.2.gem.sha512 +1 -0
- data/checksum/metric_fu-4.4.3.gem.sha512 +1 -0
- data/checksum/metric_fu-4.4.4.gem.sha512 +1 -0
- data/checksum/metric_fu-4.5.0.gem.sha512 +1 -0
- data/checksum/metric_fu-4.5.1.gem.sha512 +1 -0
- data/checksum/metric_fu-4.5.2.gem.sha512 +1 -0
- data/checksum/metric_fu-4.6.0.gem.sha512 +1 -0
- data/checksum/metric_fu-4.7.0.gem.sha512 +1 -0
- data/checksum/metric_fu-4.7.1.gem.sha512 +1 -0
- data/checksum/metric_fu-4.7.2.gem.sha512 +1 -0
- data/checksum/metric_fu-4.7.3.gem.sha512 +1 -0
- data/checksum/metric_fu-4.7.4.gem.sha512 +1 -0
- data/checksum/metric_fu-4.8.0.gem.sha512 +1 -0
- data/checksum/metric_fu-4.9.0.gem.sha512 +1 -0
- data/config/roodi_config.yml +22 -0
- data/config/rubocop.yml +269 -0
- data/gem_tasks/build.rake +197 -0
- data/gem_tasks/rubocop.rake +10 -0
- data/gem_tasks/usage_test.rake +19 -0
- data/gem_tasks/yard.rake +24 -0
- data/lib/metric_fu.rb +151 -0
- data/lib/metric_fu/calculate.rb +10 -0
- data/lib/metric_fu/cli/client.rb +26 -0
- data/lib/metric_fu/cli/helper.rb +80 -0
- data/lib/metric_fu/cli/parser.rb +138 -0
- data/lib/metric_fu/configuration.rb +150 -0
- data/lib/metric_fu/constantize.rb +57 -0
- data/lib/metric_fu/data_structures/line_numbers.rb +112 -0
- data/lib/metric_fu/data_structures/location.rb +110 -0
- data/lib/metric_fu/data_structures/sexp_node.rb +107 -0
- data/lib/metric_fu/environment.rb +129 -0
- data/lib/metric_fu/errors/analysis_error.rb +4 -0
- data/lib/metric_fu/formatter.rb +40 -0
- data/lib/metric_fu/formatter/html.rb +96 -0
- data/lib/metric_fu/formatter/syntax.rb +45 -0
- data/lib/metric_fu/formatter/yaml.rb +18 -0
- data/lib/metric_fu/gem_run.rb +70 -0
- data/lib/metric_fu/gem_version.rb +92 -0
- data/lib/metric_fu/generator.rb +135 -0
- data/lib/metric_fu/io.rb +132 -0
- data/lib/metric_fu/loader.rb +105 -0
- data/lib/metric_fu/logger.rb +62 -0
- data/lib/metric_fu/logging/mf_debugger.rb +23 -0
- data/lib/metric_fu/metric.rb +143 -0
- data/lib/metric_fu/metrics/cane/generator.rb +95 -0
- data/lib/metric_fu/metrics/cane/grapher.rb +37 -0
- data/lib/metric_fu/metrics/cane/metric.rb +34 -0
- data/lib/metric_fu/metrics/cane/report.html.erb +87 -0
- data/lib/metric_fu/metrics/cane/violations.rb +46 -0
- data/lib/metric_fu/metrics/churn/generator.rb +37 -0
- data/lib/metric_fu/metrics/churn/hotspot.rb +43 -0
- data/lib/metric_fu/metrics/churn/metric.rb +29 -0
- data/lib/metric_fu/metrics/churn/report.html.erb +58 -0
- data/lib/metric_fu/metrics/flay/generator.rb +51 -0
- data/lib/metric_fu/metrics/flay/grapher.rb +37 -0
- data/lib/metric_fu/metrics/flay/hotspot.rb +52 -0
- data/lib/metric_fu/metrics/flay/metric.rb +28 -0
- data/lib/metric_fu/metrics/flay/report.html.erb +29 -0
- data/lib/metric_fu/metrics/flog/generator.rb +113 -0
- data/lib/metric_fu/metrics/flog/grapher.rb +77 -0
- data/lib/metric_fu/metrics/flog/hotspot.rb +46 -0
- data/lib/metric_fu/metrics/flog/metric.rb +29 -0
- data/lib/metric_fu/metrics/flog/report.html.erb +50 -0
- data/lib/metric_fu/metrics/hotspots/analysis/analyzed_problems.rb +34 -0
- data/lib/metric_fu/metrics/hotspots/analysis/analyzer_tables.rb +114 -0
- data/lib/metric_fu/metrics/hotspots/analysis/grouping.rb +23 -0
- data/lib/metric_fu/metrics/hotspots/analysis/groupings.rb +12 -0
- data/lib/metric_fu/metrics/hotspots/analysis/problems.rb +20 -0
- data/lib/metric_fu/metrics/hotspots/analysis/ranked_problem_location.rb +70 -0
- data/lib/metric_fu/metrics/hotspots/analysis/ranking.rb +29 -0
- data/lib/metric_fu/metrics/hotspots/analysis/rankings.rb +91 -0
- data/lib/metric_fu/metrics/hotspots/analysis/record.rb +32 -0
- data/lib/metric_fu/metrics/hotspots/analysis/scoring_strategies.rb +24 -0
- data/lib/metric_fu/metrics/hotspots/analysis/table.rb +67 -0
- data/lib/metric_fu/metrics/hotspots/generator.rb +40 -0
- data/lib/metric_fu/metrics/hotspots/hotspot.rb +87 -0
- data/lib/metric_fu/metrics/hotspots/hotspot_analyzer.rb +61 -0
- data/lib/metric_fu/metrics/hotspots/metric.rb +20 -0
- data/lib/metric_fu/metrics/hotspots/report.html.erb +60 -0
- data/lib/metric_fu/metrics/rails_best_practices/generator.rb +47 -0
- data/lib/metric_fu/metrics/rails_best_practices/grapher.rb +38 -0
- data/lib/metric_fu/metrics/rails_best_practices/metric.rb +31 -0
- data/lib/metric_fu/metrics/rails_best_practices/report.html.erb +22 -0
- data/lib/metric_fu/metrics/rcov/external_client.rb +22 -0
- data/lib/metric_fu/metrics/rcov/generator.rb +75 -0
- data/lib/metric_fu/metrics/rcov/grapher.rb +37 -0
- data/lib/metric_fu/metrics/rcov/hotspot.rb +46 -0
- data/lib/metric_fu/metrics/rcov/metric.rb +61 -0
- data/lib/metric_fu/metrics/rcov/rcov_format_coverage.rb +149 -0
- data/lib/metric_fu/metrics/rcov/rcov_line.rb +48 -0
- data/lib/metric_fu/metrics/rcov/report.html.erb +40 -0
- data/lib/metric_fu/metrics/rcov/simplecov_formatter.rb +74 -0
- data/lib/metric_fu/metrics/reek/generator.rb +94 -0
- data/lib/metric_fu/metrics/reek/grapher.rb +55 -0
- data/lib/metric_fu/metrics/reek/hotspot.rb +95 -0
- data/lib/metric_fu/metrics/reek/metric.rb +26 -0
- data/lib/metric_fu/metrics/reek/report.html.erb +35 -0
- data/lib/metric_fu/metrics/roodi/generator.rb +40 -0
- data/lib/metric_fu/metrics/roodi/grapher.rb +37 -0
- data/lib/metric_fu/metrics/roodi/hotspot.rb +39 -0
- data/lib/metric_fu/metrics/roodi/metric.rb +24 -0
- data/lib/metric_fu/metrics/roodi/report.html.erb +22 -0
- data/lib/metric_fu/metrics/saikuro/generator.rb +145 -0
- data/lib/metric_fu/metrics/saikuro/hotspot.rb +51 -0
- data/lib/metric_fu/metrics/saikuro/metric.rb +31 -0
- data/lib/metric_fu/metrics/saikuro/parsing_element.rb +37 -0
- data/lib/metric_fu/metrics/saikuro/report.html.erb +71 -0
- data/lib/metric_fu/metrics/saikuro/scratch_file.rb +108 -0
- data/lib/metric_fu/metrics/stats/generator.rb +82 -0
- data/lib/metric_fu/metrics/stats/grapher.rb +40 -0
- data/lib/metric_fu/metrics/stats/hotspot.rb +35 -0
- data/lib/metric_fu/metrics/stats/metric.rb +28 -0
- data/lib/metric_fu/metrics/stats/report.html.erb +44 -0
- data/lib/metric_fu/reporter.rb +37 -0
- data/lib/metric_fu/reporting/graphs/graph.rb +69 -0
- data/lib/metric_fu/reporting/graphs/grapher.rb +66 -0
- data/lib/metric_fu/reporting/result.rb +59 -0
- data/lib/metric_fu/run.rb +82 -0
- data/lib/metric_fu/tasks/metric_fu.rake +54 -0
- data/lib/metric_fu/templates/_graph.html.erb +2 -0
- data/lib/metric_fu/templates/_report_footer.html.erb +1 -0
- data/lib/metric_fu/templates/configuration.rb +25 -0
- data/lib/metric_fu/templates/css/bluff.css +15 -0
- data/lib/metric_fu/templates/css/buttons.css +82 -0
- data/lib/metric_fu/templates/css/default.css +43 -0
- data/lib/metric_fu/templates/css/integrity.css +337 -0
- data/lib/metric_fu/templates/css/rcov.css +32 -0
- data/lib/metric_fu/templates/css/reset.css +7 -0
- data/lib/metric_fu/templates/css/syntax.css +19 -0
- data/lib/metric_fu/templates/index.html.erb +10 -0
- data/lib/metric_fu/templates/javascripts/bluff-min.js +1 -0
- data/lib/metric_fu/templates/javascripts/bluff_graph.js +15 -0
- data/lib/metric_fu/templates/javascripts/excanvas.js +35 -0
- data/lib/metric_fu/templates/javascripts/highcharts.js +294 -0
- data/lib/metric_fu/templates/javascripts/highcharts_graph.js +38 -0
- data/lib/metric_fu/templates/javascripts/js-class.js +1 -0
- data/lib/metric_fu/templates/javascripts/standalone-framework.js +17 -0
- data/lib/metric_fu/templates/javascripts/utils.js +9 -0
- data/lib/metric_fu/templates/layout.html.erb +37 -0
- data/lib/metric_fu/templates/metrics_template.rb +80 -0
- data/lib/metric_fu/templates/report.html.erb +31 -0
- data/lib/metric_fu/templates/report.rb +41 -0
- data/lib/metric_fu/templates/template.rb +244 -0
- data/lib/metric_fu/utility.rb +79 -0
- data/lib/metric_fu/version.rb +9 -0
- data/metric_fu.gemspec +71 -0
- data/spec/capture_warnings.rb +55 -0
- data/spec/cli/helper_spec.rb +165 -0
- data/spec/dummy/.gitignore +1 -0
- data/spec/dummy/.gitkeep +0 -0
- data/spec/dummy/lib/.gitkeep +0 -0
- data/spec/dummy/lib/bad_encoding.rb +6 -0
- data/spec/dummy/spec/.gitkeep +0 -0
- data/spec/fixtures/20090630.yml +7922 -0
- data/spec/fixtures/coverage-153.rb +11 -0
- data/spec/fixtures/coverage.rb +13 -0
- data/spec/fixtures/exit0.sh +3 -0
- data/spec/fixtures/exit1.sh +3 -0
- data/spec/fixtures/hotspots/flog.yml +86 -0
- data/spec/fixtures/hotspots/generator.yml +47 -0
- data/spec/fixtures/hotspots/generator_analysis.yml +53 -0
- data/spec/fixtures/hotspots/reek.yml +14 -0
- data/spec/fixtures/hotspots/roodi.yml +13 -0
- data/spec/fixtures/hotspots/saikuro.yml +27 -0
- data/spec/fixtures/hotspots/several_metrics.yml +47 -0
- data/spec/fixtures/hotspots/stats.yml +4 -0
- data/spec/fixtures/hotspots/three_metrics_on_same_file.yml +36 -0
- data/spec/fixtures/line_numbers/foo.rb +33 -0
- data/spec/fixtures/line_numbers/module.rb +11 -0
- data/spec/fixtures/line_numbers/module_surrounds_class.rb +15 -0
- data/spec/fixtures/line_numbers/two_classes.rb +11 -0
- data/spec/fixtures/metric_missing.yml +1 -0
- data/spec/fixtures/rcov_output.txt +135 -0
- data/spec/fixtures/saikuro/app/controllers/sessions_controller.rb_cyclo.html +10 -0
- data/spec/fixtures/saikuro/app/controllers/users_controller.rb_cyclo.html +16 -0
- data/spec/fixtures/saikuro/index_cyclo.html +155 -0
- data/spec/fixtures/saikuro_sfiles/thing.rb_cyclo.html +11 -0
- data/spec/metric_fu/calculate_spec.rb +21 -0
- data/spec/metric_fu/configuration_spec.rb +90 -0
- data/spec/metric_fu/data_structures/line_numbers_spec.rb +63 -0
- data/spec/metric_fu/data_structures/location_spec.rb +110 -0
- data/spec/metric_fu/formatter/configuration_spec.rb +44 -0
- data/spec/metric_fu/formatter/html_spec.rb +138 -0
- data/spec/metric_fu/formatter/yaml_spec.rb +61 -0
- data/spec/metric_fu/formatter_spec.rb +49 -0
- data/spec/metric_fu/gem_version_spec.rb +12 -0
- data/spec/metric_fu/generator_spec.rb +130 -0
- data/spec/metric_fu/loader_spec.rb +13 -0
- data/spec/metric_fu/metric_spec.rb +46 -0
- data/spec/metric_fu/metrics/cane/configuration_spec.rb +22 -0
- data/spec/metric_fu/metrics/cane/generator_spec.rb +184 -0
- data/spec/metric_fu/metrics/churn/configuration_spec.rb +13 -0
- data/spec/metric_fu/metrics/churn/generator_spec.rb +64 -0
- data/spec/metric_fu/metrics/flay/configuration_spec.rb +13 -0
- data/spec/metric_fu/metrics/flay/generator_spec.rb +105 -0
- data/spec/metric_fu/metrics/flay/grapher_spec.rb +57 -0
- data/spec/metric_fu/metrics/flog/configuration_spec.rb +18 -0
- data/spec/metric_fu/metrics/flog/generator_spec.rb +77 -0
- data/spec/metric_fu/metrics/flog/grapher_spec.rb +107 -0
- data/spec/metric_fu/metrics/hotspots/analysis/analyzed_problems_spec.rb +104 -0
- data/spec/metric_fu/metrics/hotspots/analysis/analyzer_tables_spec.rb +71 -0
- data/spec/metric_fu/metrics/hotspots/analysis/ranking_spec.rb +30 -0
- data/spec/metric_fu/metrics/hotspots/analysis/rankings_spec.rb +97 -0
- data/spec/metric_fu/metrics/hotspots/analysis/table_spec.rb +6 -0
- data/spec/metric_fu/metrics/hotspots/generator_spec.rb +46 -0
- data/spec/metric_fu/metrics/hotspots/hotspot_analyzer_spec.rb +10 -0
- data/spec/metric_fu/metrics/hotspots/hotspot_spec.rb +16 -0
- data/spec/metric_fu/metrics/rails_best_practices/configuration_spec.rb +55 -0
- data/spec/metric_fu/metrics/rails_best_practices/generator_spec.rb +33 -0
- data/spec/metric_fu/metrics/rails_best_practices/grapher_spec.rb +62 -0
- data/spec/metric_fu/metrics/rcov/configuration_spec.rb +28 -0
- data/spec/metric_fu/metrics/rcov/generator_spec.rb +22 -0
- data/spec/metric_fu/metrics/rcov/grapher_spec.rb +57 -0
- data/spec/metric_fu/metrics/rcov/hotspot_spec.rb +20 -0
- data/spec/metric_fu/metrics/rcov/rcov_line_spec.rb +89 -0
- data/spec/metric_fu/metrics/rcov/simplecov_formatter_spec.rb +67 -0
- data/spec/metric_fu/metrics/reek/configuration_spec.rb +13 -0
- data/spec/metric_fu/metrics/reek/generator_spec.rb +203 -0
- data/spec/metric_fu/metrics/reek/grapher_spec.rb +66 -0
- data/spec/metric_fu/metrics/roodi/configuration_spec.rb +14 -0
- data/spec/metric_fu/metrics/roodi/generator_spec.rb +82 -0
- data/spec/metric_fu/metrics/roodi/grapher_spec.rb +57 -0
- data/spec/metric_fu/metrics/saikuro/configuration_spec.rb +25 -0
- data/spec/metric_fu/metrics/saikuro/generator_spec.rb +71 -0
- data/spec/metric_fu/metrics/stats/generator_spec.rb +96 -0
- data/spec/metric_fu/metrics/stats/grapher_spec.rb +69 -0
- data/spec/metric_fu/reporter_spec.rb +41 -0
- data/spec/metric_fu/reporting/graphs/graph_spec.rb +44 -0
- data/spec/metric_fu/reporting/graphs/grapher_spec.rb +24 -0
- data/spec/metric_fu/reporting/result_spec.rb +50 -0
- data/spec/metric_fu/run_spec.rb +197 -0
- data/spec/metric_fu/templates/configuration_spec.rb +51 -0
- data/spec/metric_fu/templates/metrics_template_spec.rb +11 -0
- data/spec/metric_fu/templates/report_spec.rb +15 -0
- data/spec/metric_fu/templates/template_spec.rb +233 -0
- data/spec/metric_fu/utility_spec.rb +12 -0
- data/spec/metric_fu_spec.rb +52 -0
- data/spec/quality_spec.rb +114 -0
- data/spec/shared/configured.rb +45 -0
- data/spec/shared/test_coverage.rb +95 -0
- data/spec/spec_helper.rb +46 -0
- data/spec/support/.metrics +4 -0
- data/spec/support/deferred_garbaged_collection.rb +33 -0
- data/spec/support/helper_methods.rb +32 -0
- data/spec/support/matcher_create_file.rb +37 -0
- data/spec/support/matcher_create_files.rb +43 -0
- data/spec/support/samples/reek/alfa.rb +1 -0
- data/spec/support/suite.rb +26 -0
- data/spec/support/test_fixtures.rb +37 -0
- data/spec/support/timeout.rb +7 -0
- data/spec/support/usage_test.rb +150 -0
- data/spec/usage_test_spec.rb +93 -0
- metadata +735 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
module MetricFu
|
|
2
|
+
class MetricStats < Metric
|
|
3
|
+
def name
|
|
4
|
+
:stats
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def default_run_options
|
|
8
|
+
{
|
|
9
|
+
# returns a list of directories that contains the glob of files that have the file_pattern in the file names
|
|
10
|
+
additional_test_directories: [{ glob_pattern: File.join(".", "spec", "**", "*_spec.rb"), file_pattern: "spec" }],
|
|
11
|
+
additional_app_directories: [{ glob_pattern: File.join(".", "engines", "**", "*.rb"), file_pattern: "" }],
|
|
12
|
+
}
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def has_graph?
|
|
16
|
+
true
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def enable
|
|
20
|
+
super
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def activate
|
|
24
|
+
activate_library "code_metrics"
|
|
25
|
+
super
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
<h3>Lines of Code/Tests Metric Results</h3>
|
|
2
|
+
|
|
3
|
+
<%= render_partial 'graph', {:graph_name => 'stats'} %>
|
|
4
|
+
|
|
5
|
+
<p>Lines of Code/Tests Metrics Results</p>
|
|
6
|
+
<table>
|
|
7
|
+
<tr>
|
|
8
|
+
<th>Lines of Code</th>
|
|
9
|
+
<th>Lines of Test</th>
|
|
10
|
+
<th>Code to test ratio</th>
|
|
11
|
+
</tr>
|
|
12
|
+
<tr>
|
|
13
|
+
<td><%= @stats[:codeLOC] %></td>
|
|
14
|
+
<td><%= @stats[:testLOC] %></td>
|
|
15
|
+
<td>1:<%= @stats[:code_to_test_ratio] %></td>
|
|
16
|
+
</tr>
|
|
17
|
+
</table>
|
|
18
|
+
|
|
19
|
+
<table>
|
|
20
|
+
<tr>
|
|
21
|
+
<th>Name</th>
|
|
22
|
+
<th>Lines</th>
|
|
23
|
+
<th>LOC</th>
|
|
24
|
+
<th>Classes</th>
|
|
25
|
+
<th>Methods</th>
|
|
26
|
+
<th>Methods per class</th>
|
|
27
|
+
<th>LOC per method</th>
|
|
28
|
+
</tr>
|
|
29
|
+
<% count = 0 %>
|
|
30
|
+
<% @stats[:lines].each do |line| %>
|
|
31
|
+
<tr>
|
|
32
|
+
<td><%= line[:name] %></td>
|
|
33
|
+
<td><%= line[:lines] %></td>
|
|
34
|
+
<td><%= line[:loc] %></td>
|
|
35
|
+
<td><%= line[:classes] %></td>
|
|
36
|
+
<td><%= line[:methods] %></td>
|
|
37
|
+
<td><%= line[:methods_per_class] %></td>
|
|
38
|
+
<td><%= line[:loc_per_method] %></td>
|
|
39
|
+
</tr>
|
|
40
|
+
<% count += 1 %>
|
|
41
|
+
<% end %>
|
|
42
|
+
</table>
|
|
43
|
+
|
|
44
|
+
<%= render_partial 'report_footer' %>
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
module MetricFu
|
|
2
|
+
class Reporter
|
|
3
|
+
def initialize(formatters = nil)
|
|
4
|
+
@formatters = Array(formatters)
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def start
|
|
8
|
+
notify :start
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def finish
|
|
12
|
+
notify :finish
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def start_metric(metric)
|
|
16
|
+
mf_log "** STARTING METRIC #{metric}"
|
|
17
|
+
notify :start_metric, metric
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def finish_metric(metric)
|
|
21
|
+
mf_log "** ENDING METRIC #{metric}"
|
|
22
|
+
notify :finish_metric, metric
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def display_results
|
|
26
|
+
notify :display_results
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
protected
|
|
30
|
+
|
|
31
|
+
def notify(event, *args)
|
|
32
|
+
@formatters.each do |formatter|
|
|
33
|
+
formatter.send(event, *args) if formatter.respond_to?(event)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
module MetricFu
|
|
2
|
+
def self.graph
|
|
3
|
+
@graph ||= Graph.new
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
class Graph
|
|
7
|
+
attr_accessor :graphers
|
|
8
|
+
|
|
9
|
+
def initialize
|
|
10
|
+
self.graphers = []
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def add(metric_name, _graph_engine, output_directory = MetricFu::Io::FileSystem.directory("output_directory"))
|
|
14
|
+
grapher = MetricFu::Grapher.get_grapher(metric_name).
|
|
15
|
+
new.tap { |g| g.output_directory = output_directory }
|
|
16
|
+
graphers.push grapher
|
|
17
|
+
rescue NameError => e
|
|
18
|
+
mf_log "#{e.message} called in MetricFu::Graph.add with #{graph_type}"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def generate
|
|
22
|
+
return if graphers.empty?
|
|
23
|
+
mf_log "Generating graphs"
|
|
24
|
+
generate_graphs_for_files
|
|
25
|
+
graph!
|
|
26
|
+
rescue NameError => e
|
|
27
|
+
mf_log "#{e.message} called in MetricFu::Graph generate"
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
|
|
32
|
+
def metric_files
|
|
33
|
+
MetricFu::Utility.glob(
|
|
34
|
+
File.join(MetricFu::Io::FileSystem.directory("data_directory"), "*.yml")
|
|
35
|
+
).sort
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def generate_graphs_for_files
|
|
39
|
+
metric_files.each do |metric_file|
|
|
40
|
+
generate_graphs_for_file(metric_file)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def generate_graphs_for_file(metric_file)
|
|
45
|
+
mf_log "Generating graphs for #{metric_file}"
|
|
46
|
+
date_parts = year_month_day_from_filename(metric_file)
|
|
47
|
+
metrics = MetricFu::Utility.load_yaml(metric_file)
|
|
48
|
+
|
|
49
|
+
build_graph(metrics, "#{date_parts[:m]}/#{date_parts[:d]}")
|
|
50
|
+
rescue NameError => e
|
|
51
|
+
mf_log "#{e.message} called in MetricFu::Graph.generate with #{metric_file}"
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def build_graph(metrics, sortable_prefix)
|
|
55
|
+
graphers.each do |grapher|
|
|
56
|
+
grapher.get_metrics(metrics, sortable_prefix)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def graph!
|
|
61
|
+
graphers.each(&:graph!)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def year_month_day_from_filename(path_to_file_with_date)
|
|
65
|
+
date = path_to_file_with_date.match(/\/(\d+).yml$/)[1]
|
|
66
|
+
{ y: date[0..3].to_i, m: date[4..5].to_i, d: date[6..7].to_i }
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
require "multi_json"
|
|
2
|
+
module MetricFu
|
|
3
|
+
class Grapher
|
|
4
|
+
@graphers = []
|
|
5
|
+
# @return all subclassed graphers [Array<MetricFu::Grapher>]
|
|
6
|
+
def self.graphers
|
|
7
|
+
@graphers
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def self.inherited(subclass)
|
|
11
|
+
@graphers << subclass
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def self.get_grapher(metric)
|
|
15
|
+
graphers.find { |grapher|grapher.metric.to_s == metric.to_s }
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
attr_accessor :output_directory
|
|
19
|
+
|
|
20
|
+
def initialize(opts = {})
|
|
21
|
+
self.output_directory = opts[:output_directory]
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def output_directory
|
|
25
|
+
@output_directory || MetricFu::Io::FileSystem.directory("output_directory")
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def get_metrics(_metrics, _sortable_prefix)
|
|
29
|
+
not_implemented
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def graph!
|
|
33
|
+
labels = MultiJson.dump(@labels)
|
|
34
|
+
content = <<-EOS
|
|
35
|
+
var graph_title = '#{title}';
|
|
36
|
+
#{build_data(data)}
|
|
37
|
+
var graph_labels = #{labels};
|
|
38
|
+
EOS
|
|
39
|
+
File.open(File.join(output_directory, output_filename), "w") { |f| f << content }
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def title
|
|
43
|
+
not_implemented
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def date
|
|
47
|
+
not_implemented
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def output_filename
|
|
51
|
+
not_implemented
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
private
|
|
55
|
+
|
|
56
|
+
def build_data(data)
|
|
57
|
+
"var graph_series = [" << Array(data).map do |label, datum|
|
|
58
|
+
"{name: '#{label}', data: [#{datum}]}"
|
|
59
|
+
end.join(",") << "];"
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def not_implemented
|
|
63
|
+
raise "#{__LINE__} in #{__FILE__} from #{caller[0]}"
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
module MetricFu
|
|
2
|
+
# MetricFu.result memoizes access to a Result object, that will be
|
|
3
|
+
# used throughout the lifecycle of the MetricFu app.
|
|
4
|
+
def self.result
|
|
5
|
+
@result ||= Result.new
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
# = Result
|
|
9
|
+
#
|
|
10
|
+
# The Result class is responsible for one thing:
|
|
11
|
+
#
|
|
12
|
+
# It tracks the results generated by each metric used in this test run.
|
|
13
|
+
class Result
|
|
14
|
+
# Renders the result of the result_hash into a yaml serialization
|
|
15
|
+
# ready for writing out to a file.
|
|
16
|
+
#
|
|
17
|
+
# @return YAML
|
|
18
|
+
# A YAML object containing the results of the result generation
|
|
19
|
+
# process
|
|
20
|
+
def as_yaml
|
|
21
|
+
result_hash.to_yaml
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def per_file_data
|
|
25
|
+
@per_file_data ||= Hash.new do |hash, filename|
|
|
26
|
+
hash[filename] = Hash.new do |h, line|
|
|
27
|
+
h[line] = Array.new
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def result_hash #:nodoc:
|
|
33
|
+
@result_hash ||= {}
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Adds a hash from a passed result, produced by one of the Generator
|
|
37
|
+
# classes to the aggregate result_hash managed by this hash.
|
|
38
|
+
#
|
|
39
|
+
# @param result_type Hash
|
|
40
|
+
# The hash to add to the aggregate result_hash
|
|
41
|
+
def add(result_type)
|
|
42
|
+
mf_debug "result requested #{result_type}"
|
|
43
|
+
metric_options = metric_options_for_result_type(result_type)
|
|
44
|
+
generator_class = MetricFu::Generator.get_generator(result_type)
|
|
45
|
+
mf_debug "result class found #{generator_class}"
|
|
46
|
+
generator = generator_class.new(metric_options)
|
|
47
|
+
|
|
48
|
+
result_hash.merge!(generator.generate_result)
|
|
49
|
+
|
|
50
|
+
generator.per_file_info(per_file_data) if generator.respond_to?(:per_file_info)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
private
|
|
54
|
+
|
|
55
|
+
def metric_options_for_result_type(result_type)
|
|
56
|
+
MetricFu::Metric.get_metric(result_type).run_options
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
module MetricFu
|
|
2
|
+
class Run
|
|
3
|
+
def initialize
|
|
4
|
+
STDOUT.sync = true
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def run(options = {})
|
|
8
|
+
configure_run(options)
|
|
9
|
+
measure
|
|
10
|
+
display_results if options[:open]
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def report_metrics(metrics = MetricFu::Metric.enabled_metrics)
|
|
14
|
+
metrics.map(&:name)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def measure
|
|
18
|
+
reporter.start
|
|
19
|
+
report_metrics.each {|metric|
|
|
20
|
+
reporter.start_metric(metric)
|
|
21
|
+
MetricFu.result.add(metric)
|
|
22
|
+
reporter.finish_metric(metric)
|
|
23
|
+
}
|
|
24
|
+
reporter.finish
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def display_results
|
|
28
|
+
reporter.display_results
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
def configure_run(options)
|
|
34
|
+
disable_metrics(options)
|
|
35
|
+
configure_formatters(options)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def disable_metrics(options)
|
|
39
|
+
return if options.size == 0
|
|
40
|
+
report_metrics.each do |metric|
|
|
41
|
+
metric = metric.to_sym
|
|
42
|
+
if (metric_options = options[metric])
|
|
43
|
+
mf_debug "using metric #{metric}"
|
|
44
|
+
configure_metric(metric, metric_options) if metric_options.is_a?(Hash)
|
|
45
|
+
else
|
|
46
|
+
mf_debug "disabling metric #{metric}"
|
|
47
|
+
MetricFu::Metric.get_metric(metric).enabled = false
|
|
48
|
+
mf_debug "active metrics are #{MetricFu::Metric.enabled_metrics.inspect}"
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def configure_metric(metric, metric_options)
|
|
54
|
+
MetricFu::Configuration.configure_metric(metric) do |metric|
|
|
55
|
+
metric_options.each do |option, value|
|
|
56
|
+
mf_log "Setting #{metric} option #{option} to #{value}"
|
|
57
|
+
metric.public_send("#{option}=", value)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def configure_formatters(options)
|
|
63
|
+
# Configure from command line if any.
|
|
64
|
+
if options[:format]
|
|
65
|
+
MetricFu.configuration.formatters.clear # Command-line format takes precedence.
|
|
66
|
+
Array(options[:format]).each do |format, o|
|
|
67
|
+
MetricFu.configuration.configure_formatter(format, o)
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
# If no formatters specified, use defaults.
|
|
71
|
+
if MetricFu.configuration.formatters.empty?
|
|
72
|
+
Array(MetricFu::Formatter::DEFAULT).each do |format, o|
|
|
73
|
+
MetricFu.configuration.configure_formatter(format, o)
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def reporter
|
|
79
|
+
MetricFu::Reporter.new(MetricFu.configuration.formatters)
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
require "rake"
|
|
2
|
+
require "metric_fu/run"
|
|
3
|
+
namespace :metrics do
|
|
4
|
+
def options_tip(task_name)
|
|
5
|
+
"with options, for example: rake metrics:#{task_name}['cane: {abc_max: 81}']"
|
|
6
|
+
end
|
|
7
|
+
desc "Generate all metrics reports, or #{options_tip('all')}"
|
|
8
|
+
task :all, [:options] do |_t, args|
|
|
9
|
+
MetricFu.run(process_options(args.options))
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
desc "Run only specified ;-separated metrics, for example, metrics:only[cane;flog] or #{options_tip('only')}"
|
|
13
|
+
task :only, [:metrics, :options] do |_t, args|
|
|
14
|
+
requested_metrics = args.metrics.to_s.split(";").map(&:strip)
|
|
15
|
+
enabled_metrics = MetricFu::Metric.enabled_metrics.map(&:name)
|
|
16
|
+
metrics_to_run = enabled_metrics.select { |metric| requested_metrics.include?(metric.to_s) }
|
|
17
|
+
MetricFu.run_only(metrics_to_run, process_options(args.options))
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
MetricFu::Metric.enabled_metrics.each do |metric|
|
|
21
|
+
name = metric.name
|
|
22
|
+
desc "Generate report for #{name}, or #{options_tip('cane')}"
|
|
23
|
+
task name, [:options] do |_t, args|
|
|
24
|
+
MetricFu.run_only(name, process_options(args.options))
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
# from https://github.com/rails/rails/blob/master/activesupport/lib/active_support/core_ext/hash/keys.rb
|
|
31
|
+
class Hash
|
|
32
|
+
# Destructively, recursively convert all keys to symbols, as long as they respond
|
|
33
|
+
# to +to_sym+.
|
|
34
|
+
def recursively_symbolize_keys!
|
|
35
|
+
keys.each do |key|
|
|
36
|
+
value = delete(key)
|
|
37
|
+
new_key = key.intern # rescue
|
|
38
|
+
self[new_key] = (value.is_a?(Hash) ? value.dup.recursively_symbolize_keys! : value)
|
|
39
|
+
end
|
|
40
|
+
self
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def process_options(options)
|
|
45
|
+
return {} if options.nil? or options.empty?
|
|
46
|
+
options = YAML.load(options)
|
|
47
|
+
if options.is_a?(Hash)
|
|
48
|
+
p "Got options #{options.recursively_symbolize_keys!.inspect}"
|
|
49
|
+
options
|
|
50
|
+
else
|
|
51
|
+
raise "Invalid options #{options.inspect}, is a #{options.class}, should be a Hash"
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|