code_metric_fu 4.14.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 +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,129 @@
|
|
|
1
|
+
require "redcard"
|
|
2
|
+
require "rbconfig"
|
|
3
|
+
MetricFu.lib_require { "logger" }
|
|
4
|
+
module MetricFu
|
|
5
|
+
module Environment
|
|
6
|
+
# TODO: Set log_level here, instead
|
|
7
|
+
def verbose
|
|
8
|
+
MetricFu.logger.debug_on
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def verbose=(toggle)
|
|
12
|
+
MetricFu.logger.debug_on = toggle
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Perform a simple check to try and guess if we're running
|
|
16
|
+
# against a rails app.
|
|
17
|
+
#
|
|
18
|
+
# TODO This should probably be made a bit more robust.
|
|
19
|
+
def rails?
|
|
20
|
+
@rails ||= begin
|
|
21
|
+
exists = File.exist?("config/environment.rb")
|
|
22
|
+
def MetricFu.rails?
|
|
23
|
+
exists
|
|
24
|
+
end
|
|
25
|
+
exists
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def is_cruise_control_rb?
|
|
30
|
+
!!ENV["CC_BUILD_ARTIFACTS"]
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def jruby?
|
|
34
|
+
@jruby ||= !!RedCard.check(:jruby)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def mri?
|
|
38
|
+
@mri ||= !!RedCard.check(:ruby)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def ruby_flavor
|
|
42
|
+
@ruby_flavor ||= RedCard.engine
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def ruby_version
|
|
46
|
+
@ruby_version ||= RedCard.engine_version
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def ruby18?
|
|
50
|
+
@ruby18 ||= mri? && !!RedCard.check("1.8"..."1.9")
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def ruby192?
|
|
54
|
+
@ruby192 ||= mri? && ruby_version == "1.9.2"
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def rubinius?
|
|
58
|
+
@rubinius ||= !!RedCard.check(:rubinius)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def supports_ripper?
|
|
62
|
+
@supports_ripper ||= begin
|
|
63
|
+
require "ripper"
|
|
64
|
+
true
|
|
65
|
+
rescue LoadError
|
|
66
|
+
false
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def platform #:nodoc:
|
|
71
|
+
RUBY_PLATFORM
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def version
|
|
75
|
+
MetricFu::VERSION
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def environment_details
|
|
79
|
+
@environment_details ||= {
|
|
80
|
+
"VERBOSE" => $VERBOSE.inspect,
|
|
81
|
+
"External Encoding" => Encoding.default_external.to_s,
|
|
82
|
+
"Internal Encoding" => Encoding.default_internal.to_s,
|
|
83
|
+
"Host Architecture" => RbConfig::CONFIG["build"],
|
|
84
|
+
"Ruby Prefix" => RbConfig::CONFIG["prefix"],
|
|
85
|
+
"Ruby Options" => ENV.keys.grep(/RUBYOPT/).map { |key| "#{key}=#{ENV[key]}" }.join(", "),
|
|
86
|
+
}
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# To consider
|
|
90
|
+
# $LOADED_FEATURES
|
|
91
|
+
# $LOAD_PATH
|
|
92
|
+
def ruby_details
|
|
93
|
+
@ruby_details ||= {
|
|
94
|
+
"Engine" => ruby_flavor,
|
|
95
|
+
"Version" => ruby_version,
|
|
96
|
+
"Patchlevel" => (defined?(RUBY_PATCHLEVEL) && RUBY_PATCHLEVEL),
|
|
97
|
+
"Ripper Support" => supports_ripper?,
|
|
98
|
+
"Rubygems Version" => Gem::VERSION,
|
|
99
|
+
"Long Description" => (defined?(RUBY_DESCRIPTION) ? RUBY_DESCRIPTION : platform),
|
|
100
|
+
}
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def library_details
|
|
104
|
+
@library_details ||= {
|
|
105
|
+
"Version" => version,
|
|
106
|
+
"Verbose Mode" => verbose,
|
|
107
|
+
"Enabled Metrics" => MetricFu::Metric.enabled_metrics.map(&:name),
|
|
108
|
+
"Dependencies" => MetricFu::GemVersion.dependencies_summary,
|
|
109
|
+
}
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def debug_info
|
|
113
|
+
@debug_info ||= {
|
|
114
|
+
"Ruby" => ruby_details,
|
|
115
|
+
"Environment" => environment_details,
|
|
116
|
+
"MetricFu" => library_details,
|
|
117
|
+
}
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def osx?
|
|
121
|
+
@osx ||= platform.include?("darwin")
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def ruby_strangely_makes_accessors_private?
|
|
125
|
+
@private_accessors ||= ruby192? || jruby?
|
|
126
|
+
end
|
|
127
|
+
module_function :ruby_strangely_makes_accessors_private?
|
|
128
|
+
end
|
|
129
|
+
end
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
require "launchy"
|
|
2
|
+
MetricFu.formatter_require { "yaml" }
|
|
3
|
+
MetricFu.reporting_require { "graphs/graph" }
|
|
4
|
+
module MetricFu
|
|
5
|
+
module Formatter
|
|
6
|
+
class HTML
|
|
7
|
+
include MetricFu::Io
|
|
8
|
+
|
|
9
|
+
def initialize(opts = {})
|
|
10
|
+
@options = opts
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def finish
|
|
14
|
+
mf_log "** SAVING REPORTS"
|
|
15
|
+
mf_debug "** SAVING REPORT YAML OUTPUT TO #{MetricFu::Io::FileSystem.directory('base_directory')}"
|
|
16
|
+
MetricFu::Formatter::YAML.new.finish
|
|
17
|
+
|
|
18
|
+
mf_debug "** SAVING REPORT DATA OUTPUT TO #{MetricFu::Io::FileSystem.directory('data_directory')}"
|
|
19
|
+
# TODO: Allow customizing output filenames
|
|
20
|
+
MetricFu::Formatter::YAML.new(
|
|
21
|
+
output: MetricFu.run_path.join("#{MetricFu::Io::FileSystem.directory('data_directory')}/#{MetricFu.report_id}.yml")
|
|
22
|
+
).finish
|
|
23
|
+
|
|
24
|
+
mf_debug "** SAVING TEMPLATIZED REPORT"
|
|
25
|
+
save_templatized_result
|
|
26
|
+
save_graphs
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def write_template(output, file)
|
|
30
|
+
write_output(output, "#{output_directory}/#{file}")
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def display_results
|
|
34
|
+
if self.open_in_browser?
|
|
35
|
+
mf_debug "** OPENING IN BROWSER FROM #{output_directory}"
|
|
36
|
+
show_in_browser(output_directory)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
protected
|
|
41
|
+
|
|
42
|
+
def output_directory
|
|
43
|
+
@output ||= dir_for(@options[:output]) || MetricFu.run_path.join(MetricFu::Io::FileSystem.directory("output_directory"))
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Instantiates a new template class based on the configuration set
|
|
47
|
+
# in MetricFu::Configuration, or through the MetricFu.config block
|
|
48
|
+
# in your rake file (defaults to the included MetricFu::Templates::MetricsTemplate),
|
|
49
|
+
# assigns the result_hash to the result_hash in the template, and
|
|
50
|
+
# tells the template to to write itself out.
|
|
51
|
+
def save_templatized_result
|
|
52
|
+
@template = MetricFu::Formatter::Templates.option("template_class").new
|
|
53
|
+
@template.output_directory = output_directory
|
|
54
|
+
@template.result = MetricFu.result.result_hash
|
|
55
|
+
@template.per_file_data = MetricFu.result.per_file_data
|
|
56
|
+
@template.formatter = self
|
|
57
|
+
@template.write
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def save_graphs
|
|
61
|
+
mf_log "** GENERATING GRAPHS"
|
|
62
|
+
mf_debug "** PREPARING TO GRAPH"
|
|
63
|
+
MetricFu.configuration.graphed_metrics.each {|graphed_metric|
|
|
64
|
+
mf_debug "** Graphing #{graphed_metric} with #{MetricFu.configuration.graph_engine}"
|
|
65
|
+
# TODO: This should probably be defined on configuration
|
|
66
|
+
# rather than the module. See MetricFu::Graph
|
|
67
|
+
MetricFu.graph.add(graphed_metric, MetricFu.configuration.graph_engine, output_directory)
|
|
68
|
+
}
|
|
69
|
+
mf_debug "** GENERATING GRAPH"
|
|
70
|
+
MetricFu.graph.generate
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Checks to discover whether we should try and open the results
|
|
74
|
+
# of the report in the browser on this system. We only try and open
|
|
75
|
+
# in the browser if we're not running in a CruiseControl.rb environment.
|
|
76
|
+
# See MetricFu.configuration for more details about how we make those guesses.
|
|
77
|
+
#
|
|
78
|
+
# @return Boolean
|
|
79
|
+
# Should we open in the browser or not?
|
|
80
|
+
def open_in_browser?
|
|
81
|
+
!MetricFu.configuration.is_cruise_control_rb?
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# Shows 'index.html' from the passed directory in the browser
|
|
85
|
+
# if we're able to open the browser on this platform.
|
|
86
|
+
#
|
|
87
|
+
# @param dir Pathname
|
|
88
|
+
# The directory path where the 'index.html' we want to open is
|
|
89
|
+
# stored
|
|
90
|
+
def show_in_browser(dir)
|
|
91
|
+
uri = URI.join(URI.escape("file://#{dir}/"), "index.html")
|
|
92
|
+
Launchy.open(uri) if open_in_browser?
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
require "coderay"
|
|
2
|
+
MetricFu.lib_require { "utility" }
|
|
3
|
+
# CodeRay options
|
|
4
|
+
# used to analyze source code, because object Tokens is a list of tokens with specified types.
|
|
5
|
+
# :tab_width – tabulation width in spaces. Default: 8
|
|
6
|
+
# :css – how to include the styles (:class и :style). Default: :class)
|
|
7
|
+
#
|
|
8
|
+
# :wrap – wrap result in html tag :page, :div, :span or not to wrap (nil)
|
|
9
|
+
#
|
|
10
|
+
# :line_numbers – how render line numbers (:table, :inline, :list or nil)
|
|
11
|
+
#
|
|
12
|
+
# :line_number_start – first line number
|
|
13
|
+
#
|
|
14
|
+
# :bold_every – make every n-th line number bold. Default: 10
|
|
15
|
+
module MetricFu
|
|
16
|
+
module Formatter
|
|
17
|
+
class Syntax
|
|
18
|
+
def initialize
|
|
19
|
+
@options = { css: :class, style: :alpha }
|
|
20
|
+
@line_number_options = { line_numbers: :inline, line_number_start: 0 }
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def highlight(ruby_text, line_number)
|
|
24
|
+
tokens = tokenize(ruby_text)
|
|
25
|
+
tokens.div(highlight_options(line_number))
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def highlight_options(line_number)
|
|
29
|
+
line_number = line_number.to_i
|
|
30
|
+
if line_number > 0
|
|
31
|
+
@options.merge(@line_number_options.merge(line_number_start: line_number))
|
|
32
|
+
else
|
|
33
|
+
@options
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
|
|
39
|
+
def tokenize(ruby_text)
|
|
40
|
+
ascii_text = MetricFu::Utility.clean_ascii_text(ruby_text)
|
|
41
|
+
tokens = CodeRay.scan(ascii_text, :ruby)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module MetricFu
|
|
2
|
+
module Formatter
|
|
3
|
+
class YAML
|
|
4
|
+
include MetricFu::Io
|
|
5
|
+
|
|
6
|
+
DEFAULT_PATH = "report.yml"
|
|
7
|
+
|
|
8
|
+
def initialize(opts = {})
|
|
9
|
+
@options = opts
|
|
10
|
+
@path_or_io = @options[:output] || DEFAULT_PATH
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def finish
|
|
14
|
+
write_output(MetricFu.result.as_yaml, @path_or_io)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
require "metric_fu/constantize"
|
|
2
|
+
module MetricFu
|
|
3
|
+
module Formatter
|
|
4
|
+
BUILTIN_FORMATS = {
|
|
5
|
+
"html" => ["MetricFu::Formatter::HTML", "Generates a templated HTML report using the configured template class and graph engine."],
|
|
6
|
+
"yaml" => ["MetricFu::Formatter::YAML", "Generates the raw output as yaml"]
|
|
7
|
+
}
|
|
8
|
+
DEFAULT = [[:html]]
|
|
9
|
+
|
|
10
|
+
class << self
|
|
11
|
+
include MetricFu::Constantize
|
|
12
|
+
|
|
13
|
+
def class_for(format)
|
|
14
|
+
if (builtin = BUILTIN_FORMATS[format.to_s])
|
|
15
|
+
constantize(builtin[0])
|
|
16
|
+
else
|
|
17
|
+
constantize(format.to_s)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
module Templates
|
|
23
|
+
MetricFu.lib_require { "templates/metrics_template" }
|
|
24
|
+
|
|
25
|
+
module_function
|
|
26
|
+
|
|
27
|
+
def templates_configuration=(templates_configuration)
|
|
28
|
+
@templates_configuration = templates_configuration
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def option(name)
|
|
32
|
+
templates_configuration.option(name)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def templates_configuration
|
|
36
|
+
@templates_configuration ||= MetricFu::Templates::Configuration.new
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
require "open3"
|
|
3
|
+
require "shellwords"
|
|
4
|
+
require "metric_fu"
|
|
5
|
+
MetricFu.lib_require { "logger" }
|
|
6
|
+
MetricFu.lib_require { "gem_version" }
|
|
7
|
+
module MetricFu
|
|
8
|
+
class GemRun
|
|
9
|
+
attr_reader :output, :gem_name, :library_name, :version, :arguments
|
|
10
|
+
def initialize(arguments = {})
|
|
11
|
+
@gem_name = arguments.fetch(:gem_name)
|
|
12
|
+
@library_name = arguments.fetch(:metric_name)
|
|
13
|
+
@version = arguments.fetch(:version) { MetricFu::GemVersion.for(library_name) }
|
|
14
|
+
args = arguments.fetch(:args)
|
|
15
|
+
@arguments = args.respond_to?(:scan) ? Shellwords.shellwords(args) : args
|
|
16
|
+
@output = ""
|
|
17
|
+
@errors = []
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def summary
|
|
21
|
+
"RubyGem #{gem_name}, library #{library_name}, version #{version}, arguments #{arguments}"
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def run
|
|
25
|
+
@output = execute
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def execute
|
|
29
|
+
mf_debug "Running #{summary}"
|
|
30
|
+
captured_output = ""
|
|
31
|
+
captured_errors = ""
|
|
32
|
+
thread = ""
|
|
33
|
+
Open3.popen3("#{library_name}", *arguments) do |_stdin, stdout, stderr, wait_thr|
|
|
34
|
+
captured_output << stdout.read.chomp
|
|
35
|
+
captured_errors << stderr.read.chomp
|
|
36
|
+
thread = wait_thr
|
|
37
|
+
end
|
|
38
|
+
rescue StandardError => run_error
|
|
39
|
+
handle_run_error(run_error)
|
|
40
|
+
rescue SystemExit => system_exit
|
|
41
|
+
handle_system_exit(system_exit)
|
|
42
|
+
ensure
|
|
43
|
+
print_errors
|
|
44
|
+
return captured_output, captured_errors, thread.value
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def handle_run_error(run_error)
|
|
48
|
+
@errors << "ERROR: #{run_error.inspect}"
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def handle_system_exit(system_exit)
|
|
52
|
+
status = system_exit.success? ? "SUCCESS" : "FAILURE"
|
|
53
|
+
message = "#{status} with code #{system_exit.status}: " <<
|
|
54
|
+
"#{system_exit.message}: #{system_exit.backtrace.inspect}"
|
|
55
|
+
if status == "SUCCESS"
|
|
56
|
+
mf_debug message
|
|
57
|
+
else
|
|
58
|
+
@errors << message
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def print_errors
|
|
63
|
+
return if @errors.empty?
|
|
64
|
+
STDERR.puts "ERRORS running #{summary}"
|
|
65
|
+
@errors.each do |error|
|
|
66
|
+
STDERR.puts "\t" << error
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
require "rubygems"
|
|
3
|
+
module MetricFu
|
|
4
|
+
class GemVersion
|
|
5
|
+
# regexp from https://github.com/gemnasium/gemnasium-parser/blob/807d7ccc/lib/gemnasium/parser/patterns.rb#L11
|
|
6
|
+
# under MIT License
|
|
7
|
+
GEM_NAME = /[a-zA-Z0-9\-_\.]+/
|
|
8
|
+
QUOTED_GEM_NAME = /(?:(?<gq>["'])(?<name>#{GEM_NAME})\k<gq>|%q<(?<name>#{GEM_NAME})>)/
|
|
9
|
+
MATCHER = /(?:=|!=|>|<|>=|<=|~>)/
|
|
10
|
+
VERSION = /[0-9]+(?:\.[a-zA-Z0-9]+)*/
|
|
11
|
+
REQUIREMENT = /[ \t]*(?:#{MATCHER}[ \t]*)?#{VERSION}[ \t]*/
|
|
12
|
+
REQUIREMENT_LIST = /(?<qr1>["'])(?<req1>#{REQUIREMENT})\k<qr1>(?:[ \t]*,[ \t]*(?<qr2>["'])(?<req2>#{REQUIREMENT})\k<qr2>)?/
|
|
13
|
+
REQUIREMENTS = /(?:#{REQUIREMENT_LIST}|\[[ \t]*#{REQUIREMENT_LIST}[ \t]*\])/
|
|
14
|
+
COMMENT = /(#[^\n]*)?/
|
|
15
|
+
ADD_DEPENDENCY_CALL = /^[ \t]*\w+\.add(?<type>_runtime|_development)?_dependency\(?[ \t]*#{QUOTED_GEM_NAME}(.freeze)?(?:[ \t]*,[ \t]*#{REQUIREMENTS})?[ \t]*\)?[ \t]*#{COMMENT}$/
|
|
16
|
+
|
|
17
|
+
def initialize
|
|
18
|
+
@gem_spec = File.open(gemspec, "rb") { |f| f.readlines }
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def gemspec
|
|
22
|
+
File.join(MetricFu.root_dir, "metric_fu.gemspec")
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def new_dependency(name, version)
|
|
26
|
+
Gem::Dependency.new(name, version, :runtime)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def gem_runtime_dependencies
|
|
30
|
+
@gem_runtime_dependencies ||=
|
|
31
|
+
begin
|
|
32
|
+
@gem_spec.grep(/add_dependency|add_runtime/).map do |line|
|
|
33
|
+
match = line.match(ADD_DEPENDENCY_CALL)
|
|
34
|
+
name = match["name"].downcase.sub("metric_fu-", "")
|
|
35
|
+
version = [match["req1"], match["req2"]].compact
|
|
36
|
+
new_dependency(name, version)
|
|
37
|
+
end.compact << new_dependency("rcov", ["~> 0.8"])
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def for(name)
|
|
42
|
+
name.downcase!
|
|
43
|
+
dep = gem_runtime_dependencies.find(unknown_dependency(name)) do |gem_dep|
|
|
44
|
+
gem_dep.name == name
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
dep.requirements_list
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def unknown_dependency(name)
|
|
51
|
+
-> { new_dependency(name, [">= 0"]) }
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
RESOLVER = new
|
|
55
|
+
def self.for(name)
|
|
56
|
+
RESOLVER.for(name).dup
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def self.dependencies
|
|
60
|
+
RESOLVER.gem_runtime_dependencies.dup
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def self.activated_gems
|
|
64
|
+
if Gem::Specification.respond_to?(:stubs)
|
|
65
|
+
Gem::Specification.stubs
|
|
66
|
+
else
|
|
67
|
+
Gem.loaded_specs.values
|
|
68
|
+
end.select(&:activated?)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def self.activated_version(name)
|
|
72
|
+
activated_gems.find do |gem|
|
|
73
|
+
return gem.version.version if gem.name == name
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def self.dependency_summary(gem_dep)
|
|
78
|
+
name = gem_dep.name
|
|
79
|
+
version = activated_version(gem_dep.name) || gem_dep.requirements_list
|
|
80
|
+
{
|
|
81
|
+
"name" => name,
|
|
82
|
+
"version" => version,
|
|
83
|
+
}
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def self.dependencies_summary
|
|
87
|
+
dependencies.map do |gem_dep|
|
|
88
|
+
dependency_summary(gem_dep)
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
MetricFu.lib_require { "utility" }
|
|
2
|
+
module MetricFu
|
|
3
|
+
# = Generator
|
|
4
|
+
#
|
|
5
|
+
# The Generator class is an abstract class that provides the
|
|
6
|
+
# skeleton for producing different types of metrics.
|
|
7
|
+
#
|
|
8
|
+
# It drives the production of the metrics through a template
|
|
9
|
+
# method - #generate_result(options={}). This method calls
|
|
10
|
+
# #emit, #analyze and #to_h in order to produce the metrics.
|
|
11
|
+
#
|
|
12
|
+
# To implement a concrete class to generate a metric, therefore,
|
|
13
|
+
# the class must implement those three methods.
|
|
14
|
+
#
|
|
15
|
+
# * #emit should take care of running the metric tool and
|
|
16
|
+
# gathering its output.
|
|
17
|
+
# * #analyze should take care of manipulating the output from
|
|
18
|
+
# #emit and making it possible to store it in a programmatic way.
|
|
19
|
+
# * #to_h should provide a hash representation of the output from
|
|
20
|
+
# #analyze ready to be serialized into yaml at some point.
|
|
21
|
+
#
|
|
22
|
+
# == Pre-conditions
|
|
23
|
+
#
|
|
24
|
+
# Based on the class name of the concrete class implementing a
|
|
25
|
+
# Generator, the Generator class will create a 'metric_directory'
|
|
26
|
+
# named after the metric under the scratch_directory, where
|
|
27
|
+
# any output from the #emit method should go.
|
|
28
|
+
#
|
|
29
|
+
# It will also create the output_directory if neccessary, and
|
|
30
|
+
# in general setup the directory structure that the MetricFu system
|
|
31
|
+
# expects.
|
|
32
|
+
class Generator
|
|
33
|
+
attr_reader :result, :template, :options
|
|
34
|
+
|
|
35
|
+
def initialize(options = {})
|
|
36
|
+
@options = options
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def self.metric
|
|
40
|
+
not_implemented
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def metric
|
|
44
|
+
self.class.metric
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
@generators = []
|
|
48
|
+
# @return all subclassed generators [Array<MetricFu::Generator>]
|
|
49
|
+
def self.generators
|
|
50
|
+
@generators
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def self.get_generator(metric)
|
|
54
|
+
generators.find { |generator|generator.metric.to_s == metric.to_s.downcase }
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def self.inherited(subclass)
|
|
58
|
+
@generators << subclass
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Returns the directory where the Generator will write any output
|
|
62
|
+
def self.metric_directory
|
|
63
|
+
@metric_directory ||=
|
|
64
|
+
MetricFu::Metric.get_metric(metric).run_options[:output_directory] ||
|
|
65
|
+
begin
|
|
66
|
+
metric_directory = MetricFu::Io::FileSystem.scratch_directory(metric)
|
|
67
|
+
MetricFu::Utility.mkdir_p(metric_directory, verbose: false)
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# @return [String]
|
|
72
|
+
# The path of the metric directory this class is using.
|
|
73
|
+
def metric_directory
|
|
74
|
+
self.class.metric_directory
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def remove_excluded_files(paths, globs_to_remove = MetricFu::Io::FileSystem.file_globs_to_ignore)
|
|
78
|
+
files_to_remove = []
|
|
79
|
+
globs_to_remove.each do |glob|
|
|
80
|
+
files_to_remove.concat(Dir[glob])
|
|
81
|
+
end
|
|
82
|
+
paths - files_to_remove
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def metric_config
|
|
86
|
+
MetricFu::Metric.get_metric(metric)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def run!(args)
|
|
90
|
+
metric_config.run_external(args)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Provides a template method to drive the production of a metric
|
|
94
|
+
# from a concrete implementation of this class. Each concrete
|
|
95
|
+
# class must implement the three methods that this template method
|
|
96
|
+
# calls: #emit, #analyze and #to_h. For more details, see the
|
|
97
|
+
# class documentation.
|
|
98
|
+
#
|
|
99
|
+
# This template method also calls before_emit, after_emit... etc.
|
|
100
|
+
# methods to allow extra hooks into the processing methods, and help
|
|
101
|
+
# to keep the logic of your Generators clean.
|
|
102
|
+
def generate_result
|
|
103
|
+
mf_debug "Executing #{metric}"
|
|
104
|
+
emit
|
|
105
|
+
analyze
|
|
106
|
+
to_h
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def round_to_tenths(decimal)
|
|
110
|
+
decimal = 0.0 if decimal.to_s.eql?("NaN")
|
|
111
|
+
(decimal * 10).round / 10.0
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def emit #:nodoc:
|
|
115
|
+
self.class.not_implemented
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def analyze #:nodoc:
|
|
119
|
+
self.class.not_implemented
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def to_h #:nodoc:
|
|
123
|
+
self.class.not_implemented
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def self.not_implemented
|
|
127
|
+
raise NotImplementedError.new <<-EOF
|
|
128
|
+
Required method #{caller[0]} not implemented in #{__FILE__}.
|
|
129
|
+
This method must be implemented by a concrete class descending
|
|
130
|
+
from Generator. See generator class documentation for more
|
|
131
|
+
information.
|
|
132
|
+
EOF
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|