code_metric_fu 4.14.0
Sign up to get free protection for your applications and to get access to all the features.
- 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 +22 -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 +74 -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 +31 -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/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/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/formatter.rb +40 -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 +97 -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 +41 -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/_gem_info.html.erb +8 -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 +13 -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 +41 -0
- data/lib/metric_fu/templates/metrics_template.rb +86 -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 +247 -0
- data/lib/metric_fu/utility.rb +79 -0
- data/lib/metric_fu/version.rb +9 -0
- data/lib/metric_fu.rb +143 -0
- data/metric_fu.gemspec +72 -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/.metrics +4 -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 +10 -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 +169 -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 +33 -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 +54 -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/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 +757 -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, "results", 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
|
@@ -0,0 +1,8 @@
|
|
1
|
+
<%
|
2
|
+
gem_spec = MetricFu::GemVersion.activated_gems.find { |g| g.name =~ /metric_fu/ }
|
3
|
+
gem_name = gem_spec.name
|
4
|
+
gem_version = gem_spec.version.to_s
|
5
|
+
gem_description = gem_spec.description
|
6
|
+
gem_homepage = gem_spec.homepage
|
7
|
+
%>
|
8
|
+
<p>Generated by <a href="<%= gem_homepage %>" title="<%= gem_description %>"><%= gem_name %></a> (v<%= gem_version %>)</p>
|
@@ -0,0 +1 @@
|
|
1
|
+
<p>Generated on <%= MetricFu.current_time %></p>
|
@@ -0,0 +1,25 @@
|
|
1
|
+
MetricFu.lib_require { "templates/metrics_template" }
|
2
|
+
module MetricFu::Templates
|
3
|
+
class Configuration
|
4
|
+
FILE_PREFIX = "file:/"
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@options = {}
|
8
|
+
@options[:template_class] = MetricFu::Templates::MetricsTemplate
|
9
|
+
@options[:darwin_txmt_protocol_no_thanks] = true
|
10
|
+
# turning off syntax_highlighting may avoid some UTF-8 issues
|
11
|
+
@options[:syntax_highlighting] = true
|
12
|
+
@options[:link_prefix] = FILE_PREFIX
|
13
|
+
end
|
14
|
+
|
15
|
+
[:template_class, :link_prefix, :syntax_highlighting, :darwin_txmt_protocol_no_thanks].each do |option|
|
16
|
+
define_method("#{option}=") do |arg|
|
17
|
+
@options[option] = arg
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def option(name)
|
22
|
+
@options.fetch(name.to_sym) { raise "No such template option: #{name}" }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
.bluff-tooltip {
|
2
|
+
background: #fff;
|
3
|
+
border: 1px solid #d1edf5;
|
4
|
+
padding: 8px 8px 6px;
|
5
|
+
}
|
6
|
+
.bluff-tooltip .color {
|
7
|
+
display: block;
|
8
|
+
height: 4px;
|
9
|
+
width: 30px;
|
10
|
+
margin: 0 0 4px;
|
11
|
+
overflow: hidden;
|
12
|
+
}
|
13
|
+
.bluff-tooltip .data {
|
14
|
+
font-weight: bold;
|
15
|
+
}
|
@@ -0,0 +1,82 @@
|
|
1
|
+
/* --------------------------------------------------------------
|
2
|
+
|
3
|
+
buttons.css
|
4
|
+
* Gives you some great CSS-only buttons.
|
5
|
+
|
6
|
+
Created by Kevin Hale [particletree.com]
|
7
|
+
* particletree.com/features/rediscovering-the-button-element
|
8
|
+
|
9
|
+
See Readme.txt in this folder for instructions.
|
10
|
+
|
11
|
+
-------------------------------------------------------------- */
|
12
|
+
|
13
|
+
button {
|
14
|
+
display:block;
|
15
|
+
float:left;
|
16
|
+
margin:0 0.583em 0.667em 0;
|
17
|
+
padding:5px 10px 5px 7px; /* Links */
|
18
|
+
|
19
|
+
border:1px solid #dedede;
|
20
|
+
border-top:1px solid #eee;
|
21
|
+
border-left:1px solid #eee;
|
22
|
+
|
23
|
+
background-color:#f5f5f5;
|
24
|
+
font-family:"Lucida Grande", Tahoma, Arial, Verdana, sans-serif;
|
25
|
+
font-size:100%;
|
26
|
+
line-height:130%;
|
27
|
+
text-decoration:none;
|
28
|
+
font-weight:bold;
|
29
|
+
color:#565656;
|
30
|
+
cursor:pointer;
|
31
|
+
}
|
32
|
+
button {
|
33
|
+
width:auto;
|
34
|
+
overflow:visible;
|
35
|
+
padding:4px 10px 3px 7px; /* IE6 */
|
36
|
+
}
|
37
|
+
button[type] {
|
38
|
+
padding:4px 10px 4px 7px; /* Firefox */
|
39
|
+
line-height:17px; /* Safari */
|
40
|
+
}
|
41
|
+
*:first-child+html button[type] {
|
42
|
+
padding:4px 10px 3px 7px; /* IE7 */
|
43
|
+
}
|
44
|
+
button img {
|
45
|
+
margin:0 3px -3px 0 !important;
|
46
|
+
padding:0;
|
47
|
+
border:none;
|
48
|
+
width:16px;
|
49
|
+
height:16px;
|
50
|
+
float:none;
|
51
|
+
}
|
52
|
+
|
53
|
+
|
54
|
+
/* Button colors
|
55
|
+
-------------------------------------------------------------- */
|
56
|
+
|
57
|
+
/* Standard */
|
58
|
+
button:hover {
|
59
|
+
background-color:#dff4ff;
|
60
|
+
border:1px solid #c2e1ef;
|
61
|
+
color:#336699;
|
62
|
+
}
|
63
|
+
|
64
|
+
/* Positive */
|
65
|
+
body .positive {
|
66
|
+
color:#529214;
|
67
|
+
}
|
68
|
+
button.positive:hover {
|
69
|
+
background-color:#E6EFC2;
|
70
|
+
border:1px solid #C6D880;
|
71
|
+
color:#529214;
|
72
|
+
}
|
73
|
+
|
74
|
+
/* Negative */
|
75
|
+
body .negative {
|
76
|
+
color:#d12f19;
|
77
|
+
}
|
78
|
+
button.negative:hover {
|
79
|
+
background:#fbe3e4;
|
80
|
+
border:1px solid #fbc2c4;
|
81
|
+
color:#d12f19;
|
82
|
+
}
|
@@ -0,0 +1,43 @@
|
|
1
|
+
table {
|
2
|
+
margin-top: 20px;
|
3
|
+
border-collapse: collapse;
|
4
|
+
border: 1px solid #666;
|
5
|
+
background: #fff;
|
6
|
+
margin-bottom: 20px;
|
7
|
+
}
|
8
|
+
|
9
|
+
table tr.light {
|
10
|
+
background: #fff;
|
11
|
+
}
|
12
|
+
|
13
|
+
table tr.dark {
|
14
|
+
background: #f9f9f9;
|
15
|
+
}
|
16
|
+
|
17
|
+
table tr:hover {
|
18
|
+
background: #FFFFC0;
|
19
|
+
}
|
20
|
+
|
21
|
+
table td, table th {
|
22
|
+
padding: 4px;
|
23
|
+
font-size: 11px;
|
24
|
+
}
|
25
|
+
table th {
|
26
|
+
text-align: center;
|
27
|
+
color: #337022;
|
28
|
+
background: #DDFFCC;
|
29
|
+
font-weight: bold;
|
30
|
+
border: #99D688 1px solid;
|
31
|
+
}
|
32
|
+
|
33
|
+
table td {
|
34
|
+
border: #d0d0d0 1px solid;
|
35
|
+
}
|
36
|
+
|
37
|
+
table td.score {
|
38
|
+
text-align: right;
|
39
|
+
}
|
40
|
+
|
41
|
+
.warning {
|
42
|
+
background: yellow;
|
43
|
+
}
|