web-console 2.0.0 → 2.1.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.
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