rails 1.2.6 → 2.0.0
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 +491 -12
- data/MIT-LICENSE +1 -1
- data/README +17 -25
- data/Rakefile +41 -18
- data/bin/about +1 -1
- data/bin/console +1 -1
- data/bin/destroy +1 -1
- data/bin/generate +1 -1
- data/bin/performance/request +3 -0
- data/bin/plugin +1 -1
- data/bin/runner +1 -1
- data/bin/server +1 -1
- data/builtin/rails_info/rails/info.rb +2 -2
- data/configs/apache.conf +1 -1
- data/configs/databases/mysql.yml +9 -3
- data/configs/databases/postgresql.yml +16 -12
- data/configs/initializers/inflections.rb +10 -0
- data/configs/initializers/mime_types.rb +5 -0
- data/configs/routes.rb +23 -11
- data/doc/README_FOR_APP +1 -1
- data/environments/boot.rb +95 -26
- data/environments/development.rb +2 -5
- data/environments/environment.rb +24 -25
- data/environments/test.rb +4 -1
- data/helpers/application.rb +5 -2
- data/helpers/test_helper.rb +10 -0
- data/html/422.html +30 -0
- data/html/500.html +1 -1
- data/html/index.html +2 -2
- data/html/javascripts/controls.js +484 -354
- data/html/javascripts/dragdrop.js +88 -58
- data/html/javascripts/effects.js +396 -364
- data/html/javascripts/prototype.js +2817 -1107
- data/html/robots.txt +5 -1
- data/lib/commands/console.rb +12 -5
- data/lib/commands/performance/request.rb +6 -0
- data/lib/commands/plugin.rb +15 -10
- data/lib/commands/process/spawner.rb +14 -4
- data/lib/commands/servers/base.rb +12 -0
- data/lib/commands/servers/mongrel.rb +5 -1
- data/lib/commands/servers/webrick.rb +14 -7
- data/lib/console_app.rb +5 -2
- data/lib/console_with_helpers.rb +5 -2
- data/lib/dispatcher.rb +3 -151
- data/lib/fcgi_handler.rb +79 -81
- data/lib/initializer.rb +125 -169
- data/lib/rails/plugin.rb +84 -0
- data/lib/rails/plugin/loader.rb +150 -0
- data/lib/rails/plugin/locator.rb +78 -0
- data/lib/rails/version.rb +3 -3
- data/lib/rails_generator/base.rb +11 -9
- data/lib/rails_generator/commands.rb +20 -10
- data/lib/rails_generator/generators/applications/app/USAGE +0 -7
- data/lib/rails_generator/generators/applications/app/app_generator.rb +25 -6
- data/lib/rails_generator/generators/components/controller/USAGE +11 -12
- data/lib/rails_generator/generators/components/controller/controller_generator.rb +2 -2
- data/lib/rails_generator/generators/components/controller/templates/functional_test.rb +1 -11
- data/lib/rails_generator/generators/components/controller/templates/{view.rhtml → view.html.erb} +0 -0
- data/lib/rails_generator/generators/components/integration_test/USAGE +5 -11
- data/lib/rails_generator/generators/components/mailer/USAGE +8 -10
- data/lib/rails_generator/generators/components/mailer/mailer_generator.rb +3 -3
- data/lib/rails_generator/generators/components/mailer/templates/fixture.erb +3 -0
- data/lib/rails_generator/generators/components/mailer/templates/fixture.rhtml +0 -3
- data/lib/rails_generator/generators/components/mailer/templates/unit_test.rb +8 -24
- data/lib/rails_generator/generators/components/mailer/templates/view.erb +3 -0
- data/lib/rails_generator/generators/components/mailer/templates/view.rhtml +0 -3
- data/lib/rails_generator/generators/components/migration/USAGE +23 -8
- data/lib/rails_generator/generators/components/migration/migration_generator.rb +15 -2
- data/lib/rails_generator/generators/components/migration/templates/migration.rb +6 -2
- data/lib/rails_generator/generators/components/model/USAGE +15 -14
- data/lib/rails_generator/generators/components/model/model_generator.rb +10 -3
- data/lib/rails_generator/generators/components/model/templates/fixtures.yml +11 -3
- data/lib/rails_generator/generators/components/model/templates/migration.rb +4 -1
- data/lib/rails_generator/generators/components/model/templates/unit_test.rb +1 -3
- data/lib/rails_generator/generators/components/observer/USAGE +5 -7
- data/lib/rails_generator/generators/components/observer/templates/unit_test.rb +0 -2
- data/lib/rails_generator/generators/components/plugin/USAGE +8 -18
- data/lib/rails_generator/generators/components/plugin/plugin_generator.rb +1 -0
- data/lib/rails_generator/generators/components/plugin/templates/MIT-LICENSE +20 -0
- data/lib/rails_generator/generators/components/plugin/templates/README +10 -1
- data/lib/rails_generator/generators/components/plugin/templates/USAGE +1 -1
- data/lib/rails_generator/generators/components/plugin/templates/init.rb +1 -1
- data/lib/rails_generator/generators/components/plugin/templates/plugin.rb +1 -1
- data/lib/rails_generator/generators/components/plugin/templates/tasks.rake +1 -1
- data/lib/rails_generator/generators/components/resource/USAGE +23 -0
- data/lib/rails_generator/generators/components/resource/resource_generator.rb +13 -15
- data/lib/rails_generator/generators/components/resource/templates/controller.rb +1 -1
- data/lib/rails_generator/generators/components/resource/templates/functional_test.rb +2 -14
- data/lib/rails_generator/generators/components/scaffold/USAGE +24 -31
- data/lib/rails_generator/generators/components/scaffold/scaffold_generator.rb +45 -146
- data/lib/rails_generator/generators/components/scaffold/templates/controller.rb +64 -37
- data/lib/rails_generator/generators/components/scaffold/templates/functional_test.rb +23 -80
- data/lib/rails_generator/generators/components/scaffold/templates/{layout.rhtml → layout.html.erb} +0 -0
- data/lib/rails_generator/generators/components/scaffold/templates/style.css +1 -1
- data/lib/rails_generator/generators/components/{scaffold_resource/templates/view_edit.rhtml → scaffold/templates/view_edit.html.erb} +4 -4
- data/lib/rails_generator/generators/components/{scaffold_resource/templates/view_index.rhtml → scaffold/templates/view_index.html.erb} +4 -4
- data/lib/rails_generator/generators/components/{scaffold_resource/templates/view_new.rhtml → scaffold/templates/view_new.html.erb} +3 -3
- data/lib/rails_generator/generators/components/{scaffold_resource/templates/view_show.rhtml → scaffold/templates/view_show.html.erb} +1 -1
- data/lib/rails_generator/generators/components/session_migration/USAGE +6 -11
- data/lib/rails_generator/generators/components/session_migration/templates/migration.rb +3 -3
- data/lib/rails_generator/lookup.rb +45 -10
- data/lib/rails_generator/scripts.rb +6 -3
- data/lib/rails_generator/scripts/destroy.rb +23 -0
- data/lib/rails_generator/secret_key_generator.rb +160 -0
- data/lib/rails_generator/spec.rb +1 -1
- data/lib/source_annotation_extractor.rb +62 -0
- data/lib/tasks/annotations.rake +23 -0
- data/lib/tasks/databases.rake +249 -83
- data/lib/tasks/documentation.rake +11 -13
- data/lib/tasks/framework.rake +1 -1
- data/lib/tasks/rails.rb +1 -1
- data/lib/tasks/testing.rake +5 -7
- data/lib/test_help.rb +4 -3
- data/lib/webrick_server.rb +3 -4
- metadata +31 -49
- data/bin/breakpointer +0 -3
- data/lib/binding_of_caller.rb +0 -85
- data/lib/breakpoint.rb +0 -553
- data/lib/breakpoint_client.rb +0 -196
- data/lib/commands/breakpointer.rb +0 -1
- data/lib/rails_generator/generators/components/resource/templates/USAGE +0 -18
- data/lib/rails_generator/generators/components/resource/templates/fixtures.yml +0 -11
- data/lib/rails_generator/generators/components/resource/templates/migration.rb +0 -13
- data/lib/rails_generator/generators/components/resource/templates/model.rb +0 -2
- data/lib/rails_generator/generators/components/resource/templates/unit_test.rb +0 -10
- data/lib/rails_generator/generators/components/scaffold/templates/form.rhtml +0 -3
- data/lib/rails_generator/generators/components/scaffold/templates/form_scaffolding.rhtml +0 -1
- data/lib/rails_generator/generators/components/scaffold/templates/view_edit.rhtml +0 -9
- data/lib/rails_generator/generators/components/scaffold/templates/view_list.rhtml +0 -27
- data/lib/rails_generator/generators/components/scaffold/templates/view_new.rhtml +0 -8
- data/lib/rails_generator/generators/components/scaffold/templates/view_show.rhtml +0 -8
- data/lib/rails_generator/generators/components/scaffold_resource/USAGE +0 -29
- data/lib/rails_generator/generators/components/scaffold_resource/scaffold_resource_generator.rb +0 -93
- data/lib/rails_generator/generators/components/scaffold_resource/templates/controller.rb +0 -79
- data/lib/rails_generator/generators/components/scaffold_resource/templates/fixtures.yml +0 -11
- data/lib/rails_generator/generators/components/scaffold_resource/templates/functional_test.rb +0 -57
- data/lib/rails_generator/generators/components/scaffold_resource/templates/helper.rb +0 -2
- data/lib/rails_generator/generators/components/scaffold_resource/templates/layout.rhtml +0 -17
- data/lib/rails_generator/generators/components/scaffold_resource/templates/migration.rb +0 -13
- data/lib/rails_generator/generators/components/scaffold_resource/templates/model.rb +0 -2
- data/lib/rails_generator/generators/components/scaffold_resource/templates/style.css +0 -74
- data/lib/rails_generator/generators/components/scaffold_resource/templates/unit_test.rb +0 -10
- data/lib/rails_generator/generators/components/web_service/USAGE +0 -28
- data/lib/rails_generator/generators/components/web_service/templates/api_definition.rb +0 -5
- data/lib/rails_generator/generators/components/web_service/templates/controller.rb +0 -8
- data/lib/rails_generator/generators/components/web_service/templates/functional_test.rb +0 -19
- data/lib/rails_generator/generators/components/web_service/web_service_generator.rb +0 -29
- data/lib/tasks/pre_namespace_aliases.rake +0 -53
data/lib/breakpoint.rb
DELETED
@@ -1,553 +0,0 @@
|
|
1
|
-
# The Breakpoint library provides the convenience of
|
2
|
-
# being able to inspect and modify state, diagnose
|
3
|
-
# bugs all via IRB by simply setting breakpoints in
|
4
|
-
# your applications by the call of a method.
|
5
|
-
#
|
6
|
-
# This library was written and is supported by me,
|
7
|
-
# Florian Gross. I can be reached at flgr@ccan.de
|
8
|
-
# and enjoy getting feedback about my libraries.
|
9
|
-
#
|
10
|
-
# The whole library (including breakpoint_client.rb
|
11
|
-
# and binding_of_caller.rb) is licensed under the
|
12
|
-
# same license that Ruby uses. (Which is currently
|
13
|
-
# either the GNU General Public License or a custom
|
14
|
-
# one that allows for commercial usage.) If you for
|
15
|
-
# some good reason need to use this under another
|
16
|
-
# license please contact me.
|
17
|
-
|
18
|
-
require 'irb'
|
19
|
-
if RUBY_VERSION == '1.8.5'
|
20
|
-
def Binding.of_caller(&block)
|
21
|
-
raise "Breakpoints are not currently working with Ruby 1.8.5"
|
22
|
-
end
|
23
|
-
else
|
24
|
-
require 'binding_of_caller'
|
25
|
-
end
|
26
|
-
require 'drb'
|
27
|
-
require 'drb/acl'
|
28
|
-
|
29
|
-
module Breakpoint
|
30
|
-
id = %q$Id: breakpoint.rb 92 2005-02-04 22:35:53Z flgr $
|
31
|
-
Version = id.split(" ")[2].to_i
|
32
|
-
|
33
|
-
extend self
|
34
|
-
|
35
|
-
# This will pop up an interactive ruby session at a
|
36
|
-
# pre-defined break point in a Ruby application. In
|
37
|
-
# this session you can examine the environment of
|
38
|
-
# the break point.
|
39
|
-
#
|
40
|
-
# You can get a list of variables in the context using
|
41
|
-
# local_variables via +local_variables+. You can then
|
42
|
-
# examine their values by typing their names.
|
43
|
-
#
|
44
|
-
# You can have a look at the call stack via +caller+.
|
45
|
-
#
|
46
|
-
# The source code around the location where the breakpoint
|
47
|
-
# was executed can be examined via +source_lines+. Its
|
48
|
-
# argument specifies how much lines of context to display.
|
49
|
-
# The default amount of context is 5 lines. Note that
|
50
|
-
# the call to +source_lines+ can raise an exception when
|
51
|
-
# it isn't able to read in the source code.
|
52
|
-
#
|
53
|
-
# breakpoints can also return a value. They will execute
|
54
|
-
# a supplied block for getting a default return value.
|
55
|
-
# A custom value can be returned from the session by doing
|
56
|
-
# +throw(:debug_return, value)+.
|
57
|
-
#
|
58
|
-
# You can also give names to break points which will be
|
59
|
-
# used in the message that is displayed upon execution
|
60
|
-
# of them.
|
61
|
-
#
|
62
|
-
# Here's a sample of how breakpoints should be placed:
|
63
|
-
#
|
64
|
-
# class Person
|
65
|
-
# def initialize(name, age)
|
66
|
-
# @name, @age = name, age
|
67
|
-
# breakpoint("Person#initialize")
|
68
|
-
# end
|
69
|
-
#
|
70
|
-
# attr_reader :age
|
71
|
-
# def name
|
72
|
-
# breakpoint("Person#name") { @name }
|
73
|
-
# end
|
74
|
-
# end
|
75
|
-
#
|
76
|
-
# person = Person.new("Random Person", 23)
|
77
|
-
# puts "Name: #{person.name}"
|
78
|
-
#
|
79
|
-
# And here is a sample debug session:
|
80
|
-
#
|
81
|
-
# Executing break point "Person#initialize" at file.rb:4 in `initialize'
|
82
|
-
# irb(#<Person:0x292fbe8>):001:0> local_variables
|
83
|
-
# => ["name", "age", "_", "__"]
|
84
|
-
# irb(#<Person:0x292fbe8>):002:0> [name, age]
|
85
|
-
# => ["Random Person", 23]
|
86
|
-
# irb(#<Person:0x292fbe8>):003:0> [@name, @age]
|
87
|
-
# => ["Random Person", 23]
|
88
|
-
# irb(#<Person:0x292fbe8>):004:0> self
|
89
|
-
# => #<Person:0x292fbe8 @age=23, @name="Random Person">
|
90
|
-
# irb(#<Person:0x292fbe8>):005:0> @age += 1; self
|
91
|
-
# => #<Person:0x292fbe8 @age=24, @name="Random Person">
|
92
|
-
# irb(#<Person:0x292fbe8>):006:0> exit
|
93
|
-
# Executing break point "Person#name" at file.rb:9 in `name'
|
94
|
-
# irb(#<Person:0x292fbe8>):001:0> throw(:debug_return, "Overriden name")
|
95
|
-
# Name: Overriden name
|
96
|
-
#
|
97
|
-
# Breakpoint sessions will automatically have a few
|
98
|
-
# convenience methods available. See Breakpoint::CommandBundle
|
99
|
-
# for a list of them.
|
100
|
-
#
|
101
|
-
# Breakpoints can also be used remotely over sockets.
|
102
|
-
# This is implemented by running part of the IRB session
|
103
|
-
# in the application and part of it in a special client.
|
104
|
-
# You have to call Breakpoint.activate_drb to enable
|
105
|
-
# support for remote breakpoints and then run
|
106
|
-
# breakpoint_client.rb which is distributed with this
|
107
|
-
# library. See the documentation of Breakpoint.activate_drb
|
108
|
-
# for details.
|
109
|
-
def breakpoint(id = nil, context = nil, &block)
|
110
|
-
callstack = caller
|
111
|
-
callstack.slice!(0, 3) if callstack.first["breakpoint"]
|
112
|
-
file, line, method = *callstack.first.match(/^(.+?):(\d+)(?::in `(.*?)')?/).captures
|
113
|
-
|
114
|
-
message = "Executing break point " + (id ? "#{id.inspect} " : "") +
|
115
|
-
"at #{file}:#{line}" + (method ? " in `#{method}'" : "")
|
116
|
-
|
117
|
-
if context then
|
118
|
-
return handle_breakpoint(context, message, file, line, &block)
|
119
|
-
end
|
120
|
-
|
121
|
-
Binding.of_caller do |binding_context|
|
122
|
-
handle_breakpoint(binding_context, message, file, line, &block)
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
module CommandBundle
|
127
|
-
# Proxy to a Breakpoint client. Lets you directly execute code
|
128
|
-
# in the context of the client.
|
129
|
-
class Client
|
130
|
-
def initialize(eval_handler) # :nodoc:
|
131
|
-
eval_handler.untaint
|
132
|
-
@eval_handler = eval_handler
|
133
|
-
end
|
134
|
-
|
135
|
-
instance_methods.each do |method|
|
136
|
-
next if method[/^__.+__$/]
|
137
|
-
undef_method method
|
138
|
-
end
|
139
|
-
|
140
|
-
# Executes the specified code at the client.
|
141
|
-
def eval(code)
|
142
|
-
@eval_handler.call(code)
|
143
|
-
end
|
144
|
-
|
145
|
-
# Will execute the specified statement at the client.
|
146
|
-
def method_missing(method, *args, &block)
|
147
|
-
if args.empty? and not block
|
148
|
-
result = eval "#{method}"
|
149
|
-
else
|
150
|
-
# This is a bit ugly. The alternative would be using an
|
151
|
-
# eval context instead of an eval handler for executing
|
152
|
-
# the code at the client. The problem with that approach
|
153
|
-
# is that we would have to handle special expressions
|
154
|
-
# like "self", "nil" or constants ourself which is hard.
|
155
|
-
remote = eval %{
|
156
|
-
result = lambda { |block, *args| #{method}(*args, &block) }
|
157
|
-
def result.call_with_block(*args, &block)
|
158
|
-
call(block, *args)
|
159
|
-
end
|
160
|
-
result
|
161
|
-
}
|
162
|
-
remote.call_with_block(*args, &block)
|
163
|
-
end
|
164
|
-
|
165
|
-
return result
|
166
|
-
end
|
167
|
-
end
|
168
|
-
|
169
|
-
# Returns the source code surrounding the location where the
|
170
|
-
# breakpoint was issued.
|
171
|
-
def source_lines(context = 5, return_line_numbers = false)
|
172
|
-
lines = File.readlines(@__bp_file).map { |line| line.chomp }
|
173
|
-
|
174
|
-
break_line = @__bp_line
|
175
|
-
start_line = [break_line - context, 1].max
|
176
|
-
end_line = break_line + context
|
177
|
-
|
178
|
-
result = lines[(start_line - 1) .. (end_line - 1)]
|
179
|
-
|
180
|
-
if return_line_numbers then
|
181
|
-
return [start_line, break_line, result]
|
182
|
-
else
|
183
|
-
return result
|
184
|
-
end
|
185
|
-
end
|
186
|
-
|
187
|
-
# Prints the source code surrounding the location where the
|
188
|
-
# breakpoint was issued.
|
189
|
-
def show_source_list(context = 5)
|
190
|
-
start_line, break_line, result = source_lines(context, true)
|
191
|
-
offset = [(break_line + context).to_s.length, 4].max
|
192
|
-
result.each_with_index do |line, i|
|
193
|
-
mark = (start_line + i == break_line ? '->' : ' ')
|
194
|
-
client.puts("%0#{offset}d%s#{line}" % [start_line + i, mark])
|
195
|
-
end
|
196
|
-
Pathname.new(@__bp_file).cleanpath.to_s
|
197
|
-
end
|
198
|
-
|
199
|
-
# Prints the call stack.
|
200
|
-
def show_call_stack(depth = 10)
|
201
|
-
base = Pathname.new(RAILS_ROOT).cleanpath.to_s
|
202
|
-
caller[1..depth].each do |line|
|
203
|
-
line.sub!(/^[^:]*/) do |path|
|
204
|
-
Pathname.new(path).cleanpath.to_s
|
205
|
-
end
|
206
|
-
client.puts(line.index(base) == 0 ? line[(base.length + 1)..-1] : line)
|
207
|
-
end
|
208
|
-
"#{Pathname.new(@__bp_file).cleanpath.to_s}:#{@__bp_line}"
|
209
|
-
end
|
210
|
-
|
211
|
-
# Lets an object that will forward method calls to the breakpoint
|
212
|
-
# client. This is useful for outputting longer things at the client
|
213
|
-
# and so on. You can for example do these things:
|
214
|
-
#
|
215
|
-
# client.puts "Hello" # outputs "Hello" at client console
|
216
|
-
# # outputs "Hello" into the file temp.txt at the client
|
217
|
-
# client.File.open("temp.txt", "w") { |f| f.puts "Hello" }
|
218
|
-
def client()
|
219
|
-
if Breakpoint.use_drb? then
|
220
|
-
sleep(0.5) until Breakpoint.drb_service.eval_handler
|
221
|
-
Client.new(Breakpoint.drb_service.eval_handler)
|
222
|
-
else
|
223
|
-
Client.new(lambda { |code| eval(code, TOPLEVEL_BINDING) })
|
224
|
-
end
|
225
|
-
end
|
226
|
-
end
|
227
|
-
|
228
|
-
def handle_breakpoint(context, message, file = "", line = "", &block) # :nodoc:
|
229
|
-
catch(:debug_return) do |value|
|
230
|
-
eval(%{
|
231
|
-
@__bp_file = #{file.inspect}
|
232
|
-
@__bp_line = #{line}
|
233
|
-
extend Breakpoint::CommandBundle
|
234
|
-
extend DRbUndumped if self
|
235
|
-
}, context) rescue nil
|
236
|
-
|
237
|
-
if not use_drb? then
|
238
|
-
puts message
|
239
|
-
IRB.start(nil, IRB::WorkSpace.new(context))
|
240
|
-
else
|
241
|
-
@drb_service.add_breakpoint(context, message)
|
242
|
-
end
|
243
|
-
|
244
|
-
block.call if block
|
245
|
-
end
|
246
|
-
end
|
247
|
-
|
248
|
-
# These exceptions will be raised on failed asserts
|
249
|
-
# if Breakpoint.asserts_cause_exceptions is set to
|
250
|
-
# true.
|
251
|
-
class FailedAssertError < RuntimeError
|
252
|
-
end
|
253
|
-
|
254
|
-
# This asserts that the block evaluates to true.
|
255
|
-
# If it doesn't evaluate to true a breakpoint will
|
256
|
-
# automatically be created at that execution point.
|
257
|
-
#
|
258
|
-
# You can disable assert checking in production
|
259
|
-
# code by setting Breakpoint.optimize_asserts to
|
260
|
-
# true. (It will still be enabled when Ruby is run
|
261
|
-
# via the -d argument.)
|
262
|
-
#
|
263
|
-
# Example:
|
264
|
-
# person_name = "Foobar"
|
265
|
-
# assert { not person_name.nil? }
|
266
|
-
#
|
267
|
-
# Note: If you want to use this method from an
|
268
|
-
# unit test, you will have to call it by its full
|
269
|
-
# name, Breakpoint.assert.
|
270
|
-
def assert(context = nil, &condition)
|
271
|
-
return if Breakpoint.optimize_asserts and not $DEBUG
|
272
|
-
return if yield
|
273
|
-
|
274
|
-
callstack = caller
|
275
|
-
callstack.slice!(0, 3) if callstack.first["assert"]
|
276
|
-
file, line, method = *callstack.first.match(/^(.+?):(\d+)(?::in `(.*?)')?/).captures
|
277
|
-
|
278
|
-
message = "Assert failed at #{file}:#{line}#{" in `#{method}'" if method}."
|
279
|
-
|
280
|
-
if Breakpoint.asserts_cause_exceptions and not $DEBUG then
|
281
|
-
raise(Breakpoint::FailedAssertError, message)
|
282
|
-
end
|
283
|
-
|
284
|
-
message += " Executing implicit breakpoint."
|
285
|
-
|
286
|
-
if context then
|
287
|
-
return handle_breakpoint(context, message, file, line)
|
288
|
-
end
|
289
|
-
|
290
|
-
Binding.of_caller do |context|
|
291
|
-
handle_breakpoint(context, message, file, line)
|
292
|
-
end
|
293
|
-
end
|
294
|
-
|
295
|
-
# Whether asserts should be ignored if not in debug mode.
|
296
|
-
# Debug mode can be enabled by running ruby with the -d
|
297
|
-
# switch or by setting $DEBUG to true.
|
298
|
-
attr_accessor :optimize_asserts
|
299
|
-
self.optimize_asserts = false
|
300
|
-
|
301
|
-
# Whether an Exception should be raised on failed asserts
|
302
|
-
# in non-$DEBUG code or not. By default this is disabled.
|
303
|
-
attr_accessor :asserts_cause_exceptions
|
304
|
-
self.asserts_cause_exceptions = false
|
305
|
-
@use_drb = false
|
306
|
-
|
307
|
-
attr_reader :drb_service # :nodoc:
|
308
|
-
|
309
|
-
class DRbService # :nodoc:
|
310
|
-
include DRbUndumped
|
311
|
-
|
312
|
-
def initialize
|
313
|
-
@handler = @eval_handler = @collision_handler = nil
|
314
|
-
|
315
|
-
IRB.instance_eval { @CONF[:RC] = true }
|
316
|
-
IRB.run_config
|
317
|
-
end
|
318
|
-
|
319
|
-
def collision
|
320
|
-
sleep(0.5) until @collision_handler
|
321
|
-
|
322
|
-
@collision_handler.untaint
|
323
|
-
|
324
|
-
@collision_handler.call
|
325
|
-
end
|
326
|
-
|
327
|
-
def ping() end
|
328
|
-
|
329
|
-
def add_breakpoint(context, message)
|
330
|
-
workspace = IRB::WorkSpace.new(context)
|
331
|
-
workspace.extend(DRbUndumped)
|
332
|
-
|
333
|
-
sleep(0.5) until @handler
|
334
|
-
|
335
|
-
@handler.untaint
|
336
|
-
@handler.call(workspace, message)
|
337
|
-
end
|
338
|
-
|
339
|
-
attr_accessor :handler, :eval_handler, :collision_handler
|
340
|
-
end
|
341
|
-
|
342
|
-
# Will run Breakpoint in DRb mode. This will spawn a server
|
343
|
-
# that can be attached to via the breakpoint-client command
|
344
|
-
# whenever a breakpoint is executed. This is useful when you
|
345
|
-
# are debugging CGI applications or other applications where
|
346
|
-
# you can't access debug sessions via the standard input and
|
347
|
-
# output of your application.
|
348
|
-
#
|
349
|
-
# You can specify an URI where the DRb server will run at.
|
350
|
-
# This way you can specify the port the server runs on. The
|
351
|
-
# default URI is druby://localhost:42531.
|
352
|
-
#
|
353
|
-
# Please note that breakpoints will be skipped silently in
|
354
|
-
# case the DRb server can not spawned. (This can happen if
|
355
|
-
# the port is already used by another instance of your
|
356
|
-
# application on CGI or another application.)
|
357
|
-
#
|
358
|
-
# Also note that by default this will only allow access
|
359
|
-
# from localhost. You can however specify a list of
|
360
|
-
# allowed hosts or nil (to allow access from everywhere).
|
361
|
-
# But that will still not protect you from somebody
|
362
|
-
# reading the data as it goes through the net.
|
363
|
-
#
|
364
|
-
# A good approach for getting security and remote access
|
365
|
-
# is setting up an SSH tunnel between the DRb service
|
366
|
-
# and the client. This is usually done like this:
|
367
|
-
#
|
368
|
-
# $ ssh -L20000:127.0.0.1:20000 -R10000:127.0.0.1:10000 example.com
|
369
|
-
# (This will connect port 20000 at the client side to port
|
370
|
-
# 20000 at the server side, and port 10000 at the server
|
371
|
-
# side to port 10000 at the client side.)
|
372
|
-
#
|
373
|
-
# After that do this on the server side: (the code being debugged)
|
374
|
-
# Breakpoint.activate_drb("druby://127.0.0.1:20000", "localhost")
|
375
|
-
#
|
376
|
-
# And at the client side:
|
377
|
-
# ruby breakpoint_client.rb -c druby://127.0.0.1:10000 -s druby://127.0.0.1:20000
|
378
|
-
#
|
379
|
-
# Running through such a SSH proxy will also let you use
|
380
|
-
# breakpoint.rb in case you are behind a firewall.
|
381
|
-
#
|
382
|
-
# Detailed information about running DRb through firewalls is
|
383
|
-
# available at http://www.rubygarden.org/ruby?DrbTutorial
|
384
|
-
def activate_drb(uri = nil, allowed_hosts = ['localhost', '127.0.0.1', '::1'],
|
385
|
-
ignore_collisions = false)
|
386
|
-
|
387
|
-
return false if @use_drb
|
388
|
-
|
389
|
-
uri ||= 'druby://localhost:42531'
|
390
|
-
|
391
|
-
if allowed_hosts then
|
392
|
-
acl = ["deny", "all"]
|
393
|
-
|
394
|
-
Array(allowed_hosts).each do |host|
|
395
|
-
acl += ["allow", host]
|
396
|
-
end
|
397
|
-
|
398
|
-
DRb.install_acl(ACL.new(acl))
|
399
|
-
end
|
400
|
-
|
401
|
-
@use_drb = true
|
402
|
-
@drb_service = DRbService.new
|
403
|
-
did_collision = false
|
404
|
-
begin
|
405
|
-
@service = DRb.start_service(uri, @drb_service)
|
406
|
-
rescue Errno::EADDRINUSE
|
407
|
-
if ignore_collisions then
|
408
|
-
nil
|
409
|
-
else
|
410
|
-
# The port is already occupied by another
|
411
|
-
# Breakpoint service. We will try to tell
|
412
|
-
# the old service that we want its port.
|
413
|
-
# It will then forward that request to the
|
414
|
-
# user and retry.
|
415
|
-
unless did_collision then
|
416
|
-
DRbObject.new(nil, uri).collision
|
417
|
-
did_collision = true
|
418
|
-
end
|
419
|
-
sleep(10)
|
420
|
-
retry
|
421
|
-
end
|
422
|
-
end
|
423
|
-
|
424
|
-
return true
|
425
|
-
end
|
426
|
-
|
427
|
-
# Deactivates a running Breakpoint service.
|
428
|
-
def deactivate_drb
|
429
|
-
@service.stop_service unless @service.nil?
|
430
|
-
@service = nil
|
431
|
-
@use_drb = false
|
432
|
-
@drb_service = nil
|
433
|
-
end
|
434
|
-
|
435
|
-
# Returns true when Breakpoints are used over DRb.
|
436
|
-
# Breakpoint.activate_drb causes this to be true.
|
437
|
-
def use_drb?
|
438
|
-
@use_drb == true
|
439
|
-
end
|
440
|
-
end
|
441
|
-
|
442
|
-
module IRB # :nodoc:
|
443
|
-
class << self; remove_method :start; end
|
444
|
-
def self.start(ap_path = nil, main_context = nil, workspace = nil)
|
445
|
-
$0 = File::basename(ap_path, ".rb") if ap_path
|
446
|
-
|
447
|
-
# suppress some warnings about redefined constants
|
448
|
-
old_verbose, $VERBOSE = $VERBOSE, nil
|
449
|
-
IRB.setup(ap_path)
|
450
|
-
$VERBOSE = old_verbose
|
451
|
-
|
452
|
-
if @CONF[:SCRIPT] then
|
453
|
-
irb = Irb.new(main_context, @CONF[:SCRIPT])
|
454
|
-
else
|
455
|
-
irb = Irb.new(main_context)
|
456
|
-
end
|
457
|
-
|
458
|
-
if workspace then
|
459
|
-
irb.context.workspace = workspace
|
460
|
-
end
|
461
|
-
|
462
|
-
@CONF[:IRB_RC].call(irb.context) if @CONF[:IRB_RC]
|
463
|
-
@CONF[:MAIN_CONTEXT] = irb.context
|
464
|
-
|
465
|
-
old_sigint = trap("SIGINT") do
|
466
|
-
begin
|
467
|
-
irb.signal_handle
|
468
|
-
rescue RubyLex::TerminateLineInput
|
469
|
-
# ignored
|
470
|
-
end
|
471
|
-
end
|
472
|
-
|
473
|
-
catch(:IRB_EXIT) do
|
474
|
-
irb.eval_input
|
475
|
-
end
|
476
|
-
ensure
|
477
|
-
trap("SIGINT", old_sigint)
|
478
|
-
end
|
479
|
-
|
480
|
-
class << self
|
481
|
-
alias :old_CurrentContext :CurrentContext
|
482
|
-
remove_method :CurrentContext
|
483
|
-
end
|
484
|
-
def IRB.CurrentContext
|
485
|
-
if old_CurrentContext.nil? and Breakpoint.use_drb? then
|
486
|
-
result = Object.new
|
487
|
-
def result.last_value; end
|
488
|
-
return result
|
489
|
-
else
|
490
|
-
old_CurrentContext
|
491
|
-
end
|
492
|
-
end
|
493
|
-
def IRB.parse_opts() end
|
494
|
-
|
495
|
-
class Context #:nodoc:
|
496
|
-
alias :old_evaluate :evaluate
|
497
|
-
def evaluate(line, line_no)
|
498
|
-
if line.chomp == "exit" then
|
499
|
-
exit
|
500
|
-
else
|
501
|
-
old_evaluate(line, line_no)
|
502
|
-
end
|
503
|
-
end
|
504
|
-
end
|
505
|
-
|
506
|
-
class WorkSpace #:nodoc:
|
507
|
-
alias :old_evaluate :evaluate
|
508
|
-
|
509
|
-
def evaluate(*args)
|
510
|
-
if Breakpoint.use_drb? then
|
511
|
-
result = old_evaluate(*args)
|
512
|
-
if args[0] != :no_proxy and
|
513
|
-
not [true, false, nil].include?(result)
|
514
|
-
then
|
515
|
-
result.extend(DRbUndumped) rescue nil
|
516
|
-
end
|
517
|
-
return result
|
518
|
-
else
|
519
|
-
old_evaluate(*args)
|
520
|
-
end
|
521
|
-
end
|
522
|
-
end
|
523
|
-
|
524
|
-
module InputCompletor #:nodoc:
|
525
|
-
def self.eval(code, context, *more)
|
526
|
-
# Big hack, this assumes that InputCompletor
|
527
|
-
# will only call eval() when it wants code
|
528
|
-
# to be executed in the IRB context.
|
529
|
-
IRB.conf[:MAIN_CONTEXT].workspace.evaluate(:no_proxy, code, *more)
|
530
|
-
end
|
531
|
-
end
|
532
|
-
end
|
533
|
-
|
534
|
-
module DRb #:nodoc:
|
535
|
-
class DRbObject #:nodoc:
|
536
|
-
undef :inspect if method_defined?(:inspect)
|
537
|
-
undef :clone if method_defined?(:clone)
|
538
|
-
end
|
539
|
-
end
|
540
|
-
|
541
|
-
# See Breakpoint.breakpoint
|
542
|
-
def breakpoint(id = nil, &block)
|
543
|
-
Binding.of_caller do |context|
|
544
|
-
Breakpoint.breakpoint(id, context, &block)
|
545
|
-
end
|
546
|
-
end
|
547
|
-
|
548
|
-
# See Breakpoint.assert
|
549
|
-
def assert(&block)
|
550
|
-
Binding.of_caller do |context|
|
551
|
-
Breakpoint.assert(context, &block)
|
552
|
-
end
|
553
|
-
end
|