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,110 @@
|
|
|
1
|
+
module MetricFu
|
|
2
|
+
class Location
|
|
3
|
+
include Comparable
|
|
4
|
+
|
|
5
|
+
attr_accessor :file_path, :file_name, :line_number,
|
|
6
|
+
:class_name, :method_name, :simple_method_name, :hash, :hash_key
|
|
7
|
+
|
|
8
|
+
def self.get(file_path, class_name, method_name)
|
|
9
|
+
location = new(file_path, class_name, method_name)
|
|
10
|
+
@@locations ||= {}
|
|
11
|
+
@@locations.fetch(location.hash_key) do
|
|
12
|
+
@@locations[location.hash_key] = location
|
|
13
|
+
location.finalize
|
|
14
|
+
location
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def initialize(file_path, class_name, method_name)
|
|
19
|
+
@file_path = file_path
|
|
20
|
+
@file_name, @line_number = file_path.to_s.split(/:/)
|
|
21
|
+
@class_name = class_name
|
|
22
|
+
@method_name = method_name
|
|
23
|
+
@simple_method_name = @method_name.to_s.sub(@class_name.to_s, "")
|
|
24
|
+
@hash_key = to_key
|
|
25
|
+
@hash = @hash_key.hash
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def to_hash
|
|
29
|
+
hash = {
|
|
30
|
+
"class_name" => class_name,
|
|
31
|
+
"method_name" => method_name,
|
|
32
|
+
"file_path" => file_path,
|
|
33
|
+
"file_name" => file_name,
|
|
34
|
+
"line_number" => line_number,
|
|
35
|
+
"hash_key" => hash_key,
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if method_name.to_s.size > 0
|
|
39
|
+
hash = hash.merge("simple_method_name" => simple_method_name)
|
|
40
|
+
else
|
|
41
|
+
hash
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# defining :eql? and :hash to use Location as a hash key
|
|
46
|
+
def eql?(other)
|
|
47
|
+
@hash == other.hash
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def <=>(other)
|
|
51
|
+
hash <=> other.hash
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Generates the @hash key
|
|
55
|
+
def to_key
|
|
56
|
+
[@file_path, @class_name, @method_name].inspect
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def self.for(class_or_method_name)
|
|
60
|
+
class_or_method_name = strip_modules(class_or_method_name)
|
|
61
|
+
if class_or_method_name
|
|
62
|
+
begin
|
|
63
|
+
match = class_or_method_name.match(/(.*)((\.|\#|\:\:[a-z])(.+))/)
|
|
64
|
+
rescue => error
|
|
65
|
+
# new error during port to metric_fu occasionally a unintialized
|
|
66
|
+
# MatchData object shows up here. Not expected.
|
|
67
|
+
mf_debug "ERROR on getting location for #{class_or_method_name} #{error.inspect}"
|
|
68
|
+
match = nil
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# reek reports the method with :: not # on modules like
|
|
72
|
+
# module ApplicationHelper \n def signed_in?, convert it so it records correctly
|
|
73
|
+
# but classes have to start with a capital letter... HACK for REEK bug, reported underlying issue to REEK
|
|
74
|
+
if match
|
|
75
|
+
class_name = strip_modules(match[1])
|
|
76
|
+
method_name = class_or_method_name.gsub(/\:\:/, "#")
|
|
77
|
+
else
|
|
78
|
+
class_name = strip_modules(class_or_method_name)
|
|
79
|
+
method_name = nil
|
|
80
|
+
end
|
|
81
|
+
else
|
|
82
|
+
class_name = nil
|
|
83
|
+
method_name = nil
|
|
84
|
+
end
|
|
85
|
+
get(nil, class_name, method_name)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def finalize
|
|
89
|
+
@file_path &&= @file_path.clone
|
|
90
|
+
@file_name &&= @file_name.clone
|
|
91
|
+
@line_number &&= @line_number.clone
|
|
92
|
+
@class_name &&= @class_name.clone
|
|
93
|
+
@method_name &&= @method_name.clone
|
|
94
|
+
freeze # we cache a lot of method call results, so we want location to be immutable
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
private
|
|
98
|
+
|
|
99
|
+
def self.strip_modules(class_or_method_name)
|
|
100
|
+
# reek reports the method with :: not # on modules like
|
|
101
|
+
# module ApplicationHelper \n def signed_in?, convert it so it records correctly
|
|
102
|
+
# but classes have to start with a capital letter... HACK for REEK bug, reported underlying issue to REEK
|
|
103
|
+
if class_or_method_name =~ /\:\:[A-Z]/
|
|
104
|
+
class_or_method_name.split("::").last
|
|
105
|
+
else
|
|
106
|
+
class_or_method_name
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
require "ruby_parser"
|
|
2
|
+
module MetricFu
|
|
3
|
+
SexpNode = Struct.new(:sexp) do
|
|
4
|
+
# @return file_sexp
|
|
5
|
+
def self.parse(contents)
|
|
6
|
+
rp = RubyParser.new
|
|
7
|
+
rp.parse(contents)
|
|
8
|
+
end
|
|
9
|
+
def nil?
|
|
10
|
+
sexp.nil?
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def node_type
|
|
14
|
+
sexp[0]
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def name
|
|
18
|
+
sexp[1]
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def each_of_type(type, node_class = SexpNode)
|
|
22
|
+
sexp.each_of_type(type) do |child_sexp|
|
|
23
|
+
yield node_class.new(child_sexp)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def each_module(&block)
|
|
28
|
+
each_of_type(:module, &block)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def each_class(&block)
|
|
32
|
+
each_of_type(:class, &block)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def each_singleton_class(&block)
|
|
36
|
+
each_of_type(:sclass, SingletonMethodNode, &block)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def each_instance_method(&block)
|
|
40
|
+
each_of_type(:defn, InstanceMethodNode, &block)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def each_class_method(&block)
|
|
44
|
+
each_of_type(:defs, ClassMethodNode, &block)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def first_line
|
|
48
|
+
sexp.line
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def last_line
|
|
52
|
+
sexp.last.line
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def line_range
|
|
56
|
+
(first_line..last_line)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def hide_methods_from_next_round
|
|
60
|
+
sexp.find_and_replace_all(:defn, :ignore_me)
|
|
61
|
+
sexp.find_and_replace_all(:defs, :ignore_me)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def full_method_name(method_separator, class_name, module_name = nil)
|
|
65
|
+
[module_namespace(module_name), class_name, method_separator, name].join
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def module_namespace(module_name = nil)
|
|
69
|
+
if module_name.nil?
|
|
70
|
+
nil
|
|
71
|
+
else
|
|
72
|
+
[module_name, class_method_separator].join
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def instance_method_separator
|
|
77
|
+
"#"
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def class_method_separator
|
|
81
|
+
"::"
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
class ClassMethodNode < SexpNode
|
|
85
|
+
def name
|
|
86
|
+
sexp[2]
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def full_name(module_name, class_name)
|
|
90
|
+
full_method_name(class_method_separator, class_name, module_name)
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
class InstanceMethodNode < SexpNode
|
|
94
|
+
def full_name(module_name, class_name)
|
|
95
|
+
full_method_name(instance_method_separator, class_name, module_name)
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
class SingletonMethodNode < SexpNode
|
|
99
|
+
def full_name(class_name)
|
|
100
|
+
full_method_name(class_method_separator, class_name)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def each_singleton_method(&block)
|
|
104
|
+
each_of_type(:defn, SingletonMethodNode, &block)
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
@@ -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,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,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
|