ladybug 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4240a28699151639735baf1b2a68005222ceea4d
4
- data.tar.gz: 1f06bc9dd9b9160624c3fde749432f3f5353516b
3
+ metadata.gz: b73479c1e9523e9a0f5798daed1707ed24baf74c
4
+ data.tar.gz: d046e7c87d246a2e3a156ad1bf71c23fc256789c
5
5
  SHA512:
6
- metadata.gz: 11bb0607a071ac3cad9d837eaa8c325d37ca2c5d8b00bae16f59a06f6b8c0fcad725d375368cabb47e19f4de72276180cdd830a96e93e9776943898f9b831355
7
- data.tar.gz: b8d1f5faeaaf0745bcda7416617f3e3720a3aec5c31ca072e781165321fa3880a8cb05f0e553e55d6835a17937bb0c37e1f136ff95e1492bb96656134f251f57
6
+ metadata.gz: c79d7443d7cebedbb3174fe5a340aa21d2c23d201df2fab87aa6294326c839b3371e187f46eb7d351f4c7c8ad8bf103197882ded9dfb588284f1ae3422eca4ed
7
+ data.tar.gz: 58f696d4d5dc454c68215c0a3780f9ea2c45d070db1e168f915f2be26bf7ec5e567a02c110439291962f8db88f4e481a4d70978e669f0d7f01c0129c8f8893b4
data/README.md CHANGED
@@ -6,7 +6,7 @@ Chrome Devtools as a user interface.
6
6
  It aims to provide a rich backend debugging experience in a UI that many
7
7
  web developers are already familiar with for debugging frontend Javascript.
8
8
 
9
- **This project is currently in a very early experimental phase.** Expect many limitations and bugs, and use at your own risk. If you try it out, please file
9
+ **This project is currently in an early experimental phase.** Expect many limitations and bugs. If you try it out, please file
10
10
  Github issues or [email me](mailto:gklitt@gmail.com) to help make this a
11
11
  more useful tool.
12
12
 
@@ -14,9 +14,9 @@ more useful tool.
14
14
 
15
15
  ## Get started
16
16
 
17
- 1) Install the gem:
17
+ 1) Install the gem, or add it to your Gemfile:
18
18
 
19
- `gem install --pre ladybug`
19
+ `gem install ladybug`
20
20
 
21
21
  2) ladybug is implemented as a Rack middleware, so you'll need to add
22
22
  `Ladybug::Middleware` to the Rack middleware stack.
@@ -24,7 +24,7 @@ For example, in Rails 5, add
24
24
  the following line to `config/application.rb`:
25
25
 
26
26
  ```
27
- config.middleware.insert_before(Rack::Sendfile, Ladybug::Middleware)
27
+ config.middleware.use(Ladybug::Middleware)
28
28
  ```
29
29
 
30
30
  3) Make sure you're using the puma web server, which is currently the
@@ -41,7 +41,11 @@ You should see your server program output something like:
41
41
  In the Sources tab, you can view your Ruby source code.
42
42
  If you set a breakpoint and then make another request to your server,
43
43
  it should pause on the breakpoint and you'll be able to inspect
44
- some variables in Devtools.
44
+ local and instance variables in Devtools.
45
+
46
+ 6) You can then use the "step over" button to step through your code,
47
+ or "continue" to continue code execution. "Step into" and "Step out"
48
+ also work in some contexts.
45
49
 
46
50
  **Security warning:** This debugger should only be run in local development.
47
51
  Running it on a server open to the internet could allow anyone to
@@ -49,11 +53,10 @@ execute code on your server without authenticating.
49
53
 
50
54
  ## Development status
51
55
 
52
- * basic pause/continue breakpoint control is supported, but "step over" and "step into" aren't fully supported yet.
53
- * inspecting primtive objects like strings and numbers works okay; support for more complex objects is in development.
54
56
  * So far, ladybug has only been tested with simple Rails applications running on
55
57
  Rails 5 with the puma web server. Eventually it aims to support more Rack
56
58
  applications and web servers (and perhaps even non-Rack applications).
59
+ * inspecting primtive objects like strings and numbers works okay; support for more complex objects is in development.
57
60
 
58
61
  ## Author
59
62
 
@@ -25,6 +25,8 @@ module Ladybug
25
25
 
26
26
  @parsed_files = {}
27
27
 
28
+ @break = nil
29
+
28
30
  # Todo: consider thread safety of mutating this hash
29
31
  Thread.new do
30
32
  preload_paths.each do |preload_path|
@@ -41,6 +43,20 @@ module Ladybug
41
43
  set_trace_func trace_func
42
44
  end
43
45
 
46
+ def debug
47
+ RubyVM::InstructionSequence.compile_option = {
48
+ trace_instruction: true
49
+ }
50
+ Thread.current.set_trace_func trace_func
51
+
52
+ yield
53
+ ensure
54
+ RubyVM::InstructionSequence.compile_option = {
55
+ trace_instruction: false
56
+ }
57
+ Thread.current.set_trace_func nil
58
+ end
59
+
44
60
  def on_pause(&block)
45
61
  @on_pause = block
46
62
  end
@@ -131,12 +147,12 @@ module Ladybug
131
147
  # remove ladybug code from a callstack and prepare it for comparison
132
148
  # this is a hack implemenetation for now, can be made better
133
149
  def clean(callstack)
134
- callstack.drop_while { |frame| frame.to_s.include? "ladybug" }
150
+ callstack.drop_while { |frame| frame.to_s.include? "ladybug/debugger.rb" }
135
151
  end
136
152
 
137
153
  # If we're in step over/in/out mode,
138
154
  # detect if we should break even if there's not a breakpoint set here
139
- def break_on_step?
155
+ def break_on_step?(filename:)
140
156
  # This is an important early return;
141
157
  # we don't want to do anything w/ the callstack unless
142
158
  # we're looking for a breakpoint, because
@@ -144,22 +160,21 @@ module Ladybug
144
160
  # which makes things really slow
145
161
  return false if @break.nil?
146
162
 
163
+ return false if @break == 'step_over' &&
164
+ @breakpoint_filename != filename
165
+
147
166
  bp_callstack = clean(@breakpoint_callstack)
148
167
  current_callstack = clean(Thread.current.backtrace_locations)
149
168
 
150
169
  if @break == 'step_over'
151
- return bp_callstack[1].to_s == current_callstack[1].to_s
170
+ return current_callstack[1].to_s == bp_callstack[1].to_s
152
171
  elsif @break == 'step_into'
153
- return stacks_equal?(bp_callstack, current_callstack[1..-1])
172
+ return current_callstack[1].to_s == bp_callstack[0].to_s
154
173
  elsif @break == 'step_out'
155
- return stacks_equal?(current_callstack, bp_callstack[1..-1])
174
+ return current_callstack[0].to_s == bp_callstack[1].to_s
156
175
  end
157
176
  end
158
177
 
159
- def stacks_equal?(stack1, stack2)
160
- stack1.map(&:to_s) == stack2.map(&:to_s)
161
- end
162
-
163
178
  def trace_func
164
179
  proc { |event, filename, line_number, id, binding, klass, *rest|
165
180
  # This check is called a lot so perhaps worth making faster,
@@ -168,12 +183,15 @@ module Ladybug
168
183
  bp[:filename] == filename && bp[:line_number] == line_number
169
184
  end
170
185
 
171
- if breakpoint_hit || break_on_step?
186
+ if breakpoint_hit || break_on_step?(filename: filename)
172
187
  local_variables =
173
188
  binding.local_variables.each_with_object({}) do |lvar, hash|
174
189
  hash[lvar] = binding.local_variable_get(lvar)
175
190
  end
176
191
 
192
+ # todo: may want to offer classes the ability to
193
+ # override this and define which instance variables to expose here?
194
+
177
195
  instance_variables =
178
196
  binding.eval("instance_variables").each_with_object({}) do |ivar, hash|
179
197
  hash[ivar] = binding.eval("instance_variable_get(:#{ivar})")
@@ -215,10 +233,12 @@ module Ladybug
215
233
  case message[:command]
216
234
  when 'continue'
217
235
  @break = nil
236
+ @breakpoint_filename = nil
218
237
  break
219
238
  when 'step_over'
220
239
  @break = 'step_over'
221
240
  @breakpoint_callstack = Thread.current.backtrace_locations
241
+ @breakpoint_filename = filename
222
242
  break
223
243
  when 'step_into'
224
244
  @break = 'step_into'
@@ -31,7 +31,9 @@ module Ladybug
31
31
  # Return async Rack response
32
32
  ws.rack_response
33
33
  else
34
- @app.call(env)
34
+ @debugger.debug do
35
+ @app.call(env)
36
+ end
35
37
  end
36
38
  end
37
39
 
@@ -224,42 +226,50 @@ module Ladybug
224
226
 
225
227
  script = @script_repository.find(absolute_path: info[:filename])
226
228
 
227
- location = {
228
- scriptId: script.id,
229
- lineNumber: info[:line_number] - 1,
230
- columnNumber: 0
231
- }
229
+ # currently we don't support going into functions
230
+ # that aren't in the path of our current app.
231
+ if script.nil?
232
+ puts "Debugger was paused on file outside of app: #{info[:filename]}"
233
+ puts "ladybug currently only supports pausing in app files."
234
+ @debugger.resume
235
+ else
236
+ location = {
237
+ scriptId: script.id,
238
+ lineNumber: info[:line_number] - 1,
239
+ columnNumber: 0
240
+ }
232
241
 
233
- msg_to_client = {
234
- method: "Debugger.paused",
235
- params: {
236
- callFrames: [
237
- {
238
- location: location,
239
- callFrameId: SecureRandom.uuid,
240
- functionName: info[:label],
241
- scopeChain: [
242
- {
243
- type: "local",
244
- startLocation: location,
245
- endLocation: location,
246
- object: {
247
- className: "Object",
248
- description: "Object",
249
- type: "object",
250
- objectId: object_id
242
+ msg_to_client = {
243
+ method: "Debugger.paused",
244
+ params: {
245
+ callFrames: [
246
+ {
247
+ location: location,
248
+ callFrameId: SecureRandom.uuid,
249
+ functionName: info[:label],
250
+ scopeChain: [
251
+ {
252
+ type: "local",
253
+ startLocation: location,
254
+ endLocation: location,
255
+ object: {
256
+ className: "Object",
257
+ description: "Object",
258
+ type: "object",
259
+ objectId: object_id
260
+ }
251
261
  }
252
- }
253
- ],
254
- url: script.virtual_url
255
- }
256
- ],
257
- hitBreakpoints: info[:breakpoint_id] ? [info[:breakpoint_id]] : [],
258
- reason: "other"
262
+ ],
263
+ url: script.virtual_url
264
+ }
265
+ ],
266
+ hitBreakpoints: info[:breakpoint_id] ? [info[:breakpoint_id]] : [],
267
+ reason: "other"
268
+ }
259
269
  }
260
- }
261
270
 
262
- ws.send(msg_to_client.to_json)
271
+ ws.send(msg_to_client.to_json)
272
+ end
263
273
  end
264
274
 
265
275
  @debugger.on_resume do
@@ -271,8 +281,6 @@ module Ladybug
271
281
  ws.send(msg_to_client.to_json)
272
282
  end
273
283
 
274
- @debugger.start
275
-
276
284
  ws
277
285
  end
278
286
  end
@@ -99,12 +99,10 @@ module Ladybug
99
99
  elsif object.is_a? Hash
100
100
  object.
101
101
  map do |key, value|
102
- kv = {
102
+ {
103
103
  name: key,
104
104
  value: serialize(value)
105
105
  }
106
-
107
- kv
108
106
  end.
109
107
  reject { |property| property[:value].nil? }
110
108
  elsif object.is_a? Array
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ladybug
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Geoffrey Litt