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.
Files changed (296) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +28 -0
  3. data/.metrics +3 -0
  4. data/.rspec +2 -0
  5. data/.rubocop.yml +15 -0
  6. data/.rubocop_todo.yml +69 -0
  7. data/.simplecov +74 -0
  8. data/.travis.yml +18 -0
  9. data/.yardopts +4 -0
  10. data/AUTHORS +12 -0
  11. data/CONTRIBUTING.md +47 -0
  12. data/CONTRIBUTORS +76 -0
  13. data/DEV.md +76 -0
  14. data/Gemfile +58 -0
  15. data/Guardfile +30 -0
  16. data/HISTORY.md +705 -0
  17. data/MIT-LICENSE +22 -0
  18. data/README.md +299 -0
  19. data/Rakefile +27 -0
  20. data/TODO.md +118 -0
  21. data/appveyor.yml +29 -0
  22. data/bin/metric_fu +9 -0
  23. data/bin/mf-cane +10 -0
  24. data/bin/mf-churn +10 -0
  25. data/bin/mf-flay +10 -0
  26. data/bin/mf-reek +10 -0
  27. data/bin/mf-roodi +10 -0
  28. data/bin/mf-saikuro +10 -0
  29. data/certs/bf4.pem +22 -0
  30. data/checksum/.gitkeep +0 -0
  31. data/checksum/metric_fu-4.10.0.gem.sha512 +1 -0
  32. data/checksum/metric_fu-4.11.0.gem.sha512 +1 -0
  33. data/checksum/metric_fu-4.11.1.gem.sha512 +1 -0
  34. data/checksum/metric_fu-4.11.2.gem.sha512 +1 -0
  35. data/checksum/metric_fu-4.11.3.gem.sha512 +1 -0
  36. data/checksum/metric_fu-4.11.4.gem.sha512 +1 -0
  37. data/checksum/metric_fu-4.12.0.gem.sha512 +1 -0
  38. data/checksum/metric_fu-4.2.0.gem.sha512 +1 -0
  39. data/checksum/metric_fu-4.2.1.gem.sha512 +1 -0
  40. data/checksum/metric_fu-4.3.0.gem.sha512 +1 -0
  41. data/checksum/metric_fu-4.3.1.gem.sha512 +1 -0
  42. data/checksum/metric_fu-4.4.0.gem.sha512 +1 -0
  43. data/checksum/metric_fu-4.4.1.gem.sha512 +1 -0
  44. data/checksum/metric_fu-4.4.2.gem.sha512 +1 -0
  45. data/checksum/metric_fu-4.4.3.gem.sha512 +1 -0
  46. data/checksum/metric_fu-4.4.4.gem.sha512 +1 -0
  47. data/checksum/metric_fu-4.5.0.gem.sha512 +1 -0
  48. data/checksum/metric_fu-4.5.1.gem.sha512 +1 -0
  49. data/checksum/metric_fu-4.5.2.gem.sha512 +1 -0
  50. data/checksum/metric_fu-4.6.0.gem.sha512 +1 -0
  51. data/checksum/metric_fu-4.7.0.gem.sha512 +1 -0
  52. data/checksum/metric_fu-4.7.1.gem.sha512 +1 -0
  53. data/checksum/metric_fu-4.7.2.gem.sha512 +1 -0
  54. data/checksum/metric_fu-4.7.3.gem.sha512 +1 -0
  55. data/checksum/metric_fu-4.7.4.gem.sha512 +1 -0
  56. data/checksum/metric_fu-4.8.0.gem.sha512 +1 -0
  57. data/checksum/metric_fu-4.9.0.gem.sha512 +1 -0
  58. data/config/roodi_config.yml +22 -0
  59. data/config/rubocop.yml +269 -0
  60. data/gem_tasks/build.rake +197 -0
  61. data/gem_tasks/rubocop.rake +10 -0
  62. data/gem_tasks/usage_test.rake +19 -0
  63. data/gem_tasks/yard.rake +24 -0
  64. data/lib/metric_fu.rb +151 -0
  65. data/lib/metric_fu/calculate.rb +10 -0
  66. data/lib/metric_fu/cli/client.rb +26 -0
  67. data/lib/metric_fu/cli/helper.rb +80 -0
  68. data/lib/metric_fu/cli/parser.rb +138 -0
  69. data/lib/metric_fu/configuration.rb +150 -0
  70. data/lib/metric_fu/constantize.rb +57 -0
  71. data/lib/metric_fu/data_structures/line_numbers.rb +112 -0
  72. data/lib/metric_fu/data_structures/location.rb +110 -0
  73. data/lib/metric_fu/data_structures/sexp_node.rb +107 -0
  74. data/lib/metric_fu/environment.rb +129 -0
  75. data/lib/metric_fu/errors/analysis_error.rb +4 -0
  76. data/lib/metric_fu/formatter.rb +40 -0
  77. data/lib/metric_fu/formatter/html.rb +96 -0
  78. data/lib/metric_fu/formatter/syntax.rb +45 -0
  79. data/lib/metric_fu/formatter/yaml.rb +18 -0
  80. data/lib/metric_fu/gem_run.rb +70 -0
  81. data/lib/metric_fu/gem_version.rb +92 -0
  82. data/lib/metric_fu/generator.rb +135 -0
  83. data/lib/metric_fu/io.rb +132 -0
  84. data/lib/metric_fu/loader.rb +105 -0
  85. data/lib/metric_fu/logger.rb +62 -0
  86. data/lib/metric_fu/logging/mf_debugger.rb +23 -0
  87. data/lib/metric_fu/metric.rb +143 -0
  88. data/lib/metric_fu/metrics/cane/generator.rb +95 -0
  89. data/lib/metric_fu/metrics/cane/grapher.rb +37 -0
  90. data/lib/metric_fu/metrics/cane/metric.rb +34 -0
  91. data/lib/metric_fu/metrics/cane/report.html.erb +87 -0
  92. data/lib/metric_fu/metrics/cane/violations.rb +46 -0
  93. data/lib/metric_fu/metrics/churn/generator.rb +37 -0
  94. data/lib/metric_fu/metrics/churn/hotspot.rb +43 -0
  95. data/lib/metric_fu/metrics/churn/metric.rb +29 -0
  96. data/lib/metric_fu/metrics/churn/report.html.erb +58 -0
  97. data/lib/metric_fu/metrics/flay/generator.rb +51 -0
  98. data/lib/metric_fu/metrics/flay/grapher.rb +37 -0
  99. data/lib/metric_fu/metrics/flay/hotspot.rb +52 -0
  100. data/lib/metric_fu/metrics/flay/metric.rb +28 -0
  101. data/lib/metric_fu/metrics/flay/report.html.erb +29 -0
  102. data/lib/metric_fu/metrics/flog/generator.rb +113 -0
  103. data/lib/metric_fu/metrics/flog/grapher.rb +77 -0
  104. data/lib/metric_fu/metrics/flog/hotspot.rb +46 -0
  105. data/lib/metric_fu/metrics/flog/metric.rb +29 -0
  106. data/lib/metric_fu/metrics/flog/report.html.erb +50 -0
  107. data/lib/metric_fu/metrics/hotspots/analysis/analyzed_problems.rb +34 -0
  108. data/lib/metric_fu/metrics/hotspots/analysis/analyzer_tables.rb +114 -0
  109. data/lib/metric_fu/metrics/hotspots/analysis/grouping.rb +23 -0
  110. data/lib/metric_fu/metrics/hotspots/analysis/groupings.rb +12 -0
  111. data/lib/metric_fu/metrics/hotspots/analysis/problems.rb +20 -0
  112. data/lib/metric_fu/metrics/hotspots/analysis/ranked_problem_location.rb +70 -0
  113. data/lib/metric_fu/metrics/hotspots/analysis/ranking.rb +29 -0
  114. data/lib/metric_fu/metrics/hotspots/analysis/rankings.rb +91 -0
  115. data/lib/metric_fu/metrics/hotspots/analysis/record.rb +32 -0
  116. data/lib/metric_fu/metrics/hotspots/analysis/scoring_strategies.rb +24 -0
  117. data/lib/metric_fu/metrics/hotspots/analysis/table.rb +67 -0
  118. data/lib/metric_fu/metrics/hotspots/generator.rb +40 -0
  119. data/lib/metric_fu/metrics/hotspots/hotspot.rb +87 -0
  120. data/lib/metric_fu/metrics/hotspots/hotspot_analyzer.rb +61 -0
  121. data/lib/metric_fu/metrics/hotspots/metric.rb +20 -0
  122. data/lib/metric_fu/metrics/hotspots/report.html.erb +60 -0
  123. data/lib/metric_fu/metrics/rails_best_practices/generator.rb +47 -0
  124. data/lib/metric_fu/metrics/rails_best_practices/grapher.rb +38 -0
  125. data/lib/metric_fu/metrics/rails_best_practices/metric.rb +31 -0
  126. data/lib/metric_fu/metrics/rails_best_practices/report.html.erb +22 -0
  127. data/lib/metric_fu/metrics/rcov/external_client.rb +22 -0
  128. data/lib/metric_fu/metrics/rcov/generator.rb +75 -0
  129. data/lib/metric_fu/metrics/rcov/grapher.rb +37 -0
  130. data/lib/metric_fu/metrics/rcov/hotspot.rb +46 -0
  131. data/lib/metric_fu/metrics/rcov/metric.rb +61 -0
  132. data/lib/metric_fu/metrics/rcov/rcov_format_coverage.rb +149 -0
  133. data/lib/metric_fu/metrics/rcov/rcov_line.rb +48 -0
  134. data/lib/metric_fu/metrics/rcov/report.html.erb +40 -0
  135. data/lib/metric_fu/metrics/rcov/simplecov_formatter.rb +74 -0
  136. data/lib/metric_fu/metrics/reek/generator.rb +94 -0
  137. data/lib/metric_fu/metrics/reek/grapher.rb +55 -0
  138. data/lib/metric_fu/metrics/reek/hotspot.rb +95 -0
  139. data/lib/metric_fu/metrics/reek/metric.rb +26 -0
  140. data/lib/metric_fu/metrics/reek/report.html.erb +35 -0
  141. data/lib/metric_fu/metrics/roodi/generator.rb +40 -0
  142. data/lib/metric_fu/metrics/roodi/grapher.rb +37 -0
  143. data/lib/metric_fu/metrics/roodi/hotspot.rb +39 -0
  144. data/lib/metric_fu/metrics/roodi/metric.rb +24 -0
  145. data/lib/metric_fu/metrics/roodi/report.html.erb +22 -0
  146. data/lib/metric_fu/metrics/saikuro/generator.rb +145 -0
  147. data/lib/metric_fu/metrics/saikuro/hotspot.rb +51 -0
  148. data/lib/metric_fu/metrics/saikuro/metric.rb +31 -0
  149. data/lib/metric_fu/metrics/saikuro/parsing_element.rb +37 -0
  150. data/lib/metric_fu/metrics/saikuro/report.html.erb +71 -0
  151. data/lib/metric_fu/metrics/saikuro/scratch_file.rb +108 -0
  152. data/lib/metric_fu/metrics/stats/generator.rb +82 -0
  153. data/lib/metric_fu/metrics/stats/grapher.rb +40 -0
  154. data/lib/metric_fu/metrics/stats/hotspot.rb +35 -0
  155. data/lib/metric_fu/metrics/stats/metric.rb +28 -0
  156. data/lib/metric_fu/metrics/stats/report.html.erb +44 -0
  157. data/lib/metric_fu/reporter.rb +37 -0
  158. data/lib/metric_fu/reporting/graphs/graph.rb +69 -0
  159. data/lib/metric_fu/reporting/graphs/grapher.rb +66 -0
  160. data/lib/metric_fu/reporting/result.rb +59 -0
  161. data/lib/metric_fu/run.rb +82 -0
  162. data/lib/metric_fu/tasks/metric_fu.rake +54 -0
  163. data/lib/metric_fu/templates/_graph.html.erb +2 -0
  164. data/lib/metric_fu/templates/_report_footer.html.erb +1 -0
  165. data/lib/metric_fu/templates/configuration.rb +25 -0
  166. data/lib/metric_fu/templates/css/bluff.css +15 -0
  167. data/lib/metric_fu/templates/css/buttons.css +82 -0
  168. data/lib/metric_fu/templates/css/default.css +43 -0
  169. data/lib/metric_fu/templates/css/integrity.css +337 -0
  170. data/lib/metric_fu/templates/css/rcov.css +32 -0
  171. data/lib/metric_fu/templates/css/reset.css +7 -0
  172. data/lib/metric_fu/templates/css/syntax.css +19 -0
  173. data/lib/metric_fu/templates/index.html.erb +10 -0
  174. data/lib/metric_fu/templates/javascripts/bluff-min.js +1 -0
  175. data/lib/metric_fu/templates/javascripts/bluff_graph.js +15 -0
  176. data/lib/metric_fu/templates/javascripts/excanvas.js +35 -0
  177. data/lib/metric_fu/templates/javascripts/highcharts.js +294 -0
  178. data/lib/metric_fu/templates/javascripts/highcharts_graph.js +38 -0
  179. data/lib/metric_fu/templates/javascripts/js-class.js +1 -0
  180. data/lib/metric_fu/templates/javascripts/standalone-framework.js +17 -0
  181. data/lib/metric_fu/templates/javascripts/utils.js +9 -0
  182. data/lib/metric_fu/templates/layout.html.erb +37 -0
  183. data/lib/metric_fu/templates/metrics_template.rb +80 -0
  184. data/lib/metric_fu/templates/report.html.erb +31 -0
  185. data/lib/metric_fu/templates/report.rb +41 -0
  186. data/lib/metric_fu/templates/template.rb +244 -0
  187. data/lib/metric_fu/utility.rb +79 -0
  188. data/lib/metric_fu/version.rb +9 -0
  189. data/metric_fu.gemspec +71 -0
  190. data/spec/capture_warnings.rb +55 -0
  191. data/spec/cli/helper_spec.rb +165 -0
  192. data/spec/dummy/.gitignore +1 -0
  193. data/spec/dummy/.gitkeep +0 -0
  194. data/spec/dummy/lib/.gitkeep +0 -0
  195. data/spec/dummy/lib/bad_encoding.rb +6 -0
  196. data/spec/dummy/spec/.gitkeep +0 -0
  197. data/spec/fixtures/20090630.yml +7922 -0
  198. data/spec/fixtures/coverage-153.rb +11 -0
  199. data/spec/fixtures/coverage.rb +13 -0
  200. data/spec/fixtures/exit0.sh +3 -0
  201. data/spec/fixtures/exit1.sh +3 -0
  202. data/spec/fixtures/hotspots/flog.yml +86 -0
  203. data/spec/fixtures/hotspots/generator.yml +47 -0
  204. data/spec/fixtures/hotspots/generator_analysis.yml +53 -0
  205. data/spec/fixtures/hotspots/reek.yml +14 -0
  206. data/spec/fixtures/hotspots/roodi.yml +13 -0
  207. data/spec/fixtures/hotspots/saikuro.yml +27 -0
  208. data/spec/fixtures/hotspots/several_metrics.yml +47 -0
  209. data/spec/fixtures/hotspots/stats.yml +4 -0
  210. data/spec/fixtures/hotspots/three_metrics_on_same_file.yml +36 -0
  211. data/spec/fixtures/line_numbers/foo.rb +33 -0
  212. data/spec/fixtures/line_numbers/module.rb +11 -0
  213. data/spec/fixtures/line_numbers/module_surrounds_class.rb +15 -0
  214. data/spec/fixtures/line_numbers/two_classes.rb +11 -0
  215. data/spec/fixtures/metric_missing.yml +1 -0
  216. data/spec/fixtures/rcov_output.txt +135 -0
  217. data/spec/fixtures/saikuro/app/controllers/sessions_controller.rb_cyclo.html +10 -0
  218. data/spec/fixtures/saikuro/app/controllers/users_controller.rb_cyclo.html +16 -0
  219. data/spec/fixtures/saikuro/index_cyclo.html +155 -0
  220. data/spec/fixtures/saikuro_sfiles/thing.rb_cyclo.html +11 -0
  221. data/spec/metric_fu/calculate_spec.rb +21 -0
  222. data/spec/metric_fu/configuration_spec.rb +90 -0
  223. data/spec/metric_fu/data_structures/line_numbers_spec.rb +63 -0
  224. data/spec/metric_fu/data_structures/location_spec.rb +110 -0
  225. data/spec/metric_fu/formatter/configuration_spec.rb +44 -0
  226. data/spec/metric_fu/formatter/html_spec.rb +138 -0
  227. data/spec/metric_fu/formatter/yaml_spec.rb +61 -0
  228. data/spec/metric_fu/formatter_spec.rb +49 -0
  229. data/spec/metric_fu/gem_version_spec.rb +12 -0
  230. data/spec/metric_fu/generator_spec.rb +130 -0
  231. data/spec/metric_fu/loader_spec.rb +13 -0
  232. data/spec/metric_fu/metric_spec.rb +46 -0
  233. data/spec/metric_fu/metrics/cane/configuration_spec.rb +22 -0
  234. data/spec/metric_fu/metrics/cane/generator_spec.rb +184 -0
  235. data/spec/metric_fu/metrics/churn/configuration_spec.rb +13 -0
  236. data/spec/metric_fu/metrics/churn/generator_spec.rb +64 -0
  237. data/spec/metric_fu/metrics/flay/configuration_spec.rb +13 -0
  238. data/spec/metric_fu/metrics/flay/generator_spec.rb +105 -0
  239. data/spec/metric_fu/metrics/flay/grapher_spec.rb +57 -0
  240. data/spec/metric_fu/metrics/flog/configuration_spec.rb +18 -0
  241. data/spec/metric_fu/metrics/flog/generator_spec.rb +77 -0
  242. data/spec/metric_fu/metrics/flog/grapher_spec.rb +107 -0
  243. data/spec/metric_fu/metrics/hotspots/analysis/analyzed_problems_spec.rb +104 -0
  244. data/spec/metric_fu/metrics/hotspots/analysis/analyzer_tables_spec.rb +71 -0
  245. data/spec/metric_fu/metrics/hotspots/analysis/ranking_spec.rb +30 -0
  246. data/spec/metric_fu/metrics/hotspots/analysis/rankings_spec.rb +97 -0
  247. data/spec/metric_fu/metrics/hotspots/analysis/table_spec.rb +6 -0
  248. data/spec/metric_fu/metrics/hotspots/generator_spec.rb +46 -0
  249. data/spec/metric_fu/metrics/hotspots/hotspot_analyzer_spec.rb +10 -0
  250. data/spec/metric_fu/metrics/hotspots/hotspot_spec.rb +16 -0
  251. data/spec/metric_fu/metrics/rails_best_practices/configuration_spec.rb +55 -0
  252. data/spec/metric_fu/metrics/rails_best_practices/generator_spec.rb +33 -0
  253. data/spec/metric_fu/metrics/rails_best_practices/grapher_spec.rb +62 -0
  254. data/spec/metric_fu/metrics/rcov/configuration_spec.rb +28 -0
  255. data/spec/metric_fu/metrics/rcov/generator_spec.rb +22 -0
  256. data/spec/metric_fu/metrics/rcov/grapher_spec.rb +57 -0
  257. data/spec/metric_fu/metrics/rcov/hotspot_spec.rb +20 -0
  258. data/spec/metric_fu/metrics/rcov/rcov_line_spec.rb +89 -0
  259. data/spec/metric_fu/metrics/rcov/simplecov_formatter_spec.rb +67 -0
  260. data/spec/metric_fu/metrics/reek/configuration_spec.rb +13 -0
  261. data/spec/metric_fu/metrics/reek/generator_spec.rb +203 -0
  262. data/spec/metric_fu/metrics/reek/grapher_spec.rb +66 -0
  263. data/spec/metric_fu/metrics/roodi/configuration_spec.rb +14 -0
  264. data/spec/metric_fu/metrics/roodi/generator_spec.rb +82 -0
  265. data/spec/metric_fu/metrics/roodi/grapher_spec.rb +57 -0
  266. data/spec/metric_fu/metrics/saikuro/configuration_spec.rb +25 -0
  267. data/spec/metric_fu/metrics/saikuro/generator_spec.rb +71 -0
  268. data/spec/metric_fu/metrics/stats/generator_spec.rb +96 -0
  269. data/spec/metric_fu/metrics/stats/grapher_spec.rb +69 -0
  270. data/spec/metric_fu/reporter_spec.rb +41 -0
  271. data/spec/metric_fu/reporting/graphs/graph_spec.rb +44 -0
  272. data/spec/metric_fu/reporting/graphs/grapher_spec.rb +24 -0
  273. data/spec/metric_fu/reporting/result_spec.rb +50 -0
  274. data/spec/metric_fu/run_spec.rb +197 -0
  275. data/spec/metric_fu/templates/configuration_spec.rb +51 -0
  276. data/spec/metric_fu/templates/metrics_template_spec.rb +11 -0
  277. data/spec/metric_fu/templates/report_spec.rb +15 -0
  278. data/spec/metric_fu/templates/template_spec.rb +233 -0
  279. data/spec/metric_fu/utility_spec.rb +12 -0
  280. data/spec/metric_fu_spec.rb +52 -0
  281. data/spec/quality_spec.rb +114 -0
  282. data/spec/shared/configured.rb +45 -0
  283. data/spec/shared/test_coverage.rb +95 -0
  284. data/spec/spec_helper.rb +46 -0
  285. data/spec/support/.metrics +4 -0
  286. data/spec/support/deferred_garbaged_collection.rb +33 -0
  287. data/spec/support/helper_methods.rb +32 -0
  288. data/spec/support/matcher_create_file.rb +37 -0
  289. data/spec/support/matcher_create_files.rb +43 -0
  290. data/spec/support/samples/reek/alfa.rb +1 -0
  291. data/spec/support/suite.rb +26 -0
  292. data/spec/support/test_fixtures.rb +37 -0
  293. data/spec/support/timeout.rb +7 -0
  294. data/spec/support/usage_test.rb +150 -0
  295. data/spec/usage_test_spec.rb +93 -0
  296. 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,4 @@
1
+ module MetricFu
2
+ class AnalysisError < RuntimeError
3
+ end
4
+ 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