rails 0.14.3 → 0.14.4

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.

Files changed (53) hide show
  1. data/CHANGELOG +51 -0
  2. data/Rakefile +8 -7
  3. data/bin/about +1 -1
  4. data/bin/breakpointer +1 -1
  5. data/bin/console +1 -1
  6. data/bin/destroy +1 -1
  7. data/bin/generate +1 -1
  8. data/bin/performance/benchmarker +1 -1
  9. data/bin/performance/profiler +1 -1
  10. data/bin/plugin +1 -1
  11. data/bin/process/reaper +1 -1
  12. data/bin/process/spawner +1 -1
  13. data/bin/process/spinner +1 -1
  14. data/bin/rails +1 -1
  15. data/bin/runner +1 -1
  16. data/bin/server +1 -1
  17. data/builtin/controllers/rails_info_controller.rb +11 -0
  18. data/environments/boot.rb +2 -0
  19. data/environments/development.rb +2 -0
  20. data/environments/environment.rb +4 -2
  21. data/environments/production.rb +2 -0
  22. data/environments/test.rb +2 -0
  23. data/html/images/rails.png +0 -0
  24. data/html/index.html +270 -71
  25. data/html/javascripts/controls.js +30 -1
  26. data/html/javascripts/dragdrop.js +37 -17
  27. data/html/javascripts/effects.js +3 -91
  28. data/html/javascripts/prototype.js +109 -67
  29. data/lib/commands/console.rb +1 -0
  30. data/lib/commands/performance/benchmarker.rb +0 -2
  31. data/lib/commands/performance/profiler.rb +0 -1
  32. data/lib/commands/plugin.rb +1 -1
  33. data/lib/commands/servers/lighttpd.rb +25 -21
  34. data/lib/dispatcher.rb +1 -0
  35. data/lib/initializer.rb +10 -5
  36. data/lib/rails_generator/commands.rb +53 -4
  37. data/lib/rails_generator/generators/applications/app/app_generator.rb +6 -4
  38. data/lib/rails_generator/generators/components/migration/migration_generator.rb +0 -51
  39. data/lib/rails_generator/generators/components/model/model_generator.rb +1 -1
  40. data/lib/rails_generator/generators/components/model/templates/unit_test.rb +1 -1
  41. data/lib/rails_generator/generators/components/session_migration/USAGE +15 -0
  42. data/lib/rails_generator/generators/components/session_migration/session_migration_generator.rb +12 -0
  43. data/lib/rails_generator/generators/components/session_migration/templates/migration.rb +15 -0
  44. data/lib/rails_generator/options.rb +6 -1
  45. data/lib/rails_info.rb +12 -2
  46. data/lib/rails_version.rb +2 -2
  47. data/lib/railties_path.rb +1 -1
  48. data/lib/tasks/databases.rake +9 -6
  49. data/lib/tasks/documentation.rake +3 -4
  50. data/lib/tasks/framework.rake +22 -22
  51. data/lib/tasks/javascripts.rake +1 -1
  52. data/lib/test_help.rb +4 -0
  53. metadata +17 -7
@@ -3,6 +3,7 @@ irb = RUBY_PLATFORM =~ /mswin32/ ? 'irb.bat' : 'irb'
3
3
  require 'optparse'
4
4
  options = { :sandbox => false, :irb => irb }
5
5
  OptionParser.new do |opt|
6
+ opt.banner = "Usage: console [environment] [options]"
6
7
  opt.on('-s', '--sandbox', 'Rollback database modifications on exit.') { |options[:sandbox]| }
7
8
  opt.on("--irb=[#{irb}]", 'Invoke a different irb.') { |options[:irb]| }
8
9
  opt.parse!(ARGV)
@@ -1,5 +1,3 @@
1
- #!/usr/local/bin/ruby
2
-
3
1
  if ARGV.empty?
4
2
  puts "Usage: ./script/perform benchmarker [times] 'Person.expensive_way' 'Person.another_expensive_way' ..."
5
3
  exit 1
@@ -1,4 +1,3 @@
1
- #!/usr/local/bin/ruby
2
1
  if ARGV.empty?
3
2
  $stderr.puts "Usage: ./script/perform profiler 'Person.expensive_method(10)' [times]"
4
3
  exit(1)
@@ -119,7 +119,7 @@ class RailsEnvironment
119
119
 
120
120
  def externals
121
121
  return [] unless use_externals?
122
- ext = silence_stderr { `svn propget svn:externals #{root}/vendor/plugins` }
122
+ ext = `svn propget svn:externals #{root}/vendor/plugins`
123
123
  ext.reject{ |line| line.strip == '' }.map do |line|
124
124
  line.strip.split(/\s+/, 2)
125
125
  end
@@ -8,16 +8,8 @@ unless defined?(FCGI)
8
8
  exit 1
9
9
  end
10
10
 
11
- def tail_f(input)
12
- loop do
13
- line = input.gets
14
- yield line if line
15
- if input.eof?
16
- sleep 1
17
- input.seek(input.tell)
18
- end
19
- end
20
- end
11
+ require 'initializer'
12
+ configuration = Rails::Initializer.run(:initialize_logger).configuration
21
13
 
22
14
  config_file = "#{RAILS_ROOT}/config/lighttpd.conf"
23
15
 
@@ -29,8 +21,13 @@ unless File.exist?(config_file)
29
21
  FileUtils.cp source, config_file
30
22
  end
31
23
 
32
- port = IO.read(config_file).scan(/^server.port\s*=\s*(\d+)/).first rescue 3000
33
- puts "=> Rails application started on http://0.0.0.0:#{port}"
24
+ config = IO.read(config_file)
25
+ default_port, default_ip = 3000, '0.0.0.0'
26
+ port = config.scan(/^\s*server.port\s*=\s*(\d+)/).first rescue default_port
27
+ ip = config.scan(/^\s*server.bind\s*=\s*"([^"]+)"/).first rescue default_ip
28
+ puts "=> Rails application started on http://#{ip || default_ip}:#{port || default_port}"
29
+
30
+ tail_thread = nil
34
31
 
35
32
  if ARGV.first == "-d"
36
33
  puts "=> Configure in config/lighttpd.conf"
@@ -40,17 +37,24 @@ else
40
37
  puts "=> Ctrl-C to shutdown server (see config/lighttpd.conf for options)"
41
38
  detach = false
42
39
 
43
- Process.detach(fork do
44
- begin
45
- File.open("#{RAILS_ROOT}/log/#{RAILS_ENV}.log", 'r') do |log|
46
- log.seek(0, IO::SEEK_END)
47
- tail_f(log) {|line| puts line}
40
+ cursor = File.size(configuration.log_path)
41
+ last_checked = Time.now
42
+ tail_thread = Thread.new do
43
+ File.open(configuration.log_path, 'r') do |f|
44
+ loop do
45
+ f.seek cursor
46
+ if f.mtime > last_checked
47
+ last_checked = f.mtime
48
+ contents = f.read
49
+ cursor += contents.length
50
+ print contents
51
+ end
52
+ sleep 1
48
53
  end
49
- rescue Exception
50
54
  end
51
- exit
52
- end)
55
+ end
53
56
  end
54
57
 
55
- trap(:INT) {exit}
58
+ trap(:INT) { exit }
56
59
  `lighttpd #{!detach ? "-D " : ""}-f #{config_file}`
60
+ tail_thread.kill if tail_thread
@@ -73,6 +73,7 @@ class Dispatcher
73
73
 
74
74
  def reset_after_dispatch
75
75
  reset_application! if Dependencies.load?
76
+ ActiveRecord::Base.clear_connection_cache!
76
77
  Breakpoint.deactivate_drb if defined?(BREAKPOINT_SERVER_PORT)
77
78
  end
78
79
 
@@ -1,5 +1,6 @@
1
1
  require 'logger'
2
2
  require 'set'
3
+ require File.join(File.dirname(__FILE__), 'railties_path')
3
4
 
4
5
  RAILS_ENV = (ENV['RAILS_ENV'] || 'development').dup unless defined?(RAILS_ENV)
5
6
 
@@ -37,7 +38,9 @@ module Rails
37
38
  # incuring the overhead of completely loading the entire environment.
38
39
  def self.run(command = :process, configuration = Configuration.new)
39
40
  yield configuration if block_given?
40
- new(configuration).send(command)
41
+ initializer = new configuration
42
+ initializer.send(command)
43
+ initializer
41
44
  end
42
45
 
43
46
  # Create a new Initializer instance that references the given Configuration
@@ -81,7 +84,6 @@ module Rails
81
84
  initialize_logger
82
85
  initialize_framework_logging
83
86
  initialize_framework_views
84
- initialize_routing
85
87
  initialize_dependency_mechanism
86
88
  initialize_breakpoints
87
89
  initialize_whiny_nils
@@ -96,6 +98,9 @@ module Rails
96
98
  load_framework_info
97
99
 
98
100
  load_plugins
101
+
102
+ # Routing must be initialized after plugins to allow the former to extend the routes
103
+ initialize_routing
99
104
  end
100
105
 
101
106
  # Set the <tt>$LOAD_PATH</tt> based on the value of
@@ -120,7 +125,7 @@ module Rails
120
125
  configuration.frameworks.each { |framework| require(framework.to_s) }
121
126
  end
122
127
 
123
- # Loads Rails::Version and Rails::Info.
128
+ # Loads Rails::VERSION and Rails::Info.
124
129
  # TODO: Make this work via dependencies.rb/const_missing instead.
125
130
  def load_framework_info
126
131
  require 'rails_info'
@@ -303,7 +308,7 @@ module Rails
303
308
  config = configuration
304
309
 
305
310
  # Evaluate init.rb.
306
- silence_warnings { eval(IO.read(init_path), binding) } if has_init
311
+ silence_warnings { eval(IO.read(init_path), binding, init_path) } if has_init
307
312
 
308
313
  # Add to set of loaded plugins.
309
314
  loaded_plugins << name
@@ -488,7 +493,7 @@ module Rails
488
493
  end
489
494
 
490
495
  def default_controller_paths
491
- [ File.join(root_path, 'app', 'controllers'), File.join(root_path, 'components') ]
496
+ [ File.join(root_path, 'app', 'controllers'), File.join(root_path, 'components'), File.join(RAILTIES_PATH, 'builtin', 'controllers') ]
492
497
  end
493
498
 
494
499
  def default_dependency_mechanism
@@ -55,6 +55,34 @@ module Rails
55
55
  def readme(*args)
56
56
  end
57
57
 
58
+ protected
59
+ def migration_directory(relative_path)
60
+ directory(@migration_directory = relative_path)
61
+ end
62
+
63
+ def existing_migrations(file_name)
64
+ Dir.glob("#{@migration_directory}/[0-9]*_#{file_name}.rb")
65
+ end
66
+
67
+ def migration_exists?(file_name)
68
+ not existing_migrations(file_name).empty?
69
+ end
70
+
71
+ def current_migration_number
72
+ Dir.glob("#{@migration_directory}/[0-9]*.rb").inject(0) do |max, file_path|
73
+ n = File.basename(file_path).split('_', 2).first.to_i
74
+ if n > max then n else max end
75
+ end
76
+ end
77
+
78
+ def next_migration_number
79
+ current_migration_number + 1
80
+ end
81
+
82
+ def next_migration_string(padding = 3)
83
+ "%.#{padding}d" % next_migration_number
84
+ end
85
+
58
86
  private
59
87
  # Ask the user interactively whether to force collision.
60
88
  def force_file_collision?(destination)
@@ -84,10 +112,10 @@ module Rails
84
112
  begin_mark = template_part_mark(template_options[:begin_mark], template_options[:mark_id])
85
113
  end_mark = template_part_mark(template_options[:end_mark], template_options[:mark_id])
86
114
  begin_mark + rendered_part + end_mark
87
- end
115
+ end
88
116
 
89
- def template_part_mark(name, id)
90
- "<!--[#{name}:#{id}]-->\n"
117
+ def template_part_mark(name, id)
118
+ "<!--[#{name}:#{id}]-->\n"
91
119
  end
92
120
  end
93
121
 
@@ -192,7 +220,7 @@ module Rails
192
220
  if block_given?
193
221
  df.write(yield(sf))
194
222
  else
195
- line = sf.gets
223
+ line = sf.gets || ''
196
224
  if file_options[:shebang]
197
225
  df.puts("#!#{file_options[:shebang]}")
198
226
  df.puts(line) if line !~ /^#!/
@@ -279,6 +307,13 @@ module Rails
279
307
  end
280
308
  end
281
309
 
310
+ # When creating a migration, it knows to find the first available file in db/migrate and use the migration.rb template.
311
+ def migration_template(relative_source, relative_destination, template_options = {})
312
+ migration_directory relative_destination
313
+ raise "Another migration is already named #{file_name}: #{existing_migrations(file_name).first}" if migration_exists?(file_name)
314
+ template(relative_source, "#{relative_destination}/#{next_migration_string}_#{file_name}.rb", template_options)
315
+ end
316
+
282
317
  private
283
318
  # Raise a usage error with an informative WordNet suggestion.
284
319
  # Thanks to Florian Gross (flgr).
@@ -385,6 +420,15 @@ end_message
385
420
  def complex_template(*args)
386
421
  # nothing should be done here
387
422
  end
423
+
424
+ # When deleting a migration, it knows to delete every file named "[0-9]*_#{file_name}".
425
+ def migration_template(relative_source, relative_destination, template_options = {})
426
+ migration_directory relative_destination
427
+ raise "There is no migration named #{file_name}" unless migration_exists?(file_name)
428
+ existing_migrations(file_name).each do |file_path|
429
+ file(relative_source, file_path, template_options)
430
+ end
431
+ end
388
432
  end
389
433
 
390
434
 
@@ -417,6 +461,11 @@ end_message
417
461
  def readme(*args)
418
462
  logger.readme args.join(', ')
419
463
  end
464
+
465
+ def migration_template(relative_source, relative_destination, options = {})
466
+ migration_directory relative_destination
467
+ logger.migration_template file_name
468
+ end
420
469
  end
421
470
 
422
471
  # Update generator's action manifest.
@@ -16,7 +16,8 @@ class AppGenerator < Rails::Generator::Base
16
16
  end
17
17
 
18
18
  def manifest
19
- script_options = { :chmod => 0755, :shebang => options[:shebang] }
19
+ script_options = { :chmod => 0755 }
20
+ dispatcher_options = { :chmod => 0755, :shebang => options[:shebang] }
20
21
 
21
22
  record do |m|
22
23
  # Root directory and all subdirectories.
@@ -53,9 +54,9 @@ class AppGenerator < Rails::Generator::Base
53
54
  end
54
55
 
55
56
  # Dispatches
56
- m.file "dispatches/dispatch.rb", "public/dispatch.rb", script_options
57
- m.file "dispatches/dispatch.rb", "public/dispatch.cgi", script_options
58
- m.file "dispatches/dispatch.fcgi", "public/dispatch.fcgi", script_options
57
+ m.file "dispatches/dispatch.rb", "public/dispatch.rb", dispatcher_options
58
+ m.file "dispatches/dispatch.rb", "public/dispatch.cgi", dispatcher_options
59
+ m.file "dispatches/dispatch.fcgi", "public/dispatch.fcgi", dispatcher_options
59
60
 
60
61
  # HTML files
61
62
  %w(404 500 index).each do |file|
@@ -64,6 +65,7 @@ class AppGenerator < Rails::Generator::Base
64
65
 
65
66
  m.template "html/favicon.ico", "public/favicon.ico"
66
67
  m.template "html/robots.txt", "public/robots.txt"
68
+ m.file "html/images/rails.png", "public/images/rails.png"
67
69
 
68
70
  # Javascripts
69
71
  m.file "html/javascripts/prototype.js", "public/javascripts/prototype.js"
@@ -1,58 +1,7 @@
1
1
  class MigrationGenerator < Rails::Generator::NamedBase
2
2
  def manifest
3
3
  record do |m|
4
- m.directory 'db/migrate'
5
4
  m.migration_template 'migration.rb', 'db/migrate'
6
5
  end
7
6
  end
8
-
9
- protected
10
- def existing_migrations(file_name)
11
- Dir.glob("db/migrate/[0-9]*_#{file_name}.rb")
12
- end
13
-
14
- def migration_exists?(file_name)
15
- not existing_migrations(file_name).empty?
16
- end
17
-
18
- def current_migration_number
19
- Dir.glob('db/migrate/[0-9]*.rb').inject(0) do |max, file_path|
20
- n = File.basename(file_path).split('_', 2).first.to_i
21
- if n > max then n else max end
22
- end
23
- end
24
-
25
- def next_migration_number
26
- current_migration_number + 1
27
- end
28
-
29
- def next_migration_string(padding = 3)
30
- "%.#{padding}d" % next_migration_number
31
- end
32
- end
33
-
34
- module Rails::Generator::Commands
35
- # When creating, it knows to find the first available file in db/migrate and use the migration.rb template.
36
- class Create
37
- def migration_template(relative_source, relative_destination, template_options = {})
38
- raise "Another migration is already named #{file_name}: #{existing_migrations(file_name).first}" if migration_exists?(file_name)
39
- template(relative_source, "#{relative_destination}/#{next_migration_string}_#{file_name}.rb", template_options)
40
- end
41
- end
42
-
43
- # When deleting, it knows to delete every file named "[0-9]*_#{file_name}".
44
- class Destroy
45
- def migration_template(relative_source, relative_destination, template_options = {})
46
- raise "There is no migration named #{file_name}" unless migration_exists?(file_name)
47
- existing_migrations(file_name).each do |file_path|
48
- file(relative_source, file_path, template_options)
49
- end
50
- end
51
- end
52
-
53
- class List
54
- def migration_template(relative_source, relative_destination, options = {})
55
- logger.migration_template file_name
56
- end
57
- end
58
7
  end
@@ -12,7 +12,7 @@ class ModelGenerator < Rails::Generator::NamedBase
12
12
  # Model class, unit test, and fixtures.
13
13
  m.template 'model.rb', File.join('app/models', class_path, "#{file_name}.rb")
14
14
  m.template 'unit_test.rb', File.join('test/unit', class_path, "#{file_name}_test.rb")
15
- m.template 'fixtures.yml', File.join('test/fixtures', class_path, "#{ActiveRecord::Base.pluralize_table_names ? plural_name : singular_name}.yml")
15
+ m.template 'fixtures.yml', File.join('test/fixtures', class_path, "#{table_name}.yml")
16
16
  end
17
17
  end
18
18
  end
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + '/../test_helper'
1
+ require File.dirname(__FILE__) + '<%= '/..' * class_nesting_depth %>/../test_helper'
2
2
 
3
3
  class <%= class_name %>Test < Test::Unit::TestCase
4
4
  fixtures :<%= table_name %>
@@ -0,0 +1,15 @@
1
+ Description:
2
+ The session table migration generator creates a migration for adding a session table
3
+ used by CGI::Session::ActiveRecordStore.
4
+
5
+ The generator takes a migration name as its argument. The migration name may be
6
+ given in CamelCase or under_score.
7
+
8
+ The generator creates a migration class in db/migrate prefixed by its number
9
+ in the queue.
10
+
11
+ Example:
12
+ ./script/generate session_migration AddSessionTable
13
+
14
+ With 4 existing migrations, this will create an AddSessionTable migration in the
15
+ file db/migrate/5_add_session_table.rb
@@ -0,0 +1,12 @@
1
+ class SessionMigrationGenerator < Rails::Generator::NamedBase
2
+ def initialize(runtime_args, runtime_options = {})
3
+ runtime_args << 'add_session_table' if runtime_args.empty?
4
+ super
5
+ end
6
+
7
+ def manifest
8
+ record do |m|
9
+ m.migration_template 'migration.rb', 'db/migrate'
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,15 @@
1
+ class <%= class_name %> < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :sessions do |t|
4
+ t.column :session_id, :string
5
+ t.column :data, :text
6
+ t.column :updated_at, :datetime
7
+ end
8
+
9
+ add_index :sessions, :session_id
10
+ end
11
+
12
+ def self.down
13
+ drop_table :sessions
14
+ end
15
+ end
@@ -127,7 +127,12 @@ module Rails
127
127
  opt.on('-q', '--quiet', 'Suppress normal output.') { |options[:quiet]| }
128
128
  opt.on('-t', '--backtrace', 'Debugging: show backtrace on errors.') { |options[:backtrace]| }
129
129
  opt.on('-h', '--help', 'Show this help message.') { |options[:help]| }
130
- opt.on('-c', '--svn', 'Modify files with subversion. (Note: svn must be in path)') { options[:svn] = Hash[*`svn status`.collect { |e| e.chop.split.reverse unless e.chop.split.size != 2 }.flatten] }
130
+ opt.on('-c', '--svn', 'Modify files with subversion. (Note: svn must be in path)') do
131
+ options[:svn] = `svn status`.inject({}) do |opt, e|
132
+ opt[e.chomp[7..-1]] = true
133
+ opt
134
+ end
135
+ end
131
136
  end
132
137
 
133
138
  end
@@ -26,7 +26,7 @@ module Rails
26
26
 
27
27
  def component_version(component)
28
28
  require "#{component}/version"
29
- "#{component.classify}::Version::STRING".constantize
29
+ "#{component.classify}::VERSION::STRING".constantize
30
30
  end
31
31
 
32
32
  def edge_rails_revision(info = svn_info)
@@ -42,6 +42,16 @@ module Rails
42
42
 
43
43
  alias inspect to_s
44
44
 
45
+ def to_html
46
+ returning table = '<table>' do
47
+ properties.each do |(name, value)|
48
+ table << %(<tr><td class="name">#{CGI.escapeHTML(name)}</td>)
49
+ table << %(<td class="value">#{CGI.escapeHTML(value)}</td></tr>)
50
+ end
51
+ table << '</table>'
52
+ end
53
+ end
54
+
45
55
  protected
46
56
  def svn_info
47
57
  Dir.chdir("#{RAILS_ROOT}/vendor/rails") do
@@ -60,7 +70,7 @@ module Rails
60
70
 
61
71
  # The Rails version.
62
72
  property 'Rails version' do
63
- Rails::Version::STRING
73
+ Rails::VERSION::STRING
64
74
  end
65
75
 
66
76
  # Versions of each Rails component (Active Record, Action Pack,