localtower 0.2.3 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/README.md +11 -8
- data/app/controllers/localtower/pages_controller.rb +17 -0
- data/app/views/localtower/pages/logs.html.erb +42 -28
- data/config/routes.rb +2 -0
- data/lib/localtower/plugins/capture.rb +66 -45
- data/lib/localtower/tools.rb +1 -1
- data/lib/localtower/version.rb +1 -1
- data/lib/localtower.rb +1 -3
- data/public/screenshots/v0.1.6/5_capture.png +0 -0
- data/spec/dummy/Gemfile +1 -21
- data/spec/dummy/Gemfile.lock +104 -146
- data/spec/dummy/app/controllers/pages_controller.rb +8 -0
- data/spec/dummy/app/views/pages/home.html.erb +1 -0
- data/spec/dummy/config/application.rb +0 -9
- data/spec/dummy/config/environments/development.rb +0 -7
- data/spec/dummy/config/initializers/new_framework_defaults.rb +0 -3
- data/spec/dummy/config/routes.rb +2 -0
- data/spec/dummy/log/development.log +2 -158
- data/spec/dummy/log/localtower.log +1735 -1984
- data/spec/dummy/log/test.log +1829 -2183
- data/spec/factories/migration.rb +161 -139
- data/spec/factories/model.rb +34 -30
- data/spec/lib/localtower/generators/model_spec.rb +6 -7
- data/spec/lib/localtower/generators/relation_spec.rb +6 -3
- data/spec/spec_helper.rb +3 -12
- metadata +63 -159
- data/spec/dummy/coverage/assets/0.10.0/application.css +0 -799
- data/spec/dummy/coverage/assets/0.10.0/application.js +0 -1707
- data/spec/dummy/coverage/assets/0.10.0/colorbox/border.png +0 -0
- data/spec/dummy/coverage/assets/0.10.0/colorbox/controls.png +0 -0
- data/spec/dummy/coverage/assets/0.10.0/colorbox/loading.gif +0 -0
- data/spec/dummy/coverage/assets/0.10.0/colorbox/loading_background.png +0 -0
- data/spec/dummy/coverage/assets/0.10.0/favicon_green.png +0 -0
- data/spec/dummy/coverage/assets/0.10.0/favicon_red.png +0 -0
- data/spec/dummy/coverage/assets/0.10.0/favicon_yellow.png +0 -0
- data/spec/dummy/coverage/assets/0.10.0/loading.gif +0 -0
- data/spec/dummy/coverage/assets/0.10.0/magnify.png +0 -0
- data/spec/dummy/coverage/assets/0.10.0/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/spec/dummy/coverage/assets/0.10.0/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/spec/dummy/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- data/spec/dummy/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/spec/dummy/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
- data/spec/dummy/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- data/spec/dummy/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/spec/dummy/coverage/assets/0.10.0/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- data/spec/dummy/coverage/assets/0.10.0/smoothness/images/ui-icons_222222_256x240.png +0 -0
- data/spec/dummy/coverage/assets/0.10.0/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
- data/spec/dummy/coverage/assets/0.10.0/smoothness/images/ui-icons_454545_256x240.png +0 -0
- data/spec/dummy/coverage/assets/0.10.0/smoothness/images/ui-icons_888888_256x240.png +0 -0
- data/spec/dummy/coverage/assets/0.10.0/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
- data/spec/dummy/coverage/index.html +0 -294
- data/spec/dummy/tmp/restart.txt +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 775afdc803d752a87109e8942ff71d1e7829ea59f19234933c477aff3956b7c3
|
|
4
|
+
data.tar.gz: 0d856ca281329b65d2cd9c82836077e1cfdd4f6b35625ade9b118628b00c065b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3bf27bfb43dc6a7428efa4279d832407749e576877d9813ab0c5c615374558a30617167952f170a2e48e4dda8e893a8871f357bf2c87ae7160a884e6d96dfbf7
|
|
7
|
+
data.tar.gz: e908d290a06fb7493b547b4bb4c3d1ea8a2538d5b13992748b9f41c189104658531d446118e95703106003217ae7a4870e08f92d23d979a344381370501f8107
|
data/README.md
CHANGED
|
@@ -14,11 +14,12 @@
|
|
|
14
14
|
### Create a migration
|
|
15
15
|

|
|
16
16
|
|
|
17
|
+
### Using the Capture plugin
|
|
18
|
+

|
|
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
|
|
@@ -63,12 +64,14 @@ You can put this line anywhere in your code:
|
|
|
63
64
|
|
|
64
65
|
For example:
|
|
65
66
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
```ruby
|
|
68
|
+
def my_method
|
|
69
|
+
user = User.find(1)
|
|
70
|
+
some_data = {foo: "bar"}
|
|
69
71
|
|
|
70
|
-
|
|
71
|
-
|
|
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
|
|
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"
|
|
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>
|
|
44
|
-
<th>
|
|
45
|
-
<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
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
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
|
|
@@ -2,6 +2,7 @@ module Localtower
|
|
|
2
2
|
module Plugins
|
|
3
3
|
class Capture
|
|
4
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
|
|
@@ -47,15 +47,14 @@ module Localtower
|
|
|
47
47
|
end
|
|
48
48
|
|
|
49
49
|
def logs
|
|
50
|
-
|
|
51
|
-
content = File.open(LOG_FILE.call).read
|
|
52
|
-
else
|
|
53
|
-
content = nil
|
|
54
|
-
end
|
|
50
|
+
list = []
|
|
55
51
|
|
|
56
|
-
|
|
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
|
-
|
|
57
|
+
list
|
|
59
58
|
end
|
|
60
59
|
|
|
61
60
|
def my_logger
|
|
@@ -70,16 +69,24 @@ module Localtower
|
|
|
70
69
|
def values
|
|
71
70
|
hash = {}
|
|
72
71
|
|
|
73
|
-
|
|
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["
|
|
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
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
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
|
-
|
|
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
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
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
|
-
|
|
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,29 +165,25 @@ module Localtower
|
|
|
140
165
|
value.to_s
|
|
141
166
|
end
|
|
142
167
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
168
|
+
def clear
|
|
169
|
+
Dir["#{LOG_PATH.call}/localtower_capture_*.json"].each do |file|
|
|
170
|
+
File.delete(file)
|
|
171
|
+
end
|
|
146
172
|
|
|
147
|
-
|
|
148
|
-
# Clear the logs
|
|
149
|
-
File.open(LOG_FILE.call, 'w') { |f| f.write("{}") }
|
|
173
|
+
self
|
|
150
174
|
end
|
|
151
175
|
|
|
152
176
|
def save
|
|
177
|
+
# We don't want to save logs in production:
|
|
153
178
|
return nil if Rails.env.production?
|
|
154
179
|
|
|
155
|
-
self.
|
|
180
|
+
self.clear
|
|
156
181
|
|
|
157
182
|
data = self.values
|
|
158
|
-
data.each do |value|
|
|
159
|
-
puts value
|
|
160
|
-
end
|
|
161
|
-
|
|
162
183
|
json = data.to_json
|
|
184
|
+
file = "#{LOG_PATH.call}/localtower_capture_#{data['md5']}.json"
|
|
163
185
|
|
|
164
|
-
File.open(
|
|
165
|
-
# log "#{json}\n"
|
|
186
|
+
File.open(file, 'w') { |f| f.write(json) }
|
|
166
187
|
end
|
|
167
188
|
|
|
168
189
|
def log(str)
|
data/lib/localtower/tools.rb
CHANGED
|
@@ -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
|
|
157
|
+
cmd = standalone ? cmd_str : "cd \"#{root_dir}\" && #{cmd_str}"
|
|
158
158
|
cmd = cmd.strip
|
|
159
159
|
|
|
160
160
|
self.log("DOING...: #{cmd}")
|
data/lib/localtower/version.rb
CHANGED
data/lib/localtower.rb
CHANGED
|
Binary file
|
data/spec/dummy/Gemfile
CHANGED
|
@@ -1,32 +1,12 @@
|
|
|
1
1
|
source 'https://rubygems.org'
|
|
2
2
|
|
|
3
|
-
|
|
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.0.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
|