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.
@@ -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
- Simply add one line to your app's Gemfile and the Rails exception page just got better.
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
- Now when you're running in development (or any environment with config.consider_all_requests_local=true) whenever you see a exception page you'll be able to click on the stack and see it inside CodeBuddy.
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 Sinatra app
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
 
@@ -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(.*)/ #&& Rails.env.development?
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.$("#stack").append(view.render().el);
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
- this.el.toggle()
182
+ this.el.toggle()
183
183
  },
184
184
 
185
185
  editCode: function() {
186
- $.get('../edit/' + CodeBuddy.stack.get('selected'))
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
- $("#code-viewer").hide()
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
- $("#code-viewer").show()
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
  }
@@ -18,4 +18,3 @@ module ActionController
18
18
  end
19
19
  end
20
20
 
21
- CodeBuddy::App.path_prefix = '/code_buddy'
@@ -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 ActionDispatch::ShowExceptions, CodeBuddy::ShowExceptions
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&nbsp;\"#{@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
- case ENV['EDITOR']
45
+ editor = ENV['CODE_BUDDY_EDITOR'] || ENV['EDITOR']
46
+ case editor
45
47
  when 'mate'
46
48
  `mate #{path} -l #{line}`
47
- when 'mvim'
48
- `mvim +#{line} #{path}`
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 EDITOR=mate' and restart the server"
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
@@ -1,3 +1,3 @@
1
1
  module CodeBuddy
2
- VERSION = '0.0.8'
2
+ VERSION = '0.1.0'
3
3
  end
@@ -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
- <div class="link"><a href="<%= @static_file_prefix %>new">paste stack</a></div>
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="/new">
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: 15
5
- prerelease: false
4
+ hash: 27
5
+ prerelease:
6
6
  segments:
7
7
  - 0
8
+ - 1
8
9
  - 0
9
- - 8
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-01-11 00:00:00 -05:00
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.3.7
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>