web-console 2.3.0 → 3.3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 02d40821ae813ac4e5893b4c853725833017cb46
4
- data.tar.gz: 56b2826919677b8a93e6ecedce69a176949d15ee
3
+ metadata.gz: caf063e0c1a30832d5fa0b6ce776514809889448
4
+ data.tar.gz: 0ea92426f743c1463500a0367b8d490501b80e20
5
5
  SHA512:
6
- metadata.gz: 6c6a07f241b5bfad39c7a588ac92bccc8f0786db1b807d3ab94b4ec13464d7d8514493634c88247a868e78e43169094d216da6f01c3559be45af39854a76a0a0
7
- data.tar.gz: 4b656f08efb441715996f541f94806d9f6249171502fded529041c5fc5cead0a73ce4f155fe246f0c4a36c4a0b54f9bdd65fb3091ed5e9b9bfa86b9d95f3a552
6
+ metadata.gz: dc7485fccd26fc2af5a0110215df7baf09188f6ee94d2cb02a6da71c649bb22f84070ff4f7dd0d1c34ba355ff962ac590f1cf8520b04bc4db91ef5256e8b7b49
7
+ data.tar.gz: f8e6b128bfc10fba1c76d95287a0316d028281acac1853b451f024a99c23b6c2d26a6ad3cb1fa4b87395aaabd4c446f2dc3a9d1f792ceff2e86b34c1b7e92e76
data/CHANGELOG.markdown CHANGED
@@ -2,14 +2,51 @@
2
2
 
3
3
  ## master (unreleased)
4
4
 
5
+ ## 3.3.1
6
+
7
+ Drop support for Rails `4.2.0`.
8
+
9
+ ## 3.3.0
10
+
11
+ * [203](https://github.com/rails/web-console/pull/203) Map bindings to traces based on the trace __FILE__ and __LINE__ ([@gsamokovarov])
12
+
13
+ ## 3.2.1
14
+
15
+ * [#202](https://github.com/rails/web-console/pull/202) Use first binding when there is no application binding ([@sh19910711])
16
+
17
+ ## 3.2.0
18
+
19
+ * [#198](https://github.com/rails/web-console/pull/198) Pick the first application trace binding on errors ([@sh19910711])
20
+ * [#189](https://github.com/rails/web-console/pull/189) Silence ActionView rendering information ([@gsamokovarov])
21
+
22
+ ## 3.1.1
23
+
24
+ * [#185](https://github.com/rails/web-console/pull/185) Fix `rails console` startup ([@gsamokovarov])
25
+
26
+ ## 3.1.0
27
+
28
+ * [#182](https://github.com/rails/web-console/pull/182) Let `#console` live in `Kernel` ([@schneems])
29
+ * [#181](https://github.com/rails/web-console/pull/181) Log internal Web Console errors ([@gsamokovarov])
30
+ * [#180](https://github.com/rails/web-console/pull/180) Autoload Web Console constants for faster Rails boot time ([@herminiotorres])
31
+
32
+ ## 3.0.0
33
+
34
+ * [#173](https://github.com/rails/web-console/pull/173) Revert "Change config.development_only default until 4.2.4 is released" ([@gsamokovarov])
35
+ * [#171](https://github.com/rails/web-console/pull/171) Fixed blocked IP logging ([@gsamokovarov])
36
+ * [#162](https://github.com/rails/web-console/pull/162) Render the console inside the body tag ([@gsamokovarov])
37
+ * [#165](https://github.com/rails/web-console/pull/165) Revamped integrations for CRuby and Rubinius ([@gsamokovarov])
38
+
5
39
  ## 2.3.0
6
40
 
7
- * [#181](https://github.com/rails/web-console/pull/181) Log internal Web Console errors ([@schneems])
8
- * [#150](https://github.com/rails/web-console/pull/150) Revert #150. ([@gsamokovarov])
41
+ This is mainly a Rails 5 compatibility release. If you have the chance, please
42
+ go to 3.1.0 instead.
43
+
44
+ * [#181](https://github.com/rails/web-console/pull/181) Log internal Web Console errors (@schneems)
45
+ * [#150](https://github.com/rails/web-console/pull/150) Revert #150. (@gsamokovarov)
9
46
 
10
47
  ## 2.2.1
11
48
 
12
- * [#150](https://github.com/rails/web-console/pull/150) Change config.development_only default until 4.2.4 is released. ([@gsamokovarov])
49
+ * [#150](https://github.com/rails/web-console/pull/150) Change config.development_only default until 4.2.4 is released ([@gsamokovarov])
13
50
 
14
51
  ## 2.2.0
15
52
 
@@ -53,4 +90,5 @@
53
90
  [@parterburn]: https://github.com/parterburn
54
91
  [@sh19910711]: https://github.com/sh19910711
55
92
  [@frenesim]: https://github.com/frenesim
93
+ [@herminiotorres]: https://github.com/herminiotorres
56
94
  [@schneems]: https://github.com/schneems
data/MIT-LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright 2014 Charlie Somerville, Genadi Samokovarov, Guillermo Iguaran and Ryan Dao
1
+ Copyright 2014-2016 Charlie Somerville, Genadi Samokovarov, Guillermo Iguaran and Ryan Dao
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.markdown CHANGED
@@ -1,10 +1,8 @@
1
1
  <p align=right>
2
2
  Documentation for:
3
- <a href=https://github.com/rails/web-console/tree/v2.0.0>v2.0.0</a>
4
- <a href=https://github.com/rails/web-console/tree/v2.1.0>v2.1.0</a>
5
- <a href=https://github.com/rails/web-console/tree/v2.1.1>v2.1.1</a>
6
- <a href=https://github.com/rails/web-console/tree/v2.1.2>v2.1.2</a>
7
- <a href=https://github.com/rails/web-console/tree/v2.1.3>v2.1.3</a>
3
+ <a href=https://github.com/rails/web-console/tree/v1.0.4>v1.0.4</a>
4
+ <a href=https://github.com/rails/web-console/tree/v2.2.1>v2.2.1</a>
5
+ <a href=https://github.com/rails/web-console/tree/v3.0.0>v3.0.0</a>
8
6
  </p>
9
7
 
10
8
  # Web Console [![Build Status](https://travis-ci.org/rails/web-console.svg?branch=master)](https://travis-ci.org/rails/web-console)
@@ -28,7 +26,7 @@ application, add the following to your `Gemfile`.
28
26
 
29
27
  ```ruby
30
28
  group :development do
31
- gem 'web-console', '~> 2.0'
29
+ gem 'web-console'
32
30
  end
33
31
  ```
34
32
 
@@ -37,35 +35,9 @@ restart your server for the _Web Console_ to kick in.
37
35
 
38
36
  ## Runtime
39
37
 
40
- _Web Console_ uses [John Mair]'s [binding_of_caller] to spawn a console in a
41
- specific binding. This comes at the price of limited Ruby runtime support.
42
-
43
38
  ### CRuby
44
39
 
45
- CRuby 1.9.2 and below is **not** supported.
46
-
47
- ### JRuby
48
-
49
- JRuby needs to run in interpreted mode. You can enable it by:
50
-
51
- ```bash
52
- export JRUBY_OPTS=-J-Djruby.compile.mode=OFF
53
-
54
- # If you run JRuby 1.7.12 and above, you can use:
55
- export JRUBY_OPTS=--dev
56
- ```
57
-
58
- An unstable version of [binding_of_caller] is needed as the latest stable one
59
- won't compile on _JRuby_. To install it, put the following in your application
60
- `Gemfile`:
61
-
62
- ```ruby
63
- group :development do
64
- gem 'binding_of_caller', '0.7.3.pre1'
65
- end
66
- ```
67
-
68
- Only _JRuby_ 1.7, is supported (no JRuby 9K support at the moment).
40
+ CRuby 2.2 and above is required.
69
41
 
70
42
  ### Rubinius
71
43
 
@@ -75,7 +47,7 @@ Internal errors like `ZeroDevisionError` aren't caught.
75
47
 
76
48
  The web console allows you to create an interactive Ruby session in your
77
49
  browser. Those sessions are launched automatically in case on an error, but
78
- they can also be launched manually in in any page.
50
+ they can also be launched manually in any page.
79
51
 
80
52
  For example, calling `console` in a view will display a console in the current
81
53
  page in the context of the view binding.
@@ -96,8 +68,10 @@ class PostsController < ApplicationController
96
68
  end
97
69
  ```
98
70
 
99
- Only one `console` invocation is allowed per request. If you happen to have
100
- multiple ones, a `WebConsole::DoubleRenderError` is raised.
71
+ The method is defined in `Kernel` and you can invoke it any application code.
72
+
73
+ Only one `console` invocation is allowed once per request. If you happen to
74
+ have multiple ones, a `WebConsole::DoubleRenderError` will be raised.
101
75
 
102
76
  ## Configuration
103
77
 
@@ -215,17 +189,16 @@ Make sure you configuration lives in `config/environments/development.rb`.
215
189
 
216
190
  ## Credits
217
191
 
218
- * Shoutout to [Charlie Somerville] for [better_errors] and [this] code.
219
- * Kudos to [John Mair] for [binding_of_caller].
192
+ * Shoutout to [Charlie Somerville] for [better_errors].
193
+ * Kudos to [John Mair] for [debug_inspector].
220
194
  * Thanks to [Charles Oliver Nutter] for all the _JRuby_ feedback.
221
- * Hugs and kisses to all of our [contributors].
195
+ * Hugs and kisses to all of our [contributors]!
222
196
 
223
197
  [better_errors]: https://github.com/charliesome/better_errors
224
- [binding_of_caller]: https://github.com/banister/binding_of_caller
198
+ [debug_inspector]: https://github.com/banister/debug_inspector
225
199
  [Charlie Somerville]: https://github.com/charliesome
226
200
  [John Mair]: https://github.com/banister
227
201
  [Charles Oliver Nutter]: https://github.com/headius
228
202
  [templates]: https://github.com/rails/web-console/tree/master/lib/web_console/templates
229
- [this]: https://github.com/rails/web-console/blob/master/lib/web_console/integration/cruby.rb#L20-L32
230
203
  [rvt]: https://github.com/gsamokovarov/rvt
231
204
  [contributors]: https://github.com/rails/web-console/graphs/contributors
@@ -0,0 +1,33 @@
1
+ module WebConsole
2
+ class ExceptionMapper
3
+ def initialize(exception)
4
+ @backtrace = exception.backtrace
5
+ @bindings = exception.bindings
6
+ end
7
+
8
+ def first
9
+ guess_the_first_application_binding || @bindings.first
10
+ end
11
+
12
+ def [](index)
13
+ guess_binding_for_index(index) || @bindings[index]
14
+ end
15
+
16
+ private
17
+
18
+ def guess_binding_for_index(index)
19
+ file, line = @backtrace[index].to_s.split(':')
20
+ line = line.to_i
21
+
22
+ @bindings.find do |binding|
23
+ binding.eval('__FILE__') == file && binding.eval('__LINE__') == line
24
+ end
25
+ end
26
+
27
+ def guess_the_first_application_binding
28
+ @bindings.find do |binding|
29
+ binding.eval('__FILE__').to_s.start_with?(Rails.root.to_s)
30
+ end
31
+ end
32
+ end
33
+ end
@@ -1,23 +1,45 @@
1
- ActionDispatch::DebugExceptions.class_eval do
2
- def render_exception_with_web_console(request, exception)
3
- render_exception_without_web_console(request, exception).tap do
4
- # Retain superficial Rails 5 compatibility.
5
- env = Hash === request ? request : request.env
1
+ module Kernel
2
+ module_function
6
3
 
7
- error = ActionDispatch::ExceptionWrapper.new(env, exception).exception
4
+ # Instructs Web Console to render a console in the specified binding.
5
+ #
6
+ # If +bidning+ isn't explicitly given it will default to the binding of the
7
+ # previous frame. E.g. the one that invoked +console+.
8
+ #
9
+ # Raises DoubleRenderError if a double +console+ invocation per request is
10
+ # detected.
11
+ def console(binding = WebConsole.caller_bindings.first)
12
+ raise WebConsole::DoubleRenderError if Thread.current[:__web_console_binding]
8
13
 
9
- # Get the original exception if ExceptionWrapper decides to follow it.
10
- env['web_console.exception'] = error
14
+ Thread.current[:__web_console_binding] = binding
11
15
 
12
- # ActionView::Template::Error bypass ExceptionWrapper original
13
- # exception following. The backtrace in the view is generated from
14
- # reaching out to original_exception in the view.
15
- if error.is_a?(ActionView::Template::Error)
16
- env['web_console.exception'] = error.original_exception
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
+
23
+ module ActionDispatch
24
+ class DebugExceptions
25
+ def render_exception_with_web_console(request, exception)
26
+ render_exception_without_web_console(request, exception).tap do
27
+ backtrace_cleaner = request.get_header('action_dispatch.backtrace_cleaner')
28
+ error = ExceptionWrapper.new(backtrace_cleaner, exception).exception
29
+
30
+ # Get the original exception if ExceptionWrapper decides to follow it.
31
+ Thread.current[:__web_console_exception] = error
32
+
33
+ # ActionView::Template::Error bypass ExceptionWrapper original
34
+ # exception following. The backtrace in the view is generated from
35
+ # reaching out to original_exception in the view.
36
+ if error.is_a?(ActionView::Template::Error)
37
+ Thread.current[:__web_console_exception] = error.cause
38
+ end
17
39
  end
18
40
  end
19
- end
20
41
 
21
- alias_method :render_exception_without_web_console, :render_exception
22
- alias_method :render_exception, :render_exception_with_web_console
42
+ alias_method :render_exception_without_web_console, :render_exception
43
+ alias_method :render_exception, :render_exception_with_web_console
44
+ end
23
45
  end
@@ -1,40 +1,23 @@
1
- class Exception
2
- begin
3
- # We share the same exception binding extraction mechanism as better_errors,
4
- # so try to use it if it is already available. It also solves problems like
5
- # charliesome/better_errors#272, caused by an infinite recursion.
6
- require 'better_errors'
1
+ require 'debug_inspector'
7
2
 
8
- # The bindings in which the exception originated in.
9
- def bindings
10
- @bindings || __better_errors_bindings_stack
11
- end
12
- rescue LoadError
13
- # The bindings in which the exception originated in.
14
- def bindings
15
- @bindings || []
16
- end
17
-
18
- # CRuby calls #set_backtrace every time it raises an exception. Overriding
19
- # it to assign the #bindings.
20
- def set_backtrace_with_binding_of_caller(*args)
21
- # Thanks to @charliesome who wrote this bit for better_errors.
22
- unless Thread.current[:__web_console_exception_lock]
23
- Thread.current[:__web_console_exception_lock] = true
24
- begin
25
- # Raising an exception here will cause all of the rubies to go into a
26
- # stack overflow. Some rubies may even segfault. See
27
- # https://bugs.ruby-lang.org/issues/10164 for details.
28
- @bindings = binding.callers.drop(1)
29
- ensure
30
- Thread.current[:__web_console_exception_lock] = false
31
- end
32
- end
3
+ def WebConsole.caller_bindings
4
+ bindings = RubyVM::DebugInspector.open do |context|
5
+ context.backtrace_locations.each_index.map { |i| context.frame_binding(i) }
6
+ end
33
7
 
34
- set_backtrace_without_binding_of_caller(*args)
35
- end
8
+ # For C functions, we can't extract a binding. In this case,
9
+ # DebugInspector#frame_binding would have returned us nil. That's why we need
10
+ # to compact the bindings.
11
+ #
12
+ # Dropping two bindings, removes the current Ruby one in this exact method,
13
+ # and the one in the caller method. The caller method binding can be obtained
14
+ # by Kernel#binding, if needed.
15
+ bindings.compact.drop(2)
16
+ end
36
17
 
37
- alias_method :set_backtrace_without_binding_of_caller, :set_backtrace
38
- alias_method :set_backtrace, :set_backtrace_with_binding_of_caller
18
+ TracePoint.trace(:raise) do |context|
19
+ exc = context.raised_exception
20
+ if exc.bindings.empty?
21
+ exc.instance_variable_set(:@bindings, WebConsole.caller_bindings)
39
22
  end
40
23
  end
@@ -1,62 +1,34 @@
1
- module WebConsole
2
- module Rubinius
3
- # Filters internal Rubinius locations.
4
- #
5
- # There are a couple of reasons why we wanna filter out the locations.
6
- #
7
- # * ::Kernel.raise, is implemented in Ruby for Rubinius. We don't wanna
8
- # have the frame for it to align with the CRuby and JRuby implementations.
9
- #
10
- # * For internal methods location variables can be nil. We can't create a
11
- # bindings for them.
12
- #
13
- # * Bindings from the current file are considered internal and ignored.
14
- #
15
- # We do that all that so we can align the bindings with the backtraces
16
- # entries.
17
- class InternalLocationFilter
18
- def initialize(locations)
19
- @locations = locations
20
- end
1
+ def WebConsole.caller_bindings
2
+ locations = ::Rubinius::VM.backtrace(1, true)
21
3
 
22
- def filter
23
- @locations.reject do |location|
24
- location.file.start_with?('kernel/delta/kernel.rb') ||
25
- location.file == __FILE__ ||
26
- location.variables.nil?
27
- end
28
- end
29
- end
30
-
31
- # Gets the current bindings for all available Ruby frames.
32
- #
33
- # Filters the internal Rubinius and WebConsole frames.
34
- def self.current_bindings
35
- locations = ::Rubinius::VM.backtrace(1, true)
36
-
37
- InternalLocationFilter.new(locations).filter.map do |location|
38
- Binding.setup(
39
- location.variables,
40
- location.variables.method,
41
- location.constant_scope,
42
- location.variables.self,
43
- location
44
- )
45
- end
46
- end
4
+ # Kernel.raise, is implemented in Ruby for Rubinius. We don't wanna have
5
+ # the frame for it to align with the CRuby and JRuby implementations.
6
+ #
7
+ # For internal methods location variables can be nil. We can't create a
8
+ # bindings for them.
9
+ locations.reject! do |location|
10
+ location.file.start_with?('kernel/delta/kernel.rb') || location.variables.nil?
47
11
  end
48
- end
49
12
 
50
- ::Exception.class_eval do
51
- def bindings
52
- @bindings || []
13
+ bindings = locations.map do |location|
14
+ Binding.setup(
15
+ location.variables,
16
+ location.variables.method,
17
+ location.constant_scope,
18
+ location.variables.self,
19
+ location
20
+ )
53
21
  end
22
+
23
+ # Drop the binding of the direct caller. That one can be created by
24
+ # Kernel#binding.
25
+ bindings.drop(1)
54
26
  end
55
27
 
56
28
  ::Rubinius.singleton_class.class_eval do
57
29
  def raise_exception_with_current_bindings(exc)
58
30
  if exc.bindings.empty?
59
- exc.instance_variable_set(:@bindings, WebConsole::Rubinius.current_bindings)
31
+ exc.instance_variable_set(:@bindings, WebConsole.caller_bindings)
60
32
  end
61
33
 
62
34
  raise_exception_without_current_bindings(exc)
@@ -1,8 +1,33 @@
1
+ class Exception
2
+ # Returns an array of the exception backtrace locations bindings.
3
+ #
4
+ # The list won't map to the traces in #backtrace 1 to 1, because we can't
5
+ # build bindings for every trace (C functions, for example).
6
+ #
7
+ # Every integration should set the instance variable.
8
+ def bindings
9
+ defined?(@bindings) ? @bindings : []
10
+ end
11
+ end
12
+
1
13
  case RUBY_ENGINE
2
14
  when 'rbx'
3
15
  require 'web_console/integration/rubinius'
4
- when 'jruby'
5
- require 'web_console/integration/jruby'
6
16
  when 'ruby'
7
17
  require 'web_console/integration/cruby'
18
+ else
19
+ # Prevent a `method redefined; discarding old caller_bindings` warning.
20
+
21
+ module WebConsole
22
+ # Returns the Ruby bindings of Kernel#callers locations.
23
+ #
24
+ # The list of bindings here doesn't map 1 to 1 with Kernel#callers, as we
25
+ # can't build Ruby bindings for C functions or the equivalent native
26
+ # implementations in JRuby and Rubinius.
27
+ #
28
+ # This method needs to be overridden by every integration.
29
+ def self.caller_bindings
30
+ raise NotImplementedError
31
+ end
32
+ end
8
33
  end
@@ -17,7 +17,7 @@ module WebConsole
17
17
  def call(env)
18
18
  app_exception = catch :app_exception do
19
19
  request = create_regular_or_whiny_request(env)
20
- return @app.call(env) unless request.from_whitelited_ip?
20
+ return call_app(env) unless request.from_whitelisted_ip?
21
21
 
22
22
  if id = id_for_repl_session_update(request)
23
23
  return update_repl_session(id, request)
@@ -25,15 +25,9 @@ module WebConsole
25
25
  return change_stack_trace(id, request)
26
26
  end
27
27
 
28
- status, headers, body = @app.call(env)
28
+ status, headers, body = call_app(env)
29
29
 
30
- if exception = env['web_console.exception']
31
- session = Session.from_exception(exception)
32
- elsif binding = env['web_console.binding']
33
- session = Session.from_binding(binding)
34
- end
35
-
36
- if session && acceptable_content_type?(headers)
30
+ if session = Session.from(Thread.current) and acceptable_content_type?(headers)
37
31
  response = Response.new(body, status, headers)
38
32
  template = Template.new(env, session)
39
33
 
@@ -49,13 +43,18 @@ module WebConsole
49
43
  WebConsole.logger.error("\n#{e.class}: #{e}\n\tfrom #{e.backtrace.join("\n\tfrom ")}")
50
44
  raise e
51
45
  ensure
46
+ # Clean up the fiber locals after the session creation. Object#console
47
+ # uses those to communicate the current binding or exception to the middleware.
48
+ Thread.current[:__web_console_exception] = nil
49
+ Thread.current[:__web_console_binding] = nil
50
+
52
51
  raise app_exception if Exception === app_exception
53
52
  end
54
53
 
55
54
  private
56
55
 
57
56
  def acceptable_content_type?(headers)
58
- Mime::Type.parse(headers['Content-Type']).first == Mime::HTML
57
+ Mime::Type.parse(headers['Content-Type']).first == Mime[:html]
59
58
  end
60
59
 
61
60
  def json_response(opts = {})
@@ -6,21 +6,18 @@ module WebConsole
6
6
  config.web_console.whitelisted_ips = %w( 127.0.0.1 ::1 )
7
7
 
8
8
  initializer 'web_console.initialize' do
9
+ require 'web_console/integration'
9
10
  require 'web_console/extensions'
10
11
 
11
- ActiveSupport.on_load(:action_view) do
12
- ActionView::Base.send(:include, Helper)
13
- end
14
-
15
- ActiveSupport.on_load(:action_controller) do
16
- ActionController::Base.send(:include, Helper)
12
+ if logger = ::Rails.logger
13
+ WebConsole.logger = logger
17
14
  end
18
15
  end
19
16
 
20
17
  initializer 'web_console.development_only' do
21
18
  unless (config.web_console.development_only == false) || Rails.env.development?
22
19
  abort <<-END.strip_heredoc
23
- Web Console is activated in the #{Rails.env} environment, which is
20
+ Web Console is activated in the #{Rails.env} environment. This is
24
21
  usually a mistake. To ensure it's only activated in development
25
22
  mode, move it to the development group of your Gemfile:
26
23
 
@@ -5,14 +5,14 @@ module WebConsole
5
5
  cattr_accessor :whitelisted_ips
6
6
  @@whitelisted_ips = Whitelist.new
7
7
 
8
- # Define a vendor MIME type. We can call it using Mime::WEB_CONSOLE_V2 constant.
8
+ # Define a vendor MIME type. We can call it using Mime[:web_console_v2].
9
9
  Mime::Type.register 'application/vnd.web-console.v2', :web_console_v2
10
10
 
11
11
  # Returns whether a request came from a whitelisted IP.
12
12
  #
13
13
  # For a request to hit Web Console features, it needs to come from a white
14
14
  # listed IP.
15
- def from_whitelited_ip?
15
+ def from_whitelisted_ip?
16
16
  whitelisted_ips.include?(strict_remote_ip)
17
17
  end
18
18
 
@@ -23,7 +23,7 @@ module WebConsole
23
23
 
24
24
  # Returns whether the request is acceptable.
25
25
  def acceptable?
26
- xhr? && accepts.any? { |mime| Mime::WEB_CONSOLE_V2 == mime }
26
+ xhr? && accepts.any? { |mime| Mime[:web_console_v2] == mime }
27
27
  end
28
28
 
29
29
  private
@@ -1,9 +1,9 @@
1
1
  module WebConsole
2
- # A session lets you persist wrap an +Evaluator+ instance in memory
3
- # associated with multiple bindings.
2
+ # A session lets you persist an +Evaluator+ instance in memory associated
3
+ # with multiple bindings.
4
4
  #
5
5
  # Each newly created session is persisted into memory and you can find it
6
- # later its +id+.
6
+ # later by its +id+.
7
7
  #
8
8
  # A session may be associated with multiple bindings. This is used by the
9
9
  # error pages only, as currently, this is the only client that needs to do
@@ -21,14 +21,19 @@ module WebConsole
21
21
  inmemory_storage[id]
22
22
  end
23
23
 
24
- # Create a Session from an exception.
25
- def from_exception(exc)
26
- new(exc.bindings)
27
- end
28
-
29
- # Create a Session from a single binding.
30
- def from_binding(binding)
31
- new(binding)
24
+ # Create a Session from an binding or exception in a storage.
25
+ #
26
+ # The storage is expected to respond to #[]. The binding is expected in
27
+ # :__web_console_binding and the exception in :__web_console_exception.
28
+ #
29
+ # Can return nil, if no binding or exception have been preserved in the
30
+ # storage.
31
+ def from(storage)
32
+ if exc = storage[:__web_console_exception]
33
+ new(ExceptionMapper.new(exc))
34
+ elsif binding = storage[:__web_console_binding]
35
+ new([binding])
36
+ end
32
37
  end
33
38
  end
34
39
 
@@ -37,8 +42,8 @@ module WebConsole
37
42
 
38
43
  def initialize(bindings)
39
44
  @id = SecureRandom.hex(16)
40
- @bindings = Array(bindings)
41
- @evaluator = Evaluator.new(@bindings[0])
45
+ @bindings = bindings
46
+ @evaluator = Evaluator.new(bindings.first)
42
47
 
43
48
  store_into_memory
44
49
  end
@@ -488,7 +488,7 @@ REPLConsole.request = function request(method, url, params, callback) {
488
488
  xhr.open(method, url, true);
489
489
  xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
490
490
  xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
491
- xhr.setRequestHeader("Accept", "<%= Mime::WEB_CONSOLE_V2 %>");
491
+ xhr.setRequestHeader("Accept", "<%= Mime[:web_console_v2] %>");
492
492
  xhr.send(params);
493
493
 
494
494
  xhr.onreadystatechange = function() {
@@ -1,4 +1,4 @@
1
- <script type="text/javascript">
1
+ <script type="text/javascript" data-template="<%= @template %>">
2
2
  (function() {
3
3
  <%= yield %>
4
4
  }).call(this);
@@ -1,11 +1,7 @@
1
1
  require 'action_view'
2
- require 'action_dispatch'
3
- require 'active_support/core_ext/string/access'
4
- require 'json'
5
- require 'web_console/whitelist'
6
- require 'web_console/request'
7
- require 'web_console/view'
2
+ require 'web_console'
8
3
  require 'web_console/testing/helper'
4
+ Mime = { web_console_v2: 'fake' }
9
5
 
10
6
  module WebConsole
11
7
  module Testing
@@ -1,3 +1,3 @@
1
1
  module WebConsole
2
- VERSION = '2.3.0'
2
+ VERSION = '3.3.1'
3
3
  end
@@ -5,7 +5,7 @@ module WebConsole
5
5
  # The error pages are special, because they are the only pages that
6
6
  # currently require multiple bindings. We get those from exceptions.
7
7
  def only_on_error_page(*args)
8
- yield if @env['web_console.exception'].present?
8
+ yield if Thread.current[:__web_console_exception].present?
9
9
  end
10
10
 
11
11
  # Render JavaScript inside a script tag and a closure.
@@ -14,6 +14,7 @@ module WebConsole
14
14
  # script tag and enclosed in a closure, so you don't have to worry for
15
15
  # leaking globals, unless you explicitly want to.
16
16
  def render_javascript(template)
17
+ assign(template: template)
17
18
  render(template: template, layout: 'layouts/javascript')
18
19
  end
19
20
 
@@ -25,6 +26,14 @@ module WebConsole
25
26
  render(template: template, layout: 'layouts/inlined_string')
26
27
  end
27
28
 
29
+ # Custom ActionView::Base#render wrapper which silences all the log
30
+ # printings.
31
+ #
32
+ # Helps to keep the Rails logs clean during errors.
33
+ def render(*)
34
+ WebConsole.logger.silence { super }
35
+ end
36
+
28
37
  # Override method for ActionView::Helpers::TranslationHelper#t.
29
38
  #
30
39
  # This method escapes the original return value for JavaScript, since the
@@ -4,9 +4,9 @@ module WebConsole
4
4
  # If any calls to +from_whitelisted_ip?+ and +acceptable_content_type?+
5
5
  # return false, an info log message will be displayed in users' logs.
6
6
  class WhinyRequest < SimpleDelegator
7
- def from_whitelited_ip?
8
- whine_unless request.from_whitelited_ip? do
9
- "Cannot render console from #{request.remote_ip}! " \
7
+ def from_whitelisted_ip?
8
+ whine_unless request.from_whitelisted_ip? do
9
+ "Cannot render console from #{request.strict_remote_ip}! " \
10
10
  "Allowed networks: #{request.whitelisted_ips}"
11
11
  end
12
12
  end
data/lib/web_console.rb CHANGED
@@ -1,25 +1,30 @@
1
- require 'binding_of_caller'
2
-
1
+ require 'active_support/dependencies/autoload'
3
2
  require 'active_support/lazy_load_hooks'
4
3
  require 'active_support/logger'
5
4
 
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/response'
17
- require 'web_console/view'
18
- require 'web_console/whiny_request'
19
-
20
5
  module WebConsole
6
+ extend ActiveSupport::Autoload
7
+
8
+ autoload :View
9
+ autoload :Evaluator
10
+ autoload :ExceptionMapper
11
+ autoload :Session
12
+ autoload :Response
13
+ autoload :Request
14
+ autoload :WhinyRequest
15
+ autoload :Whitelist
16
+ autoload :Template
17
+ autoload :Middleware
18
+
19
+ autoload_at 'web_console/errors' do
20
+ autoload :Error
21
+ autoload :DoubleRenderError
22
+ end
23
+
21
24
  mattr_accessor :logger
22
25
  @@logger = ActiveSupport::Logger.new($stderr)
23
26
 
24
27
  ActiveSupport.run_load_hooks(:web_console, self)
25
28
  end
29
+
30
+ require 'web_console/railtie'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: web-console
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.0
4
+ version: 3.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Charlie Somerville
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2016-01-27 00:00:00.000000000 Z
14
+ date: 2016-07-05 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: railties
@@ -19,90 +19,56 @@ dependencies:
19
19
  requirements:
20
20
  - - ">="
21
21
  - !ruby/object:Gem::Version
22
- version: '4.0'
22
+ version: '5.0'
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
27
  - - ">="
28
28
  - !ruby/object:Gem::Version
29
- version: '4.0'
29
+ version: '5.0'
30
30
  - !ruby/object:Gem::Dependency
31
31
  name: activemodel
32
32
  requirement: !ruby/object:Gem::Requirement
33
33
  requirements:
34
34
  - - ">="
35
35
  - !ruby/object:Gem::Version
36
- version: '4.0'
36
+ version: '5.0'
37
37
  type: :runtime
38
38
  prerelease: false
39
39
  version_requirements: !ruby/object:Gem::Requirement
40
40
  requirements:
41
41
  - - ">="
42
42
  - !ruby/object:Gem::Version
43
- version: '4.0'
43
+ version: '5.0'
44
44
  - !ruby/object:Gem::Dependency
45
- name: sprockets-rails
45
+ name: actionview
46
46
  requirement: !ruby/object:Gem::Requirement
47
47
  requirements:
48
48
  - - ">="
49
49
  - !ruby/object:Gem::Version
50
- version: '2.0'
51
- - - "<"
52
- - !ruby/object:Gem::Version
53
- version: '4.0'
50
+ version: '5.0'
54
51
  type: :runtime
55
52
  prerelease: false
56
53
  version_requirements: !ruby/object:Gem::Requirement
57
54
  requirements:
58
55
  - - ">="
59
56
  - !ruby/object:Gem::Version
60
- version: '2.0'
61
- - - "<"
62
- - !ruby/object:Gem::Version
63
- version: '4.0'
57
+ version: '5.0'
64
58
  - !ruby/object:Gem::Dependency
65
- name: binding_of_caller
59
+ name: debug_inspector
66
60
  requirement: !ruby/object:Gem::Requirement
67
61
  requirements:
68
62
  - - ">="
69
63
  - !ruby/object:Gem::Version
70
- version: 0.7.2
64
+ version: '0'
71
65
  type: :runtime
72
66
  prerelease: false
73
67
  version_requirements: !ruby/object:Gem::Requirement
74
68
  requirements:
75
69
  - - ">="
76
70
  - !ruby/object:Gem::Version
77
- version: 0.7.2
78
- - !ruby/object:Gem::Dependency
79
- name: actionmailer
80
- requirement: !ruby/object:Gem::Requirement
81
- requirements:
82
- - - ">="
83
- - !ruby/object:Gem::Version
84
- version: '4.0'
85
- type: :development
86
- prerelease: false
87
- version_requirements: !ruby/object:Gem::Requirement
88
- requirements:
89
- - - ">="
90
- - !ruby/object:Gem::Version
91
- version: '4.0'
92
- - !ruby/object:Gem::Dependency
93
- name: activerecord
94
- requirement: !ruby/object:Gem::Requirement
95
- requirements:
96
- - - ">="
97
- - !ruby/object:Gem::Version
98
- version: '4.0'
99
- type: :development
100
- prerelease: false
101
- version_requirements: !ruby/object:Gem::Requirement
102
- requirements:
103
- - - ">="
104
- - !ruby/object:Gem::Version
105
- version: '4.0'
71
+ version: '0'
106
72
  description:
107
73
  email:
108
74
  - charlie@charliesomerville.com
@@ -121,11 +87,10 @@ files:
121
87
  - lib/web_console.rb
122
88
  - lib/web_console/errors.rb
123
89
  - lib/web_console/evaluator.rb
90
+ - lib/web_console/exception_mapper.rb
124
91
  - lib/web_console/extensions.rb
125
- - lib/web_console/helper.rb
126
92
  - lib/web_console/integration.rb
127
93
  - lib/web_console/integration/cruby.rb
128
- - lib/web_console/integration/jruby.rb
129
94
  - lib/web_console/integration/rubinius.rb
130
95
  - lib/web_console/locales/en.yml
131
96
  - lib/web_console/middleware.rb
@@ -165,7 +130,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
165
130
  requirements:
166
131
  - - ">="
167
132
  - !ruby/object:Gem::Version
168
- version: '0'
133
+ version: 2.2.2
169
134
  required_rubygems_version: !ruby/object:Gem::Requirement
170
135
  requirements:
171
136
  - - ">="
@@ -1,22 +0,0 @@
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
@@ -1,111 +0,0 @@
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