deforest 0.0.1 → 1.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 (72) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/deforest/application.js +1 -1
  3. data/app/assets/javascripts/deforest/bootstrap.js +4356 -0
  4. data/app/assets/javascripts/deforest/bootstrap.js.map +1 -0
  5. data/app/assets/stylesheets/deforest/{application.css → application.scss} +0 -0
  6. data/app/assets/stylesheets/deforest/bootstrap-grid.css +3872 -0
  7. data/app/assets/stylesheets/deforest/bootstrap.css +10332 -0
  8. data/app/assets/stylesheets/deforest/bootstrap.css.map +1 -0
  9. data/app/controllers/deforest/files_controller.rb +27 -4
  10. data/app/models/deforest/log.rb +9 -6
  11. data/app/views/deforest/files/_percentile_table.html.erb +35 -0
  12. data/app/views/deforest/files/dashboard.html.erb +26 -25
  13. data/config/routes.rb +1 -0
  14. data/lib/deforest/version.rb +1 -1
  15. data/lib/deforest.rb +73 -54
  16. data/lib/tasks/deforest_initializer.rb +2 -0
  17. data/test/deforest_test.rb +11 -6
  18. data/test/dummy/app/models/comment.rb +12 -0
  19. data/test/dummy/app/models/post.rb +19 -0
  20. data/test/dummy/app/models/special/custom/post.rb +2 -0
  21. data/test/dummy/app/models/special/post.rb +2 -0
  22. data/test/dummy/app/models/user.rb +3 -0
  23. data/test/dummy/config/initializers/deforest.rb +7 -0
  24. data/test/dummy/db/development.sqlite3 +0 -0
  25. data/test/dummy/db/migrate/20230211204438_create_users.rb +1 -1
  26. data/test/dummy/db/migrate/20230216154544_create_posts.rb +11 -0
  27. data/test/dummy/db/migrate/20230218121433_create_special_posts.rb +10 -0
  28. data/test/dummy/db/migrate/20230218161957_create_special_custom_posts.rb +10 -0
  29. data/test/dummy/db/migrate/20230219174900_create_comments.rb +11 -0
  30. data/test/dummy/db/schema.rb +28 -4
  31. data/test/dummy/db/test.sqlite3 +0 -0
  32. data/test/dummy/deforest.log +0 -0
  33. data/test/dummy/log/development.log +188 -0
  34. data/test/dummy/log/test.log +12072 -0
  35. data/test/dummy/test/fixtures/comments.yml +11 -0
  36. data/test/dummy/test/fixtures/special/custom/posts.yml +9 -0
  37. data/test/dummy/test/fixtures/special/posts.yml +9 -0
  38. data/test/dummy/test/models/comment_test.rb +7 -0
  39. data/test/dummy/test/models/special/custom/post_test.rb +7 -0
  40. data/test/dummy/test/models/special/post_test.rb +7 -0
  41. data/test/dummy/test/test_helper.rb +20 -0
  42. data/test/dummy/tmp/cache/assets/sprockets/v3.0/-T/-T8OIATNI3evoKq5bZdOBNbU0tZeQYxDHGmMOQnF2MM.cache +1 -0
  43. data/test/dummy/tmp/cache/assets/sprockets/v3.0/5L/5Lly_CA8DZvPhQV2jDQx-Y6P_y3Ygra9t5jfSlGhHDA.cache +2 -0
  44. data/test/dummy/tmp/cache/assets/sprockets/v3.0/5U/5U1ZhgjUSyIuw2yEYRCbe2n0xGeyHmYwnDlSdtQ2Dnw.cache +1 -0
  45. data/test/dummy/tmp/cache/assets/sprockets/v3.0/AX/AXrDvl0RN_5S8jW0MwnE13ukiiihtUTsaSvoKDVlam4.cache +0 -0
  46. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Cz/Cz2gWla4RNTXNuZf93le7clQqax63V1EHdQWaHR0s-8.cache +1 -0
  47. data/test/dummy/tmp/cache/assets/sprockets/v3.0/DS/DSvREN-eIb--STC5GdXcwmlJjFTw6ZmUVNmW_Sdh1-s.cache +0 -0
  48. data/test/dummy/tmp/cache/assets/sprockets/v3.0/GH/GH5mD035fZ1hsoErrkyMEorz6bwqi30T9a8f3zBIqtE.cache +1 -0
  49. data/test/dummy/tmp/cache/assets/sprockets/v3.0/NL/NLspqKUPe4g6Q4WEvWHMjSTqkF8YS4m2vcBhHBuhVqc.cache +2 -0
  50. data/test/dummy/tmp/cache/assets/sprockets/v3.0/OI/OI6uxGcnsKavdWTtwDAasU3wPx8QXhzBgV0X2n1KjMQ.cache +2 -0
  51. data/test/dummy/tmp/cache/assets/sprockets/v3.0/S3/S36SlXZyuQfqj2KG4e2Dpj_ZdUQbe2VflfsqjgLNSag.cache +1 -0
  52. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Sh/ShNcRHXrLA44HDRhTj2J11rZhqAuc56Kdr5Ea6O31Mk.cache +0 -0
  53. data/test/dummy/tmp/cache/assets/sprockets/v3.0/TL/TLNT1dXfMKTBmLi7RI_AoPSFmUtB9LfMeG6OuTkR1HQ.cache +1 -0
  54. data/test/dummy/tmp/cache/assets/sprockets/v3.0/ba/ba0VOL0KrwkwcfcuKSnYe1tT0ccddXS8z2KVn_cjtnI.cache +1 -0
  55. data/test/dummy/tmp/cache/assets/sprockets/v3.0/eV/eVN4NMxJn9WpXFRvBaX65H7Ni3Ux4agZLg6r04-9Zf0.cache +0 -0
  56. data/test/dummy/tmp/cache/assets/sprockets/v3.0/gK/gKO1oowLJsUvxaYbr5rucOzM9MDl7D4Ppj8l7q3AX0g.cache +1 -0
  57. data/test/dummy/tmp/cache/assets/sprockets/v3.0/h-/h-Bt2tKoZ131FgeX_De5387nfrje85Zsquko2lu_uL4.cache +0 -0
  58. data/test/dummy/tmp/cache/assets/sprockets/v3.0/hR/hRDjpdlCa6CLHs-KV6u1wHhQ842r9m1R5eEpivfiFBE.cache +1 -0
  59. data/test/dummy/tmp/cache/assets/sprockets/v3.0/hZ/hZi1k6tpxxCGYxRe7zY74ItcOI8gZrREOpGuA8JSpGg.cache +2 -0
  60. data/test/dummy/tmp/cache/assets/sprockets/v3.0/jD/jDJ0_EfCHu9gwyqis3I2-EsrfB7dBs8YZzvyqaWoOjU.cache +1 -0
  61. data/test/dummy/tmp/cache/assets/sprockets/v3.0/ly/ly49UX-4__EP86mWF_vobKTgvtAGLxUXqGOAPOzY53g.cache +1 -0
  62. data/test/dummy/tmp/cache/assets/sprockets/v3.0/pE/pEhaat2KBd5SrT7szC_8R1_6hK17FTpvoRFkmCRSD3M.cache +2 -0
  63. data/test/dummy/tmp/cache/assets/sprockets/v3.0/qM/qMiFkN6R1w5uIr6HRgTrSHnbEVddbDAVdz0D1XF7T2I.cache +0 -0
  64. data/test/dummy/tmp/cache/assets/sprockets/v3.0/th/thNa8SIbNZvQMtDF3-dUnEJNEFYxRsND8XYtqA2t328.cache +0 -0
  65. data/test/dummy/tmp/cache/assets/sprockets/v3.0/ui/uiFXrn_ILoEjcXpHWygBCsbEcWFKSiMvofYK6-saGVY.cache +1 -0
  66. data/test/dummy/tmp/cache/assets/sprockets/v3.0/xw/xwxSZPjNVcvVU7DwpeJBJ1ZX6yyIFiCvf0GKrN6bZgc.cache +0 -0
  67. data/test/dummy/tmp/cache/assets/sprockets/v3.0/yp/ypFoyURV_Y0NHlBKznetHE6cVjR-mmRHcGSGQ_hERVg.cache +2 -0
  68. data/test/fixtures/posts.yml +11 -0
  69. data/test/models/deforest/log_test.rb +2 -1
  70. data/test/models/post_test.rb +35 -0
  71. metadata +119 -9
  72. data/test/dummy/deforest_db_sync.txt +0 -1
@@ -3,19 +3,20 @@ require_dependency "deforest/application_controller"
3
3
  module Deforest
4
4
  class FilesController < ApplicationController
5
5
  before_action :check_if_admin_logged_in
6
+ before_action :should_render_source, only: [:index, :show]
6
7
 
7
8
  def dashboard
8
9
  @top_percentile_methods = {}
9
10
  @medium_percentile_methods = {}
10
11
  @low_percentile_methods = {}
11
12
 
12
- Deforest::Log.percentile().each do |log, pcnt|
13
+ Deforest::Log.percentile(params[:dir] || "/app/models").each do |log, pcnt|
13
14
  if pcnt >= Deforest.most_used_percentile_threshold
14
- @top_percentile_methods["#{log.model_name}##{log.method_name}"] = { color: "highlight-red", total_call_count: log.count_sum, file_name: log.file_name, line_no: log.line_no }
15
+ @top_percentile_methods[log.method_name] = { color: "highlight-red", total_call_count: log.count_sum, file_name: log.file_name, line_no: log.line_no }
15
16
  elsif pcnt <= Deforest.least_used_percentile_threshold
16
- @low_percentile_methods["#{log.model_name}##{log.method_name}"] = { color: "highlight-green", total_call_count: log.count_sum, file_name: log.file_name, line_no: log.line_no }
17
+ @low_percentile_methods[log.method_name] = { color: "highlight-green", total_call_count: log.count_sum, file_name: log.file_name, line_no: log.line_no }
17
18
  else
18
- @medium_percentile_methods["#{log.model_name}##{log.method_name}"] = { color: "highlight-yellow", total_call_count: log.count_sum, file_name: log.file_name, line_no: log.line_no }
19
+ @medium_percentile_methods[log.method_name] = { color: "highlight-yellow", total_call_count: log.count_sum, file_name: log.file_name, line_no: log.line_no }
19
20
  end
20
21
  end
21
22
  end
@@ -39,6 +40,22 @@ module Deforest
39
40
  # @full_path = "#{params[:path]}/#{params[:file_name]}.rb"
40
41
  end
41
42
 
43
+ def extension_data
44
+ result = Hash.new { |h,k| h[k] = [] }
45
+ Deforest.track_dirs.each do |dir|
46
+ Log.percentile(dir).each do |log, pcnt|
47
+ if pcnt >= Deforest.most_used_percentile_threshold
48
+ result[log.file_name] << { line_no: log.line_no, use_type: "most_used", call_count: log.count_sum }
49
+ elsif pcnt <= Deforest.least_used_percentile_threshold
50
+ result[log.file_name] << { line_no: log.line_no, use_type: "least_used", call_count: log.count_sum }
51
+ else
52
+ result[log.file_name] << { line_no: log.line_no, use_type: "medium_used", call_count: log.count_sum }
53
+ end
54
+ end
55
+ end
56
+ send_data result.to_json, filename: "deforest.json", type: "application/json", disposition: "attachment"
57
+ end
58
+
42
59
  private
43
60
 
44
61
  def check_if_admin_logged_in
@@ -46,5 +63,11 @@ module Deforest
46
63
  raise ActionController::RoutingError.new('Not Found')
47
64
  end
48
65
  end
66
+
67
+ def should_render_source
68
+ if !Deforest.render_source_on_browser
69
+ redirect_to files_dashboard_path and return
70
+ end
71
+ end
49
72
  end
50
73
  end
@@ -1,14 +1,16 @@
1
1
  module Deforest
2
2
  class Log < ActiveRecord::Base
3
3
  def model_name
4
- idx = self.file_name.index(/\/app\/models\/(\w)*.rb/)
5
- if idx.present?
6
- self.file_name[idx, file_name.size].gsub("/app/models/", "").chomp(".rb").camelize
4
+ Deforest.track_dirs.map { |d| Regexp.escape(d) }.each do |d|
5
+ idx = self.file_name.index(/\#{d}\/(\w)*.rb/)
6
+ if idx.present?
7
+ return self.file_name[idx, file_name.size].gsub("#{d}/", "").chomp(".rb").camelize
8
+ end
7
9
  end
8
10
  end
9
11
 
10
- def self.percentile()
11
- grouped_logs = Deforest::Log.where("file_name like '%/app/models/%'").group(:file_name, :line_no, :method_name).select("file_name, line_no, method_name, SUM(count) AS count_sum")
12
+ def self.percentile(dir)
13
+ grouped_logs = Deforest::Log.where("file_name like '%#{dir}/%'").group(:file_name, :line_no, :method_name).select("file_name, line_no, method_name, SUM(count) AS count_sum")
12
14
  groups_of_count_sum = grouped_logs.group_by { |r| r.count_sum }
13
15
  n = groups_of_count_sum.size
14
16
  result = Hash.new { |h,k| h[k] = nil }
@@ -22,7 +24,8 @@ module Deforest
22
24
 
23
25
  def self.get_highlight_colors_for_file(file_name)
24
26
  result = {}
25
- self.percentile.select { |log, _| log.file_name == file_name }.each do |log, pcnt|
27
+ dir = Deforest.track_dirs.find { |d| file_name.include?(d) }
28
+ self.percentile(dir).select { |log, _| log.file_name == file_name }.each do |log, pcnt|
26
29
  result[log.line_no] = if pcnt <= Deforest.least_used_percentile_threshold
27
30
  "highlight-green"
28
31
  elsif pcnt >= Deforest.most_used_percentile_threshold
@@ -0,0 +1,35 @@
1
+ <h4><%= heading %></h4>
2
+ <table class="table table-striped">
3
+ <thead>
4
+ <tr>
5
+ <th>File Name</th>
6
+ <th>Method Name</th>
7
+ <th>Line Number</th>
8
+ <th>Count</th>
9
+ </tr>
10
+ </thead>
11
+ <tbody>
12
+ <% method_stats.each do |method_name, color_and_count| %>
13
+ <tr>
14
+ <td>
15
+ <%= color_and_count[:file_name] %>
16
+ </td>
17
+ <td>
18
+ <% if Deforest.render_source_on_browser %>
19
+ <a href=<%= file_path(path: color_and_count[:file_name], line_no: color_and_count[:line_no]) %>>
20
+ <%= method_name %>
21
+ </a>
22
+ <% else %>
23
+ <%= method_name %>
24
+ <% end %>
25
+ </td>
26
+ <td>
27
+ <%= color_and_count[:line_no] %>
28
+ </td>
29
+ <td>
30
+ <%= color_and_count[:total_call_count] %>
31
+ </td>
32
+ </tr>
33
+ <% end %>
34
+ </tbody>
35
+ </table>
@@ -1,28 +1,29 @@
1
- <h2>Top <%= 100 - Deforest.most_used_percentile_threshold %> percentile</h2>
2
- <% @top_percentile_methods.each do |method_name, color_and_count| %>
3
- <a href=<%= file_path(path: "#{color_and_count[:file_name]}", line_no: color_and_count[:line_no]) %> class="<%= color_and_count[:color] %>"><%= method_name %> = <%= color_and_count[:total_call_count] %></a><br/><br/>
4
- <% end %>
1
+ <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
2
+ <a class="navbar-brand" href="#">Deforest</a>
3
+ <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
4
+ <span class="navbar-toggler-icon"></span>
5
+ </button>
5
6
 
6
- <h2>Bottom <%= Deforest.least_used_percentile_threshold %> percentile</h2>
7
- <% @low_percentile_methods.each do |method_name, color_and_count| %>
8
- <a href=<%= file_path(path: "#{color_and_count[:file_name]}", line_no: color_and_count[:line_no]) %> class="<%= color_and_count[:color] %>"><%= method_name %> = <%= color_and_count[:total_call_count] %></a><br/><br/>
9
- <% end %>
7
+ <div class="collapse navbar-collapse" id="navbarSupportedContent">
8
+ <ul class="navbar-nav mr-auto">
9
+ <li class="nav-item active">
10
+ <%= link_to "Extension Data", files_extension_data_path, class: "nav-link active", aria: { current: "page" } %>
11
+ </li>
12
+ <li class="nav-item dropdown">
13
+ <a class="nav-link dropdown-toggle" href="#" role="button" data-toggle="dropdown" aria-expanded="false">
14
+ Directory
15
+ </a>
16
+ <div class="dropdown-menu">
17
+ <% Deforest.track_dirs.each do |dir| %>
18
+ <a class="dropdown-item" href="<%= files_dashboard_path(dir: dir) %>"><%= dir %></a>
19
+ <% end %>
20
+ </div>
21
+ </li>
22
+ </ul>
23
+ </div>
24
+ </nav>
10
25
 
11
- <h2>Between <%= Deforest.least_used_percentile_threshold %> and <%= Deforest.most_used_percentile_threshold %> percentile</h2>
12
- <% @medium_percentile_methods.each do |method_name, color_and_count| %>
13
- <a href=<%= file_path(path: "#{color_and_count[:file_name]}", line_no: color_and_count[:line_no]) %> class="<%= color_and_count[:color] %>"><%= method_name %> = <%= color_and_count[:total_call_count] %></a><br/><br/>
14
- <% end %>
15
26
 
16
- <style>
17
- .highlight-red {
18
- background: rgba(245, 66, 72, 0.8);
19
- }
20
- .highlight-yellow {
21
- background: rgba(240, 240, 5, 0.8);
22
- color: #000;
23
- }
24
- .highlight-green {
25
- background: rgba(0, 227, 38, 0.8);
26
- color: #000;
27
- }
28
- </style>
27
+ <%= render partial: "percentile_table", locals: { heading: "Top #{100 - Deforest.most_used_percentile_threshold} percentile", method_stats: @top_percentile_methods } %>
28
+ <%= render partial: "percentile_table", locals: { heading: "Bottom #{100 - Deforest.most_used_percentile_threshold} percentile", method_stats: @low_percentile_methods } %>
29
+ <%= render partial: "percentile_table", locals: { heading: "Between #{Deforest.least_used_percentile_threshold} and #{Deforest.most_used_percentile_threshold} percentile", method_stats: @medium_percentile_methods } %>
data/config/routes.rb CHANGED
@@ -2,4 +2,5 @@ Deforest::Engine.routes.draw do
2
2
  get "/files", controller: "files", action: "index"
3
3
  get "/file", controller: "files", action: "show"
4
4
  get "/files/dashboard", controller: "files", action: "dashboard"
5
+ get "/files/extension_data", controller: "files", action: "extension_data"
5
6
  end
@@ -1,3 +1,3 @@
1
1
  module Deforest
2
- VERSION = "0.0.1"
2
+ VERSION = "1.0.0"
3
3
  end
data/lib/deforest.rb CHANGED
@@ -4,18 +4,14 @@ require "active_support"
4
4
  require "active_record"
5
5
 
6
6
  module Deforest
7
- mattr_accessor :write_logs_to_db_every, :current_admin_method_name, :most_used_percentile_threshold, :least_used_percentile_threshold
7
+ mattr_accessor :write_logs_to_db_every, :current_admin_method_name, :most_used_percentile_threshold, :least_used_percentile_threshold, :track_dirs, :render_source_on_browser
8
8
  @@last_saved_log_file_at = nil
9
9
  @@saving_log_file = false
10
10
 
11
- def self.initialize!
12
- if block_given?
13
- yield self
14
- end
15
- self.initialize_db_sync_file()
16
- Dir["#{Rails.root}/app/models/**/*.rb"].map do |f|
17
- idx = f.index("app/models")
18
- models_heirarchy = f[idx..-1].gsub("app/models/","")
11
+ def self.get_app_classes(dir)
12
+ Dir["#{Rails.root}#{dir}/**/*.rb"].each do |f|
13
+ idx = f.index(dir)
14
+ models_heirarchy = f[idx..-1].gsub(dir,"")
19
15
  exec_str = ""
20
16
  loop do
21
17
  parent, *children = models_heirarchy.split("/")
@@ -29,59 +25,79 @@ module Deforest
29
25
  end
30
26
  begin
31
27
  model = exec_str.constantize
28
+ yield model
32
29
  rescue
33
30
  puts "Deforest warning: could not track #{exec_str}"
34
31
  end
35
- if model.present?
36
- model.instance_methods(false).each do |mname|
37
- model.instance_eval do
38
- alias_method "old_#{mname}", mname
39
- define_method mname do |*args, &block|
40
- old_method = self.class.instance_method("old_#{mname}")
41
- file_name, line_no = old_method.source_location
42
- if file_name.include?("/app/models")
43
- Deforest.insert_into_logs(mname, file_name, line_no)
44
- end
45
- Deforest.insert_into_logs(mname, file_name, line_no)
46
- if @@last_saved_log_file_at < Deforest.write_logs_to_db_every.ago && !@@saving_log_file
47
- Deforest.parse_and_save_log_file()
48
- t = Time.zone.now
49
- @@last_saved_log_file_at = t
50
- File.open("deforest_db_sync.txt", "w") { |fl| fl.write(t.to_i) }
51
- end
52
- old_method.bind(self).call(*args, &block)
53
- end
32
+ end
33
+ end
34
+
35
+ def self.override_instance_methods_for(klass, dir)
36
+ klass.instance_methods(false).each do |mname|
37
+ klass.instance_eval do
38
+ alias_method "old_#{mname}", mname
39
+ define_method mname do |*args, &block|
40
+ old_method = self.class.instance_method("old_#{mname}")
41
+ file_name, line_no = old_method.source_location
42
+ if file_name.include?(dir)
43
+ Deforest.insert_into_logs(mname, file_name, line_no)
54
44
  end
55
- end
56
- model.singleton_methods(false).each do |mname|
57
- model.singleton_class.send(:alias_method, "old_#{mname}", mname)
58
- model.define_singleton_method mname do |*args, &block|
59
- old_method = self.singleton_method("old_#{mname}")
60
- file_name, line_no = old_method.source_location
61
- if file_name.include?("/app/models")
62
- Deforest.insert_into_logs(mname, file_name, line_no)
63
- end
64
- if @@last_saved_log_file_at < Deforest.write_logs_to_db_every.ago && !@@saving_log_file
65
- Deforest.parse_and_save_log_file()
66
- t = Time.zone.now
67
- @@last_saved_log_file_at = t
68
- File.open("deforest_db_sync.txt", "w") { |fl| fl.write(t.to_i) }
69
- end
70
- old_method.unbind.bind(self).call(*args, &block)
45
+ if @@last_saved_log_file_at < Deforest.write_logs_to_db_every.ago && !@@saving_log_file
46
+ Deforest.parse_and_save_log_file()
47
+ t = Time.zone.now
48
+ @@last_saved_log_file_at = t
49
+ File.open("deforest_db_sync.txt", "w") { |fl| fl.write(t.to_i) }
71
50
  end
51
+ old_method.bind(self).call(*args, &block)
52
+ end
53
+ end
54
+ end
55
+ end
56
+
57
+ def self.override_class_methods_for(klass, dir)
58
+ klass.singleton_methods(false).each do |mname|
59
+ klass.singleton_class.send(:alias_method, "old_#{mname}", mname)
60
+ klass.define_singleton_method mname do |*args, &block|
61
+ old_method = self.singleton_method("old_#{mname}")
62
+ file_name, line_no = old_method.source_location
63
+ if file_name.include?(dir)
64
+ Deforest.insert_into_logs(mname, file_name, line_no)
65
+ end
66
+ if @@last_saved_log_file_at < Deforest.write_logs_to_db_every.ago && !@@saving_log_file
67
+ Deforest.parse_and_save_log_file()
68
+ t = Time.zone.now
69
+ @@last_saved_log_file_at = t
70
+ File.open("deforest_db_sync.txt", "w") { |fl| fl.write(t.to_i) }
71
+ end
72
+ old_method.unbind.bind(self).call(*args, &block)
73
+ end
74
+ end
75
+ end
76
+
77
+ def self.initialize!
78
+ if block_given?
79
+ yield self
80
+ end
81
+ self.initialize_db_sync_file()
82
+ Deforest.track_dirs.each do |dir|
83
+ self.get_app_classes(dir) do |model|
84
+ if model.present?
85
+ self.override_instance_methods_for(model, dir)
86
+ self.override_class_methods_for(model, dir) unless dir.include?("/app/controllers")
72
87
  end
73
88
  end
74
89
  end
75
90
  end
76
91
 
77
92
  def self.initialize_db_sync_file
78
- if File.exists?("deforest_db_sync.txt")
93
+ File.open("deforest.log", "w") unless File.exist?("deforest.log")
94
+ if File.exist?("deforest_db_sync.txt")
79
95
  @@last_saved_log_file_at = Time.at(File.open("deforest_db_sync.txt").read.to_i)
80
96
  else
81
97
  File.open("deforest_db_sync.txt", "w") do |f|
82
- current_time = Time.zone.now.to_i
98
+ current_time = Time.zone.now
83
99
  @@last_saved_log_file_at = current_time
84
- f.write(current_time)
100
+ f.write(current_time.to_i)
85
101
  end
86
102
  end
87
103
  end
@@ -107,16 +123,19 @@ module Deforest
107
123
  end
108
124
  end
109
125
  hash.each do |loc, count|
110
- sql_stmt += "(#{loc.split("|").map { |s| "'#{s}'" }.join(",")}, #{count}, current_timestamp, current_timestamp),"
126
+ t = Time.zone.now
127
+ sql_stmt += "(#{loc.split("|").map { |s| "'#{s}'" }.join(",")}, #{count}, '#{t}', '#{t}'),"
111
128
  end
112
129
  sql_stmt.chomp!(",")
113
130
  sql_stmt += ";"
114
- ActiveRecord::Base.connection.execute(sql_stmt)
115
- if File.exists?("deforest_tmp.log")
116
- File.delete("deforest.log")
117
- File.rename("deforest_tmp.log", "deforest.log")
118
- else
119
- File.delete("deforest.log")
131
+ if hash.present?
132
+ ActiveRecord::Base.connection.execute(sql_stmt)
133
+ if File.exist?("deforest_tmp.log")
134
+ File.delete("deforest.log")
135
+ File.rename("deforest_tmp.log", "deforest.log")
136
+ else
137
+ File.delete("deforest.log")
138
+ end
120
139
  end
121
140
  @@saving_log_file = false
122
141
  end
@@ -3,4 +3,6 @@ Deforest.initialize! do |config|
3
3
  config.current_admin_method_name = :current_admin
4
4
  config.most_used_percentile_threshold = 80
5
5
  config.least_used_percentile_threshold = 20
6
+ config.track_dirs = ["/app/models", "/app/controllers", "/app/helpers"]
7
+ config.render_source_on_browser = true
6
8
  end
@@ -2,15 +2,20 @@ require 'test_helper'
2
2
 
3
3
  class DeforestTest < ActiveSupport::TestCase
4
4
  setup do
5
- Deforest.class_variable_set("@@last_saved_log_file_at", nil)
5
+ File.open("deforest_db_sync.txt", "w") { |f| f.write(1.hour.ago.to_i.to_s) }
6
+ Deforest.initialize_db_sync_file
7
+ Deforest.class_variable_set('@@write_logs_to_db_every', 1.minute)
8
+ end
9
+
10
+ teardown do
11
+ File.delete("deforest_db_sync.txt") if File.exist?("deforest_db_sync.txt")
12
+ File.delete("deforest.log") if File.exist?("deforest.log")
6
13
  end
7
14
 
8
15
  test "initialize db_sync_file when db_sync_file does not exist" do
9
- if File.exist?("deforest_db_sync.txt")
10
- File.delete("deforest_db_sync.txt")
11
- Deforest.initialize_db_sync_file
12
- assert Deforest.class_variable_get("@@last_saved_log_file_at") > 1.minute.ago.to_i
13
- end
16
+ File.delete("deforest_db_sync.txt")
17
+ Deforest.initialize_db_sync_file
18
+ assert Deforest.class_variable_get("@@last_saved_log_file_at") > 1.minute.ago
14
19
  end
15
20
 
16
21
  test "initialize db_sync_file when db_sync_file does exist" do
@@ -0,0 +1,12 @@
1
+ class Comment < ActiveRecord::Base
2
+ belongs_to :post
3
+
4
+ def stupid_comment?
5
+ stupid_words = ["very good", "nice"]
6
+ self.body.length < 20 && stupid_words.find { |w| self.body.include?(w) }
7
+ end
8
+
9
+ def contains_embedded_links?
10
+ (self.body =~ /<a.*>.+<\/a>/i) != nil
11
+ end
12
+ end
@@ -0,0 +1,19 @@
1
+ class Post < ActiveRecord::Base
2
+ has_many :comments
3
+
4
+ def self.get_titles
5
+ Post.all.map(&:title)
6
+ end
7
+
8
+ def get_title_with_italics
9
+ "<i>#{self.title}</i>"
10
+ end
11
+
12
+ def self.get_posts_created_after(date)
13
+ self.where("DATE(created_at) > DATE(?)", date)
14
+ end
15
+
16
+ def self.posts_created_yesterday
17
+ self.where("DATE(created_at) = DATE(?)", Date.yesterday)
18
+ end
19
+ end
@@ -0,0 +1,2 @@
1
+ class Special::Custom::Post < ActiveRecord::Base
2
+ end
@@ -0,0 +1,2 @@
1
+ class Special::Post < ActiveRecord::Base
2
+ end
@@ -0,0 +1,3 @@
1
+ class User < ActiveRecord::Base
2
+
3
+ end
@@ -0,0 +1,7 @@
1
+ Deforest.initialize! do |config|
2
+ config.write_logs_to_db_every = 1.minute
3
+ config.current_admin_method_name = :current_admin
4
+ config.most_used_percentile_threshold = 80
5
+ config.least_used_percentile_threshold = 20
6
+ config.track_dirs = ["/app/models"]
7
+ end
Binary file
@@ -1,6 +1,6 @@
1
1
  class CreateUsers < ActiveRecord::Migration
2
2
  def change
3
- create_table :deforest_users do |t|
3
+ create_table :users do |t|
4
4
  t.string :first_name
5
5
  t.string :last_name
6
6
  t.string :email
@@ -0,0 +1,11 @@
1
+ class CreatePosts < ActiveRecord::Migration
2
+ def change
3
+ create_table :posts do |t|
4
+ t.string :title
5
+ t.text :body
6
+ t.integer :author_id
7
+
8
+ t.timestamps null: false
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,10 @@
1
+ class CreateSpecialPosts < ActiveRecord::Migration
2
+ def change
3
+ create_table :special_posts do |t|
4
+ t.string :title
5
+ t.text :body
6
+
7
+ t.timestamps null: false
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ class CreateSpecialCustomPosts < ActiveRecord::Migration
2
+ def change
3
+ create_table :special_custom_posts do |t|
4
+ t.string :title
5
+ t.text :body
6
+
7
+ t.timestamps null: false
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,11 @@
1
+ class CreateComments < ActiveRecord::Migration
2
+ def change
3
+ create_table :comments do |t|
4
+ t.text :body
5
+ t.integer :author_id
6
+ t.integer :post_id
7
+
8
+ t.timestamps null: false
9
+ end
10
+ end
11
+ end
@@ -11,10 +11,12 @@
11
11
  #
12
12
  # It's strongly recommended that you check this file into your version control system.
13
13
 
14
- ActiveRecord::Schema.define(version: 20230211204438) do
14
+ ActiveRecord::Schema.define(version: 20230219174900) do
15
15
 
16
- create_table "ar_internal_metadata", primary_key: "key", force: :cascade do |t|
17
- t.string "value"
16
+ create_table "comments", force: :cascade do |t|
17
+ t.text "body"
18
+ t.integer "author_id"
19
+ t.integer "post_id"
18
20
  t.datetime "created_at", null: false
19
21
  t.datetime "updated_at", null: false
20
22
  end
@@ -28,7 +30,29 @@ ActiveRecord::Schema.define(version: 20230211204438) do
28
30
  t.datetime "updated_at", null: false
29
31
  end
30
32
 
31
- create_table "deforest_users", force: :cascade do |t|
33
+ create_table "posts", force: :cascade do |t|
34
+ t.string "title"
35
+ t.text "body"
36
+ t.integer "author_id"
37
+ t.datetime "created_at", null: false
38
+ t.datetime "updated_at", null: false
39
+ end
40
+
41
+ create_table "special_custom_posts", force: :cascade do |t|
42
+ t.string "title"
43
+ t.text "body"
44
+ t.datetime "created_at", null: false
45
+ t.datetime "updated_at", null: false
46
+ end
47
+
48
+ create_table "special_posts", force: :cascade do |t|
49
+ t.string "title"
50
+ t.text "body"
51
+ t.datetime "created_at", null: false
52
+ t.datetime "updated_at", null: false
53
+ end
54
+
55
+ create_table "users", force: :cascade do |t|
32
56
  t.string "first_name"
33
57
  t.string "last_name"
34
58
  t.string "email"
Binary file
File without changes