web-console 2.0.0 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of web-console might be problematic. Click here for more details.

Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/README.markdown +132 -85
  3. data/lib/web_console.rb +14 -13
  4. data/lib/web_console/errors.rb +7 -0
  5. data/lib/web_console/{repl.rb → evaluator.rb} +7 -10
  6. data/lib/web_console/helper.rb +22 -0
  7. data/lib/web_console/integration.rb +8 -0
  8. data/lib/web_console/{core_ext/exception → integration}/cruby.rb +0 -0
  9. data/lib/web_console/integration/jruby.rb +111 -0
  10. data/lib/web_console/integration/rubinius.rb +66 -0
  11. data/lib/web_console/middleware.rb +117 -0
  12. data/lib/web_console/railtie.rb +61 -0
  13. data/lib/web_console/request.rb +30 -0
  14. data/lib/web_console/session.rb +65 -0
  15. data/lib/web_console/template.rb +49 -0
  16. data/lib/web_console/templates/_inner_console_markup.html +3 -0
  17. data/lib/web_console/templates/_markup.html +4 -0
  18. data/lib/web_console/templates/_prompt_box_markup.html +2 -0
  19. data/lib/web_console/templates/console.js +373 -0
  20. data/lib/web_console/templates/error_page.js +83 -0
  21. data/lib/web_console/templates/index.html +8 -0
  22. data/lib/web_console/templates/layouts/inlined_string.erb +1 -0
  23. data/lib/web_console/templates/layouts/javascript.erb +5 -0
  24. data/lib/web_console/templates/main.js +24 -0
  25. data/lib/web_console/templates/style.css +9 -0
  26. data/lib/web_console/version.rb +1 -1
  27. data/lib/web_console/whiny_request.rb +38 -0
  28. data/lib/web_console/whitelist.rb +42 -0
  29. data/test/dummy/config/environments/test.rb +0 -4
  30. data/test/dummy/log/development.log +7075 -0
  31. data/test/dummy/log/test.log +66006 -0
  32. data/test/dummy/tmp/cache/assets/development/sprockets/13fe41fee1fe35b49d145bcc06610705 +0 -0
  33. data/test/dummy/tmp/cache/assets/development/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
  34. data/test/dummy/tmp/cache/assets/development/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
  35. data/test/dummy/tmp/cache/assets/development/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
  36. data/test/dummy/tmp/cache/assets/development/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
  37. data/test/dummy/tmp/cache/assets/development/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
  38. data/test/support/scenarios/bad_custom_error_scenario.rb +17 -0
  39. data/test/support/scenarios/basic_nested_scenario.rb +15 -0
  40. data/test/support/scenarios/custom_error_scenario.rb +11 -0
  41. data/test/support/scenarios/eval_nested_scenario.rb +15 -0
  42. data/test/support/scenarios/flat_scenario.rb +9 -0
  43. data/test/support/scenarios/reraised_scenario.rb +21 -0
  44. data/test/test_helper.rb +50 -3
  45. data/test/web_console/evaluator_test.rb +73 -0
  46. data/test/web_console/helper_test.rb +76 -0
  47. data/test/web_console/integration_test.rb +47 -0
  48. data/test/web_console/middleware_test.rb +116 -0
  49. data/test/web_console/railtie_test.rb +99 -0
  50. data/test/web_console/request_test.rb +52 -0
  51. data/test/web_console/session_test.rb +59 -0
  52. data/test/web_console/whiny_request_test.rb +33 -0
  53. data/test/web_console/whitelist_test.rb +43 -0
  54. metadata +66 -56
  55. data/lib/action_dispatch/debug_exceptions.rb +0 -105
  56. data/lib/action_dispatch/exception_wrapper.rb +0 -38
  57. data/lib/action_dispatch/templates/rescues/_request_and_response.html.erb +0 -34
  58. data/lib/action_dispatch/templates/rescues/_request_and_response.text.erb +0 -23
  59. data/lib/action_dispatch/templates/rescues/_source.erb +0 -29
  60. data/lib/action_dispatch/templates/rescues/_trace.html.erb +0 -72
  61. data/lib/action_dispatch/templates/rescues/_trace.text.erb +0 -9
  62. data/lib/action_dispatch/templates/rescues/_web_console.html.erb +0 -420
  63. data/lib/action_dispatch/templates/rescues/diagnostics.html.erb +0 -18
  64. data/lib/action_dispatch/templates/rescues/diagnostics.text.erb +0 -9
  65. data/lib/action_dispatch/templates/rescues/layout.erb +0 -160
  66. data/lib/action_dispatch/templates/rescues/missing_template.html.erb +0 -13
  67. data/lib/action_dispatch/templates/rescues/missing_template.text.erb +0 -3
  68. data/lib/action_dispatch/templates/rescues/routing_error.html.erb +0 -34
  69. data/lib/action_dispatch/templates/rescues/routing_error.text.erb +0 -11
  70. data/lib/action_dispatch/templates/rescues/template_error.html.erb +0 -22
  71. data/lib/action_dispatch/templates/rescues/template_error.text.erb +0 -7
  72. data/lib/action_dispatch/templates/rescues/unknown_action.html.erb +0 -6
  73. data/lib/action_dispatch/templates/rescues/unknown_action.text.erb +0 -3
  74. data/lib/action_dispatch/templates/routes/_route.html.erb +0 -16
  75. data/lib/action_dispatch/templates/routes/_table.html.erb +0 -200
  76. data/lib/assets/javascripts/web-console.js +0 -1
  77. data/lib/assets/javascripts/web_console.js +0 -41
  78. data/lib/web_console/controller_helpers.rb +0 -46
  79. data/lib/web_console/core_ext/exception.rb +0 -7
  80. data/lib/web_console/core_ext/exception/jruby.rb +0 -25
  81. data/lib/web_console/core_ext/exception/rubinius.rb +0 -32
  82. data/lib/web_console/engine.rb +0 -47
  83. data/lib/web_console/repl_session.rb +0 -89
  84. data/lib/web_console/unsupported_platforms.rb +0 -28
  85. data/lib/web_console/view_helpers.rb +0 -16
  86. data/test/action_pack/exception_wrapper_test.rb +0 -26
  87. data/test/controllers/tests_controller_test.rb +0 -41
  88. data/test/web_console/core_ext/exception_test.rb +0 -46
  89. data/test/web_console/engine_test.rb +0 -108
  90. data/test/web_console/repl_session_test.rb +0 -32
  91. data/test/web_console/repl_test.rb +0 -75
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3ba3b9c75139d0d2ccfdbc4e676fe7206491fc64
4
- data.tar.gz: 46fd6d3d95b76a757d64719d2effdb7c6a69276c
3
+ metadata.gz: 9668f63dcb4699154e023fe36cfc97167572f43a
4
+ data.tar.gz: 238fc2451d041ea8a063052ee3665edce6a4db3b
5
5
  SHA512:
6
- metadata.gz: 9d55c967bb0a036e5b5343ae29af236c1e313ed29927ca7d477b9f2463a9e16d12a3f7aae53d24c13871a7caafaaba73d6bf9754da1620da4f45d95925f3714b
7
- data.tar.gz: 488fa77b5fe910bc08cdf50c87ae3cebb84b91b49412621fd132095a3fbf2b6fc13cdbcf8b0e2e60262e2cc20e812f4275b09411fdf42cea8ca8f69e83af470c
6
+ metadata.gz: d7a8aa82a257fd3386fc0506f6af4d73c727771824e97d5474755485597dcc15ef517c9bd7b1561258d9b38c46219f1d62ae7ea6cf1e56dc23cd214fc3fa2548
7
+ data.tar.gz: 4707a1c5c5c4d5d2d22d8931b99fad9e91f6f411db89d364a7b381585a523aad3b23818b12f142743c0bc961b17059ebe17cec7e68235d4b93c0823487a41b99
@@ -1,105 +1,122 @@
1
1
  <p align=right>
2
2
  Documentation for:
3
- <a href=https://github.com/rails/web-console/tree/v0.1.0>v0.1.0</a>
4
- <a href=https://github.com/rails/web-console/tree/v0.2.0>v0.2.0</a>
5
- <a href=https://github.com/rails/web-console/tree/v0.3.0>v0.3.0</a>
6
- <a href=https://github.com/rails/web-console/tree/v0.4.0>v0.4.0</a>
7
- <a href=https://github.com/rails/web-console/tree/v1.0.4>v1.0.4</a>
3
+ <a href=https://github.com/rails/web-console/tree/v2.0.0>v2.0.0</a>
8
4
  </p>
9
5
 
10
- Web Console [![Build Status](https://travis-ci.org/rails/web-console.svg?branch=master)](https://travis-ci.org/rails/web-console)
11
- ===========
6
+ # Web Console [![Build Status](https://travis-ci.org/rails/web-console.svg?branch=master)](https://travis-ci.org/rails/web-console)
12
7
 
13
- _Web Console_ is a set of debugging tools for your Rails application.
8
+ _Web Console_ is a debugging tool for your Ruby on Rails applications.
14
9
 
15
- **A debugging tool in the default error page.**
10
+ - [Installation](#installation)
11
+ - [Runtime](#runtime)
12
+ - [CRuby](#cruby)
13
+ - [JRuby](#jruby)
14
+ - [Rubinius](#rubinius)
15
+ - [Configuration](#configuration)
16
+ - [Usage](#usage)
17
+ - [FAQ](#faq)
18
+ - [Credits](#credits)
16
19
 
17
- An interactive console is launched automatically in the default Rails error
18
- page. It makes it easy to inspect the stack trace and execute Ruby code in the stack
19
- trace's bindings.
20
+ ## Installation
20
21
 
21
- _(Check out [better_errors] as a great alternative for any Rack application!)_
22
+ _Web Console_ is meant to work as a Rails plugin. To install it in your current
23
+ application, add the following to your `Gemfile`.
22
24
 
23
- ![image](https://cloud.githubusercontent.com/assets/705116/3825943/a010af92-1d5a-11e4-84c2-4ed0ba367f4e.gif)
25
+ ```ruby
26
+ group :development do
27
+ gem 'web-console', '~> 2.0'
28
+ end
29
+ ```
24
30
 
25
- **A debugging tool in your controllers and views.**
31
+ After you save the `Gemfile` changes, make sure to run `bundle install` and
32
+ restart your server for the _Web Console_ to kick in.
26
33
 
27
- Drop `<%= console %>` anywhere in a view to launch an interactive console
28
- session and execute code in it. Drop `console` anywhere in a controler and do
29
- the same in the context of the controller action.
34
+ ## Runtime
30
35
 
31
- ![image](https://cloud.githubusercontent.com/assets/705116/3825939/7e284de0-1d5a-11e4-9896-81465a38da76.gif)
36
+ _Web Console_ uses [John Mair]'s [binding_of_caller] to spawn a console in a
37
+ specific binding. This comes at the price of limited Ruby runtime support.
32
38
 
33
- Requirements
34
- ------------
39
+ ### CRuby
35
40
 
36
- _Web Console_ has been tested on the following rubies.
41
+ CRuby 1.9.2 and below is **not** supported.
37
42
 
38
- * _MRI Ruby_ 2.1.0
39
- * _MRI Ruby_ 2.0.0
40
- * _MRI Ruby_ 1.9.3
43
+ ### JRuby
41
44
 
42
- There is an experimental _JRuby_ 1.7 support. See Installation section for more
43
- information.
45
+ JRuby needs to run in interpreted mode. You can enable it by:
44
46
 
45
- _Web Console_ is built explicitly for _Rails 4_.
47
+ ```bash
48
+ export JRUBY_OPTS=-J-Djruby.compile.mode=OFF
46
49
 
47
- Installation
48
- ------------
50
+ # If you run JRuby 1.7.12 and above, you can use:
51
+ export JRUBY_OPTS=--dev
52
+ ```
49
53
 
50
- To install it in your current application, add the following to your `Gemfile`.
54
+ An unstable version of [binding_of_caller] is needed as the latest stable one
55
+ won't compile on _JRuby_. To install it, put the following in your application
56
+ `Gemfile`:
51
57
 
52
58
  ```ruby
53
59
  group :development do
54
- gem 'web-console', '~> 2.0'
60
+ gem 'binding_of_caller', '0.7.3.pre1'
55
61
  end
56
62
  ```
57
63
 
58
- If you are running JRuby, you can get experimental support with adding a
59
- pre-release version of [binding_of_caller].
64
+ Only _JRuby_ 1.7, is supported (no JRuby 9K support at the moment).
60
65
 
61
- ```ruby
62
- group :development do
63
- gem 'web-console', '~> 2.0'
66
+ ### Rubinius
64
67
 
65
- gem 'binding_of_caller', '0.7.3.pre1'
66
- end
68
+ Internal errors like `ZeroDevisionError` aren't caught.
69
+
70
+ ## Usage
71
+
72
+ The web console allows you to create an interactive Ruby session in your
73
+ browser. Those sessions are launched automatically in case on an error, but
74
+ they can also be launched manually in in any page.
75
+
76
+ For example, calling `console` in a view will display a console in the current
77
+ page in the context of the view binding.
78
+
79
+ ```html
80
+ <% console %>
67
81
  ```
68
82
 
69
- After you save the `Gemfile` changes, make sure to run `bundle install` and
70
- restart your server for the _Web Console_ to kick in.
83
+ Calling `console` in a controller will result in a console in the context of
84
+ the controller action:
71
85
 
72
- Configuration
73
- -------------
86
+ ```ruby
87
+ class PostsController < ApplicationController
88
+ def new
89
+ console
90
+ @post = Post.new
91
+ end
92
+ end
93
+ ```
74
94
 
75
- > Today we have learned in the agony of war that great power involves great
76
- > responsibility.
77
- >
78
- > -- <cite>Franklin D. Roosevelt</cite>
95
+ Only one `console` invocation is allowed per request. If you happen to have
96
+ multiple ones, a `WebConsole::DoubleRenderError` is raised.
79
97
 
80
- _Web Console_ is a powerful tool. It allows you to execute arbitrary code on
81
- the server, so you should be very careful, who you give access to it.
98
+ ## Configuration
99
+
100
+ _Web Console_ allows you to execute arbitrary code on the server, so you
101
+ should be very careful, who you give access to.
82
102
 
83
103
  ### config.web_console.whitelisted_ips
84
104
 
85
- By default, only requests coming from `127.0.0.1` are allowed.
105
+ By default, only requests coming from IPv4 and IPv6 localhosts are allowed.
86
106
 
87
107
  `config.web_console.whitelisted_ips` lets you control which IP's have access to
88
108
  the console.
89
109
 
90
- Let's say you want to share your console with `192.168.0.100`. You can do this:
110
+ You can whitelist single IP's or whole networks. Say you want to share your
111
+ console with `192.168.0.100`. You can do this:
91
112
 
92
113
  ```ruby
93
114
  class Application < Rails::Application
94
- config.web_console.whitelisted_ips = %w( 127.0.0.1 192.168.0.100 )
115
+ config.web_console.whitelisted_ips = '192.168.0.100'
95
116
  end
96
117
  ```
97
118
 
98
- From the example, you can guess that `config.web_console.whitelisted_ips`
99
- accepts an array of ip addresses, provided as strings. An important thing to
100
- note here is that, we won't push `127.0.0.1` if you manually set the option!
101
-
102
- If you want to whitelist a whole network, you can do:
119
+ If you want to whitelist the whole private network, you can do:
103
120
 
104
121
  ```ruby
105
122
  class Application < Rails::Application
@@ -107,46 +124,76 @@ class Application < Rails::Application
107
124
  end
108
125
  ```
109
126
 
110
- Again, note that this network doesn't allow `127.0.0.1`. If you want to access
111
- the console, you have to do so from it's external IP or add `127.0.0.1` to the
112
- mix.
113
-
114
- Credits
115
- -------
127
+ Take a note that IPv4 and IPv6 localhosts are always allowed. This wasn't the
128
+ case in 2.0.
116
129
 
117
- * Shoutout to [Charlie Somerville] for [better_errors]! Most of the exception
118
- binding code is coming straight out of the [better_errors] project.
130
+ ### config.web_console.whiny_requests
119
131
 
120
- * _Web Console_ wouldn't be possible without the work [John Mair] put in
121
- [binding_of_caller]. This is the technology that let us execute a console
122
- right where an error occurred.
132
+ When a console cannot be shown for a given IP address or content type, a
133
+ messages like the following is printed in the server logs:
123
134
 
124
- * Thanks to [Charles Oliver Nutter] for all the JRuby feedback and support he
125
- has given us.
135
+ > Cannot render console from 192.168.1.133! Allowed networks:
136
+ > 127.0.0.0/127.255.255.255, ::1
126
137
 
127
- FAQ
128
- ---
138
+ If you don't wanna see this message anymore, set this option to `false`:
129
139
 
130
- ### I'm running JRuby and there's no console on the default error page.
140
+ ```ruby
141
+ class Application < Rails::Application
142
+ config.web_console.whiny_requests = false
143
+ end
144
+ ```
131
145
 
132
- You would also have to run you Rails server in JRuby's interpreted mode. Enable
133
- it with code snippet below, then start your development Rails server with
134
- `rails server`, as usual.
146
+ ### config.web_console.templates_path
135
147
 
136
- ```bash
137
- export JRUBY_OPTS=-J-Djruby.compile.mode=OFF
148
+ If you wanna style the console yourself, you can place `style.css` at a
149
+ directory pointed by `config.web_console.templates_path`:
138
150
 
139
- # If you run JRuby 1.7.12 and above, you can use:
140
- # export JRUBY_OPTS=--dev
151
+ ```ruby
152
+ class Application < Rails::Application
153
+ config.web_console.templates_path = 'app/views/web_console'
154
+ end
141
155
  ```
142
156
 
157
+ You may wanna check the [templates] folder at the source tree for the files you
158
+ may override.
159
+
160
+ ## FAQ
161
+
162
+ ### Where did /console go?
163
+
164
+ The remote terminal emulator was extracted in its own gem that is no longer
165
+ bundled with _Web Console_.
166
+
167
+ If you miss this feature, check out [rvt].
168
+
169
+ ### Why I constantly get unavailable session errors?
170
+
171
+ All of _Web Console_ sessions are stored in memory. If you happen to run on a
172
+ multi-process server (like Unicorn) you may get unavailable session errors
173
+ while the server is still running. This is because a request may hit a
174
+ different worker (process) that doesn't have the desired session in memory.
175
+
176
+ To avoid that, if you use such servers in development, configure them so they
177
+ server requests only out of one process.
178
+
143
179
  ### How to inspect local and instance variables?
144
180
 
145
181
  The interactive console executes Ruby code. Invoking `instance_variables` and
146
182
  `local_variables` will give you what you want.
147
183
 
148
- [better_errors]: https://github.com/charliesome/better_errors
149
- [binding_of_caller]: https://github.com/banister/binding_of_caller
150
- [Charlie Somerville]: https://github.com/charliesome
151
- [John Mair]: https://github.com/banister
152
- [Charles Oliver Nutter]: https://github.com/headius
184
+ ## Credits
185
+
186
+ * Shoutout to [Charlie Somerville] for [better_errors] and [this] code.
187
+ * Kudos to [John Mair] for [binding_of_caller].
188
+ * Thanks to [Charles Oliver Nutter] for all the _JRuby_ feedback.
189
+ * Hugs and kisses to all of our [contributors].
190
+
191
+ [better_errors]: https://github.com/charliesome/better_errors
192
+ [binding_of_caller]: https://github.com/banister/binding_of_caller
193
+ [Charlie Somerville]: https://github.com/charliesome
194
+ [John Mair]: https://github.com/banister
195
+ [Charles Oliver Nutter]: https://github.com/headius
196
+ [templates]: https://github.com/rails/web-console/tree/master/lib/web_console/templates
197
+ [this]: https://github.com/rails/web-console/blob/master/lib/web_console/integration/cruby.rb#L20-L32
198
+ [rvt]: https://github.com/gsamokovarov/rvt
199
+ [contributors]: https://github.com/rails/web-console/graphs/contributors
@@ -1,22 +1,23 @@
1
1
  require 'binding_of_caller'
2
2
 
3
3
  require 'active_support/lazy_load_hooks'
4
- require 'action_dispatch/exception_wrapper'
5
- require 'action_dispatch/debug_exceptions'
4
+ require 'active_support/logger'
6
5
 
7
- require 'web_console/core_ext/exception'
8
- require "web_console/view_helpers"
9
- require "web_console/controller_helpers"
10
- require 'web_console/engine'
11
- require 'web_console/repl'
12
- require 'web_console/repl_session'
13
- require 'web_console/unsupported_platforms'
6
+ require 'web_console/integration'
7
+ require 'web_console/railtie'
8
+ require 'web_console/errors'
9
+ require 'web_console/helper'
10
+ require 'web_console/evaluator'
11
+ require 'web_console/session'
12
+ require 'web_console/template'
13
+ require 'web_console/middleware'
14
+ require 'web_console/whitelist'
15
+ require 'web_console/request'
16
+ require 'web_console/whiny_request'
14
17
 
15
18
  module WebConsole
16
- # Shortcut the +WebConsole::Engine.config.web_console+.
17
- def self.config
18
- Engine.config.web_console
19
- end
19
+ mattr_accessor :logger
20
+ @@logger = ActiveSupport::Logger.new($stderr)
20
21
 
21
22
  ActiveSupport.run_load_hooks(:web_console, self)
22
23
  end
@@ -0,0 +1,7 @@
1
+ module WebConsole
2
+ # The base class for every Web Console related error.
3
+ Error = Class.new(StandardError)
4
+
5
+ # Raised when there is an attempt to render a console more than once.
6
+ DoubleRenderError = Class.new(Error)
7
+ end
@@ -1,10 +1,11 @@
1
1
  module WebConsole
2
- # Simple read–eval–print implementation.
2
+ # Simple Ruby code evaluator.
3
3
  #
4
- # Provides only the most basic code evaluation with no multiline code
5
- # support.
6
- class REPL
7
- # Cleanses exceptions raised inside #send_input.
4
+ # This class wraps a +Binding+ object and evaluates code inside of it. The
5
+ # difference of a regular +Binding+ eval is that +Evaluator+ will always
6
+ # return a string and will format exception output.
7
+ class Evaluator
8
+ # Cleanses exceptions raised inside #eval.
8
9
  cattr_reader :cleaner
9
10
  @@cleaner = ActiveSupport::BacktraceCleaner.new
10
11
  @@cleaner.add_silencer { |line| line.start_with?(File.expand_path('..', __FILE__)) }
@@ -13,11 +14,7 @@ module WebConsole
13
14
  @binding = binding
14
15
  end
15
16
 
16
- def prompt
17
- '>> '
18
- end
19
-
20
- def send_input(input)
17
+ def eval(input)
21
18
  "=> #{@binding.eval(input).inspect}\n"
22
19
  rescue Exception => exc
23
20
  format_exception(exc)
@@ -0,0 +1,22 @@
1
+ module WebConsole
2
+ module Helper
3
+ # Communicates with the middleware to render a console in a +binding+.
4
+ #
5
+ # If +bidning+ isn't explicitly given, Binding#of_caller will be used to
6
+ # get the binding of the previous frame. E.g. the one that invoked
7
+ # +console+.
8
+ #
9
+ # Raises DoubleRenderError if a double +console+ invocation per request is
10
+ # detected.
11
+ def console(binding = nil)
12
+ raise DoubleRenderError if request.env['web_console.binding']
13
+
14
+ request.env['web_console.binding'] = binding || ::Kernel.binding.of_caller(1)
15
+
16
+ # Make sure nothing is rendered from the view helper. Otherwise
17
+ # you're gonna see unexpected #<Binding:0x007fee4302b078> in the
18
+ # templates.
19
+ nil
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,8 @@
1
+ case RUBY_ENGINE
2
+ when 'rbx'
3
+ require 'web_console/integration/rubinius'
4
+ when 'jruby'
5
+ require 'web_console/integration/jruby'
6
+ when 'ruby'
7
+ require 'web_console/integration/cruby'
8
+ end
@@ -0,0 +1,111 @@
1
+ require 'English'
2
+ require 'active_support/core_ext/string/strip'
3
+
4
+ java_import org.jruby.RubyInstanceConfig
5
+
6
+ module WebConsole
7
+ module JRuby
8
+ class << self
9
+ # Returns whether JRuby is ran in interpreted mode.
10
+ def interpreted_mode?
11
+ compile_mode = ::JRuby.runtime.instance_config.compile_mode
12
+ interpreted_mode = RubyInstanceConfig::CompileMode::OFF
13
+
14
+ compile_mode == interpreted_mode
15
+ end
16
+
17
+ # A proc to be used in Kernel#set_trace_func.
18
+ #
19
+ # It sets Exception#bindings for an error with all the bindings the
20
+ # current ThreadContext contains.
21
+ def set_exception_bindings_trace_func
22
+ proc do |event, file, line, id, binding, classname|
23
+ case event
24
+ when 'raise'
25
+ if $ERROR_INFO.bindings.empty?
26
+ # binding_of_caller will generate an improperly built binding at
27
+ # caller[1]. Every call to a non existent method, constant or a
28
+ # local variable will result in a Java NullPointerException.
29
+ #
30
+ # The binding that Kernel#set_trace_func is giving us is properly
31
+ # built, so we can use in place of the broken one.
32
+ bindings = ::Kernel.binding.callers.drop(2).unshift(binding)
33
+ $ERROR_INFO.instance_variable_set(:@bindings, bindings)
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+
40
+ # A fake binding for JRuby in non interpreted mode.
41
+ #
42
+ # It won't actually evaluate any code, rather it will tell the user how to
43
+ # enable interpreted mode.
44
+ class FakeJRubyBinding
45
+ TURN_ON_INTERPRETED_MODE_TEXT = <<-END.strip_heredoc
46
+ JRuby needs to run in interpreted mode for introspection support.
47
+
48
+ To turn on interpreted mode, put -J-Djruby.compile.mode=OFF in the
49
+ JRUBY_OPTS environment variable.
50
+ END
51
+
52
+ def TURN_ON_INTERPRETED_MODE_TEXT.inspect
53
+ self
54
+ end
55
+
56
+ TURN_ON_INTERPRETED_MODE_TEXT.freeze
57
+
58
+ def eval(*)
59
+ TURN_ON_INTERPRETED_MODE_TEXT
60
+ end
61
+ end
62
+
63
+ # A fake array of FakeJRubyBinding objects.
64
+ #
65
+ # It is used in Exception#bindings to make sure that when users switch
66
+ # bindings on the UI, they get a FakeJRubyBinding notifying them what to do
67
+ # if they want introspection.
68
+ class FakeJRubyBindingsArray < Array
69
+ def [](*)
70
+ FakeJRubyBinding.new
71
+ end
72
+
73
+ # For Kernel#Array and other implicit conversion API. JRuby expects it to
74
+ # return an object that is_a? an Array. This is the reasoning of
75
+ # FakeJRubyBindingsArray being a subclass of Array.
76
+ def to_ary
77
+ self
78
+ end
79
+ end
80
+ end
81
+ end
82
+
83
+ if WebConsole::JRuby.interpreted_mode?
84
+ ::Exception.class_eval do
85
+ def bindings
86
+ @bindings || []
87
+ end
88
+ end
89
+
90
+ # Kernel#set_trace_func will complain about not being able to capture all the
91
+ # events without the JRuby --debug flag.
92
+ silence_warnings do
93
+ set_trace_func WebConsole::JRuby.set_exception_bindings_trace_func
94
+ end
95
+ else
96
+ ::Exception.class_eval do
97
+ def bindings
98
+ WebConsole::JRuby::FakeJRubyBindingsArray.new
99
+ end
100
+ end
101
+
102
+ ::Binding.class_eval do
103
+ def of_caller(*)
104
+ WebConsole::JRuby::FakeJRubyBinding.new
105
+ end
106
+
107
+ def callers
108
+ WebConsole::JRuby::FakeJRubyBindingsArray.new
109
+ end
110
+ end
111
+ end