web-console 1.0.4 → 2.0.0.beta1

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 (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