code_buddy 0.0.8 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +17 -5
- data/lib/code_buddy/app.rb +16 -11
- data/lib/code_buddy/middleware.rb +5 -3
- data/lib/code_buddy/public/javascripts/code_buddy.js +35 -30
- data/lib/code_buddy/rails2/monkey_patch_action_controller.rb +0 -1
- data/lib/code_buddy/rails3/railtie.rb +2 -3
- data/lib/code_buddy/stack_frame.rb +9 -5
- data/lib/code_buddy/version.rb +1 -1
- data/lib/code_buddy/views/banner.erb +3 -1
- data/lib/code_buddy/views/index.erb +1 -1
- metadata +6 -7
- data/lib/code_buddy/views/form.erb +0 -13
data/README.rdoc
CHANGED
@@ -2,9 +2,17 @@
|
|
2
2
|
|
3
3
|
CodeBuddy makes it easy for you to understand the code behind each line of a Ruby exception stack. When something goes wrong during development and you get an exception do you read through the stack trace and start opening files in VIM or TextMate? With CodeBuddy the stack trace and source files are all available in your browser making it easy to understand what's going on.
|
4
4
|
|
5
|
+
{See a Live Demo of CodeBuddy}[http://www.alexrothenberg.com/examples/code_buddy/]
|
6
|
+
|
5
7
|
== Use it in your Rails app
|
6
8
|
|
7
|
-
|
9
|
+
Follow the instructions below to add CodeBuddy to your Rails 3 or Rails 2 app then the Rails exception page just got better.
|
10
|
+
|
11
|
+
Make sure you've set the config setting config.consider_all_requests_local=true (it should already be that way in development.rb). Now whenever you see a exception page you'll be able to click on the stack and see it inside CodeBuddy.
|
12
|
+
|
13
|
+
=== Rails 3
|
14
|
+
|
15
|
+
Add one line to your app's Gemfile.
|
8
16
|
|
9
17
|
gem 'code_buddy'
|
10
18
|
|
@@ -12,13 +20,17 @@ And install it:
|
|
12
20
|
|
13
21
|
$ bundle install
|
14
22
|
|
15
|
-
|
23
|
+
=== Rails 2
|
24
|
+
|
25
|
+
Add these two lines to your environment.rb
|
26
|
+
|
27
|
+
config.gem 'code_buddy'
|
28
|
+
config.middleware.use "CodeBuddy::ShowApp"
|
16
29
|
|
17
|
-
== Run as a
|
30
|
+
== Run as a standalone app
|
18
31
|
|
19
32
|
$ gem install code_buddy
|
20
|
-
$ code_buddy
|
21
|
-
== Sinatra/1.1.0 has taken the stage on 4567 for development with backup from Mongrel
|
33
|
+
$ code_buddy start
|
22
34
|
|
23
35
|
Now open http://localhost:4567 and paste your stack.
|
24
36
|
|
data/lib/code_buddy/app.rb
CHANGED
@@ -2,7 +2,7 @@ module CodeBuddy
|
|
2
2
|
class App < Sinatra::Base
|
3
3
|
set :views, File.expand_path(File.dirname(__FILE__) + '/views')
|
4
4
|
set :public, File.expand_path(File.dirname(__FILE__) + '/public')
|
5
|
-
|
5
|
+
|
6
6
|
class << self
|
7
7
|
attr_reader :stack
|
8
8
|
attr_accessor :path_prefix
|
@@ -20,15 +20,6 @@ module CodeBuddy
|
|
20
20
|
redirect "#{path_prefix}/stack"
|
21
21
|
end
|
22
22
|
|
23
|
-
get '/new' do
|
24
|
-
erb :form
|
25
|
-
end
|
26
|
-
|
27
|
-
post '/new' do
|
28
|
-
self.class.stack_string = params[:stack]
|
29
|
-
redirect "#{path_prefix}/stack"
|
30
|
-
end
|
31
|
-
|
32
23
|
get '/stack' do
|
33
24
|
display_stack(0)
|
34
25
|
end
|
@@ -38,7 +29,16 @@ module CodeBuddy
|
|
38
29
|
display_stack(params[:selected].to_i)
|
39
30
|
end
|
40
31
|
|
32
|
+
post '/new' do
|
33
|
+
return 'Sorry CodeBuddy cannot paste a stack unless CodeBuddy is running locally. This is for your own safety.' unless local_request?
|
34
|
+
|
35
|
+
self.class.stack_string = params[:stack]
|
36
|
+
redirect "#{path_prefix}/stack"
|
37
|
+
end
|
38
|
+
|
41
39
|
get '/edit/:selected' do
|
40
|
+
return "Sorry CodeBuddy cannot edit a file unless CodeBuddy is running locally" unless local_request?
|
41
|
+
|
42
42
|
self.class.stack.edit(params[:selected].to_i)
|
43
43
|
end
|
44
44
|
|
@@ -49,8 +49,13 @@ module CodeBuddy
|
|
49
49
|
end
|
50
50
|
|
51
51
|
def path_prefix
|
52
|
-
self.class.path_prefix
|
52
|
+
self.class.path_prefix
|
53
|
+
end
|
54
|
+
|
55
|
+
def local_request?
|
56
|
+
request.ip == '127.0.0.1'
|
53
57
|
end
|
54
58
|
|
59
|
+
|
55
60
|
end
|
56
61
|
end
|
@@ -2,12 +2,14 @@ module CodeBuddy
|
|
2
2
|
class ShowApp
|
3
3
|
def initialize(app)
|
4
4
|
@app = app
|
5
|
+
|
6
|
+
CodeBuddy::App.path_prefix = '/code_buddy'
|
5
7
|
end
|
6
8
|
|
7
9
|
def call(env)
|
8
|
-
if env['PATH_INFO'] =~ /^\/code_buddy(.*)/
|
9
|
-
env['PATH_INFO'] = $1
|
10
|
-
App.new.call(env)
|
10
|
+
if env['PATH_INFO'] =~ /^\/code_buddy(.*)/
|
11
|
+
env['PATH_INFO'] = $1 #strip the code_buddy/ prefix
|
12
|
+
CodeBuddy::App.new.call(env)
|
11
13
|
else
|
12
14
|
@app.call(env)
|
13
15
|
end
|
@@ -10,7 +10,7 @@ CodeBuddy.backbone.Address = Backbone.Model.extend({
|
|
10
10
|
|
11
11
|
CodeBuddy.backbone.Addresses = Backbone.Collection.extend({
|
12
12
|
model:CodeBuddy.backbone.Address,
|
13
|
-
|
13
|
+
|
14
14
|
bookmarked: function() {
|
15
15
|
return this.select(function(address){
|
16
16
|
return address.get('bookmarked');
|
@@ -23,7 +23,7 @@ CodeBuddy.backbone.Stack = Backbone.Model.extend({
|
|
23
23
|
_.bindAll(this, 'toggleBookmark', 'selectNextBookmark')
|
24
24
|
this.bind('change:selected', this.selectionChanged);
|
25
25
|
this.set({
|
26
|
-
addresses: new CodeBuddy.backbone.Addresses(this.get('stack_frames'))
|
26
|
+
addresses: new CodeBuddy.backbone.Addresses(this.get('stack_frames'))
|
27
27
|
})
|
28
28
|
},
|
29
29
|
|
@@ -32,11 +32,11 @@ CodeBuddy.backbone.Stack = Backbone.Model.extend({
|
|
32
32
|
this.set({ selected: newSelected })
|
33
33
|
}
|
34
34
|
},
|
35
|
-
|
35
|
+
|
36
36
|
selectPrevious: function() {
|
37
37
|
this.setSelection(this.get('selected') - 1)
|
38
38
|
},
|
39
|
-
|
39
|
+
|
40
40
|
selectNext: function() {
|
41
41
|
this.setSelection(this.get('selected') + 1)
|
42
42
|
},
|
@@ -91,11 +91,11 @@ CodeBuddy.backbone.AddressView = Backbone.View.extend({
|
|
91
91
|
click: "open",
|
92
92
|
dblclick: "toggleBookmark"
|
93
93
|
},
|
94
|
-
|
94
|
+
|
95
95
|
open: function() {
|
96
96
|
CodeBuddy.stack.set({selected: this.model.cid.substr(1)-1});
|
97
97
|
},
|
98
|
-
|
98
|
+
|
99
99
|
toggleBookmark: function() {
|
100
100
|
this.open();
|
101
101
|
CodeBuddy.stack.toggleBookmark();
|
@@ -103,7 +103,7 @@ CodeBuddy.backbone.AddressView = Backbone.View.extend({
|
|
103
103
|
|
104
104
|
render: function() {
|
105
105
|
$(this.el).removeClass('selected bookmarked')
|
106
|
-
|
106
|
+
|
107
107
|
var html = this.template(this.model.toJSON())
|
108
108
|
|
109
109
|
$(this.el).html(html);
|
@@ -123,23 +123,23 @@ CodeBuddy.backbone.StackView = Backbone.View.extend({
|
|
123
123
|
el: $("#stack"),
|
124
124
|
|
125
125
|
initialize: function() {
|
126
|
-
_.bindAll(this, 'selectNext', 'selectPrevious')
|
126
|
+
_.bindAll(this, 'selectNext', 'selectPrevious', 'addOneAddress')
|
127
127
|
this.model.view = this;
|
128
128
|
this.model.get('addresses').each(this.addOneAddress);
|
129
129
|
},
|
130
|
-
|
130
|
+
|
131
131
|
selectPrevious: function() {
|
132
132
|
this.model.selectPrevious();
|
133
133
|
this.ensureVisibility();
|
134
134
|
return false;
|
135
135
|
},
|
136
|
-
|
136
|
+
|
137
137
|
selectNext: function() {
|
138
138
|
this.model.selectNext();
|
139
139
|
this.ensureVisibility();
|
140
140
|
return false;
|
141
141
|
},
|
142
|
-
|
142
|
+
|
143
143
|
ensureVisibility: function() {
|
144
144
|
var offset = $(CodeBuddy.stack.selectedAddress().view.el).offset()
|
145
145
|
var windowHeight = $(window).height()
|
@@ -155,48 +155,48 @@ CodeBuddy.backbone.StackView = Backbone.View.extend({
|
|
155
155
|
|
156
156
|
addOneAddress: function(address, index) {
|
157
157
|
var view = new CodeBuddy.backbone.AddressView({model: address});
|
158
|
-
this
|
158
|
+
$(this.el).append(view.render().el);
|
159
159
|
}
|
160
160
|
})
|
161
161
|
|
162
162
|
CodeBuddy.backbone.CodeView = Backbone.View.extend({
|
163
163
|
el:$("#code-viewer"),
|
164
|
-
|
164
|
+
|
165
165
|
initialize: function() {
|
166
166
|
_.bindAll(this, 'toggleCommands','increaseOpacity', 'decreaseOpacity', 'toggle')
|
167
167
|
this.code = this.$("#code")
|
168
168
|
this.current = this.$("#current")
|
169
169
|
this.opacity = parseFloat(this.el.css("opacity"))
|
170
170
|
},
|
171
|
-
|
171
|
+
|
172
172
|
render: function() {
|
173
173
|
this.current.html('<div>' + CodeBuddy.stack.selectedAddress().get('path') + '</div>')
|
174
174
|
this.code.html(CodeBuddy.stack.selectedAddress().get('code'))
|
175
175
|
},
|
176
|
-
|
176
|
+
|
177
177
|
toggleCommands: function() {
|
178
178
|
this.$("#legend").toggle()
|
179
179
|
},
|
180
|
-
|
180
|
+
|
181
181
|
toggle: function() {
|
182
|
-
|
182
|
+
this.el.toggle()
|
183
183
|
},
|
184
184
|
|
185
185
|
editCode: function() {
|
186
|
-
|
186
|
+
$.get('../edit/' + CodeBuddy.stack.get('selected'))
|
187
187
|
},
|
188
|
-
|
188
|
+
|
189
189
|
setOpacity: function(newOpacity) {
|
190
190
|
if(newOpacity < 0) newOpacity = 0;
|
191
191
|
if(newOpacity > 1) newOpacity = 1;
|
192
192
|
this.el.css("opacity", newOpacity);
|
193
193
|
this.opacity = newOpacity;
|
194
194
|
},
|
195
|
-
|
195
|
+
|
196
196
|
increaseOpacity: function() {
|
197
197
|
this.setOpacity(this.opacity + 0.1)
|
198
198
|
},
|
199
|
-
|
199
|
+
|
200
200
|
decreaseOpacity: function() {
|
201
201
|
this.setOpacity(this.opacity - 0.1)
|
202
202
|
}
|
@@ -204,22 +204,24 @@ CodeBuddy.backbone.CodeView = Backbone.View.extend({
|
|
204
204
|
|
205
205
|
CodeBuddy.backbone.FormView = Backbone.View.extend({
|
206
206
|
el:$(".form"),
|
207
|
-
|
207
|
+
|
208
208
|
initialize: function() {
|
209
209
|
_.bindAll(this, 'show', 'hide')
|
210
210
|
this.el.find('textarea').bind('keydown', 'esc', this.hide)
|
211
211
|
},
|
212
|
-
|
212
|
+
|
213
213
|
show: function(){
|
214
214
|
this.el.show();
|
215
|
-
|
215
|
+
CodeBuddy.codeView.el.hide()
|
216
|
+
CodeBuddy.stackView.el.hide()
|
216
217
|
this.el.find("textarea").focus()
|
217
218
|
return false;
|
218
219
|
},
|
219
|
-
|
220
|
+
|
220
221
|
hide: function(){
|
221
222
|
this.el.hide();
|
222
|
-
|
223
|
+
CodeBuddy.codeView.el.show()
|
224
|
+
CodeBuddy.stackView.el.show()
|
223
225
|
return false;
|
224
226
|
}
|
225
227
|
})
|
@@ -242,11 +244,11 @@ CodeBuddy.setGlobalKeyBindings = function(){
|
|
242
244
|
|
243
245
|
CodeBuddy.setup = function(stackJson) {
|
244
246
|
CodeBuddy.form = new CodeBuddy.backbone.FormView
|
245
|
-
|
247
|
+
|
248
|
+
this.stack = new this.backbone.Stack(stackJson);
|
249
|
+
this.stackView = new this.backbone.StackView({model: this.stack});
|
250
|
+
this.codeView = new this.backbone.CodeView();
|
246
251
|
if(stackJson) {
|
247
|
-
this.stack = new this.backbone.Stack(stackJson);
|
248
|
-
this.stackView = new this.backbone.StackView({model: this.stack});
|
249
|
-
this.codeView = new this.backbone.CodeView();
|
250
252
|
this.codeView.render();
|
251
253
|
this.setStackKeyBindings();
|
252
254
|
CodeBuddy.form.hide()
|
@@ -254,4 +256,7 @@ CodeBuddy.setup = function(stackJson) {
|
|
254
256
|
CodeBuddy.form.show()
|
255
257
|
}
|
256
258
|
CodeBuddy.setGlobalKeyBindings()
|
259
|
+
$('#new_stack').click(function(){
|
260
|
+
CodeBuddy.form.show()
|
261
|
+
})
|
257
262
|
}
|
@@ -2,11 +2,10 @@ module CodeBuddy
|
|
2
2
|
class Railtie < Rails::Railtie
|
3
3
|
initializer "code_buddy.add_middleware" do |app|
|
4
4
|
if app.config.action_dispatch.show_exceptions
|
5
|
-
app.middleware.swap
|
5
|
+
app.middleware.swap ActionDispatch::ShowExceptions, CodeBuddy::ShowExceptions, app.config.consider_all_requests_local
|
6
6
|
app.middleware.insert_before CodeBuddy::ShowExceptions, CodeBuddy::ShowApp
|
7
7
|
end
|
8
8
|
end
|
9
|
-
CodeBuddy::App.path_prefix = '/code_buddy'
|
10
9
|
end
|
11
10
|
|
12
11
|
class ShowExceptions < ActionDispatch::ShowExceptions
|
@@ -16,7 +15,7 @@ module CodeBuddy
|
|
16
15
|
end
|
17
16
|
|
18
17
|
def rescue_action_locally(request, exception)
|
19
|
-
App.exception = exception
|
18
|
+
CodeBuddy::App.exception = exception
|
20
19
|
super
|
21
20
|
end
|
22
21
|
end
|
@@ -39,15 +39,19 @@ module CodeBuddy
|
|
39
39
|
"<span class=\"coderay\">Unable to read file:\n \"#{@path}\"</span>"
|
40
40
|
end
|
41
41
|
end
|
42
|
-
|
42
|
+
|
43
|
+
# different syntaxes for opening to a line number for different editors
|
43
44
|
def open_in_editor
|
44
|
-
|
45
|
+
editor = ENV['CODE_BUDDY_EDITOR'] || ENV['EDITOR']
|
46
|
+
case editor
|
45
47
|
when 'mate'
|
46
48
|
`mate #{path} -l #{line}`
|
47
|
-
when
|
48
|
-
|
49
|
+
when /(mvim|emacsclient)/
|
50
|
+
`#{$1} +#{line} #{path}`
|
51
|
+
when 'netbeans'
|
52
|
+
`netbeans #{path}:#{line}`
|
49
53
|
else
|
50
|
-
puts "Sorry unable to open the file for editing. Please set your environment variable to either mate or mvim 'export
|
54
|
+
puts "Sorry unable to open the file for editing. Please set your environment variable to either mate or mvim 'export CODE_BUDDY_EDITOR=mate' and restart the server"
|
51
55
|
end
|
52
56
|
end
|
53
57
|
end
|
data/lib/code_buddy/version.rb
CHANGED
@@ -2,5 +2,7 @@
|
|
2
2
|
<div class="item"><img src="<%= @static_file_prefix %>images/buddy.jpeg" class="buddy"/></div>
|
3
3
|
<div class="item"><span class="title">CodeBuddy</span><br/>See your Ruby stack come alive</div>
|
4
4
|
<div class="link"><a href="http://github.com/patshaughnessy/code_buddy">about</a></div>
|
5
|
-
|
5
|
+
<% if local_request? %>
|
6
|
+
<div class="link"><a href="#" id='new_stack'>paste stack</a></div>
|
7
|
+
<% end %>
|
6
8
|
</div>
|
@@ -4,7 +4,7 @@
|
|
4
4
|
<%= erb :banner %>
|
5
5
|
<div class="form">
|
6
6
|
Paste your stack:
|
7
|
-
<form method="post" action="
|
7
|
+
<form method="post" action="<%= @static_file_prefix %>new">
|
8
8
|
<textarea name="stack" rows="40" cols="130" class="stack_form"></textarea><br/>
|
9
9
|
<input type="submit" value="submit"/>
|
10
10
|
</form>
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: code_buddy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
5
|
-
prerelease:
|
4
|
+
hash: 27
|
5
|
+
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
+
- 1
|
8
9
|
- 0
|
9
|
-
|
10
|
-
version: 0.0.8
|
10
|
+
version: 0.1.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Pat Shaughnessy, Alex Rothenberg, Daniel Higginbotham
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
18
|
+
date: 2011-03-11 00:00:00 -05:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -269,7 +269,6 @@ files:
|
|
269
269
|
- lib/code_buddy/stack_frame.rb
|
270
270
|
- lib/code_buddy/version.rb
|
271
271
|
- lib/code_buddy/views/banner.erb
|
272
|
-
- lib/code_buddy/views/form.erb
|
273
272
|
- lib/code_buddy/views/header.erb
|
274
273
|
- lib/code_buddy/views/index.erb
|
275
274
|
- spec/app_spec.rb
|
@@ -307,7 +306,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
307
306
|
requirements: []
|
308
307
|
|
309
308
|
rubyforge_project: code_buddy
|
310
|
-
rubygems_version: 1.
|
309
|
+
rubygems_version: 1.5.0
|
311
310
|
signing_key:
|
312
311
|
specification_version: 3
|
313
312
|
summary: See the Ruby code running in your app.
|
@@ -1,13 +0,0 @@
|
|
1
|
-
<html>
|
2
|
-
<%= erb :header %>
|
3
|
-
<body>
|
4
|
-
<%= erb :banner %>
|
5
|
-
<div class="form">
|
6
|
-
Paste your stack:
|
7
|
-
<form method="post" action="/new">
|
8
|
-
<textarea name="stack" rows="40" cols="130" class="stack_form"></textarea><br/>
|
9
|
-
<input type="submit" value="submit"/>
|
10
|
-
</form>
|
11
|
-
</div>
|
12
|
-
</body>
|
13
|
-
</html>
|