erails 2.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (193) hide show
  1. data/CHANGELOG +3 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README +309 -0
  4. data/Rakefile +339 -0
  5. data/bin/about +4 -0
  6. data/bin/console +3 -0
  7. data/bin/dbconsole +3 -0
  8. data/bin/destroy +3 -0
  9. data/bin/erails +19 -0
  10. data/bin/generate +3 -0
  11. data/bin/performance/benchmarker +3 -0
  12. data/bin/performance/profiler +3 -0
  13. data/bin/performance/request +3 -0
  14. data/bin/plugin +3 -0
  15. data/bin/process/inspector +3 -0
  16. data/bin/process/reaper +3 -0
  17. data/bin/process/spawner +3 -0
  18. data/bin/runner +3 -0
  19. data/bin/server +3 -0
  20. data/builtin/rails_info/rails/info.rb +125 -0
  21. data/builtin/rails_info/rails/info_controller.rb +9 -0
  22. data/builtin/rails_info/rails/info_helper.rb +2 -0
  23. data/builtin/rails_info/rails_info_controller.rb +2 -0
  24. data/configs/apache.conf +40 -0
  25. data/configs/databases/frontbase.yml +28 -0
  26. data/configs/databases/mysql.yml +54 -0
  27. data/configs/databases/oracle.yml +39 -0
  28. data/configs/databases/postgresql.yml +48 -0
  29. data/configs/databases/sqlite2.yml +16 -0
  30. data/configs/databases/sqlite3.yml +19 -0
  31. data/configs/empty.log +0 -0
  32. data/configs/initializers/inflections.rb +10 -0
  33. data/configs/initializers/mime_types.rb +5 -0
  34. data/configs/initializers/new_rails_defaults.rb +17 -0
  35. data/configs/lighttpd.conf +54 -0
  36. data/configs/routes.rb +43 -0
  37. data/dispatches/dispatch.fcgi +24 -0
  38. data/dispatches/dispatch.rb +10 -0
  39. data/dispatches/gateway.cgi +97 -0
  40. data/doc/README_FOR_APP +2 -0
  41. data/environments/boot.rb +109 -0
  42. data/environments/development.rb +16 -0
  43. data/environments/environment.rb +71 -0
  44. data/environments/production.rb +22 -0
  45. data/environments/test.rb +22 -0
  46. data/fresh_rakefile +10 -0
  47. data/helpers/application.rb +15 -0
  48. data/helpers/application_helper.rb +3 -0
  49. data/helpers/test_helper.rb +38 -0
  50. data/html/404.html +30 -0
  51. data/html/422.html +30 -0
  52. data/html/500.html +30 -0
  53. data/html/favicon.ico +0 -0
  54. data/html/images/rails.png +0 -0
  55. data/html/index.html +274 -0
  56. data/html/javascripts/application.js +2 -0
  57. data/html/robots.txt +5 -0
  58. data/lib/code_statistics.rb +107 -0
  59. data/lib/commands/about.rb +3 -0
  60. data/lib/commands/console.rb +32 -0
  61. data/lib/commands/dbconsole.rb +67 -0
  62. data/lib/commands/destroy.rb +6 -0
  63. data/lib/commands/generate.rb +6 -0
  64. data/lib/commands/ncgi/listener +86 -0
  65. data/lib/commands/ncgi/tracker +69 -0
  66. data/lib/commands/performance/benchmarker.rb +24 -0
  67. data/lib/commands/performance/profiler.rb +50 -0
  68. data/lib/commands/performance/request.rb +6 -0
  69. data/lib/commands/plugin.rb +950 -0
  70. data/lib/commands/process/inspector.rb +68 -0
  71. data/lib/commands/process/reaper.rb +149 -0
  72. data/lib/commands/process/spawner.rb +219 -0
  73. data/lib/commands/process/spinner.rb +57 -0
  74. data/lib/commands/runner.rb +48 -0
  75. data/lib/commands/server.rb +39 -0
  76. data/lib/commands/servers/base.rb +31 -0
  77. data/lib/commands/servers/lighttpd.rb +94 -0
  78. data/lib/commands/servers/mongrel.rb +69 -0
  79. data/lib/commands/servers/new_mongrel.rb +16 -0
  80. data/lib/commands/servers/webrick.rb +66 -0
  81. data/lib/commands/update.rb +4 -0
  82. data/lib/commands.rb +17 -0
  83. data/lib/console_app.rb +30 -0
  84. data/lib/console_sandbox.rb +6 -0
  85. data/lib/console_with_helpers.rb +26 -0
  86. data/lib/dispatcher.rb +24 -0
  87. data/lib/fcgi_handler.rb +239 -0
  88. data/lib/initializer.rb +926 -0
  89. data/lib/rails/gem_builder.rb +21 -0
  90. data/lib/rails/gem_dependency.rb +129 -0
  91. data/lib/rails/mongrel_server/commands.rb +342 -0
  92. data/lib/rails/mongrel_server/handler.rb +55 -0
  93. data/lib/rails/plugin/loader.rb +152 -0
  94. data/lib/rails/plugin/locator.rb +100 -0
  95. data/lib/rails/plugin.rb +116 -0
  96. data/lib/rails/version.rb +9 -0
  97. data/lib/rails_generator/base.rb +263 -0
  98. data/lib/rails_generator/commands.rb +622 -0
  99. data/lib/rails_generator/generated_attribute.rb +42 -0
  100. data/lib/rails_generator/generators/applications/app/USAGE +9 -0
  101. data/lib/rails_generator/generators/applications/app/app_generator.rb +174 -0
  102. data/lib/rails_generator/generators/components/controller/USAGE +29 -0
  103. data/lib/rails_generator/generators/components/controller/controller_generator.rb +37 -0
  104. data/lib/rails_generator/generators/components/controller/templates/controller.rb +7 -0
  105. data/lib/rails_generator/generators/components/controller/templates/functional_test.rb +8 -0
  106. data/lib/rails_generator/generators/components/controller/templates/helper.rb +2 -0
  107. data/lib/rails_generator/generators/components/controller/templates/view.html.erb +2 -0
  108. data/lib/rails_generator/generators/components/integration_test/USAGE +8 -0
  109. data/lib/rails_generator/generators/components/integration_test/integration_test_generator.rb +16 -0
  110. data/lib/rails_generator/generators/components/integration_test/templates/integration_test.rb +10 -0
  111. data/lib/rails_generator/generators/components/mailer/USAGE +16 -0
  112. data/lib/rails_generator/generators/components/mailer/mailer_generator.rb +30 -0
  113. data/lib/rails_generator/generators/components/mailer/templates/fixture.erb +3 -0
  114. data/lib/rails_generator/generators/components/mailer/templates/fixture.rhtml +0 -0
  115. data/lib/rails_generator/generators/components/mailer/templates/mailer.rb +15 -0
  116. data/lib/rails_generator/generators/components/mailer/templates/unit_test.rb +21 -0
  117. data/lib/rails_generator/generators/components/mailer/templates/view.erb +3 -0
  118. data/lib/rails_generator/generators/components/mailer/templates/view.rhtml +0 -0
  119. data/lib/rails_generator/generators/components/migration/USAGE +29 -0
  120. data/lib/rails_generator/generators/components/migration/migration_generator.rb +20 -0
  121. data/lib/rails_generator/generators/components/migration/templates/migration.rb +11 -0
  122. data/lib/rails_generator/generators/components/model/USAGE +27 -0
  123. data/lib/rails_generator/generators/components/model/model_generator.rb +45 -0
  124. data/lib/rails_generator/generators/components/model/templates/fixtures.yml +19 -0
  125. data/lib/rails_generator/generators/components/model/templates/migration.rb +16 -0
  126. data/lib/rails_generator/generators/components/model/templates/model.rb +2 -0
  127. data/lib/rails_generator/generators/components/model/templates/unit_test.rb +8 -0
  128. data/lib/rails_generator/generators/components/observer/USAGE +13 -0
  129. data/lib/rails_generator/generators/components/observer/observer_generator.rb +16 -0
  130. data/lib/rails_generator/generators/components/observer/templates/observer.rb +2 -0
  131. data/lib/rails_generator/generators/components/observer/templates/unit_test.rb +8 -0
  132. data/lib/rails_generator/generators/components/plugin/USAGE +25 -0
  133. data/lib/rails_generator/generators/components/plugin/plugin_generator.rb +39 -0
  134. data/lib/rails_generator/generators/components/plugin/templates/MIT-LICENSE +20 -0
  135. data/lib/rails_generator/generators/components/plugin/templates/README +13 -0
  136. data/lib/rails_generator/generators/components/plugin/templates/Rakefile +22 -0
  137. data/lib/rails_generator/generators/components/plugin/templates/USAGE +8 -0
  138. data/lib/rails_generator/generators/components/plugin/templates/generator.rb +8 -0
  139. data/lib/rails_generator/generators/components/plugin/templates/init.rb +1 -0
  140. data/lib/rails_generator/generators/components/plugin/templates/install.rb +1 -0
  141. data/lib/rails_generator/generators/components/plugin/templates/plugin.rb +1 -0
  142. data/lib/rails_generator/generators/components/plugin/templates/tasks.rake +4 -0
  143. data/lib/rails_generator/generators/components/plugin/templates/uninstall.rb +1 -0
  144. data/lib/rails_generator/generators/components/plugin/templates/unit_test.rb +8 -0
  145. data/lib/rails_generator/generators/components/resource/USAGE +23 -0
  146. data/lib/rails_generator/generators/components/resource/resource_generator.rb +74 -0
  147. data/lib/rails_generator/generators/components/resource/templates/controller.rb +2 -0
  148. data/lib/rails_generator/generators/components/resource/templates/functional_test.rb +8 -0
  149. data/lib/rails_generator/generators/components/resource/templates/helper.rb +2 -0
  150. data/lib/rails_generator/generators/components/scaffold/USAGE +25 -0
  151. data/lib/rails_generator/generators/components/scaffold/scaffold_generator.rb +93 -0
  152. data/lib/rails_generator/generators/components/scaffold/templates/controller.rb +85 -0
  153. data/lib/rails_generator/generators/components/scaffold/templates/functional_test.rb +45 -0
  154. data/lib/rails_generator/generators/components/scaffold/templates/helper.rb +2 -0
  155. data/lib/rails_generator/generators/components/scaffold/templates/layout.html.erb +17 -0
  156. data/lib/rails_generator/generators/components/scaffold/templates/style.css +54 -0
  157. data/lib/rails_generator/generators/components/scaffold/templates/view_edit.html.erb +18 -0
  158. data/lib/rails_generator/generators/components/scaffold/templates/view_index.html.erb +24 -0
  159. data/lib/rails_generator/generators/components/scaffold/templates/view_new.html.erb +17 -0
  160. data/lib/rails_generator/generators/components/scaffold/templates/view_show.html.erb +10 -0
  161. data/lib/rails_generator/generators/components/session_migration/USAGE +10 -0
  162. data/lib/rails_generator/generators/components/session_migration/session_migration_generator.rb +18 -0
  163. data/lib/rails_generator/generators/components/session_migration/templates/migration.rb +16 -0
  164. data/lib/rails_generator/lookup.rb +249 -0
  165. data/lib/rails_generator/manifest.rb +53 -0
  166. data/lib/rails_generator/options.rb +150 -0
  167. data/lib/rails_generator/scripts/destroy.rb +30 -0
  168. data/lib/rails_generator/scripts/generate.rb +7 -0
  169. data/lib/rails_generator/scripts/update.rb +12 -0
  170. data/lib/rails_generator/scripts.rb +89 -0
  171. data/lib/rails_generator/secret_key_generator.rb +164 -0
  172. data/lib/rails_generator/simple_logger.rb +46 -0
  173. data/lib/rails_generator/spec.rb +44 -0
  174. data/lib/rails_generator.rb +43 -0
  175. data/lib/railties_path.rb +1 -0
  176. data/lib/ruby_version_check.rb +17 -0
  177. data/lib/rubyprof_ext.rb +35 -0
  178. data/lib/source_annotation_extractor.rb +102 -0
  179. data/lib/tasks/annotations.rake +23 -0
  180. data/lib/tasks/databases.rake +389 -0
  181. data/lib/tasks/documentation.rake +80 -0
  182. data/lib/tasks/framework.rake +105 -0
  183. data/lib/tasks/gems.rake +64 -0
  184. data/lib/tasks/log.rake +9 -0
  185. data/lib/tasks/misc.rake +57 -0
  186. data/lib/tasks/rails.rb +8 -0
  187. data/lib/tasks/routes.rake +17 -0
  188. data/lib/tasks/statistics.rake +18 -0
  189. data/lib/tasks/testing.rake +118 -0
  190. data/lib/tasks/tmp.rake +37 -0
  191. data/lib/test_help.rb +28 -0
  192. data/lib/webrick_server.rb +165 -0
  193. metadata +356 -0
@@ -0,0 +1,94 @@
1
+ require 'rbconfig'
2
+ require 'commands/servers/base'
3
+
4
+ unless RUBY_PLATFORM !~ /mswin/ && !silence_stderr { `lighttpd -version` }.blank?
5
+ puts "PROBLEM: Lighttpd is not available on your system (or not in your path)"
6
+ exit 1
7
+ end
8
+
9
+ unless defined?(FCGI)
10
+ puts "PROBLEM: Lighttpd requires that the FCGI Ruby bindings are installed on the system"
11
+ exit 1
12
+ end
13
+
14
+ require 'initializer'
15
+ configuration = Rails::Initializer.run(:initialize_logger).configuration
16
+ default_config_file = config_file = Pathname.new("#{RAILS_ROOT}/config/lighttpd.conf").cleanpath
17
+
18
+ require 'optparse'
19
+
20
+ detach = false
21
+ command_line_port = nil
22
+
23
+ ARGV.options do |opt|
24
+ opt.on("-p", "--port=port", "Changes the server.port number in the config/lighttpd.conf") { |port| command_line_port = port }
25
+ opt.on('-c', "--config=#{config_file}", 'Specify a different lighttpd config file.') { |path| config_file = path }
26
+ opt.on('-h', '--help', 'Show this message.') { puts opt; exit 0 }
27
+ opt.on('-d', '-d', 'Call with -d to detach') { detach = true; puts "=> Configuration in config/lighttpd.conf" }
28
+ opt.parse!
29
+ end
30
+
31
+ unless File.exist?(config_file)
32
+ if config_file != default_config_file
33
+ puts "=> #{config_file} not found."
34
+ exit 1
35
+ end
36
+
37
+ require 'fileutils'
38
+
39
+ source = File.expand_path(File.join(File.dirname(__FILE__),
40
+ "..", "..", "..", "configs", "lighttpd.conf"))
41
+ puts "=> #{config_file} not found, copying from #{source}"
42
+
43
+ FileUtils.cp(source, config_file)
44
+ end
45
+
46
+ # open the config/lighttpd.conf file and add the current user defined port setting to it
47
+ if command_line_port
48
+ File.open(config_file, 'r+') do |config|
49
+ lines = config.readlines
50
+
51
+ lines.each do |line|
52
+ line.gsub!(/^\s*server.port\s*=\s*(\d+)/, "server.port = #{command_line_port}")
53
+ end
54
+
55
+ config.rewind
56
+ config.print(lines)
57
+ config.truncate(config.pos)
58
+ end
59
+ end
60
+
61
+ config = IO.read(config_file)
62
+ default_port, default_ip = 3000, '0.0.0.0'
63
+ port = config.scan(/^\s*server.port\s*=\s*(\d+)/).first rescue default_port
64
+ ip = config.scan(/^\s*server.bind\s*=\s*"([^"]+)"/).first rescue default_ip
65
+ puts "=> Enhanced Rails #{Rails.version} application starting on http://#{ip || default_ip}:#{port || default_port}"
66
+
67
+ tail_thread = nil
68
+
69
+ if !detach
70
+ puts "=> Call with -d to detach"
71
+ puts "=> Ctrl-C to shutdown server (see config/lighttpd.conf for options)"
72
+ detach = false
73
+ tail_thread = tail(configuration.log_path)
74
+ end
75
+
76
+ trap(:INT) { exit }
77
+
78
+ begin
79
+ `rake tmp:sockets:clear` # Needed if lighttpd crashes or otherwise leaves FCGI sockets around
80
+ `lighttpd #{!detach ? "-D " : ""}-f #{config_file}`
81
+ ensure
82
+ unless detach
83
+ tail_thread.kill if tail_thread
84
+ puts 'Exiting'
85
+
86
+ # Ensure FCGI processes are reaped
87
+ silence_stream(STDOUT) do
88
+ ARGV.replace ['-a', 'kill']
89
+ require 'commands/process/reaper'
90
+ end
91
+
92
+ `rake tmp:sockets:clear` # Remove sockets on clean shutdown
93
+ end
94
+ end
@@ -0,0 +1,69 @@
1
+ require 'rbconfig'
2
+ require 'commands/servers/base'
3
+
4
+ unless defined?(Mongrel)
5
+ puts "PROBLEM: Mongrel is not available on your system (or not in your path)"
6
+ exit 1
7
+ end
8
+
9
+ require 'optparse'
10
+
11
+ OPTIONS = {
12
+ :port => 3000,
13
+ :ip => "0.0.0.0",
14
+ :environment => (ENV['RAILS_ENV'] || "development").dup,
15
+ :detach => false,
16
+ :debugger => false
17
+ }
18
+
19
+ ARGV.clone.options do |opts|
20
+ opts.on("-p", "--port=port", Integer, "Runs Rails on the specified port.", "Default: 3000") { |v| OPTIONS[:port] = v }
21
+ opts.on("-b", "--binding=ip", String, "Binds Rails to the specified ip.", "Default: 0.0.0.0") { |v| OPTIONS[:ip] = v }
22
+ opts.on("-d", "--daemon", "Make server run as a Daemon.") { OPTIONS[:detach] = true }
23
+ opts.on("-u", "--debugger", "Enable ruby-debugging for the server.") { OPTIONS[:debugger] = true }
24
+ opts.on("-e", "--environment=name", String,
25
+ "Specifies the environment to run this server under (test/development/production).",
26
+ "Default: development") { |v| OPTIONS[:environment] = v }
27
+
28
+ opts.separator ""
29
+
30
+ opts.on("-h", "--help", "Show this help message.") { puts opts; exit }
31
+
32
+ opts.parse!
33
+ end
34
+
35
+ puts "=> Enhanced Rails #{Rails.version} application starting on http://#{OPTIONS[:ip]}:#{OPTIONS[:port]}"
36
+
37
+ parameters = [
38
+ "start",
39
+ "-p", OPTIONS[:port].to_s,
40
+ "-a", OPTIONS[:ip].to_s,
41
+ "-e", OPTIONS[:environment],
42
+ "-P", "#{RAILS_ROOT}/tmp/pids/mongrel.pid"
43
+ ]
44
+
45
+ if OPTIONS[:detach]
46
+ `mongrel_rails #{parameters.join(" ")} -d`
47
+ else
48
+ ENV["RAILS_ENV"] = OPTIONS[:environment]
49
+ RAILS_ENV.replace(OPTIONS[:environment]) if defined?(RAILS_ENV)
50
+
51
+ start_debugger if OPTIONS[:debugger]
52
+
53
+ puts "=> Call with -d to detach"
54
+ puts "=> Ctrl-C to shutdown server"
55
+
56
+ log = Pathname.new("#{File.expand_path(RAILS_ROOT)}/log/#{RAILS_ENV}.log").cleanpath
57
+ open(log, (File::WRONLY | File::APPEND | File::CREAT)) unless File.exist? log
58
+ tail_thread = tail(log)
59
+
60
+ trap(:INT) { exit }
61
+
62
+ begin
63
+ silence_warnings { ARGV = parameters }
64
+ load("mongrel_rails")
65
+ ensure
66
+ tail_thread.kill if tail_thread
67
+ puts 'Exiting'
68
+ end
69
+ end
@@ -0,0 +1,16 @@
1
+ unless defined?(Mongrel)
2
+ abort "PROBLEM: Mongrel is not available on your system (or not in your path)"
3
+ end
4
+
5
+ require 'rails/mongrel_server/commands'
6
+
7
+ GemPlugin::Manager.instance.load "rails::mongrel" => GemPlugin::INCLUDE, "rails" => GemPlugin::EXCLUDE
8
+
9
+ case ARGV[0] ||= 'start'
10
+ when 'start', 'stop', 'restart'
11
+ ARGV[0] = "rails::mongrelserver::#{ARGV[0]}"
12
+ end
13
+
14
+ if not Mongrel::Command::Registry.instance.run ARGV
15
+ exit 1
16
+ end
@@ -0,0 +1,66 @@
1
+ require 'webrick'
2
+ require 'optparse'
3
+ require 'commands/servers/base'
4
+
5
+ OPTIONS = {
6
+ :port => 3000,
7
+ :ip => "0.0.0.0",
8
+ :environment => (ENV['RAILS_ENV'] || "development").dup,
9
+ :server_root => File.expand_path(RAILS_ROOT + "/public/"),
10
+ :server_type => WEBrick::SimpleServer,
11
+ :charset => "UTF-8",
12
+ :mime_types => WEBrick::HTTPUtils::DefaultMimeTypes,
13
+ :debugger => false
14
+
15
+ }
16
+
17
+ ARGV.options do |opts|
18
+ script_name = File.basename($0)
19
+ opts.banner = "Usage: ruby #{script_name} [options]"
20
+
21
+ opts.separator ""
22
+
23
+ opts.on("-p", "--port=port", Integer,
24
+ "Runs Rails on the specified port.",
25
+ "Default: 3000") { |v| OPTIONS[:port] = v }
26
+ opts.on("-b", "--binding=ip", String,
27
+ "Binds Rails to the specified ip.",
28
+ "Default: 0.0.0.0") { |v| OPTIONS[:ip] = v }
29
+ opts.on("-e", "--environment=name", String,
30
+ "Specifies the environment to run this server under (test/development/production).",
31
+ "Default: development") { |v| OPTIONS[:environment] = v }
32
+ opts.on("-m", "--mime-types=filename", String,
33
+ "Specifies an Apache style mime.types configuration file to be used for mime types",
34
+ "Default: none") { |mime_types_file| OPTIONS[:mime_types] = WEBrick::HTTPUtils::load_mime_types(mime_types_file) }
35
+
36
+ opts.on("-d", "--daemon",
37
+ "Make Rails run as a Daemon (only works if fork is available -- meaning on *nix)."
38
+ ) { OPTIONS[:server_type] = WEBrick::Daemon }
39
+
40
+ opts.on("-u", "--debugger", "Enable ruby-debugging for the server.") { OPTIONS[:debugger] = true }
41
+
42
+ opts.on("-c", "--charset=charset", String,
43
+ "Set default charset for output.",
44
+ "Default: UTF-8") { |v| OPTIONS[:charset] = v }
45
+
46
+ opts.separator ""
47
+
48
+ opts.on("-h", "--help",
49
+ "Show this help message.") { puts opts; exit }
50
+
51
+ opts.parse!
52
+ end
53
+
54
+ start_debugger if OPTIONS[:debugger]
55
+
56
+ ENV["RAILS_ENV"] = OPTIONS[:environment]
57
+ RAILS_ENV.replace(OPTIONS[:environment]) if defined?(RAILS_ENV)
58
+
59
+ require RAILS_ROOT + "/config/environment"
60
+ require 'webrick_server'
61
+
62
+ OPTIONS['working_directory'] = File.expand_path(RAILS_ROOT)
63
+
64
+ puts "=> Rails #{Rails.version} application started on http://#{OPTIONS[:ip]}:#{OPTIONS[:port]}"
65
+ puts "=> Ctrl-C to shutdown server; call with --help for options" if OPTIONS[:server_type] == WEBrick::SimpleServer
66
+ DispatchServlet.dispatch(OPTIONS)
@@ -0,0 +1,4 @@
1
+ require "#{RAILS_ROOT}/config/environment"
2
+ require 'rails_generator'
3
+ require 'rails_generator/scripts/update'
4
+ Rails::Generator::Scripts::Update.new.run(ARGV)
data/lib/commands.rb ADDED
@@ -0,0 +1,17 @@
1
+ commands = Dir["#{File.dirname(__FILE__)}/commands/*.rb"].collect { |file_path| File.basename(file_path).split(".").first }
2
+
3
+ if commands.include?(ARGV.first)
4
+ require "#{File.dirname(__FILE__)}/commands/#{ARGV.shift}"
5
+ else
6
+ puts <<-USAGE
7
+ The 'run' provides a unified access point for all the default Rails' commands.
8
+
9
+ Usage: ./script/run <command> [OPTIONS]
10
+
11
+ Examples:
12
+ ./script/run generate controller Admin
13
+ ./script/run process reaper
14
+
15
+ USAGE
16
+ puts "Choose: #{commands.join(", ")}"
17
+ end
@@ -0,0 +1,30 @@
1
+ require 'action_controller/integration'
2
+
3
+ # work around the at_exit hook in test/unit, which kills IRB
4
+ Test::Unit.run = true if Test::Unit.respond_to?(:run=)
5
+
6
+ # reference the global "app" instance, created on demand. To recreate the
7
+ # instance, pass a non-false value as the parameter.
8
+ def app(create=false)
9
+ @app_integration_instance = nil if create
10
+ @app_integration_instance ||= new_session do |sess|
11
+ sess.host! "www.example.com"
12
+ end
13
+ end
14
+
15
+ # create a new session. If a block is given, the new session will be yielded
16
+ # to the block before being returned.
17
+ def new_session
18
+ session = ActionController::Integration::Session.new
19
+ yield session if block_given?
20
+ session
21
+ end
22
+
23
+ #reloads the environment
24
+ def reload!
25
+ puts "Reloading..."
26
+ dispatcher = ActionController::Dispatcher.new($stdout)
27
+ dispatcher.cleanup_application
28
+ dispatcher.reload_application
29
+ true
30
+ end
@@ -0,0 +1,6 @@
1
+ ActiveRecord::Base.send :increment_open_transactions
2
+ ActiveRecord::Base.connection.begin_db_transaction
3
+ at_exit do
4
+ ActiveRecord::Base.connection.rollback_db_transaction
5
+ ActiveRecord::Base.send :decrement_open_transactions
6
+ end
@@ -0,0 +1,26 @@
1
+ class Module
2
+ def include_all_modules_from(parent_module)
3
+ parent_module.constants.each do |const|
4
+ mod = parent_module.const_get(const)
5
+ if mod.class == Module
6
+ send(:include, mod)
7
+ include_all_modules_from(mod)
8
+ end
9
+ end
10
+ end
11
+ end
12
+
13
+ def helper(*helper_names)
14
+ returning @helper_proxy ||= Object.new do |helper|
15
+ helper_names.each { |h| helper.extend "#{h}_helper".classify.constantize }
16
+ end
17
+ end
18
+
19
+ require_dependency 'application'
20
+
21
+ class << helper
22
+ include_all_modules_from ActionView
23
+ end
24
+
25
+ @controller = ApplicationController.new
26
+ helper :application rescue nil
data/lib/dispatcher.rb ADDED
@@ -0,0 +1,24 @@
1
+ #--
2
+ # Copyright (c) 2004-2008 David Heinemeier Hansson
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #++
23
+ require 'action_controller/dispatcher'
24
+ Dispatcher = ActionController::Dispatcher
@@ -0,0 +1,239 @@
1
+ require 'fcgi'
2
+ require 'logger'
3
+ require 'dispatcher'
4
+ require 'rbconfig'
5
+
6
+ class RailsFCGIHandler
7
+ SIGNALS = {
8
+ 'HUP' => :reload,
9
+ 'INT' => :exit_now,
10
+ 'TERM' => :exit_now,
11
+ 'USR1' => :exit,
12
+ 'USR2' => :restart
13
+ }
14
+ GLOBAL_SIGNALS = SIGNALS.keys - %w(USR1)
15
+
16
+ attr_reader :when_ready
17
+
18
+ attr_accessor :log_file_path
19
+ attr_accessor :gc_request_period
20
+
21
+
22
+ # Initialize and run the FastCGI instance, passing arguments through to new.
23
+ def self.process!(*args, &block)
24
+ new(*args, &block).process!
25
+ end
26
+
27
+ # Initialize the FastCGI instance with the path to a crash log
28
+ # detailing unhandled exceptions (default RAILS_ROOT/log/fastcgi.crash.log)
29
+ # and the number of requests to process between garbage collection runs
30
+ # (default nil for normal GC behavior.) Optionally, pass a block which
31
+ # takes this instance as an argument for further configuration.
32
+ def initialize(log_file_path = nil, gc_request_period = nil)
33
+ self.log_file_path = log_file_path || "#{RAILS_ROOT}/log/fastcgi.crash.log"
34
+ self.gc_request_period = gc_request_period
35
+
36
+ # Yield for additional configuration.
37
+ yield self if block_given?
38
+
39
+ # Safely install signal handlers.
40
+ install_signal_handlers
41
+
42
+ # Start error timestamp at 11 seconds ago.
43
+ @last_error_on = Time.now - 11
44
+ end
45
+
46
+ def process!(provider = FCGI)
47
+ mark_features!
48
+
49
+ dispatcher_log :info, 'starting'
50
+ process_each_request provider
51
+ dispatcher_log :info, 'stopping gracefully'
52
+
53
+ rescue Exception => error
54
+ case error
55
+ when SystemExit
56
+ dispatcher_log :info, 'stopping after explicit exit'
57
+ when SignalException
58
+ dispatcher_error error, 'stopping after unhandled signal'
59
+ else
60
+ # Retry if exceptions occur more than 10 seconds apart.
61
+ if Time.now - @last_error_on > 10
62
+ @last_error_on = Time.now
63
+ dispatcher_error error, 'retrying after unhandled exception'
64
+ retry
65
+ else
66
+ dispatcher_error error, 'stopping after unhandled exception within 10 seconds of the last'
67
+ end
68
+ end
69
+ end
70
+
71
+
72
+ protected
73
+ def process_each_request(provider)
74
+ cgi = nil
75
+
76
+ catch :exit do
77
+ provider.each_cgi do |cgi|
78
+ process_request(cgi)
79
+
80
+ case when_ready
81
+ when :reload
82
+ reload!
83
+ when :restart
84
+ close_connection(cgi)
85
+ restart!
86
+ when :exit
87
+ close_connection(cgi)
88
+ throw :exit
89
+ end
90
+ end
91
+ end
92
+ rescue SignalException => signal
93
+ raise unless signal.message == 'SIGUSR1'
94
+ close_connection(cgi)
95
+ end
96
+
97
+ def process_request(cgi)
98
+ @processing, @when_ready = true, nil
99
+ gc_countdown
100
+
101
+ with_signal_handler 'USR1' do
102
+ begin
103
+ Dispatcher.dispatch(cgi)
104
+ rescue SignalException, SystemExit
105
+ raise
106
+ rescue Exception => error
107
+ dispatcher_error error, 'unhandled dispatch error'
108
+ end
109
+ end
110
+ ensure
111
+ @processing = false
112
+ end
113
+
114
+ def logger
115
+ @logger ||= Logger.new(@log_file_path)
116
+ end
117
+
118
+ def dispatcher_log(level, msg)
119
+ time_str = Time.now.strftime("%d/%b/%Y:%H:%M:%S")
120
+ logger.send(level, "[#{time_str} :: #{$$}] #{msg}")
121
+ rescue Exception => log_error # Logger errors
122
+ STDERR << "Couldn't write to #{@log_file_path.inspect}: #{msg}\n"
123
+ STDERR << " #{log_error.class}: #{log_error.message}\n"
124
+ end
125
+
126
+ def dispatcher_error(e, msg = "")
127
+ error_message =
128
+ "Dispatcher failed to catch: #{e} (#{e.class})\n" +
129
+ " #{e.backtrace.join("\n ")}\n#{msg}"
130
+ dispatcher_log(:error, error_message)
131
+ end
132
+
133
+ def install_signal_handlers
134
+ GLOBAL_SIGNALS.each { |signal| install_signal_handler(signal) }
135
+ end
136
+
137
+ def install_signal_handler(signal, handler = nil)
138
+ if SIGNALS.include?(signal) && self.class.method_defined?(name = "#{SIGNALS[signal]}_handler")
139
+ handler ||= method(name).to_proc
140
+
141
+ begin
142
+ trap(signal, handler)
143
+ rescue ArgumentError
144
+ dispatcher_log :warn, "Ignoring unsupported signal #{signal}."
145
+ end
146
+ else
147
+ dispatcher_log :warn, "Ignoring unsupported signal #{signal}."
148
+ end
149
+ end
150
+
151
+ def with_signal_handler(signal)
152
+ install_signal_handler(signal)
153
+ yield
154
+ ensure
155
+ install_signal_handler(signal, 'DEFAULT')
156
+ end
157
+
158
+ def exit_now_handler(signal)
159
+ dispatcher_log :info, "asked to stop immediately"
160
+ exit
161
+ end
162
+
163
+ def exit_handler(signal)
164
+ dispatcher_log :info, "asked to stop ASAP"
165
+ if @processing
166
+ @when_ready = :exit
167
+ else
168
+ throw :exit
169
+ end
170
+ end
171
+
172
+ def reload_handler(signal)
173
+ dispatcher_log :info, "asked to reload ASAP"
174
+ if @processing
175
+ @when_ready = :reload
176
+ else
177
+ reload!
178
+ end
179
+ end
180
+
181
+ def restart_handler(signal)
182
+ dispatcher_log :info, "asked to restart ASAP"
183
+ if @processing
184
+ @when_ready = :restart
185
+ else
186
+ restart!
187
+ end
188
+ end
189
+
190
+ def restart!
191
+ config = ::Config::CONFIG
192
+ ruby = File::join(config['bindir'], config['ruby_install_name']) + config['EXEEXT']
193
+ command_line = [ruby, $0, ARGV].flatten.join(' ')
194
+
195
+ dispatcher_log :info, "restarted"
196
+
197
+ # close resources as they won't be closed by
198
+ # the OS when using exec
199
+ logger.close rescue nil
200
+ RAILS_DEFAULT_LOGGER.close rescue nil
201
+
202
+ exec(command_line)
203
+ end
204
+
205
+ def reload!
206
+ run_gc! if gc_request_period
207
+ restore!
208
+ @when_ready = nil
209
+ dispatcher_log :info, "reloaded"
210
+ end
211
+
212
+ # Make a note of $" so we can safely reload this instance.
213
+ def mark_features!
214
+ @features = $".clone
215
+ end
216
+
217
+ def restore!
218
+ $".replace @features
219
+ Dispatcher.reset_application!
220
+ ActionController::Routing::Routes.reload
221
+ end
222
+
223
+ def run_gc!
224
+ @gc_request_countdown = gc_request_period
225
+ GC.enable; GC.start; GC.disable
226
+ end
227
+
228
+ def gc_countdown
229
+ if gc_request_period
230
+ @gc_request_countdown ||= gc_request_period
231
+ @gc_request_countdown -= 1
232
+ run_gc! if @gc_request_countdown <= 0
233
+ end
234
+ end
235
+
236
+ def close_connection(cgi)
237
+ cgi.instance_variable_get("@request").finish if cgi
238
+ end
239
+ end