localtower 0.2.2 → 0.4.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 (52) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +12 -9
  3. data/app/controllers/localtower/pages_controller.rb +17 -0
  4. data/app/views/localtower/pages/logs.html.erb +42 -28
  5. data/config/routes.rb +2 -0
  6. data/lib/localtower/plugins/capture.rb +72 -47
  7. data/lib/localtower/tools.rb +1 -1
  8. data/lib/localtower/version.rb +1 -1
  9. data/public/screenshots/v0.1.6/5_capture.png +0 -0
  10. data/spec/dummy/Gemfile +1 -21
  11. data/spec/dummy/Gemfile.lock +103 -144
  12. data/spec/dummy/app/controllers/pages_controller.rb +8 -0
  13. data/spec/dummy/app/views/pages/home.html.erb +1 -0
  14. data/spec/dummy/config/application.rb +0 -9
  15. data/spec/dummy/config/environments/development.rb +0 -7
  16. data/spec/dummy/config/initializers/new_framework_defaults.rb +0 -3
  17. data/spec/dummy/config/routes.rb +2 -0
  18. data/spec/dummy/log/development.log +2 -132
  19. data/spec/dummy/log/localtower.log +1220 -2014
  20. data/spec/dummy/log/test.log +1246 -2195
  21. data/spec/factories/migration.rb +161 -139
  22. data/spec/factories/model.rb +34 -30
  23. data/spec/lib/localtower/generators/model_spec.rb +6 -7
  24. data/spec/lib/localtower/generators/relation_spec.rb +6 -3
  25. data/spec/spec_helper.rb +3 -12
  26. metadata +68 -130
  27. data/spec/dummy/coverage/assets/0.10.0/application.css +0 -799
  28. data/spec/dummy/coverage/assets/0.10.0/application.js +0 -1707
  29. data/spec/dummy/coverage/assets/0.10.0/colorbox/border.png +0 -0
  30. data/spec/dummy/coverage/assets/0.10.0/colorbox/controls.png +0 -0
  31. data/spec/dummy/coverage/assets/0.10.0/colorbox/loading.gif +0 -0
  32. data/spec/dummy/coverage/assets/0.10.0/colorbox/loading_background.png +0 -0
  33. data/spec/dummy/coverage/assets/0.10.0/favicon_green.png +0 -0
  34. data/spec/dummy/coverage/assets/0.10.0/favicon_red.png +0 -0
  35. data/spec/dummy/coverage/assets/0.10.0/favicon_yellow.png +0 -0
  36. data/spec/dummy/coverage/assets/0.10.0/loading.gif +0 -0
  37. data/spec/dummy/coverage/assets/0.10.0/magnify.png +0 -0
  38. data/spec/dummy/coverage/assets/0.10.0/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  39. data/spec/dummy/coverage/assets/0.10.0/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  40. data/spec/dummy/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  41. data/spec/dummy/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  42. data/spec/dummy/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  43. data/spec/dummy/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  44. data/spec/dummy/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  45. data/spec/dummy/coverage/assets/0.10.0/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  46. data/spec/dummy/coverage/assets/0.10.0/smoothness/images/ui-icons_222222_256x240.png +0 -0
  47. data/spec/dummy/coverage/assets/0.10.0/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  48. data/spec/dummy/coverage/assets/0.10.0/smoothness/images/ui-icons_454545_256x240.png +0 -0
  49. data/spec/dummy/coverage/assets/0.10.0/smoothness/images/ui-icons_888888_256x240.png +0 -0
  50. data/spec/dummy/coverage/assets/0.10.0/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  51. data/spec/dummy/coverage/index.html +0 -294
  52. data/spec/dummy/tmp/restart.txt +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 173cfbbb7586b74e2b52c7a2cf17afe58627f545
4
- data.tar.gz: 0b4089ec63d56ec6adecbd359001f82255747217
2
+ SHA256:
3
+ metadata.gz: 6f62130e44cf4f1047a87b4ab0bed7cd6821d00a7a0767320644d9e78120bba4
4
+ data.tar.gz: a6c3f44be4d00e2b159170254e8f4424d3ae95e5d4ac0645e8aaffbb882178a6
5
5
  SHA512:
6
- metadata.gz: 4206e0c4968ee79a9655fda1325e351d270dde98acc59902bd3c4c91b3e848719d5323b75f3b92ca3f536a35f3e2133c44cd8e9f5bfe38753fb6ae3dd54e3739
7
- data.tar.gz: 2deb5b2e2459e1c8e0edf56d8886f145af525a89194b23879a3f9cf62738947359f0af27619a22212fae987675a6b3e46a642da043b295e8af855018a710f551
6
+ metadata.gz: fd0523f501766384f7e9a2013e7d0b2256443de640aa627b1513d8c8bca3269627d28fbba6db5c08a8f840deb3b2854dc364772681408cdfcefe86b4e87d9256
7
+ data.tar.gz: e1a6e0c03d83e3f12acf2e1acf617e92c0a2f4e365479b8984ad016e3f196eb77fa916378cf02d17196689fe27ed16f14333e8832ac456baa2b9469930dd5b37
data/README.md CHANGED
@@ -14,11 +14,12 @@
14
14
  ### Create a migration
15
15
  ![Migrations](https://raw.githubusercontent.com/damln/localtower/master/public/screenshots/v0.1.6/4_migrations.png)
16
16
 
17
+ ### Using the Capture plugin
18
+ ![Capture](https://raw.githubusercontent.com/damln/localtower/master/public/screenshots/v0.1.6/5_capture.png)
17
19
 
18
20
  ## INSTALL
19
21
 
20
- Only tested with Rails 4.2 and Rails 5.1 (should work with any Rails 4.2+ application).
21
- Only tested with PostgreSQL.
22
+ Only tested with Rails 4.2 and Rails 5.1 (should work with any Rails 4.2+ application). Only tested with PostgreSQL.
22
23
 
23
24
  Add to your `Gemfile` file:
24
25
  ```ruby
@@ -42,7 +43,7 @@ bundle install
42
43
  Add to your `config/routes.rb`:
43
44
  ```ruby
44
45
  MyApp::Application.routes.draw do
45
- if Rails.env.development?
46
+ if Rails.env.development? and defined?(Localtower)
46
47
  mount Localtower::Engine, at: "localtower"
47
48
  end
48
49
 
@@ -63,12 +64,14 @@ You can put this line anywhere in your code:
63
64
 
64
65
  For example:
65
66
 
66
- def my_method
67
- user = User.find(1)
68
- some_data = {foo: "bar"}
67
+ ```ruby
68
+ def my_method
69
+ user = User.find(1)
70
+ some_data = {foo: "bar"}
69
71
 
70
- Localtower::Plugins::Capture.new(self, binding).save
71
- end
72
+ Localtower::Plugins::Capture.new(self, binding).save
73
+ end
74
+ ```
72
75
 
73
76
  Then go to the Localtower intercave here: [http://localhost:3000/localtower/logs](http://localhost:3000/localtower/logs) and you will see the variables `user` and `some_data` in the UI.
74
77
 
@@ -105,6 +108,6 @@ Thanks for reporting issues, I'll do my best.
105
108
 
106
109
  ## Deploy
107
110
 
108
- rm *.gem | gem build localtower.gemspec | gem push localtower*.gem
111
+ rm *.gem | gem build localtower.gemspec && gem push localtower-*.gem
109
112
 
110
113
 
@@ -10,6 +10,23 @@ module Localtower
10
10
  @logs = Localtower::Plugins::Capture.new.logs
11
11
  end
12
12
 
13
+ def log
14
+ file = Dir["#{Localtower::Plugins::Capture::LOG_PATH.call}/localtower*#{params[:md5]}*"][0]
15
+
16
+ render json: JSON.parse(open(file).read)
17
+ end
18
+
19
+ def log_var
20
+ answer = {}
21
+
22
+ file = Dir["#{Localtower::Plugins::Capture::LOG_PATH.call}/localtower*#{params[:md5]}*"][0]
23
+ data = JSON.parse(open(file).read)
24
+
25
+ answer = data["variables"].select {|i| i["event_name"] == params[:var] }[0]["returned"]
26
+
27
+ render json: answer
28
+ end
29
+
13
30
  def status
14
31
  @data = ::Localtower::Status.new.run
15
32
  end
@@ -14,53 +14,67 @@
14
14
  border: 1px solid #cacaca;
15
15
  line-height: 1.2em;
16
16
  overflow:auto;
17
+ max-height: 800px;
18
+ max-width: 800px;
17
19
  -moz-background-clip: padding;
18
20
  -webkit-background-clip: padding-box;
19
21
  background-clip: padding-box;
20
22
  background-color: #FAFAFB;
21
23
  color: #393939;
22
24
  margin: 0px;
23
- max-width: 800px;
24
25
  display: block;
25
26
  }
26
-
27
27
  </style>
28
-
29
-
30
-
31
28
  <% content_for :title do %>Logs<% end %>
32
-
33
29
  <div class="row">
34
30
  <div class="col-md-12">
35
31
  <div class="card">
36
32
  <div class="header">
37
- <h4 class="title"></h4>
33
+ <h4 class="title">
34
+ <pre>Localtower::Plugins::Capture.new(self, binding).save</pre>
35
+ </h4>
38
36
  </div>
39
-
40
37
  <div class="content">
41
38
  <table class="table">
42
39
  <thead>
43
- <th>Variable</th>
44
- <th>Value</th>
45
- <th>Value Type</th>
40
+ <th>TYPE</th>
41
+ <th>IN CLASS</th>
42
+ <th>IN METHOD</th>
43
+ <th>VARIABLE</th>
44
+ <th>VALUE</th>
46
45
  </thead>
47
-
48
- <tbody data-selector="tbody">
49
- <% @logs["variables"].each do |item| %>
50
-
51
- <tr data-selector="tr">
52
- <td class="code">
53
- <%= item["name"] %>
54
- </td>
55
-
56
- <td>
57
- <pre class="value json code"><%= Localtower::Plugins::Capture.printable(item["value"]) %></pre>
58
- </td>
59
-
60
- <td>
61
- <pre class="code"><%= item["klass"] %></pre>
62
- </td>
63
- </tr>
46
+ <tbody>
47
+ <% @logs.each do |log| %>
48
+ <% log["variables"].each do |item| %>
49
+ <tr>
50
+ <td>
51
+ <span class="label label-success">
52
+ <%= item["type"] %>
53
+ </span>
54
+ </td>
55
+ <td>
56
+ <span>
57
+ <a class="code" href="subl://open/?url=file://<%= item["meta"]["sublime_path"] %>">
58
+ <%= item["meta"]["from_klass"] %>
59
+ </a>
60
+ </span>
61
+ </td>
62
+ <td>
63
+ <span class="code">
64
+ <%= item["meta"]["from_method"] %>
65
+ </span>
66
+ </td>
67
+ <td>
68
+ <span class="code">
69
+ <%= item["event_name"] %>
70
+ </span>
71
+ </td>
72
+ <td>
73
+ <a href="<%= log_var_path(log["md5"], item["event_name"]) %>">open</a>
74
+ <pre class="value json code"><%= Localtower::Plugins::Capture.printable(item["returned"]) %></pre>
75
+ </td>
76
+ </tr>
77
+ <% end %>
64
78
  <% end %>
65
79
  </tbody>
66
80
  </table>
data/config/routes.rb CHANGED
@@ -13,6 +13,8 @@ Localtower::Engine.routes.draw do
13
13
 
14
14
  get 'dashboard', to: 'pages#dashboard', as: 'dashboard'
15
15
  get 'logs', to: 'pages#logs', as: 'logs'
16
+ get 'logs/:md5', to: 'pages#log', as: 'log'
17
+ get 'logs/:md5/:var', to: 'pages#log_var', as: 'log_var'
16
18
 
17
19
  root :to => redirect('dashboard')
18
20
  end
@@ -1,7 +1,8 @@
1
1
  module Localtower
2
2
  module Plugins
3
3
  class Capture
4
- LOG_FILE = "#{Rails.root}/log/localtower_capture.log"
4
+ LOG_FILE = lambda { "#{Rails.root}/log/localtower_capture.log" }
5
+ LOG_PATH = lambda { "#{Rails.root}/log" }
5
6
  EXCLUDE_INSTANCE_VARIABLES = [
6
7
  "@_action_has_layout",
7
8
  "@_routes",
@@ -21,7 +22,6 @@ module Localtower
21
22
  class << self
22
23
  def printable(content)
23
24
  if content.respond_to?(:to_json)
24
- # content.to_json
25
25
  JSON.pretty_generate(content)
26
26
  else
27
27
  content.to_s
@@ -42,24 +42,23 @@ module Localtower
42
42
  end
43
43
 
44
44
  def initialize(context = nil, context_binding = nil)
45
- @context = context
46
- @context_binding = context_binding
45
+ @context = context # self
46
+ @context_binding = context_binding # binding
47
47
  end
48
48
 
49
49
  def logs
50
- if File.exist?(LOG_FILE)
51
- content = File.open(LOG_FILE).read
52
- else
53
- content = nil
54
- end
50
+ list = []
55
51
 
56
- return {"variables" => []} if not content.present?
52
+ Dir["#{LOG_PATH.call}/localtower_capture_*.json"].each do |file|
53
+ json = JSON.parse(open(file).read)
54
+ list << json
55
+ end
57
56
 
58
- data = JSON.parse(content)
57
+ list
59
58
  end
60
59
 
61
60
  def my_logger
62
- @@my_logger ||= Logger.new(LOG_FILE)
61
+ @@my_logger ||= Logger.new(LOG_FILE.call)
63
62
  @@my_logger.formatter = proc do |severity, datetime, progname, msg|
64
63
  "#{msg}\n"
65
64
  end
@@ -70,16 +69,24 @@ module Localtower
70
69
  def values
71
70
  hash = {}
72
71
 
73
- a = @context.send(:caller)[1] # xx/xx/app/controllers/clients/events_controller.rb:57:in `new'
72
+ callers = @context.send(:caller)
73
+ a = callers[1] # xx/xx/app/controllers/clients/events_controller.rb:57:in `new'
74
74
  a = a.split(Rails.root.to_s).last # events_controller.rb:57:in `new'
75
75
  a = a.split("\:")
76
76
 
77
+
77
78
  file = a[0].strip
78
79
  line_number = a[1].strip
79
80
  method = a[2].strip.gsub("in \`", "").gsub("\'", "")
80
81
 
82
+ sublime_path = "#{callers[1].split(":")[0]}:#{line_number}"
83
+
81
84
  hash["class"] = self.klass_name
82
- hash["method"] = "#{file}##{method}:#{line_number}"
85
+ hash["file"] = "#{file}##{method}:#{line_number}"
86
+ hash["method"] = method
87
+ hash["md5"] = Digest::MD5.hexdigest(hash["file"])
88
+ hash["type"] = "CAPTURE_METHOD"
89
+ hash["time"] = Time.now.utc.strftime('%Y-%m-%d %H:%M:%S.%L')
83
90
 
84
91
  variables = []
85
92
 
@@ -89,19 +96,28 @@ module Localtower
89
96
  value = @context_binding.local_variable_get(var)
90
97
  klass = self.class.type_of(value)
91
98
 
92
- variables << {
93
- name: var,
94
- value: value,
95
- klass: klass
99
+ data = {
100
+ type: 'CAPTURE',
101
+ time: Time.now.utc.strftime('%Y-%m-%d %H:%M:%S.%L'),
102
+ event_name: var,
103
+ identifier: nil,
104
+ returned: value,
105
+ meta: {
106
+ from_klass: hash["class"],
107
+ from_method: hash["method"],
108
+ klass: klass.to_s,
109
+ method: method.to_s,
110
+ # arguments: data[:arguments],
111
+ callers: callers,
112
+ # table_name: data[:table_name],
113
+ # sql: data[:sql],
114
+ sublime_path: sublime_path,
115
+ file: hash["file"],
116
+ line: line_number
117
+ }
96
118
  }
97
119
 
98
- if value.is_a?(ActiveRecord::AssociationRelation) and value.respond_to?(:count)
99
- variables << {
100
- name: "#{var}_count",
101
- value: value.count,
102
- klass: nil
103
- }
104
- end
120
+ variables << data
105
121
  end
106
122
 
107
123
  @context.instance_variables.each do |var|
@@ -110,19 +126,28 @@ module Localtower
110
126
  value = @context.instance_variable_get(var.to_sym)
111
127
  klass = self.class.type_of(value)
112
128
 
113
- variables << {
114
- name: var,
115
- value: value,
116
- klass: klass
129
+ data = {
130
+ type: 'CAPTURE',
131
+ time: Time.now.utc.strftime('%Y-%m-%d %H:%M:%S.%L'),
132
+ event_name: var,
133
+ identifier: nil,
134
+ returned: value,
135
+ meta: {
136
+ from_klass: hash["class"],
137
+ from_method: hash["method"],
138
+ klass: klass.to_s,
139
+ method: method.to_s,
140
+ # arguments: data[:arguments],
141
+ callers: callers,
142
+ # table_name: data[:table_name],
143
+ # sql: data[:sql],
144
+ sublime_path: sublime_path,
145
+ file: hash["file"],
146
+ line: line_number
147
+ }
117
148
  }
118
149
 
119
- if value.is_a?(ActiveRecord::AssociationRelation) and value.respond_to?(:count)
120
- variables << {
121
- name: "#{var}_count",
122
- value: value.count,
123
- klass: nil
124
- }
125
- end
150
+ variables << data
126
151
  end
127
152
 
128
153
  hash["variables"] = variables
@@ -140,25 +165,25 @@ module Localtower
140
165
  value.to_s
141
166
  end
142
167
 
143
- # def context_caller
144
- # @context.send(:caller)[0]
145
- # end
146
-
147
- def init
148
- # Clear the logs
149
- if File.exist?(LOG_FILE)
150
- File.open(LOG_FILE, 'w') { |f| f.write("") }
168
+ def clear
169
+ Dir["#{LOG_PATH.call}/localtower_capture_*.json"].each do |file|
170
+ File.delete(file)
151
171
  end
152
172
 
153
173
  self
154
174
  end
155
175
 
156
176
  def save
177
+ # We don't want to save logs in production:
157
178
  return nil if Rails.env.production?
158
179
 
159
- self.init
160
- json = self.values.to_json
161
- log "#{json}\n"
180
+ self.clear
181
+
182
+ data = self.values
183
+ json = data.to_json
184
+ file = "#{LOG_PATH.call}/localtower_capture_#{data['md5']}.json"
185
+
186
+ File.open(file, 'w') { |f| f.write(json) }
162
187
  end
163
188
 
164
189
  def log(str)
@@ -154,7 +154,7 @@ module Localtower
154
154
  def perform_raw_cmd(cmd_str, standalone = false, root_dir = false)
155
155
  root_dir ||= ::Rails.root
156
156
 
157
- cmd = standalone ? cmd_str : "cd '#{root_dir}' && #{cmd_str}"
157
+ cmd = standalone ? cmd_str : "cd \"#{root_dir}\" && #{cmd_str}"
158
158
  cmd = cmd.strip
159
159
 
160
160
  self.log("DOING...: #{cmd}")
@@ -1,3 +1,3 @@
1
1
  module Localtower
2
- VERSION = '0.2.2'.freeze
2
+ VERSION = '0.4.0'.freeze
3
3
  end
data/spec/dummy/Gemfile CHANGED
@@ -1,32 +1,12 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- git_source(:github) do |repo_name|
4
- repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/")
5
- "https://github.com/#{repo_name}.git"
6
- end
7
-
8
- gem 'rails', '>= 5.1.0'
9
- # gem 'rails', '>= 5.0.1'
3
+ gem 'rails', '5.2.0'
10
4
  gem 'pg'
11
5
  gem 'puma'
12
- gem 'sass-rails', '~> 5.0'
13
- gem 'uglifier', '>= 1.3.0'
14
- gem 'coffee-rails', '~> 4.2'
15
- # See https://github.com/rails/execjs#readme for more supported runtimes
16
- # gem 'therubyracer', platforms: :ruby
17
-
18
6
  gem 'jquery-rails'
19
7
  gem 'turbolinks', '~> 5'
20
8
 
21
9
  group :development, :test do
22
- # Access an IRB console on exception pages or by using <%= console %> anywhere in the code.
23
- gem 'listen', '~> 3.0.5'
24
- gem "dotenv-rails"
25
- gem "better_errors"
26
- gem "binding_of_caller"
27
- gem 'require_reloader'
28
- gem 'pry'
29
-
30
10
  localtower_path = File.expand_path(File.join(File.dirname(__FILE__), '..', '..'))
31
11
  gem "localtower", path: localtower_path
32
12
  end