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,34 @@
1
+ module MetricFu
2
+ class MetricCane < Metric
3
+ def name
4
+ :cane
5
+ end
6
+
7
+ def default_run_options
8
+ {
9
+ dirs_to_cane: MetricFu::Io::FileSystem.directory("code_dirs"),
10
+ abc_max: 15,
11
+ line_length: 80,
12
+ no_doc: "n",
13
+ no_readme: "n",
14
+ filetypes: ["rb"]
15
+ }
16
+ end
17
+
18
+ def has_graph?
19
+ true
20
+ end
21
+
22
+ def enable
23
+ if MetricFu.configuration.supports_ripper? && !MetricFu.configuration.ruby18?
24
+ super
25
+ else
26
+ MetricFu.logger.debug("Cane is only available in MRI. It requires ripper and 1.9 hash syntax support")
27
+ end
28
+ end
29
+
30
+ def activate
31
+ super
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,87 @@
1
+ <h3>Cane Results</h3>
2
+
3
+ <p><a href='https://github.com/square/cane'>Cane</a> reports code quality threshold violations.</p>
4
+
5
+ <%= render_partial 'graph', {:graph_name => 'cane'} %>
6
+
7
+ <% if @cane[:violations][:abc_complexity] && @cane[:violations][:abc_complexity].size > 0 %>
8
+ <h3>Methods exceeding allowed Abc complexity (<%= @cane[:violations][:abc_complexity].size %>)</h3>
9
+ <table>
10
+ <tr>
11
+ <th>File</th>
12
+ <th>Method</th>
13
+ <th>Complexity</th>
14
+ </tr>
15
+ <% count = 0 %>
16
+ <% @cane[:violations][:abc_complexity].each do |violation| %>
17
+ <tr class='<%= cycle("light", "dark", count) %>'>
18
+ <td><%=link_to_filename(violation[:file])%></td>
19
+ <td><%=violation[:method]%></td>
20
+ <td><%=violation[:complexity]%></td>
21
+ </tr>
22
+ <% count += 1 %>
23
+ <% end %>
24
+ </table>
25
+ <% end %>
26
+ <% if @cane[:violations][:line_style] && @cane[:violations][:line_style].size > 0 %>
27
+ <h3>Lines violating style requirements (<%= @cane[:violations][:line_style].size %>)</h3>
28
+ <table>
29
+ <tr>
30
+ <th>File</th>
31
+ <th>Description</th>
32
+ </tr>
33
+ <% count = 0 %>
34
+ <% @cane[:violations][:line_style].each do |violation| %>
35
+ <tr class='<%= cycle("light", "dark", count) %>'>
36
+ <td><%=link_to_filename(*violation[:line].split(':'))%></td>
37
+ <td><%=violation[:description]%></td>
38
+ </tr>
39
+ <% count += 1 %>
40
+ <% end %>
41
+ </table>
42
+ <% end %>
43
+ <% if @cane[:violations][:documentation] && @cane[:violations][:documentation].size > 0 %>
44
+ <h3>Missing documentation (<%= @cane[:violations][:documentation].size %>)</h3>
45
+ <table>
46
+ <tr>
47
+ <th>Description</th>
48
+ </tr>
49
+ <% @cane[:violations][:documentation].each do |violation| %>
50
+ <tr>
51
+ <td><%=violation[:description]%></td>
52
+ </tr>
53
+ <% end %>
54
+ </table>
55
+ <% end %>
56
+ <% if @cane[:violations][:comment] && @cane[:violations][:comment].size > 0 %>
57
+ <h3>Class definitions requiring comments (<%= @cane[:violations][:comment].size %>)</h3>
58
+ <table>
59
+ <tr>
60
+ <th>File</th>
61
+ <th>Class</th>
62
+ </tr>
63
+ <% count = 0 %>
64
+ <% @cane[:violations][:comment].each do |violation| %>
65
+ <tr class='<%= cycle("light", "dark", count) %>'>
66
+ <td><%=link_to_filename(*violation[:line].split(':'))%></td>
67
+ <td><%=violation[:class_name]%></td>
68
+ </tr>
69
+ <% count += 1 %>
70
+ <% end %>
71
+ </table>
72
+ <% end %>
73
+ <% if @cane[:violations][:others] && @cane[:violations][:others].size > 0 %>
74
+ <h3>Others (<%= @cane[:violations][:others].size %>)</h3>
75
+ <table>
76
+ <tr>
77
+ <th>Description</th>
78
+ </tr>
79
+ <% @cane[:violations][:others].each do |violation| %>
80
+ <tr>
81
+ <td><%=violation[:description]%></td>
82
+ </tr>
83
+ <% end %>
84
+ </table>
85
+ <% end %>
86
+
87
+ <%= render_partial 'report_footer' %>
@@ -0,0 +1,46 @@
1
+ module MetricFu
2
+ module CaneViolations
3
+ class AbcComplexity
4
+ def self.parse(violation_list)
5
+ violation_list.split(/\n/).map do |violation|
6
+ file, method, complexity = violation.split
7
+ { file: file, method: method, complexity: complexity }
8
+ end
9
+ end
10
+ end
11
+
12
+ class LineStyle
13
+ def self.parse(violation_list)
14
+ violation_list.split(/\n/).map do |violation|
15
+ line, description = violation.split(/\s{2,}/).reject { |x|x.strip == "" }
16
+ { line: line, description: description }
17
+ end
18
+ end
19
+ end
20
+
21
+ class Comment
22
+ def self.parse(violation_list)
23
+ violation_list.split(/\n/).map do |violation|
24
+ line, class_name = violation.split
25
+ { line: line, class_name: class_name }
26
+ end
27
+ end
28
+ end
29
+
30
+ class Documentation
31
+ def self.parse(violation_list)
32
+ violation_list.split(/\n/).map do |violation|
33
+ { description: violation.strip }
34
+ end
35
+ end
36
+ end
37
+
38
+ class Others
39
+ def self.parse(violation_list)
40
+ violation_list.split(/\n/).map do |violation|
41
+ { description: violation.strip }
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,37 @@
1
+ module MetricFu
2
+ class ChurnGenerator < Generator
3
+ def self.metric
4
+ :churn
5
+ end
6
+
7
+ ###
8
+ # options available are what can be passed to churn_calculator
9
+ # https://github.com/danmayer/churn#library-options
10
+ ###
11
+ def emit
12
+ @output = run(options)
13
+ end
14
+
15
+ def analyze
16
+ if @output.nil? || @output.size.zero?
17
+ @churn = { churn: {} }
18
+ else
19
+ @churn = @output
20
+ end
21
+ @churn
22
+ end
23
+
24
+ # ensure hash only has the :churn key
25
+ def to_h
26
+ { churn: @churn[:churn] }
27
+ end
28
+
29
+ # @param args [Hash] churn metric run options
30
+ # @return [Hash] churn results
31
+ def run(args)
32
+ # @note passing in false to report will return a hash
33
+ # instead of the default String
34
+ ::Churn::ChurnCalculator.new(args).report(false)
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,43 @@
1
+ class MetricFu::ChurnHotspot < MetricFu::Hotspot
2
+ COLUMNS = %w{times_changed}
3
+
4
+ def columns
5
+ COLUMNS
6
+ end
7
+
8
+ def name
9
+ :churn
10
+ end
11
+
12
+ def map_strategy
13
+ :present
14
+ end
15
+
16
+ def reduce_strategy
17
+ :sum
18
+ end
19
+
20
+ def score_strategy
21
+ :calculate_score
22
+ end
23
+
24
+ def calculate_score(metric_ranking, item)
25
+ flat_churn_score = 0.50
26
+ metric_ranking.scored?(item) ? flat_churn_score : 0
27
+ end
28
+
29
+ def generate_records(data, table)
30
+ return if data == nil
31
+ Array(data[:changes]).each do |change|
32
+ table << {
33
+ "metric" => :churn,
34
+ "times_changed" => change[:times_changed],
35
+ "file_path" => change[:file_path]
36
+ }
37
+ end
38
+ end
39
+
40
+ def present_group(group)
41
+ "detected high level of churn (changed #{group[0].times_changed} times)"
42
+ end
43
+ end
@@ -0,0 +1,29 @@
1
+ module MetricFu
2
+ class MetricChurn < Metric
3
+ def name
4
+ :churn
5
+ end
6
+
7
+ def default_run_options
8
+ {
9
+ start_date: '"1 year ago"',
10
+ minimum_churn_count: 10,
11
+ ignore_files: [],
12
+ data_directory: MetricFu::Io::FileSystem.scratch_directory(name)
13
+ }
14
+ end
15
+
16
+ def has_graph?
17
+ false
18
+ end
19
+
20
+ def enable
21
+ super
22
+ end
23
+
24
+ def activate
25
+ activate_library("churn/calculator")
26
+ super
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,58 @@
1
+ <h3>Source Control Churn Results</h3>
2
+ <p>Files that change a lot in your project may be bad a sign.
3
+ This task uses your source control log to identify those files.
4
+ </p>
5
+ <table>
6
+ <tr>
7
+ <th>File Path</th>
8
+ <th>Times Changed</th>
9
+ </tr>
10
+ <% count = 0 %>
11
+ <% if @churn[:changes] %>
12
+ <% @churn[:changes].each do |change| %>
13
+ <tr>
14
+ <td><%= link_to_filename(change[:file_path]) %></td>
15
+ <td><%= change[:times_changed] %></td>
16
+ </tr>
17
+ <% count += 1 %>
18
+ <% end %>
19
+ <% end %>
20
+ </table>
21
+
22
+ <% if @churn[:class_churn] %>
23
+ <p>Classes that change a lot in your project may be bad a sign.</p>
24
+ <table>
25
+ <tr>
26
+ <th>File Path</th>
27
+ <th>Times Changed</th>
28
+ </tr>
29
+ <% count = 0 %>
30
+ <% @churn[:class_churn].each do |change| %>
31
+ <tr>
32
+ <td><%= link_to_filename(change['klass']['file']) %> <%= change['klass']['klass'] %></td>
33
+ <td><%= change['times_changed'] %></td>
34
+ </tr>
35
+ <% count += 1 %>
36
+ <% end %>
37
+ </table>
38
+ <% end %>
39
+
40
+ <% if @churn[:method_churn] %>
41
+ <p>Methods that change a lot in your project may be bad a sign.</p>
42
+ <table>
43
+ <tr>
44
+ <th>File Path</th>
45
+ <th>Times Changed</th>
46
+ </tr>
47
+ <% count = 0 %>
48
+ <% @churn[:method_churn].each do |change| %>
49
+ <tr>
50
+ <td><%= link_to_filename(change['method']['file']) %> <%= change['method']['method'] %></td>
51
+ <td><%= change['times_changed'] %></td>
52
+ </tr>
53
+ <% count += 1 %>
54
+ <% end %>
55
+ </table>
56
+ <% end %>
57
+
58
+ <%= render_partial 'report_footer' %>
@@ -0,0 +1,51 @@
1
+ module MetricFu
2
+ class FlayGenerator < Generator
3
+ def self.metric
4
+ :flay
5
+ end
6
+
7
+ def emit
8
+ args = "#{minimum_duplication_mass} #{dirs_to_flay}"
9
+ @output = run!(args)
10
+ end
11
+
12
+ def analyze
13
+ @matches = @output.chomp.split("\n\n").map { |m| m.split("\n ") }
14
+ end
15
+
16
+ def to_h
17
+ { flay: calculate_result(@matches) }
18
+ end
19
+
20
+ # TODO: move into analyze method
21
+ def calculate_result(matches)
22
+ total_score = matches.shift.first.split("=").last.strip
23
+ target = []
24
+ matches.each do |problem|
25
+ reason = problem.shift.strip
26
+ lines_info = problem.map do |full_line|
27
+ name, line = full_line.split(":").map(&:strip)
28
+ { name: name, line: line }
29
+ end
30
+ target << [reason: reason, matches: lines_info]
31
+ end
32
+ {
33
+ total_score: total_score,
34
+ matches: target.flatten
35
+ }
36
+ end
37
+
38
+ private
39
+
40
+ def minimum_duplication_mass
41
+ flay_mass = options[:minimum_score]
42
+ return "" unless flay_mass
43
+
44
+ "--mass #{flay_mass} "
45
+ end
46
+
47
+ def dirs_to_flay
48
+ options[:dirs_to_flay].join(" ")
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,37 @@
1
+ MetricFu.reporting_require { "graphs/grapher" }
2
+ module MetricFu
3
+ class FlayGrapher < Grapher
4
+ attr_accessor :flay_score, :labels
5
+
6
+ def self.metric
7
+ :flay
8
+ end
9
+
10
+ def initialize
11
+ super
12
+ @flay_score = []
13
+ @labels = {}
14
+ end
15
+
16
+ def get_metrics(metrics, date)
17
+ if metrics && metrics[:flay]
18
+ @flay_score.push(metrics[:flay][:total_score].to_i)
19
+ @labels.update(@labels.size => date)
20
+ end
21
+ end
22
+
23
+ def title
24
+ "Flay: duplication"
25
+ end
26
+
27
+ def data
28
+ [
29
+ ["flay", @flay_score.join(",")]
30
+ ]
31
+ end
32
+
33
+ def output_filename
34
+ "flay.js"
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,52 @@
1
+ class MetricFu::FlayHotspot < MetricFu::Hotspot
2
+ COLUMNS = %w{flay_reason flay_matching_reason}
3
+
4
+ def columns
5
+ COLUMNS
6
+ end
7
+
8
+ def name
9
+ :flay
10
+ end
11
+
12
+ def map_strategy
13
+ :present
14
+ end
15
+
16
+ def reduce_strategy
17
+ :sum
18
+ end
19
+
20
+ def score_strategy
21
+ :percentile
22
+ end
23
+
24
+ def generate_records(data, table)
25
+ return if data == nil
26
+ Array(data[:matches]).each do |match|
27
+ problems = match[:reason]
28
+ matching_reason = problems.gsub(/^[0-9]+\) /, "").gsub(/\:[0-9]+/, "")
29
+ files = []
30
+ locations = []
31
+ match[:matches].each do |file_match|
32
+ file_path = file_match[:name].sub(%r{^/}, "")
33
+ locations << "#{file_path}:#{file_match[:line]}"
34
+ files << file_path
35
+ end
36
+ files = files.uniq
37
+ files.each do |file|
38
+ table << {
39
+ "metric" => name,
40
+ "file_path" => file,
41
+ "flay_reason" => problems + " files: #{locations.join(', ')}",
42
+ "flay_matching_reason" => matching_reason
43
+ }
44
+ end
45
+ end
46
+ end
47
+
48
+ def present_group(group)
49
+ occurences = group.size
50
+ "found #{occurences} code duplications"
51
+ end
52
+ end