pry-rescue 0.9.1 → 0.10.pre.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.
data/README.md CHANGED
@@ -119,6 +119,104 @@ From: examples/example.rb @ line 4 Object#test:
119
119
  foo
120
120
  ```
121
121
 
122
+ <a name="peeking"/>
123
+ Peeking
124
+ =======
125
+
126
+ Someones bugs in your program don't cause exceptions. Instead your program just gets
127
+ stuck. Examples include infinite loops, slow network calls, or badly backtracking
128
+ parsers.
129
+
130
+ In this case it's useful to be able to open a pry console when you notice that your
131
+ program is not going anywhere. To enable this feature you need to run:
132
+
133
+ ```
134
+ rescue --peek <script.rb>
135
+ ```
136
+
137
+ Then hit `<ctrl+c>` at any time to stop your program and have a peek at what it's actually
138
+ doing. Hitting `<ctrl-c>` a second time will quit your program, if that's what you were
139
+ trying to do.
140
+
141
+ Automatic peeking
142
+ =================
143
+
144
+ Remembering to run your program with `rescue --peek` manually is a bit frustrating (as you
145
+ don't know you need to peek, until you need to peek) and so pry-rescue also allows you to
146
+ peek into any program at any time by sending it a `SIGUSR2` signal.
147
+
148
+ The easiest way to do this is to hit `<ctrl-z>` to interrupt your program, then type
149
+ `kill -SIGUSR2 %1 && fg` into bash. For example:
150
+
151
+ <!-- TODO syntax highlighting! -->
152
+ ```
153
+ cirwin@localhost:/tmp/pry $ ruby examples/loop.rb
154
+ ^Z
155
+ cirwin@localhost:/tmp/pry $ kill -SIGUSR2 %1 && fg
156
+ [1] + continued ./examples/loop.rb
157
+ Preparing to peek via pry!
158
+ Frame number: 0/4
159
+
160
+ From: ./examples/loop.rb @ line 10 Object#r
161
+ 10: def r
162
+ 11: some_var = 13
163
+ 12: loop do
164
+ => 13: x = File.readlines('lib/pry-rescue.rb')
165
+ 14: end
166
+ 15: end
167
+ pry (main)>
168
+ ```
169
+
170
+ If you find that that's a bit hard to remember (I know I do), then you can make it easier
171
+ by adding the following alias to your `~/.bashrc` or similar:
172
+
173
+ ```
174
+ alias peek='kill -SIGUSR2 %1 && fg'
175
+ ```
176
+
177
+ Then you can just type `peek` instead of `kill -SIGUSR2 %1 && fg`
178
+
179
+ Advanced peeking
180
+ ================
181
+
182
+ You can configure which signal pry-rescue listens for by default by exporting the PRY_PEEK
183
+ environment variable that suits your use-case best:
184
+
185
+ ```
186
+ export PRY_PEEK="" # don't autopeek at all
187
+ export PRY_PEEK=INT # peek on SIGINT (<ctrl+c>)
188
+ export PRY_PEEK=USR1 # peek on SIGUSR1
189
+ export PRY_PEEK=USR2 # peek on SIGUSR2
190
+ export PRY_PEEK=EXIT # peek on program exit
191
+ ```
192
+
193
+ If it's only important for one program, then you can also set the environment variable in
194
+ ruby before requiring pry-rescue
195
+
196
+ ```ruby
197
+ ENV['PRY_PEEK'] = '' # disable SIGUSR2 handler
198
+ require "pry-rescue"
199
+ ```
200
+
201
+ Finally, you can enable peeking into programs that do not include pry-rescue by
202
+ configuring ruby to always load one (or several) of these files:
203
+
204
+ ```
205
+ export RUBYOPT=-rpry-rescue/peek/int # peek on SIGINT (<ctrl-c>)
206
+ export RUBYOPT=-rpry-rescue/peek/usr1 # peek on SIGUSR1
207
+ export RUBYOPT=-rpry-rescue/peek/usr2 # peek on SIGUSR2
208
+ export RUBYOPT=-rpry-rescue/peek/exit # peek on program exit
209
+ ```
210
+
211
+ These last examples relies on having pry-rescue in the load path (i.e. at least in the
212
+ gemset, or Gemfile of the program). If that is not true, you can use absolute paths. The
213
+ hook files do not require the whole of pry-rescue, nor is any of pry itself loaded until
214
+ you trigger the signal.
215
+
216
+ ```
217
+ export RUBYOPT=-r/home/cirwin/src/pry-rescue/lib/pry-rescue/peek/usr2
218
+ ```
219
+
122
220
  pry-stack explorer
123
221
  ==================
124
222
 
data/bin/rescue CHANGED
@@ -4,7 +4,7 @@ USAGE = %{
4
4
  rescue (pry-rescue wrapper)
5
5
 
6
6
  Usage:
7
- rescue <script.rb> [arguments...]
7
+ rescue [--peek] <script.rb> [arguments...]
8
8
 
9
9
  What it does:
10
10
  Runs <script.rb>, and if an uncaught exception is raised,
@@ -13,9 +13,25 @@ What it does:
13
13
 
14
14
  You can then poke around to figure out why your code broke!
15
15
 
16
- (Not yet available: fixing the problem and continuing your program.)
16
+ If --peek is specified, then you can hit <Ctrl+C> to interrupt
17
+ your program and open a pry session at any time you need.
17
18
 
19
+ See the README (http://bitly.com/pry-rescue) for more.
18
20
  }
21
+ case ARGV[0]
22
+ when '-h', '--help'
23
+ puts USAGE
24
+ exit
25
+ when /\A--peek\z/
26
+ ARGV.shift
27
+ ENV['PRY_PEEK'] = 'INT'
28
+ require "pry-rescue/peek/int"
29
+ when '--'
30
+ ARGV.shift
31
+ when /\A-/
32
+ puts USAGE
33
+ exit
34
+ end
19
35
 
20
36
  if ARGV[0] == 'rails'
21
37
  ENV['PRY_RESCUE_RAILS'] = 'true'
data/examples/example.rb CHANGED
@@ -1,3 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # cd-cause example
4
+ #
5
+ # Try running with: ./examples/example.rb
6
+ #
7
+ # When pry opens you can `cd-cause` a few times to see which exception
8
+ # triggered all these buggy rescue blocks!
1
9
  $:.unshift File.expand_path '../../lib', __FILE__
2
10
  require 'pry-rescue'
3
11
 
data/examples/example2.rb CHANGED
@@ -1,3 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+ # pry-stack_explorer example
3
+ #
4
+ # Run with ./examples/example2.rb
5
+ #
6
+ # When pry opens you'll be able to move "up" and "down" the stack and see
7
+ # what's happening at all levels.
8
+
1
9
  $:.unshift File.expand_path '../../lib', __FILE__
2
10
  require 'pry-rescue'
3
11
 
data/examples/loop.rb ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ require 'pry-rescue'
3
+
4
+ # Peeking example! Try running this example with:
5
+ #
6
+ # rescue --peek example/loop.rb
7
+ #
8
+ # Then hit <ctrl-c>, and be able to see what's going on.
9
+
10
+ def r
11
+ some_var = 13
12
+ loop do
13
+ x = File.readlines('lib/pry-rescue.rb')
14
+ end
15
+ end
16
+ r
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env ruby
2
+ # Advanced peeking example, showing how to catch the EXIT signal
3
+ #
4
+ # Try running with:
5
+ #
6
+ # RUBYOPT=-rpry-rescue/peek/exit examples/random-exit.rb
7
+ #
8
+ def haywire arg
9
+ # TODO: Figure out how to pry at the "arg" value
10
+ if 3 == arg
11
+ exit 1
12
+ end
13
+ end
14
+
15
+ def dangerous
16
+ choice = rand 55
17
+ haywire choice
18
+ end
19
+
20
+ loop do
21
+ dangerous
22
+ end
data/examples/rescue.rb CHANGED
@@ -1,5 +1,12 @@
1
+ #!/usr/bin/env ruby
1
2
  # Slightly silly example written for http://cirw.in/blog/pry-to-the-rescue
2
3
  # (NOTE: the solution in the blog post only works on ruby-1.9)
4
+ #
5
+ # try running this with: rescue ./examples/rescue.rb
6
+ #
7
+ # When pry opens, see if you can use edit-method and try-again to fix the
8
+ # code and test that your code works.
9
+ #
3
10
  def find_capitalized(a)
4
11
  a.select do |name|
5
12
  name.chars.first == name.chars.first.upcase
data/lib/pry-rescue.rb CHANGED
@@ -5,10 +5,19 @@ require 'pry'
5
5
  require File.expand_path('../pry-rescue/core_ext', __FILE__)
6
6
  require File.expand_path('../pry-rescue/commands', __FILE__)
7
7
  require File.expand_path('../pry-rescue/rack', __FILE__)
8
+ require File.expand_path('../pry-rescue/peek.rb', __FILE__)
8
9
 
9
10
  if ENV['PRY_RESCUE_RAILS']
10
11
  require File.expand_path('../pry-rescue/rails', __FILE__)
11
12
  end
13
+ case ENV['PRY_PEEK']
14
+ when nil
15
+ PryRescue.peek_on_signal('USR2')
16
+ when ''
17
+ # explicitly disable USR2.
18
+ else
19
+ PryRescue.peek_on_signal(ENV['PRY_PEEK'])
20
+ end
12
21
 
13
22
  begin
14
23
  require 'pry-stack_explorer'
@@ -94,10 +103,24 @@ class PryRescue
94
103
  # @return [Boolean]
95
104
  def user_path?(file)
96
105
  !file.start_with?(RbConfig::CONFIG['libdir']) &&
97
- !Gem::Specification.any?{ |gem| file.start_with?(gem.full_gem_path) } &&
106
+ !gem_path?(file) &&
98
107
  !(file == '<internal:prelude>')
99
108
  end
100
109
 
110
+ # Is this path included in a gem?
111
+ #
112
+ # @param [String] file the absolute path
113
+ # @return [Boolean]
114
+ def gem_path?(file)
115
+ # rubygems 1.8
116
+ if Gem::Specification.respond_to?(:any?)
117
+ Gem::Specification.any?{ |gem| file.start_with?(gem.full_gem_path) }
118
+ # rubygems 1.6
119
+ else
120
+ Gem.all_load_paths.any?{ |path| file.start_with?(path) }
121
+ end
122
+ end
123
+
101
124
  # Remove bindings that are part of Interception/Pry.rescue's internal
102
125
  # event handling that happens as part of the exception hooking process.
103
126
  #
@@ -0,0 +1,18 @@
1
+ class PryRescue
2
+ def self.peek_on_signal signal
3
+ trap signal, &method(:peek!)
4
+ end
5
+
6
+ # Called when rescue --peek is used and the user hits <Ctrl+C>
7
+ # or sends whichever signal is configured.
8
+ def self.peek!(*)
9
+ puts 'Preparing to peek via pry!' unless ENV['NO_PEEK_STARTUP_MESSAGE']
10
+ require 'pry'
11
+ unless binding.respond_to?(:of_caller)
12
+ raise "pry-stack_explorer is not installed"
13
+ end
14
+ throw :raise_up, Interrupt if Pry === binding.of_caller(1).eval('self')
15
+ binding.of_caller(1).pry
16
+ # TODO pry :call_stack => binding.of_callers, :initial_frame => 1
17
+ end
18
+ end
@@ -0,0 +1,2 @@
1
+ require File.dirname(__FILE__)
2
+ PryRescue.peek_on_signal 'EXIT'
@@ -0,0 +1,2 @@
1
+ require File.dirname(__FILE__)
2
+ PryRescue.peek_on_signal 'INT'
@@ -0,0 +1,2 @@
1
+ require File.dirname(__FILE__)
2
+ PryRescue.peek_on_signal 'USR1'
@@ -0,0 +1,2 @@
1
+ require File.dirname(__FILE__)
2
+ PryRescue.peek_on_signal 'USR2'
data/pry-rescue.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'pry-rescue'
3
- s.version = '0.9.1'
3
+ s.version = '0.10.pre.1'
4
4
  s.summary = 'Open a pry session on any unhandled exceptions'
5
5
  s.description = 'Allows you to wrap code in Pry::rescue{ } to open a pry session at any unhandled exceptions'
6
6
  s.homepage = 'https://github.com/ConradIrwin/pry-rescue'
data/spec/peek_spec.rb ADDED
@@ -0,0 +1,29 @@
1
+ ENV['NO_PEEK_STARTUP_MESSAGE'] = 'true'
2
+
3
+ describe "PryRescue.peek!" do
4
+ it "should open a pry in the binding of caller" do
5
+ Pry.config.input = StringIO.new("foo = 6\nexit\n")
6
+ Pry.config.output = StringIO.new
7
+ foo = 5
8
+
9
+ lambda do
10
+ PryRescue.peek!
11
+ end.should change{ foo }.from(5).to(6)
12
+ end
13
+
14
+ # this will fail, or not?
15
+ it 'should include the entire call stack' do
16
+ Pry.config.input = StringIO.new("up\nfoo = 6\nexit\n")
17
+ Pry.config.output = StringIO.new
18
+
19
+ def example_method
20
+ PryRescue.peek!
21
+ end
22
+
23
+ foo = 5
24
+
25
+ lambda do
26
+ PryRescue.peek!
27
+ end.should change{ foo }.from(5).to(6)
28
+ end
29
+ end
@@ -41,7 +41,11 @@ describe "PryRescue.load" do
41
41
 
42
42
  it "should open above gems" do
43
43
  PryRescue.should_receive(:pry).once do |opts|
44
- opts[:call_stack].first.eval("__FILE__").should start_with(Gem::Specification.detect{|x| x.name == 'coderay' }.full_gem_path)
44
+ coderay_path = Gem::Specification.respond_to?(:detect) ?
45
+ Gem::Specification.detect{|x| x.name == 'coderay' }.full_gem_path :
46
+ Gem.all_load_paths.grep(/coderay/).last
47
+
48
+ opts[:call_stack].first.eval("__FILE__").should start_with(coderay_path)
45
49
  end
46
50
  lambda{
47
51
  PryRescue.load("spec/fixtures/coderay.rb")
metadata CHANGED
@@ -1,97 +1,109 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: pry-rescue
3
- version: !ruby/object:Gem::Version
4
- prerelease: false
5
- segments:
6
- - 0
7
- - 9
8
- - 1
9
- version: 0.9.1
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.10.pre.1
5
+ prerelease: 5
10
6
  platform: ruby
11
- authors:
7
+ authors:
12
8
  - Conrad Irwin
13
9
  - banisterfiend
14
10
  - epitron
15
11
  autorequire:
16
12
  bindir: bin
17
13
  cert_chain: []
18
-
19
- date: 2012-09-30 00:00:00 -07:00
20
- default_executable:
21
- dependencies:
22
- - !ruby/object:Gem::Dependency
14
+ date: 2012-10-03 00:00:00.000000000 Z
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
23
17
  name: pry
24
- prerelease: false
25
- requirement: &id001 !ruby/object:Gem::Requirement
26
- requirements:
27
- - - ">="
28
- - !ruby/object:Gem::Version
29
- segments:
30
- - 0
31
- version: "0"
18
+ requirement: !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ! '>='
22
+ - !ruby/object:Gem::Version
23
+ version: '0'
32
24
  type: :runtime
33
- version_requirements: *id001
34
- - !ruby/object:Gem::Dependency
35
- name: interception
36
25
  prerelease: false
37
- requirement: &id002 !ruby/object:Gem::Requirement
38
- requirements:
39
- - - ">="
40
- - !ruby/object:Gem::Version
41
- segments:
42
- - 0
43
- - 3
44
- version: "0.3"
26
+ version_requirements: !ruby/object:Gem::Requirement
27
+ none: false
28
+ requirements:
29
+ - - ! '>='
30
+ - !ruby/object:Gem::Version
31
+ version: '0'
32
+ - !ruby/object:Gem::Dependency
33
+ name: interception
34
+ requirement: !ruby/object:Gem::Requirement
35
+ none: false
36
+ requirements:
37
+ - - ! '>='
38
+ - !ruby/object:Gem::Version
39
+ version: '0.3'
45
40
  type: :runtime
46
- version_requirements: *id002
47
- - !ruby/object:Gem::Dependency
48
- name: rspec
49
41
  prerelease: false
50
- requirement: &id003 !ruby/object:Gem::Requirement
51
- requirements:
52
- - - ">="
53
- - !ruby/object:Gem::Version
54
- segments:
55
- - 0
56
- version: "0"
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ none: false
44
+ requirements:
45
+ - - ! '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0.3'
48
+ - !ruby/object:Gem::Dependency
49
+ name: rspec
50
+ requirement: !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
57
56
  type: :development
58
- version_requirements: *id003
59
- - !ruby/object:Gem::Dependency
60
- name: yard
61
57
  prerelease: false
62
- requirement: &id004 !ruby/object:Gem::Requirement
63
- requirements:
64
- - - ">="
65
- - !ruby/object:Gem::Version
66
- segments:
67
- - 0
68
- version: "0"
58
+ version_requirements: !ruby/object:Gem::Requirement
59
+ none: false
60
+ requirements:
61
+ - - ! '>='
62
+ - !ruby/object:Gem::Version
63
+ version: '0'
64
+ - !ruby/object:Gem::Dependency
65
+ name: yard
66
+ requirement: !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ! '>='
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
69
72
  type: :development
70
- version_requirements: *id004
71
- - !ruby/object:Gem::Dependency
72
- name: redcarpet
73
73
  prerelease: false
74
- requirement: &id005 !ruby/object:Gem::Requirement
75
- requirements:
76
- - - ">="
77
- - !ruby/object:Gem::Version
78
- segments:
79
- - 0
80
- version: "0"
74
+ version_requirements: !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ! '>='
78
+ - !ruby/object:Gem::Version
79
+ version: '0'
80
+ - !ruby/object:Gem::Dependency
81
+ name: redcarpet
82
+ requirement: !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
81
88
  type: :development
82
- version_requirements: *id005
83
- description: Allows you to wrap code in Pry::rescue{ } to open a pry session at any unhandled exceptions
84
- email:
89
+ prerelease: false
90
+ version_requirements: !ruby/object:Gem::Requirement
91
+ none: false
92
+ requirements:
93
+ - - ! '>='
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ description: Allows you to wrap code in Pry::rescue{ } to open a pry session at any
97
+ unhandled exceptions
98
+ email:
85
99
  - conrad.irwin@gmail.com
86
100
  - jrmair@gmail.com
87
101
  - chris@ill-logic.com
88
- executables:
102
+ executables:
89
103
  - rescue
90
104
  extensions: []
91
-
92
105
  extra_rdoc_files: []
93
-
94
- files:
106
+ files:
95
107
  - .gitignore
96
108
  - Gemfile
97
109
  - LICENSE.MIT
@@ -100,11 +112,18 @@ files:
100
112
  - bin/rescue
101
113
  - examples/example.rb
102
114
  - examples/example2.rb
115
+ - examples/loop.rb
116
+ - examples/random-exit.rb
103
117
  - examples/rescue.rb
104
118
  - lib/pry-rescue.rb
105
119
  - lib/pry-rescue/cli.rb
106
120
  - lib/pry-rescue/commands.rb
107
121
  - lib/pry-rescue/core_ext.rb
122
+ - lib/pry-rescue/peek.rb
123
+ - lib/pry-rescue/peek/exit.rb
124
+ - lib/pry-rescue/peek/int.rb
125
+ - lib/pry-rescue/peek/usr1.rb
126
+ - lib/pry-rescue/peek/usr2.rb
108
127
  - lib/pry-rescue/rack.rb
109
128
  - lib/pry-rescue/rails.rb
110
129
  - lib/pry/rescue.rb
@@ -118,36 +137,31 @@ files:
118
137
  - spec/fixtures/simple.rb
119
138
  - spec/fixtures/super.rb
120
139
  - spec/fixtures/uri.rb
140
+ - spec/peek_spec.rb
121
141
  - spec/pry_rescue_spec.rb
122
- has_rdoc: true
123
142
  homepage: https://github.com/ConradIrwin/pry-rescue
124
143
  licenses: []
125
-
126
144
  post_install_message:
127
145
  rdoc_options: []
128
-
129
- require_paths:
146
+ require_paths:
130
147
  - lib
131
- required_ruby_version: !ruby/object:Gem::Requirement
132
- requirements:
133
- - - ">="
134
- - !ruby/object:Gem::Version
135
- segments:
136
- - 0
137
- version: "0"
138
- required_rubygems_version: !ruby/object:Gem::Requirement
139
- requirements:
140
- - - ">="
141
- - !ruby/object:Gem::Version
142
- segments:
143
- - 0
144
- version: "0"
148
+ required_ruby_version: !ruby/object:Gem::Requirement
149
+ none: false
150
+ requirements:
151
+ - - ! '>='
152
+ - !ruby/object:Gem::Version
153
+ version: '0'
154
+ required_rubygems_version: !ruby/object:Gem::Requirement
155
+ none: false
156
+ requirements:
157
+ - - ! '>'
158
+ - !ruby/object:Gem::Version
159
+ version: 1.3.1
145
160
  requirements: []
146
-
147
161
  rubyforge_project:
148
- rubygems_version: 1.3.6
162
+ rubygems_version: 1.8.23
149
163
  signing_key:
150
164
  specification_version: 3
151
165
  summary: Open a pry session on any unhandled exceptions
152
166
  test_files: []
153
-
167
+ has_rdoc: