rails 0.9.4.1 → 0.9.5
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of rails might be problematic. Click here for more details.
- data/CHANGELOG +21 -0
- data/Rakefile +6 -4
- data/fresh_rakefile +38 -26
- data/generators/scaffold/scaffold_generator.rb +8 -8
- data/generators/scaffold/templates/functional_test.rb +4 -4
- data/lib/binding_of_caller.rb +83 -85
- data/lib/breakpoint.rb +41 -48
- data/lib/breakpoint_client.rb +114 -93
- data/lib/dispatcher.rb +11 -19
- metadata +4 -4
data/CHANGELOG
CHANGED
@@ -1,3 +1,24 @@
|
|
1
|
+
*0.9.5* (January 25th, 2005)
|
2
|
+
|
3
|
+
* Fixed dependency reloading by switching to a remove_const approach where all Active Records, Active Record Observers, and Action Controllers are reloading by undefining their classes. This enables you to remove methods in all three types and see the change reflected immediately and it fixes #539. This also means that only those three types of classes will benefit from the const_missing and reloading approach. If you want other classes (like some in lib/) to reload, you must use require_dependency to do it.
|
4
|
+
|
5
|
+
* Added Florian Gross' latest version of Breakpointer and friends that fixes a variaty of bugs #441 [Florian Gross]
|
6
|
+
|
7
|
+
* Fixed skeleton Rakefile to work with sqlite3 out of the box #521 [rasputnik]
|
8
|
+
|
9
|
+
* Fixed that script/breakpointer didn't get the Ruby path rewritten as the other scripts #523 [brandt@kurowski.net]
|
10
|
+
|
11
|
+
* Fixed handling of syntax errors in models that had already been succesfully required once in the current interpreter
|
12
|
+
|
13
|
+
* Fixed that models that weren't referenced in associations weren't being reloaded in the development mode by reinstating the reload
|
14
|
+
|
15
|
+
* Fixed that generate scaffold would produce bad functional tests
|
16
|
+
|
17
|
+
* Fixed that FCGI can also display SyntaxErrors
|
18
|
+
|
19
|
+
* Upgraded to Active Record 1.6.0, Action Pack 1.4.0
|
20
|
+
|
21
|
+
|
1
22
|
*0.9.4.1* (January 18th, 2005)
|
2
23
|
|
3
24
|
* Added 5-second timeout to WordNet alternatives on creating reserved-word models #501 [Marcel Molina]
|
data/Rakefile
CHANGED
@@ -9,7 +9,7 @@ require 'rbconfig'
|
|
9
9
|
|
10
10
|
PKG_BUILD = ENV['PKG_BUILD'] ? '.' + ENV['PKG_BUILD'] : ''
|
11
11
|
PKG_NAME = 'rails'
|
12
|
-
PKG_VERSION = '0.9.
|
12
|
+
PKG_VERSION = '0.9.5' + PKG_BUILD
|
13
13
|
PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
|
14
14
|
PKG_DESTINATION = ENV["RAILS_PKG_DESTINATION"] || "../#{PKG_NAME}"
|
15
15
|
|
@@ -218,7 +218,9 @@ end
|
|
218
218
|
|
219
219
|
task :copy_gem_environment do
|
220
220
|
cp "environments/shared_for_gem.rb", "#{PKG_DESTINATION}/config/environment.rb"
|
221
|
-
|
221
|
+
dest_file = File.join(PKG_DESTINATION, 'script', 'breakpointer')
|
222
|
+
copy_with_rewritten_ruby_path(File.join('bin', 'breakpointer_for_gem'), dest_file)
|
223
|
+
chmod 0755, dest_file
|
222
224
|
end
|
223
225
|
|
224
226
|
|
@@ -245,8 +247,8 @@ spec = Gem::Specification.new do |s|
|
|
245
247
|
EOF
|
246
248
|
|
247
249
|
s.add_dependency('rake', '>= 0.4.15')
|
248
|
-
s.add_dependency('activerecord', '>= 1.
|
249
|
-
s.add_dependency('actionpack', '>= 1.
|
250
|
+
s.add_dependency('activerecord', '>= 1.6.0')
|
251
|
+
s.add_dependency('actionpack', '>= 1.4.0')
|
250
252
|
s.add_dependency('actionmailer', '>= 0.6.1')
|
251
253
|
|
252
254
|
s.has_rdoc = false
|
data/fresh_rakefile
CHANGED
@@ -73,40 +73,52 @@ end
|
|
73
73
|
|
74
74
|
desc "Recreate the test databases from the development structure"
|
75
75
|
task :clone_structure_to_test => [ :db_structure_dump, :purge_test_database ] do
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
ActiveRecord::Base.connection.execute(
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
76
|
+
abcs = ActiveRecord::Base.configurations
|
77
|
+
case abcs["test"]["adapter"]
|
78
|
+
when "mysql"
|
79
|
+
ActiveRecord::Base.establish_connection(:test)
|
80
|
+
ActiveRecord::Base.connection.execute('SET foreign_key_checks = 0')
|
81
|
+
IO.readlines("db/#{RAILS_ENV}_structure.sql").join.split("\n\n").each do |table|
|
82
|
+
ActiveRecord::Base.connection.execute(table)
|
83
|
+
end
|
84
|
+
when "postgresql"
|
85
|
+
`psql -U #{abcs["test"]["username"]} -f db/#{RAILS_ENV}_structure.sql #{abcs["test"]["database"]}`
|
86
|
+
when "sqlite", "sqlite3"
|
87
|
+
`#{abcs[RAILS_ENV]["adapter"]} #{abcs["test"]["dbfile"]} < db/#{RAILS_ENV}_structure.sql`
|
88
|
+
else
|
89
|
+
raise "Unknown database adapter '#{abcs["test"]["adapter"]}'"
|
86
90
|
end
|
87
91
|
end
|
88
92
|
|
89
93
|
desc "Dump the database structure to a SQL file"
|
90
94
|
task :db_structure_dump do
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
95
|
+
abcs = ActiveRecord::Base.configurations
|
96
|
+
case abcs[RAILS_ENV]["adapter"]
|
97
|
+
when "mysql"
|
98
|
+
ActiveRecord::Base.establish_connection(abcs[RAILS_ENV])
|
99
|
+
File.open("db/#{RAILS_ENV}_structure.sql", "w+") { |f| f << ActiveRecord::Base.connection.structure_dump }
|
100
|
+
when "postgresql"
|
101
|
+
`pg_dump -U #{abcs[RAILS_ENV]["username"]} -s -f db/#{RAILS_ENV}_structure.sql #{abcs[RAILS_ENV]["database"]}`
|
102
|
+
when "sqlite", "sqlite3"
|
103
|
+
`#{abcs[RAILS_ENV]["adapter"]} #{abcs[RAILS_ENV]["dbfile"]} .schema > db/#{RAILS_ENV}_structure.sql`
|
104
|
+
else
|
105
|
+
raise "Unknown database adapter '#{abcs["test"]["adapter"]}'"
|
98
106
|
end
|
99
107
|
end
|
100
108
|
|
101
|
-
desc "
|
109
|
+
desc "Empty the test database"
|
102
110
|
task :purge_test_database do
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
+
abcs = ActiveRecord::Base.configurations
|
112
|
+
case abcs["test"]["adapter"]
|
113
|
+
when "mysql"
|
114
|
+
ActiveRecord::Base.establish_connection(abcs[RAILS_ENV])
|
115
|
+
ActiveRecord::Base.connection.recreate_database(abcs["test"]["database"])
|
116
|
+
when "postgresql"
|
117
|
+
`dropdb -U #{abcs["test"]["username"]} #{abcs["test"]["database"]}`
|
118
|
+
`createdb -U #{abcs["test"]["username"]} #{abcs["test"]["database"]}`
|
119
|
+
when "sqlite","sqlite3"
|
120
|
+
File.delete(abcs["test"]["dbfile"]) if File.exist?(abcs["test"]["dbfile"])
|
121
|
+
else
|
122
|
+
raise "Unknown database adapter '#{abcs["test"]["adapter"]}'"
|
111
123
|
end
|
112
124
|
end
|
@@ -9,16 +9,16 @@ class ScaffoldGenerator < Rails::Generator::Base
|
|
9
9
|
template "fixtures.yml", "test/fixtures/#{table_name}.yml"
|
10
10
|
|
11
11
|
@controller_class_name = args.empty? ? Inflector.pluralize(class_name) : args.shift.sub(/^[a-z]?/) { |m| m.capitalize }
|
12
|
-
controller_name = Inflector.underscore(@controller_class_name)
|
12
|
+
@controller_name = Inflector.underscore(@controller_class_name)
|
13
13
|
|
14
14
|
# Controller class, functional test, helper, and views.
|
15
|
-
template "controller.rb", "app/controllers/#{controller_name}_controller.rb"
|
16
|
-
template "functional_test.rb", "test/functional/#{controller_name}_controller_test.rb"
|
17
|
-
template "controller/helper.rb", "app/helpers/#{controller_name}_helper.rb"
|
15
|
+
template "controller.rb", "app/controllers/#{@controller_name}_controller.rb"
|
16
|
+
template "functional_test.rb", "test/functional/#{@controller_name}_controller_test.rb"
|
17
|
+
template "controller/helper.rb", "app/helpers/#{@controller_name}_helper.rb"
|
18
18
|
|
19
19
|
# Layout and stylesheet.
|
20
|
-
unless File.file?("app/views/layouts/#{controller_name}.rhtml")
|
21
|
-
template "layout.rhtml", "app/views/layouts/#{controller_name}.rhtml"
|
20
|
+
unless File.file?("app/views/layouts/#{@controller_name}.rhtml")
|
21
|
+
template "layout.rhtml", "app/views/layouts/#{@controller_name}.rhtml"
|
22
22
|
end
|
23
23
|
unless File.file?("public/stylesheets/scaffold.css")
|
24
24
|
template "style.css", "public/stylesheets/scaffold.css"
|
@@ -26,13 +26,13 @@ class ScaffoldGenerator < Rails::Generator::Base
|
|
26
26
|
|
27
27
|
# Scaffolded views.
|
28
28
|
scaffold_views.each do |action|
|
29
|
-
template "view_#{action}.rhtml", "app/views/#{controller_name}/#{action}.rhtml"
|
29
|
+
template "view_#{action}.rhtml", "app/views/#{@controller_name}/#{action}.rhtml"
|
30
30
|
end
|
31
31
|
|
32
32
|
# Unscaffolded views.
|
33
33
|
unscaffolded_actions.each do |action|
|
34
34
|
template "controller/view.rhtml",
|
35
|
-
"app/views/#{controller_name}/#{action}.rhtml",
|
35
|
+
"app/views/#{@controller_name}/#{action}.rhtml",
|
36
36
|
binding
|
37
37
|
end
|
38
38
|
end
|
@@ -1,14 +1,14 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
-
require '<%=
|
2
|
+
require '<%= @controller_name %>_controller'
|
3
3
|
|
4
4
|
# Re-raise errors caught by the controller.
|
5
|
-
class <%=
|
5
|
+
class <%= @controller_class_name %>Controller; def rescue_action(e) raise e end; end
|
6
6
|
|
7
|
-
class <%=
|
7
|
+
class <%= @controller_class_name %>ControllerTest < Test::Unit::TestCase
|
8
8
|
fixtures :<%= table_name %>
|
9
9
|
|
10
10
|
def setup
|
11
|
-
@controller = <%=
|
11
|
+
@controller = <%= @controller_class_name %>Controller.new
|
12
12
|
@request, @response = ActionController::TestRequest.new, ActionController::TestResponse.new
|
13
13
|
end
|
14
14
|
|
data/lib/binding_of_caller.rb
CHANGED
@@ -1,85 +1,83 @@
|
|
1
|
-
begin
|
2
|
-
require 'simplecc'
|
3
|
-
rescue LoadError
|
4
|
-
class Continuation
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
if
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
end
|
85
|
-
end
|
1
|
+
begin
|
2
|
+
require 'simplecc'
|
3
|
+
rescue LoadError
|
4
|
+
class Continuation; end # :nodoc: # for RDoc
|
5
|
+
def Continuation.create(*args, &block) # :nodoc:
|
6
|
+
cc = nil; result = callcc {|c| cc = c; block.call(cc) if block and args.empty?}
|
7
|
+
result ||= args
|
8
|
+
return *[cc, *result]
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class Binding; end # for RDoc
|
13
|
+
# This method returns the binding of the method that called your
|
14
|
+
# method. It will raise an Exception when you're not inside a method.
|
15
|
+
#
|
16
|
+
# It's used like this:
|
17
|
+
# def inc_counter(amount = 1)
|
18
|
+
# Binding.of_caller do |binding|
|
19
|
+
# # Create a lambda that will increase the variable 'counter'
|
20
|
+
# # in the caller of this method when called.
|
21
|
+
# inc = eval("lambda { |arg| counter += arg }", binding)
|
22
|
+
# # We can refer to amount from inside this block safely.
|
23
|
+
# inc.call(amount)
|
24
|
+
# end
|
25
|
+
# # No other statements can go here. Put them inside the block.
|
26
|
+
# end
|
27
|
+
# counter = 0
|
28
|
+
# 2.times { inc_counter }
|
29
|
+
# counter # => 2
|
30
|
+
#
|
31
|
+
# Binding.of_caller must be the last statement in the method.
|
32
|
+
# This means that you will have to put everything you want to
|
33
|
+
# do after the call to Binding.of_caller into the block of it.
|
34
|
+
# This should be no problem however, because Ruby has closures.
|
35
|
+
# If you don't do this an Exception will be raised. Because of
|
36
|
+
# the way that Binding.of_caller is implemented it has to be
|
37
|
+
# done this way.
|
38
|
+
def Binding.of_caller(&block)
|
39
|
+
old_critical = Thread.critical
|
40
|
+
Thread.critical = true
|
41
|
+
count = 0
|
42
|
+
cc, result, error, extra_data = Continuation.create(nil, nil)
|
43
|
+
error.call if error
|
44
|
+
|
45
|
+
tracer = lambda do |*args|
|
46
|
+
type, context, extra_data = args[0], args[4], args
|
47
|
+
if type == "return"
|
48
|
+
count += 1
|
49
|
+
# First this method and then calling one will return --
|
50
|
+
# the trace event of the second event gets the context
|
51
|
+
# of the method which called the method that called this
|
52
|
+
# method.
|
53
|
+
if count == 2
|
54
|
+
# It would be nice if we could restore the trace_func
|
55
|
+
# that was set before we swapped in our own one, but
|
56
|
+
# this is impossible without overloading set_trace_func
|
57
|
+
# in current Ruby.
|
58
|
+
set_trace_func(nil)
|
59
|
+
cc.call(eval("binding", context), nil, extra_data)
|
60
|
+
end
|
61
|
+
elsif type == "line" then
|
62
|
+
nil
|
63
|
+
elsif type == "c-return" and extra_data[3] == :set_trace_func then
|
64
|
+
nil
|
65
|
+
else
|
66
|
+
set_trace_func(nil)
|
67
|
+
error_msg = "Binding.of_caller used in non-method context or " +
|
68
|
+
"trailing statements of method using it aren't in the block."
|
69
|
+
cc.call(nil, lambda { raise(ArgumentError, error_msg) }, nil)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
unless result
|
74
|
+
set_trace_func(tracer)
|
75
|
+
return nil
|
76
|
+
else
|
77
|
+
Thread.critical = old_critical
|
78
|
+
case block.arity
|
79
|
+
when 1 then yield(result)
|
80
|
+
else yield(result, extra_data)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
data/lib/breakpoint.rb
CHANGED
@@ -21,6 +21,9 @@ require 'drb'
|
|
21
21
|
require 'drb/acl'
|
22
22
|
|
23
23
|
module Breakpoint
|
24
|
+
id = %q$Id: breakpoint.rb 41 2005-01-22 20:22:10Z flgr $
|
25
|
+
Version = id.split(" ")[2].to_i
|
26
|
+
|
24
27
|
extend self
|
25
28
|
|
26
29
|
# This will pop up an interactive ruby session at a
|
@@ -114,10 +117,10 @@ module Breakpoint
|
|
114
117
|
end
|
115
118
|
end
|
116
119
|
|
117
|
-
module CommandBundle
|
120
|
+
module CommandBundle
|
118
121
|
# Proxy to a Breakpoint client. Lets you directly execute code
|
119
122
|
# in the context of the client.
|
120
|
-
class Client
|
123
|
+
class Client
|
121
124
|
def initialize(eval_handler) # :nodoc:
|
122
125
|
@eval_handler = eval_handler
|
123
126
|
end
|
@@ -133,15 +136,23 @@ module Breakpoint
|
|
133
136
|
end
|
134
137
|
|
135
138
|
# Will execute the specified statement at the client.
|
136
|
-
def method_missing(method, *args)
|
137
|
-
if args.empty?
|
138
|
-
result = eval
|
139
|
+
def method_missing(method, *args, &block)
|
140
|
+
if args.empty? and not block
|
141
|
+
result = eval "#{method}"
|
139
142
|
else
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
143
|
+
# This is a bit ugly. The alternative would be using an
|
144
|
+
# eval context instead of an eval handler for executing
|
145
|
+
# the code at the client. The problem with that approach
|
146
|
+
# is that we would have to handle special expressions
|
147
|
+
# like "self", "nil" or constants ourself which is hard.
|
148
|
+
remote = eval %{
|
149
|
+
result = lambda { |block, *args| #{method}(*args, &block) }
|
150
|
+
def result.call_with_block(*args, &block)
|
151
|
+
call(block, *args)
|
152
|
+
end
|
153
|
+
result
|
154
|
+
}
|
155
|
+
remote.call_with_block(*args, &block)
|
145
156
|
end
|
146
157
|
|
147
158
|
return result
|
@@ -175,6 +186,7 @@ module Breakpoint
|
|
175
186
|
# client.File.open("temp.txt", "w") { |f| f.puts "Hello" }
|
176
187
|
def client()
|
177
188
|
if Breakpoint.use_drb? then
|
189
|
+
sleep(0.5) until Breakpoint.drb_service.eval_handler
|
178
190
|
Client.new(Breakpoint.drb_service.eval_handler)
|
179
191
|
else
|
180
192
|
Client.new(lambda { |code| eval(code, TOPLEVEL_BINDING) })
|
@@ -205,7 +217,7 @@ module Breakpoint
|
|
205
217
|
# These exceptions will be raised on failed asserts
|
206
218
|
# if Breakpoint.asserts_cause_exceptions is set to
|
207
219
|
# true.
|
208
|
-
class FailedAssertError < RuntimeError
|
220
|
+
class FailedAssertError < RuntimeError
|
209
221
|
end
|
210
222
|
|
211
223
|
# This asserts that the block evaluates to true.
|
@@ -279,7 +291,7 @@ module Breakpoint
|
|
279
291
|
@collision_handler.call
|
280
292
|
end
|
281
293
|
|
282
|
-
def ping
|
294
|
+
def ping() end
|
283
295
|
|
284
296
|
def add_breakpoint(context, message)
|
285
297
|
workspace = IRB::WorkSpace.new(context)
|
@@ -290,31 +302,7 @@ module Breakpoint
|
|
290
302
|
@handler.call(workspace, message)
|
291
303
|
end
|
292
304
|
|
293
|
-
|
294
|
-
@handler = block
|
295
|
-
end
|
296
|
-
|
297
|
-
def unregister_handler
|
298
|
-
@handler = nil
|
299
|
-
end
|
300
|
-
|
301
|
-
attr_reader :eval_handler
|
302
|
-
|
303
|
-
def register_eval_handler(&block)
|
304
|
-
@eval_handler = block
|
305
|
-
end
|
306
|
-
|
307
|
-
def unregister_eval_handler
|
308
|
-
@eval_handler = lambda { }
|
309
|
-
end
|
310
|
-
|
311
|
-
def register_collision_handler(&block)
|
312
|
-
@collision_handler = block
|
313
|
-
end
|
314
|
-
|
315
|
-
def unregister_collision_handler
|
316
|
-
@collision_handler = lambda { }
|
317
|
-
end
|
305
|
+
attr_accessor :handler, :eval_handler, :collision_handler
|
318
306
|
end
|
319
307
|
|
320
308
|
# Will run Breakpoint in DRb mode. This will spawn a server
|
@@ -359,7 +347,8 @@ module Breakpoint
|
|
359
347
|
#
|
360
348
|
# Detailed information about running DRb through firewalls is
|
361
349
|
# available at http://www.rubygarden.org/ruby?DrbTutorial
|
362
|
-
def activate_drb(uri = nil, allowed_hosts = ['localhost', '127.0.0.1', '::1'],
|
350
|
+
def activate_drb(uri = nil, allowed_hosts = ['localhost', '127.0.0.1', '::1'],
|
351
|
+
ignore_collisions = false)
|
363
352
|
|
364
353
|
return false if @use_drb
|
365
354
|
|
@@ -402,7 +391,7 @@ module Breakpoint
|
|
402
391
|
end
|
403
392
|
|
404
393
|
# Deactivates a running Breakpoint service.
|
405
|
-
def deactivate_drb
|
394
|
+
def deactivate_drb
|
406
395
|
@service.stop_service unless @service.nil?
|
407
396
|
@service = nil
|
408
397
|
@use_drb = false
|
@@ -411,7 +400,7 @@ module Breakpoint
|
|
411
400
|
|
412
401
|
# Returns true when Breakpoints are used over DRb.
|
413
402
|
# Breakpoint.activate_drb causes this to be true.
|
414
|
-
def use_drb?
|
403
|
+
def use_drb?
|
415
404
|
@use_drb == true
|
416
405
|
end
|
417
406
|
end
|
@@ -440,7 +429,11 @@ module IRB # :nodoc:
|
|
440
429
|
@CONF[:MAIN_CONTEXT] = irb.context
|
441
430
|
|
442
431
|
old_sigint = trap("SIGINT") do
|
443
|
-
|
432
|
+
begin
|
433
|
+
irb.signal_handle
|
434
|
+
rescue RubyLex::TerminateLineInput
|
435
|
+
# ignored
|
436
|
+
end
|
444
437
|
end
|
445
438
|
|
446
439
|
catch(:IRB_EXIT) do
|
@@ -464,7 +457,7 @@ module IRB # :nodoc:
|
|
464
457
|
end
|
465
458
|
end
|
466
459
|
|
467
|
-
class Context
|
460
|
+
class Context
|
468
461
|
alias :old_evaluate :evaluate
|
469
462
|
def evaluate(line, line_no)
|
470
463
|
if line.chomp == "exit" then
|
@@ -475,7 +468,7 @@ module IRB # :nodoc:
|
|
475
468
|
end
|
476
469
|
end
|
477
470
|
|
478
|
-
class WorkSpace
|
471
|
+
class WorkSpace
|
479
472
|
alias :old_evaluate :evaluate
|
480
473
|
|
481
474
|
def evaluate(*args)
|
@@ -493,7 +486,7 @@ module IRB # :nodoc:
|
|
493
486
|
end
|
494
487
|
end
|
495
488
|
|
496
|
-
module InputCompletor
|
489
|
+
module InputCompletor
|
497
490
|
def self.eval(code, context, *more)
|
498
491
|
# Big hack, this assumes that InputCompletor
|
499
492
|
# will only call eval() when it wants code
|
@@ -504,9 +497,9 @@ module IRB # :nodoc:
|
|
504
497
|
end
|
505
498
|
|
506
499
|
module DRb # :nodoc:
|
507
|
-
class DRbObject
|
508
|
-
undef :inspect
|
509
|
-
undef :clone
|
500
|
+
class DRbObject
|
501
|
+
undef :inspect if method_defined?(:inspect)
|
502
|
+
undef :clone if method_defined?(:clone)
|
510
503
|
end
|
511
504
|
end
|
512
505
|
|
@@ -522,4 +515,4 @@ def assert(&block)
|
|
522
515
|
Binding.of_caller do |context|
|
523
516
|
Breakpoint.assert(context, &block)
|
524
517
|
end
|
525
|
-
end
|
518
|
+
end
|
data/lib/breakpoint_client.rb
CHANGED
@@ -2,17 +2,18 @@ require 'breakpoint'
|
|
2
2
|
require 'optparse'
|
3
3
|
require 'timeout'
|
4
4
|
|
5
|
-
|
5
|
+
Options = {
|
6
6
|
:ClientURI => nil,
|
7
7
|
:ServerURI => "druby://localhost:42531",
|
8
|
-
:RetryDelay =>
|
8
|
+
:RetryDelay => 3,
|
9
|
+
:Permanent => true,
|
9
10
|
:Verbose => false
|
10
11
|
}
|
11
12
|
|
12
13
|
ARGV.options do |opts|
|
13
14
|
script_name = File.basename($0)
|
14
15
|
opts.banner = [
|
15
|
-
"Usage: ruby #{script_name} [
|
16
|
+
"Usage: ruby #{script_name} [Options] [server uri]",
|
16
17
|
"",
|
17
18
|
"This tool lets you connect to a breakpoint service ",
|
18
19
|
"which was started via Breakpoint.activate_drb.",
|
@@ -29,18 +30,13 @@ ARGV.options do |opts|
|
|
29
30
|
"connections from the server.",
|
30
31
|
"Default: Find a good URI automatically.",
|
31
32
|
"Example: -c druby://localhost:12345"
|
32
|
-
) { |
|
33
|
+
) { |Options[:ClientURI]| }
|
33
34
|
|
34
35
|
opts.on("-s", "--server-uri=uri",
|
35
36
|
"Connect to the server specified at the",
|
36
37
|
"specified uri.",
|
37
38
|
"Default: druby://localhost:42531"
|
38
|
-
) { |
|
39
|
-
|
40
|
-
opts.on("-v", "--verbose",
|
41
|
-
"Report all connections and disconnections",
|
42
|
-
"Default: false"
|
43
|
-
) { |options[:Verbose]| }
|
39
|
+
) { |Options[:ServerURI]| }
|
44
40
|
|
45
41
|
opts.on("-R", "--retry-delay=delay", Integer,
|
46
42
|
"Automatically try to reconnect to the",
|
@@ -49,124 +45,149 @@ ARGV.options do |opts|
|
|
49
45
|
"A value of 0 disables automatical",
|
50
46
|
"reconnecting completely.",
|
51
47
|
"Default: 10"
|
52
|
-
) { |
|
48
|
+
) { |Options[:RetryDelay]| }
|
49
|
+
|
50
|
+
opts.on("-P", "--[no-]permanent",
|
51
|
+
"Run the breakpoint client in permanent mode.",
|
52
|
+
"This means that the client will keep continue",
|
53
|
+
"running even after the server has closed the",
|
54
|
+
"connection. Useful for example in Rails."
|
55
|
+
) { |Options[:Permanent]| }
|
56
|
+
|
57
|
+
opts.on("-V", "--[no-]verbose",
|
58
|
+
"Run the breakpoint client in verbose mode.",
|
59
|
+
"Will produce more messages, for example between",
|
60
|
+
"individual breakpoints. This might help in seeing",
|
61
|
+
"that the breakpoint client is still alive, but adds",
|
62
|
+
"quite a bit of clutter."
|
63
|
+
) { |Options[:Verbose]| }
|
53
64
|
|
54
65
|
opts.separator ""
|
55
66
|
|
56
67
|
opts.on("-h", "--help",
|
57
68
|
"Show this help message."
|
58
69
|
) { puts opts; exit }
|
70
|
+
opts.on("-v", "--version",
|
71
|
+
"Display the version information."
|
72
|
+
) do
|
73
|
+
id = %q$Id: breakpoint_client.rb 40 2005-01-22 20:05:00Z flgr $
|
74
|
+
puts id.sub("Id: ", "")
|
75
|
+
puts "(Breakpoint::Version = #{Breakpoint::Version})"
|
76
|
+
exit
|
77
|
+
end
|
59
78
|
|
60
79
|
opts.parse!
|
61
80
|
end
|
62
81
|
|
63
|
-
|
82
|
+
Options[:ServerURI] = ARGV[0] if ARGV[0]
|
64
83
|
|
65
|
-
|
84
|
+
module Handlers
|
85
|
+
extend self
|
66
86
|
|
67
|
-
|
87
|
+
def breakpoint_handler(workspace, message)
|
88
|
+
puts message
|
89
|
+
IRB.start(nil, nil, workspace)
|
90
|
+
|
91
|
+
puts ""
|
92
|
+
if Options[:Verbose] then
|
93
|
+
puts "Resumed execution. Waiting for next breakpoint...", ""
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def eval_handler(code)
|
98
|
+
result = eval(code, TOPLEVEL_BINDING)
|
99
|
+
if result then
|
100
|
+
DRbObject.new(result)
|
101
|
+
else
|
102
|
+
result
|
103
|
+
end
|
104
|
+
end
|
68
105
|
|
69
|
-
|
106
|
+
def collision_handler()
|
107
|
+
msg = [
|
108
|
+
" *** Breakpoint service collision ***",
|
109
|
+
" Another Breakpoint service tried to use the",
|
110
|
+
" port already occupied by this one. It will",
|
111
|
+
" keep waiting until this Breakpoint service",
|
112
|
+
" is shut down.",
|
113
|
+
" ",
|
114
|
+
" If you are using the Breakpoint library for",
|
115
|
+
" debugging a Rails or other CGI application",
|
116
|
+
" this likely means that this Breakpoint",
|
117
|
+
" session belongs to an earlier, outdated",
|
118
|
+
" request and should be shut down via 'exit'."
|
119
|
+
].join("\n")
|
120
|
+
|
121
|
+
if RUBY_PLATFORM["win"] then
|
122
|
+
# This sucks. Sorry, I'm not doing this because
|
123
|
+
# I like funky message boxes -- I need to do this
|
124
|
+
# because on Windows I have no way of displaying
|
125
|
+
# my notification via puts() when gets() is still
|
126
|
+
# being performed on STDIN. I have not found a
|
127
|
+
# better solution.
|
128
|
+
begin
|
129
|
+
require 'tk'
|
130
|
+
root = TkRoot.new { withdraw }
|
131
|
+
Tk.messageBox('message' => msg, 'type' => 'ok')
|
132
|
+
root.destroy
|
133
|
+
rescue Exception
|
134
|
+
puts "", msg, ""
|
135
|
+
end
|
136
|
+
else
|
137
|
+
puts "", msg, ""
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
# Used for checking whether we are currently in the reconnecting loop.
|
143
|
+
reconnecting = false
|
70
144
|
|
71
145
|
loop do
|
72
|
-
DRb.start_service(
|
146
|
+
DRb.start_service(Options[:ClientURI])
|
73
147
|
|
74
148
|
begin
|
75
|
-
service = DRbObject.new(nil,
|
149
|
+
service = DRbObject.new(nil, Options[:ServerURI])
|
76
150
|
|
77
151
|
begin
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
puts "",
|
82
|
-
" *** Breakpoint service didn't respond to ping request ***",
|
83
|
-
" This likely happened because of a misconfigured ACL (see the",
|
84
|
-
" documentation of Breakpoint.activate_drb, note that by default",
|
85
|
-
" you can only connect to a remote Breakpoint service via a SSH",
|
86
|
-
" tunnel), but might also be caused by an extremely slow connection.",
|
87
|
-
""
|
88
|
-
end
|
89
|
-
raise
|
90
|
-
end
|
152
|
+
service.eval_handler = Handlers.method(:eval_handler)
|
153
|
+
service.collision_handler = Handlers.method(:collision_handler)
|
154
|
+
service.handler = Handlers.method(:breakpoint_handler)
|
91
155
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
if result
|
96
|
-
DRbObject.new(result)
|
97
|
-
else
|
98
|
-
result
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
service.register_collision_handler do
|
103
|
-
msg = [
|
104
|
-
" *** Breakpoint service collision ***",
|
105
|
-
" Another Breakpoint service tried to use the",
|
106
|
-
" port already occupied by this one. It will",
|
107
|
-
" keep waiting until this Breakpoint service",
|
108
|
-
" is shut down.",
|
109
|
-
" ",
|
110
|
-
" If you are using the Breakpoint library for",
|
111
|
-
" debugging a Rails or other CGI application",
|
112
|
-
" this likely means that this Breakpoint",
|
113
|
-
" session belongs to an earlier, outdated",
|
114
|
-
" request and should be shut down via 'exit'."
|
115
|
-
].join("\n")
|
116
|
-
|
117
|
-
if RUBY_PLATFORM["win"] then
|
118
|
-
# This sucks. Sorry, I'm not doing this because
|
119
|
-
# I like funky message boxes -- I need to do this
|
120
|
-
# because on Windows I have no way of displaying
|
121
|
-
# my notification via puts() when gets() is still
|
122
|
-
# being performed on STDIN. I have not found a
|
123
|
-
# better solution.
|
124
|
-
begin
|
125
|
-
require 'tk'
|
126
|
-
root = TkRoot.new { withdraw }
|
127
|
-
Tk.messageBox('message' => msg, 'type' => 'ok')
|
128
|
-
root.destroy
|
129
|
-
rescue Exception
|
130
|
-
puts "", msg, ""
|
131
|
-
end
|
132
|
-
else
|
133
|
-
puts "", msg, ""
|
134
|
-
end
|
156
|
+
reconnecting = false
|
157
|
+
if Options[:Verbose] then
|
158
|
+
puts "Connection established. Waiting for breakpoint...", ""
|
135
159
|
end
|
136
160
|
|
137
|
-
|
138
|
-
puts message
|
139
|
-
IRB.start(nil, nil, workspace)
|
140
|
-
puts "", "Resumed execution. Waiting for next breakpoint...", ""
|
141
|
-
end
|
142
|
-
|
143
|
-
puts "Connection established. Waiting for breakpoint...", "" if options[:Verbose]
|
144
|
-
|
145
|
-
while $running
|
161
|
+
loop do
|
146
162
|
begin
|
147
163
|
service.ping
|
148
164
|
rescue DRb::DRbConnError => error
|
149
|
-
puts "Server exited. Closing connection..."
|
165
|
+
puts "Server exited. Closing connection...", ""
|
166
|
+
exit! unless Options[:Permanent]
|
150
167
|
break
|
151
168
|
end
|
152
169
|
|
153
170
|
sleep(0.5)
|
154
171
|
end
|
155
172
|
ensure
|
156
|
-
service.
|
173
|
+
service.eval_handler = nil
|
174
|
+
service.collision_handler = nil
|
175
|
+
service.handler = nil
|
157
176
|
end
|
158
177
|
rescue Exception => error
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
178
|
+
if Options[:RetryDelay] > 0 then
|
179
|
+
if not reconnecting then
|
180
|
+
reconnecting = true
|
181
|
+
puts "No connection to breakpoint service at #{Options[:ServerURI]} " +
|
182
|
+
"(#{error.class})"
|
183
|
+
puts error.backtrace if $DEBUG
|
184
|
+
puts "Tries to connect will be made every #{Options[:RetryDelay]} seconds..."
|
185
|
+
end
|
186
|
+
|
187
|
+
sleep Options[:RetryDelay]
|
167
188
|
retry
|
168
189
|
else
|
169
190
|
raise
|
170
191
|
end
|
171
192
|
end
|
172
|
-
end
|
193
|
+
end
|
data/lib/dispatcher.rb
CHANGED
@@ -34,30 +34,29 @@ class Dispatcher
|
|
34
34
|
|
35
35
|
controller_name, module_name = controller_name(request.parameters), module_name(request.parameters)
|
36
36
|
|
37
|
-
|
38
|
-
|
37
|
+
require_or_load("application")
|
38
|
+
require_or_load(controller_path(controller_name, module_name))
|
39
39
|
|
40
40
|
controller_class(controller_name).process(request, response).out
|
41
41
|
rescue Object => exception
|
42
42
|
ActionController::Base.process_with_exception(request, response, exception).out
|
43
43
|
ensure
|
44
|
-
reset_application
|
44
|
+
reset_application if Dependencies.load?
|
45
45
|
Breakpoint.deactivate_drb if defined?(BREAKPOINT_SERVER_PORT)
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
49
49
|
private
|
50
|
-
def reset_application
|
51
|
-
ActiveRecord::Base.reset_column_information_and_inheritable_attributes_for_all_subclasses
|
50
|
+
def reset_application
|
52
51
|
Dependencies.clear
|
53
|
-
|
52
|
+
Dependencies.remove_subclasses_for(ActiveRecord::Base, ActiveRecord::Observer, ActionController::Base)
|
54
53
|
end
|
55
|
-
|
54
|
+
|
56
55
|
def controller_path(controller_name, module_name = nil)
|
57
56
|
if module_name
|
58
|
-
"#{module_name}/#{
|
57
|
+
"#{module_name}/#{controller_name.underscore}_controller"
|
59
58
|
else
|
60
|
-
"#{
|
59
|
+
"#{controller_name.underscore}_controller"
|
61
60
|
end
|
62
61
|
end
|
63
62
|
|
@@ -66,22 +65,15 @@ class Dispatcher
|
|
66
65
|
end
|
67
66
|
|
68
67
|
def controller_class_name(controller_name)
|
69
|
-
"#{
|
68
|
+
"#{controller_name.camelize}Controller"
|
70
69
|
end
|
71
70
|
|
72
71
|
def controller_name(parameters)
|
73
|
-
parameters["controller"].gsub(/[^_a-zA-Z0-9]/, "").untaint
|
72
|
+
parameters["controller"].downcase.gsub(/[^_a-zA-Z0-9]/, "").untaint
|
74
73
|
end
|
75
74
|
|
76
75
|
def module_name(parameters)
|
77
|
-
parameters["module"].gsub(/[^_a-zA-Z0-9]/, "").untaint if parameters["module"]
|
78
|
-
end
|
79
|
-
|
80
|
-
def remove_class_hierarchy(klass, until_superclass)
|
81
|
-
while klass
|
82
|
-
Object.send(:remove_const, "#{klass}".intern)
|
83
|
-
klass = (klass.superclass unless until_superclass == klass.superclass)
|
84
|
-
end
|
76
|
+
parameters["module"].downcase.gsub(/[^_a-zA-Z0-9]/, "").untaint if parameters["module"]
|
85
77
|
end
|
86
78
|
end
|
87
79
|
end
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.4
|
|
3
3
|
specification_version: 1
|
4
4
|
name: rails
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.9.
|
7
|
-
date: 2005-01-
|
6
|
+
version: 0.9.5
|
7
|
+
date: 2005-01-25
|
8
8
|
summary: "Web-application framework with template engine, control-flow layer, and ORM."
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -138,7 +138,7 @@ dependencies:
|
|
138
138
|
-
|
139
139
|
- ">="
|
140
140
|
- !ruby/object:Gem::Version
|
141
|
-
version: 1.
|
141
|
+
version: 1.6.0
|
142
142
|
version:
|
143
143
|
- !ruby/object:Gem::Dependency
|
144
144
|
name: actionpack
|
@@ -148,7 +148,7 @@ dependencies:
|
|
148
148
|
-
|
149
149
|
- ">="
|
150
150
|
- !ruby/object:Gem::Version
|
151
|
-
version: 1.
|
151
|
+
version: 1.4.0
|
152
152
|
version:
|
153
153
|
- !ruby/object:Gem::Dependency
|
154
154
|
name: actionmailer
|