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.
- checksums.yaml +5 -5
- data/README.md +12 -9
- 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 +72 -47
- data/lib/localtower/tools.rb +1 -1
- data/lib/localtower/version.rb +1 -1
- data/public/screenshots/v0.1.6/5_capture.png +0 -0
- data/spec/dummy/Gemfile +1 -21
- data/spec/dummy/Gemfile.lock +103 -144
- 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 -132
- data/spec/dummy/log/localtower.log +1220 -2014
- data/spec/dummy/log/test.log +1246 -2195
- 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 +68 -130
- 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: 6f62130e44cf4f1047a87b4ab0bed7cd6821d00a7a0767320644d9e78120bba4
|
|
4
|
+
data.tar.gz: a6c3f44be4d00e2b159170254e8f4424d3ae95e5d4ac0645e8aaffbb882178a6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: fd0523f501766384f7e9a2013e7d0b2256443de640aa627b1513d8c8bca3269627d28fbba6db5c08a8f840deb3b2854dc364772681408cdfcefe86b4e87d9256
|
|
7
|
+
data.tar.gz: e1a6e0c03d83e3f12acf2e1acf617e92c0a2f4e365479b8984ad016e3f196eb77fa916378cf02d17196689fe27ed16f14333e8832ac456baa2b9469930dd5b37
|
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
|
|
@@ -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
|
-
|
|
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
|
|
@@ -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
|
-
|
|
51
|
-
content = File.open(LOG_FILE).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
|
|
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
|
-
|
|
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,25 +165,25 @@ module Localtower
|
|
|
140
165
|
value.to_s
|
|
141
166
|
end
|
|
142
167
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
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.
|
|
160
|
-
|
|
161
|
-
|
|
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)
|
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
|
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.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
|