web-console 1.0.4 → 2.0.0.beta1

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 (138) hide show
  1. checksums.yaml +4 -4
  2. data/README.markdown +26 -247
  3. data/lib/action_dispatch/debug_exceptions.rb +115 -0
  4. data/lib/action_dispatch/exception_wrapper.rb +15 -0
  5. data/lib/action_dispatch/templates/rescues/_request_and_response.html.erb +34 -0
  6. data/lib/action_dispatch/templates/rescues/_request_and_response.text.erb +23 -0
  7. data/lib/action_dispatch/templates/rescues/_source.erb +27 -0
  8. data/lib/action_dispatch/templates/rescues/_trace.html.erb +76 -0
  9. data/lib/action_dispatch/templates/rescues/_trace.text.erb +15 -0
  10. data/lib/action_dispatch/templates/rescues/_web_console.html.erb +382 -0
  11. data/lib/action_dispatch/templates/rescues/diagnostics.html.erb +18 -0
  12. data/lib/action_dispatch/templates/rescues/diagnostics.text.erb +9 -0
  13. data/lib/action_dispatch/templates/rescues/layout.erb +162 -0
  14. data/lib/action_dispatch/templates/rescues/missing_template.html.erb +7 -0
  15. data/lib/action_dispatch/templates/rescues/missing_template.text.erb +3 -0
  16. data/lib/action_dispatch/templates/rescues/routing_error.html.erb +30 -0
  17. data/lib/action_dispatch/templates/rescues/routing_error.text.erb +11 -0
  18. data/lib/action_dispatch/templates/rescues/template_error.html.erb +22 -0
  19. data/lib/action_dispatch/templates/rescues/template_error.text.erb +8 -0
  20. data/lib/action_dispatch/templates/rescues/unknown_action.html.erb +6 -0
  21. data/lib/action_dispatch/templates/rescues/unknown_action.text.erb +3 -0
  22. data/lib/web_console.rb +17 -7
  23. data/lib/web_console/exception_extension.rb +22 -0
  24. data/lib/web_console/railtie.rb +15 -0
  25. data/lib/web_console/repl.rb +24 -0
  26. data/lib/web_console/repl_session.rb +90 -0
  27. data/lib/web_console/version.rb +1 -1
  28. data/lib/web_console/view_helpers.rb +21 -0
  29. data/test/action_pack/exception_wrapper_test.rb +26 -0
  30. data/test/dummy/app/controllers/exception_test_controller.rb +11 -0
  31. data/test/dummy/app/controllers/helper_test_controller.rb +5 -0
  32. data/test/dummy/app/views/helper_test/index.html.erb +220 -0
  33. data/test/dummy/app/views/layouts/application.html.erb +2 -0
  34. data/test/dummy/config/application.rb +0 -34
  35. data/test/dummy/config/routes.rb +3 -0
  36. data/test/dummy/db/development.sqlite3 +0 -0
  37. data/test/dummy/log/development.log +61270 -0
  38. data/test/dummy/log/test.log +3917 -0
  39. data/test/dummy/tmp/cache/assets/development/sprockets/038461854af2e8bccdb29768efd4768f +0 -0
  40. data/test/dummy/tmp/cache/assets/development/sprockets/0ec396634a5f6808b026257fd107c355 +0 -0
  41. data/test/dummy/tmp/cache/assets/development/sprockets/127a54171eea8d294e4673599861787d +0 -0
  42. data/{app/assets/stylesheets/web_console/application.css → test/dummy/tmp/cache/assets/development/sprockets/13fe41fee1fe35b49d145bcc06610705} +0 -0
  43. data/test/dummy/tmp/cache/assets/development/sprockets/17c571144b4e44da39bddb2d2c412414 +0 -0
  44. data/test/dummy/tmp/cache/assets/development/sprockets/1cb77d8cf661ccbc9de08f347c89b9f1 +0 -0
  45. data/test/dummy/tmp/cache/assets/development/sprockets/204edd12a29660722d4e0d8de9bd6652 +0 -0
  46. data/test/dummy/tmp/cache/assets/development/sprockets/2b96b037f3dfeccfe27113eb95b06ea1 +0 -0
  47. data/test/dummy/tmp/cache/assets/development/sprockets/2c853768baf811357d81d41bdfd05dcf +0 -0
  48. data/test/dummy/tmp/cache/assets/development/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
  49. data/test/dummy/tmp/cache/assets/development/sprockets/314d48e543146f617c4d3439a4d8d40d +0 -0
  50. data/test/dummy/tmp/cache/assets/development/sprockets/34f21019a876722b8c24a6da4f0ef50b +0 -0
  51. data/test/dummy/tmp/cache/assets/development/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
  52. data/{vendor/assets/javascripts/term.js → test/dummy/tmp/cache/assets/development/sprockets/36341e42f23669574fa1027d0958ff3e} +0 -0
  53. data/test/dummy/tmp/cache/assets/development/sprockets/44117154e909436e7eeaf10cdb18d2b4 +0 -0
  54. data/test/dummy/tmp/cache/assets/development/sprockets/496864a905d53afd8e176f29500f96a8 +0 -0
  55. data/test/dummy/tmp/cache/assets/development/sprockets/55b7b76605fdffe31d737d4ac1f1ef7b +0 -0
  56. data/test/dummy/tmp/cache/assets/development/sprockets/5ac98782fe3dfd0a766f75ce1801f0a0 +0 -0
  57. data/test/dummy/tmp/cache/assets/development/sprockets/6088d6f344b38303cc8028057d69e0f9 +0 -0
  58. data/test/dummy/tmp/cache/assets/development/sprockets/676dcf9b2d01b9dc7bd3183d8da88463 +0 -0
  59. data/test/dummy/tmp/cache/assets/development/sprockets/680381170dc160e358fc28076ea6886c +0 -0
  60. data/test/dummy/tmp/cache/assets/development/sprockets/6ad7acc9a22fe2a67ec24a1fc866c20e +0 -0
  61. data/test/dummy/tmp/cache/assets/development/sprockets/6bdb0d0c602e0e1bc304dc697e2cc6de +0 -0
  62. data/test/dummy/tmp/cache/assets/development/sprockets/6dc8d7aa69668fce85683aaad6615432 +0 -0
  63. data/test/dummy/tmp/cache/assets/development/sprockets/6e4d5b32cc444226f6597198994ccd5e +0 -0
  64. data/test/dummy/tmp/cache/assets/development/sprockets/74db0ca5cb8c8c347c9131a3ff516748 +0 -0
  65. data/test/dummy/tmp/cache/assets/development/sprockets/7999e525c88173c1beb785f002effc1d +0 -0
  66. data/{lib/assets/javascripts/web_console.js → test/dummy/tmp/cache/assets/development/sprockets/7a50a9e605754e99783de95715b976b0} +0 -0
  67. data/test/dummy/tmp/cache/assets/development/sprockets/806b0e33a2fe8e1245534345fa27c30a +0 -0
  68. data/{app/assets/javascripts/web_console/console_sessions.js → test/dummy/tmp/cache/assets/development/sprockets/8aa4c7aabff23c8089d41e9e54193483} +0 -0
  69. data/test/dummy/tmp/cache/assets/development/sprockets/90396626cba6cbec37e32038e6c54e76 +0 -0
  70. data/test/dummy/tmp/cache/assets/development/sprockets/976b28910aa72c90a3b30c6e940f51df +0 -0
  71. data/test/dummy/tmp/cache/assets/development/sprockets/99e1bd7cbc437505bc8f07bc528c721c +0 -0
  72. data/test/dummy/tmp/cache/assets/development/sprockets/aaccf2c9ae2add0863c9a49e0042a097 +0 -0
  73. data/test/dummy/tmp/cache/assets/development/sprockets/ae4677d24a79d9411f2fced5011d5807 +0 -0
  74. data/test/dummy/tmp/cache/assets/development/sprockets/b2401118729720034b6f3eda0b4c5025 +0 -0
  75. data/test/dummy/tmp/cache/assets/development/sprockets/c649837df826fc310cb80f1adafd6b8d +0 -0
  76. data/test/dummy/tmp/cache/assets/development/sprockets/cac185d59612fae451a12df3fc21bb51 +0 -0
  77. data/test/dummy/tmp/cache/assets/development/sprockets/cb0065359d3b5b296f71d673f4b276e9 +0 -0
  78. data/test/dummy/tmp/cache/assets/development/sprockets/cee8c6b09c33d2b276753e959712724e +0 -0
  79. data/test/dummy/tmp/cache/assets/development/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
  80. data/test/dummy/tmp/cache/assets/development/sprockets/d1f6e06bc2f112c4ec3a4c3f68351878 +0 -0
  81. data/test/dummy/tmp/cache/assets/development/sprockets/d20d83fd7ffa378b1b2b901786d640f3 +0 -0
  82. data/test/dummy/tmp/cache/assets/development/sprockets/d38c7c3aa1e72b55769ccb3607641ef4 +0 -0
  83. data/test/dummy/tmp/cache/assets/development/sprockets/d6b85d8b0b5c569388b89e56e9f6fed7 +0 -0
  84. data/test/dummy/tmp/cache/assets/development/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
  85. data/test/dummy/tmp/cache/assets/development/sprockets/d982412def520c434e2240eae6d29cf2 +0 -0
  86. data/test/dummy/tmp/cache/assets/development/sprockets/df048a8b0897b9c04acdf59c8f95b18f +0 -0
  87. data/test/dummy/tmp/cache/assets/development/sprockets/df600f50f002512c95d93bcfbab891ed +0 -0
  88. data/test/dummy/tmp/cache/assets/development/sprockets/e6d6b8bde546349764be7b44ffcf5807 +0 -0
  89. data/test/dummy/tmp/cache/assets/development/sprockets/eb25265794d2f7afd1684779d84efdac +0 -0
  90. data/test/dummy/tmp/cache/assets/development/sprockets/ee8826b12b7d9bfd717df950b58f82ab +0 -0
  91. data/test/dummy/tmp/cache/assets/development/sprockets/ef9824789c6ed3483590e0564a12e1d1 +0 -0
  92. data/test/dummy/tmp/cache/assets/development/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
  93. data/test/dummy/tmp/cache/assets/development/sprockets/fc7201c6cbef32453aa4175c520c8eae +0 -0
  94. data/test/dummy/tmp/cache/assets/test/sprockets/17c571144b4e44da39bddb2d2c412414 +0 -0
  95. data/test/dummy/tmp/cache/assets/test/sprockets/36341e42f23669574fa1027d0958ff3e +0 -0
  96. data/test/dummy/tmp/cache/assets/test/sprockets/55b7b76605fdffe31d737d4ac1f1ef7b +0 -0
  97. data/test/dummy/tmp/cache/assets/test/sprockets/5ac98782fe3dfd0a766f75ce1801f0a0 +0 -0
  98. data/test/dummy/tmp/cache/assets/test/sprockets/680381170dc160e358fc28076ea6886c +0 -0
  99. data/test/dummy/tmp/cache/assets/test/sprockets/6ad7acc9a22fe2a67ec24a1fc866c20e +0 -0
  100. data/test/dummy/tmp/cache/assets/test/sprockets/6e4d5b32cc444226f6597198994ccd5e +0 -0
  101. data/test/dummy/tmp/cache/assets/test/sprockets/7a50a9e605754e99783de95715b976b0 +0 -0
  102. data/test/dummy/tmp/cache/assets/test/sprockets/8aa4c7aabff23c8089d41e9e54193483 +0 -0
  103. data/test/dummy/tmp/cache/assets/test/sprockets/b2401118729720034b6f3eda0b4c5025 +0 -0
  104. data/test/dummy/tmp/cache/assets/test/sprockets/cb0065359d3b5b296f71d673f4b276e9 +0 -0
  105. data/test/dummy/tmp/cache/assets/test/sprockets/d1f6e06bc2f112c4ec3a4c3f68351878 +0 -0
  106. data/test/dummy/tmp/cache/assets/test/sprockets/d6b85d8b0b5c569388b89e56e9f6fed7 +0 -0
  107. data/test/dummy/tmp/cache/assets/test/sprockets/d982412def520c434e2240eae6d29cf2 +0 -0
  108. data/test/dummy/tmp/cache/assets/test/sprockets/df048a8b0897b9c04acdf59c8f95b18f +0 -0
  109. data/test/dummy/tmp/cache/assets/test/sprockets/e6d6b8bde546349764be7b44ffcf5807 +0 -0
  110. data/test/web_console/exception_extention_test.rb +16 -0
  111. data/test/web_console/repl_session_test.rb +32 -0
  112. data/test/web_console/repl_test.rb +26 -0
  113. metadata +191 -58
  114. data/app/assets/javascripts/web_console/application.js +0 -1
  115. data/app/assets/stylesheets/web_console/console_sessions.css.erb +0 -6
  116. data/app/controllers/web_console/application_controller.rb +0 -13
  117. data/app/controllers/web_console/console_sessions_controller.rb +0 -43
  118. data/app/helpers/web_console/application_helper.rb +0 -4
  119. data/app/helpers/web_console/console_session_helper.rb +0 -4
  120. data/app/models/web_console/console_session.rb +0 -96
  121. data/app/views/layouts/web_console/application.html.erb +0 -14
  122. data/app/views/web_console/console_sessions/index.html.erb +0 -15
  123. data/config/routes.rb +0 -11
  124. data/lib/assets/javascripts/web-console.js +0 -1
  125. data/lib/web_console/colors.rb +0 -87
  126. data/lib/web_console/colors/light.rb +0 -24
  127. data/lib/web_console/colors/monokai.rb +0 -24
  128. data/lib/web_console/colors/solarized.rb +0 -47
  129. data/lib/web_console/colors/tango.rb +0 -24
  130. data/lib/web_console/colors/xterm.rb +0 -24
  131. data/lib/web_console/engine.rb +0 -77
  132. data/lib/web_console/slave.rb +0 -139
  133. data/test/controllers/web_console/console_sessions_controller_test.rb +0 -95
  134. data/test/helpers/web_console/console_session_helper_test.rb +0 -6
  135. data/test/models/console_session_test.rb +0 -58
  136. data/test/web_console/colors_test.rb +0 -58
  137. data/test/web_console/engine_test.rb +0 -136
  138. data/test/web_console/slave_test.rb +0 -71
@@ -0,0 +1,18 @@
1
+ <header>
2
+ <h1>
3
+ <%= @exception.class.to_s %>
4
+ <% if @request.parameters['controller'] %>
5
+ in <%= @request.parameters['controller'].camelize %>Controller<% if @request.parameters['action'] %>#<%= @request.parameters['action'] %><% end %>
6
+ <% end %>
7
+ </h1>
8
+ </header>
9
+
10
+ <div id="container">
11
+ <h2><%= h @exception.message %></h2>
12
+
13
+ <%= render template: "rescues/_source" %>
14
+ <%= render template: "rescues/_trace" %>
15
+ <%= render template: "rescues/_request_and_response" %>
16
+ </div>
17
+
18
+ <%= render template: "rescues/_web_console" %>
@@ -0,0 +1,9 @@
1
+ <%= @exception.class.to_s %><%
2
+ if @request.parameters['controller']
3
+ %> in <%= @request.parameters['controller'].camelize %>Controller<% if @request.parameters['action'] %>#<%= @request.parameters['action'] %><% end %>
4
+ <% end %>
5
+
6
+ <%= @exception.message %>
7
+ <%= render template: "rescues/_source" %>
8
+ <%= render template: "rescues/_trace" %>
9
+ <%= render template: "rescues/_request_and_response" %>
@@ -0,0 +1,162 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <title>Action Controller: Exception caught</title>
6
+
7
+ <style>
8
+ body {
9
+ background-color: #FAFAFA;
10
+ color: #333;
11
+ margin: 0px;
12
+ }
13
+
14
+ body, p, ol, ul, td {
15
+ font-family: helvetica, verdana, arial, sans-serif;
16
+ font-size: 13px;
17
+ line-height: 18px;
18
+ }
19
+
20
+ pre {
21
+ font-size: 11px;
22
+ white-space: pre-wrap;
23
+ }
24
+
25
+ pre.box {
26
+ border: 1px solid #EEE;
27
+ padding: 10px;
28
+ margin: 0px;
29
+ width: 958px;
30
+ }
31
+
32
+ header {
33
+ color: #F0F0F0;
34
+ background: #C52F24;
35
+ padding: 0.5em 1.5em;
36
+ }
37
+
38
+ h1 {
39
+ margin: 0.2em 0;
40
+ line-height: 1.1em;
41
+ font-size: 2em;
42
+ }
43
+
44
+ h2 {
45
+ color: #C52F24;
46
+ line-height: 25px;
47
+ }
48
+
49
+ .hidden {
50
+ display: none;
51
+ }
52
+
53
+ .details {
54
+ border: 1px solid #D0D0D0;
55
+ border-radius: 4px;
56
+ margin: 1em 0px;
57
+ display: block;
58
+ width: 978px;
59
+ }
60
+
61
+ .summary {
62
+ padding: 8px 15px;
63
+ border-bottom: 1px solid #D0D0D0;
64
+ display: block;
65
+ }
66
+
67
+ .details pre {
68
+ margin: 5px;
69
+ border: none;
70
+ }
71
+
72
+ #container {
73
+ box-sizing: border-box;
74
+ width: 100%;
75
+ padding: 0 1.5em;
76
+ }
77
+
78
+ .source * {
79
+ margin: 0px;
80
+ padding: 0px;
81
+ }
82
+
83
+ .source {
84
+ border: 1px solid #D9D9D9;
85
+ background: #ECECEC;
86
+ width: 978px;
87
+ }
88
+
89
+ .source pre {
90
+ padding: 10px 0px;
91
+ border: none;
92
+ }
93
+
94
+ .source .data {
95
+ font-size: 80%;
96
+ overflow: auto;
97
+ background-color: #FFF;
98
+ }
99
+
100
+ .info {
101
+ padding: 0.5em;
102
+ }
103
+
104
+ .source .data .line_numbers {
105
+ background-color: #ECECEC;
106
+ color: #AAA;
107
+ padding: 1em .5em;
108
+ border-right: 1px solid #DDD;
109
+ text-align: right;
110
+ }
111
+
112
+ .line {
113
+ padding-left: 10px;
114
+ }
115
+
116
+ .line:hover {
117
+ background-color: #F6F6F6;
118
+ }
119
+
120
+ .line.active {
121
+ background-color: #FFCCCC;
122
+ }
123
+
124
+ a { color: #980905; }
125
+ a:visited { color: #666; }
126
+ a.trace-frames { color: #666; }
127
+ a:hover { color: #C52F24; }
128
+ a.trace-frames.selected { color: #C52F24 }
129
+
130
+ <%= yield :style %>
131
+ </style>
132
+
133
+
134
+ <script>
135
+ var toggle = function(id) {
136
+ var s = document.getElementById(id).style;
137
+ s.display = s.display == 'none' ? 'block' : 'none';
138
+ return false;
139
+ }
140
+ var show = function(id) {
141
+ document.getElementById(id).style.display = 'block';
142
+ }
143
+ var hide = function(id) {
144
+ document.getElementById(id).style.display = 'none';
145
+ }
146
+ var toggleTrace = function() {
147
+ return toggle('blame_trace');
148
+ }
149
+ var toggleSessionDump = function() {
150
+ return toggle('session_dump');
151
+ }
152
+ var toggleEnvDump = function() {
153
+ return toggle('env_dump');
154
+ }
155
+ </script>
156
+ </head>
157
+ <body>
158
+
159
+ <%= yield %>
160
+
161
+ </body>
162
+ </html>
@@ -0,0 +1,7 @@
1
+ <header>
2
+ <h1>Template is missing</h1>
3
+ </header>
4
+
5
+ <div id="container">
6
+ <h2><%= h @exception.message %></h2>
7
+ </div>
@@ -0,0 +1,3 @@
1
+ Template is missing
2
+
3
+ <%= @exception.message %>
@@ -0,0 +1,30 @@
1
+ <header>
2
+ <h1>Routing Error</h1>
3
+ </header>
4
+ <div id="container">
5
+ <h2><%= h @exception.message %></h2>
6
+ <% unless @exception.failures.empty? %>
7
+ <p>
8
+ <h2>Failure reasons:</h2>
9
+ <ol>
10
+ <% @exception.failures.each do |route, reason| %>
11
+ <li><code><%= route.inspect.delete('\\') %></code> failed because <%= reason.downcase %></li>
12
+ <% end %>
13
+ </ol>
14
+ </p>
15
+ <% end %>
16
+
17
+ <%= render template: "rescues/_trace" %>
18
+
19
+ <% if @routes_inspector %>
20
+ <h2>
21
+ Routes
22
+ </h2>
23
+
24
+ <p>
25
+ Routes match in priority from top to bottom
26
+ </p>
27
+
28
+ <%= @routes_inspector.format(ActionDispatch::Routing::HtmlTableFormatter.new(self)) %>
29
+ <% end %>
30
+ </div>
@@ -0,0 +1,11 @@
1
+ Routing Error
2
+
3
+ <%= @exception.message %>
4
+ <% unless @exception.failures.empty? %>
5
+ Failure reasons:
6
+ <% @exception.failures.each do |route, reason| %>
7
+ - <%= route.inspect.delete('\\') %></code> failed because <%= reason.downcase %>
8
+ <% end %>
9
+ <% end %>
10
+
11
+ <%= render template: "rescues/_trace", format: :text %>
@@ -0,0 +1,22 @@
1
+ <header>
2
+ <h1>
3
+ <%= @exception.original_exception.class.to_s %> in
4
+ <%= @request.parameters["controller"].camelize if @request.parameters["controller"] %>#<%= @request.parameters["action"] %>
5
+ </h1>
6
+ </header>
7
+
8
+ <div id="container">
9
+ <p>
10
+ Showing <i><%= @exception.file_name %></i> where line <b>#<%= @exception.line_number %></b> raised:
11
+ </p>
12
+ <pre><code><%= h @exception.message %></code></pre>
13
+
14
+ <%= render template: "rescues/_source" %>
15
+
16
+ <p><%= @exception.sub_template_message %></p>
17
+
18
+ <%= render template: "rescues/_trace" %>
19
+ <%= render template: "rescues/_request_and_response" %>
20
+ </div>
21
+
22
+ <%= render template: "rescues/_web_console" %>
@@ -0,0 +1,8 @@
1
+ <% @source_extract = @exception.source_extract(0, :html) %>
2
+ <%= @exception.original_exception.class.to_s %> in <%= @request.parameters["controller"].camelize if @request.parameters["controller"] %>#<%= @request.parameters["action"] %>
3
+
4
+ Showing <%= @exception.file_name %> where line #<%= @exception.line_number %> raised:
5
+ <%= @exception.message %>
6
+ <%= @exception.sub_template_message %>
7
+ <%= render template: "rescues/_trace", format: :text %>
8
+ <%= render template: "rescues/_request_and_response", format: :text %>
@@ -0,0 +1,6 @@
1
+ <header>
2
+ <h1>Unknown action</h1>
3
+ </header>
4
+ <div id="container">
5
+ <h2><%= h @exception.message %></h2>
6
+ </div>
@@ -0,0 +1,3 @@
1
+ Unknown action
2
+
3
+ <%= @exception.message %>
@@ -1,13 +1,23 @@
1
1
  require 'active_support/lazy_load_hooks'
2
- require 'web_console/engine'
3
- require 'web_console/colors'
4
- require 'web_console/slave'
2
+ require 'web_console/repl'
3
+ require 'web_console/repl_session'
4
+ require 'action_dispatch/exception_wrapper'
5
+ require 'action_dispatch/debug_exceptions'
5
6
 
6
7
  module WebConsole
7
- # Shortcut the +WebConsole::Engine.config.web_console+.
8
- def self.config
9
- Engine.config.web_console
8
+ class << self
9
+ attr_accessor :binding_of_caller_available
10
+
11
+ alias_method :binding_of_caller_available?, :binding_of_caller_available
10
12
  end
13
+ end
11
14
 
12
- ActiveSupport.run_load_hooks(:web_console, self)
15
+ begin
16
+ require 'binding_of_caller'
17
+ WebConsole.binding_of_caller_available = true
18
+ rescue LoadError => e
19
+ WebConsole.binding_of_caller_available = false
13
20
  end
21
+
22
+ require 'web_console/exception_extension'
23
+ require 'web_console/railtie'
@@ -0,0 +1,22 @@
1
+ class Exception
2
+ original_set_backtrace = instance_method(:set_backtrace)
3
+
4
+ if WebConsole.binding_of_caller_available?
5
+ define_method :set_backtrace do |*args|
6
+ unless Thread.current[:__web_console_exception_lock]
7
+ Thread.current[:__web_console_exception_lock] = true
8
+ begin
9
+ @__web_console_bindings_stack = binding.callers.drop(1)
10
+ ensure
11
+ Thread.current[:__web_console_exception_lock] = false
12
+ end
13
+ end
14
+
15
+ original_set_backtrace.bind(self).call(*args)
16
+ end
17
+ end
18
+
19
+ def __web_console_bindings_stack
20
+ @__web_console_bindings_stack || []
21
+ end
22
+ end
@@ -0,0 +1,15 @@
1
+ require "web_console/view_helpers"
2
+
3
+ module WebConsole
4
+ class Railtie < Rails::Railtie
5
+ initializer "web_console.view_helpers" do
6
+ ActiveSupport.on_load :action_view do
7
+ include WebConsole::ViewHelpers
8
+ end
9
+
10
+ ActiveSupport.on_load :action_controller do
11
+ prepend_view_path File.dirname(__FILE__) + '/../action_dispatch/templates'
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,24 @@
1
+ module WebConsole
2
+ # Simple REPL implementation.
3
+ # It uses @binding.eval for code evaluation.
4
+ # No styling or console configurations is supported.
5
+ class REPL
6
+ attr_accessor :binding
7
+
8
+ def initialize(binding = TOPLEVEL_BINDING)
9
+ @binding = binding
10
+ end
11
+
12
+ def prompt
13
+ '>> '
14
+ end
15
+
16
+ def send_input(input)
17
+ eval_result = nil
18
+ eval_result = @binding.eval(input).inspect
19
+ "=> #{eval_result}\n"
20
+ rescue Exception => exc
21
+ "!! #{exc.inspect rescue exc.class.to_s rescue "Exception"}\n"
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,90 @@
1
+ module WebConsole
2
+ class REPLSession
3
+ include ActiveModel::Serializers::JSON
4
+
5
+ INMEMORY_STORAGE = {}
6
+
7
+ ATTRIBUTES = [ :id, :input, :output, :prompt, :binding, :binding_stack ].each do |attr|
8
+ attr_accessor attr
9
+ end
10
+
11
+ class NotFound < StandardError
12
+ def to_json(*)
13
+ { error: message }.to_json
14
+ end
15
+ end
16
+
17
+ class << self
18
+ # Finds a session by its id.
19
+ def find(id)
20
+ INMEMORY_STORAGE[id.to_i] or raise NotFound.new('Session unavailable')
21
+ end
22
+
23
+ # Creates an already persisted consolse session.
24
+ #
25
+ # Use this method if you need to persist a session, without providing it
26
+ # any input.
27
+ def create(attributes = {})
28
+ INMEMORY_STORAGE[(model = new(attributes)).id] = model
29
+ end
30
+ end
31
+
32
+ def initialize(attributes = {})
33
+ self.attributes = attributes
34
+ ensure_consequential_id!
35
+ populate_repl_attributes!(initial: true)
36
+ end
37
+
38
+ def binding=(binding)
39
+ @binding = binding
40
+ @repl = WebConsole::REPL.new binding
41
+ end
42
+
43
+ # Saves the model into the in-memory storage.
44
+ #
45
+ # Returns false if the model is not valid (e.g. its missing input).
46
+ def save(attributes = {})
47
+ self.attributes = attributes if attributes.present?
48
+ populate_repl_attributes!
49
+ store!
50
+ end
51
+
52
+ # Returns true if the current session is persisted in the in-memory storage.
53
+ def persisted?
54
+ self == INMEMORY_STORAGE[id]
55
+ end
56
+
57
+ protected
58
+ # Returns a hash of the attributes and their values.
59
+ def attributes
60
+ return Hash[ATTRIBUTES.zip([nil])]
61
+ end
62
+
63
+ # Sets model attributes from a hash.
64
+ def attributes=(attributes)
65
+ attributes.each do |attr, value|
66
+ next unless ATTRIBUTES.include?(attr.to_sym)
67
+ public_send(:"#{attr}=", value)
68
+ end
69
+ end
70
+
71
+ private
72
+ def ensure_consequential_id!
73
+ self.id = begin
74
+ @@counter ||= 0
75
+ @@counter += 1
76
+ end
77
+ end
78
+
79
+ def populate_repl_attributes!(options = {})
80
+ # Don't send any input on the initial population so we don't bump up
81
+ # the numbers in the dynamic prompts.
82
+ self.output = @repl.send_input(input) unless options[:initial]
83
+ self.prompt = @repl.prompt
84
+ end
85
+
86
+ def store!
87
+ INMEMORY_STORAGE[id] = self
88
+ end
89
+ end
90
+ end