rails 0.9.5 → 0.10.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.

Files changed (77) hide show
  1. data/CHANGELOG +46 -0
  2. data/README +36 -8
  3. data/Rakefile +18 -25
  4. data/bin/console +17 -30
  5. data/bin/console_sandbox.rb +6 -0
  6. data/bin/destroy +5 -0
  7. data/bin/generate +2 -70
  8. data/bin/rails +4 -28
  9. data/bin/server +4 -2
  10. data/bin/update +5 -0
  11. data/configs/apache.conf +7 -54
  12. data/configs/empty.log +0 -0
  13. data/configs/routes.rb +15 -0
  14. data/environments/shared.rb +14 -6
  15. data/environments/shared_for_gem.rb +12 -6
  16. data/fresh_rakefile +40 -8
  17. data/html/index.html +70 -1
  18. data/lib/breakpoint.rb +6 -1
  19. data/lib/breakpoint_client.rb +196 -193
  20. data/lib/dispatcher.rb +16 -38
  21. data/lib/rails_generator.rb +39 -198
  22. data/lib/rails_generator/base.rb +203 -0
  23. data/lib/rails_generator/commands.rb +409 -0
  24. data/lib/rails_generator/generators/applications/app/USAGE +16 -0
  25. data/lib/rails_generator/generators/applications/app/app_generator.rb +120 -0
  26. data/lib/rails_generator/generators/components/controller/USAGE +30 -0
  27. data/lib/rails_generator/generators/components/controller/controller_generator.rb +37 -0
  28. data/{generators → lib/rails_generator/generators/components}/controller/templates/controller.rb +1 -1
  29. data/lib/rails_generator/generators/components/controller/templates/functional_test.rb +18 -0
  30. data/{generators → lib/rails_generator/generators/components}/controller/templates/helper.rb +0 -0
  31. data/{generators → lib/rails_generator/generators/components}/controller/templates/view.rhtml +0 -0
  32. data/lib/rails_generator/generators/components/mailer/USAGE +19 -0
  33. data/lib/rails_generator/generators/components/mailer/mailer_generator.rb +32 -0
  34. data/{generators → lib/rails_generator/generators/components}/mailer/templates/fixture.rhtml +0 -0
  35. data/{generators → lib/rails_generator/generators/components}/mailer/templates/mailer.rb +0 -0
  36. data/{generators → lib/rails_generator/generators/components}/mailer/templates/unit_test.rb +7 -1
  37. data/{generators → lib/rails_generator/generators/components}/mailer/templates/view.rhtml +0 -0
  38. data/lib/rails_generator/generators/components/model/USAGE +17 -0
  39. data/lib/rails_generator/generators/components/model/model_generator.rb +18 -0
  40. data/{generators/scaffold → lib/rails_generator/generators/components/model}/templates/fixtures.yml +0 -2
  41. data/{generators → lib/rails_generator/generators/components}/model/templates/model.rb +0 -0
  42. data/{generators → lib/rails_generator/generators/components}/model/templates/unit_test.rb +5 -1
  43. data/lib/rails_generator/generators/components/scaffold/USAGE +32 -0
  44. data/lib/rails_generator/generators/components/scaffold/scaffold_generator.rb +178 -0
  45. data/{generators → lib/rails_generator/generators/components}/scaffold/templates/controller.rb +1 -1
  46. data/lib/rails_generator/generators/components/scaffold/templates/form.rhtml +5 -0
  47. data/{generators → lib/rails_generator/generators/components}/scaffold/templates/functional_test.rb +7 -6
  48. data/lib/rails_generator/generators/components/scaffold/templates/helper.rb +2 -0
  49. data/{generators → lib/rails_generator/generators/components}/scaffold/templates/layout.rhtml +1 -1
  50. data/{generators → lib/rails_generator/generators/components}/scaffold/templates/style.css +17 -17
  51. data/{generators → lib/rails_generator/generators/components}/scaffold/templates/view_edit.rhtml +1 -1
  52. data/{generators → lib/rails_generator/generators/components}/scaffold/templates/view_list.rhtml +1 -1
  53. data/{generators → lib/rails_generator/generators/components}/scaffold/templates/view_new.rhtml +1 -1
  54. data/{generators → lib/rails_generator/generators/components}/scaffold/templates/view_show.rhtml +0 -0
  55. data/lib/rails_generator/lookup.rb +200 -0
  56. data/lib/rails_generator/manifest.rb +53 -0
  57. data/lib/rails_generator/options.rb +134 -0
  58. data/lib/rails_generator/scripts.rb +83 -0
  59. data/lib/rails_generator/scripts/destroy.rb +7 -0
  60. data/lib/rails_generator/scripts/generate.rb +7 -0
  61. data/lib/rails_generator/scripts/update.rb +12 -0
  62. data/lib/rails_generator/simple_logger.rb +46 -0
  63. data/lib/rails_generator/spec.rb +44 -0
  64. data/lib/webrick_server.rb +15 -65
  65. metadata +92 -48
  66. data/doc/apache_protection +0 -3
  67. data/doc/index.html +0 -70
  68. data/generators/controller/USAGE +0 -28
  69. data/generators/controller/controller_generator.rb +0 -26
  70. data/generators/controller/templates/functional_test.rb +0 -17
  71. data/generators/mailer/USAGE +0 -27
  72. data/generators/mailer/mailer_generator.rb +0 -22
  73. data/generators/model/USAGE +0 -17
  74. data/generators/model/model_generator.rb +0 -10
  75. data/generators/model/templates/fixtures.yml +0 -1
  76. data/generators/scaffold/USAGE +0 -27
  77. data/generators/scaffold/scaffold_generator.rb +0 -60
@@ -1,4 +1,4 @@
1
- class <%= @controller_class_name %>Controller < ApplicationController
1
+ class <%= controller_class_name %>Controller < ApplicationController
2
2
  <% unless suffix -%>
3
3
  def index
4
4
  list
@@ -0,0 +1,5 @@
1
+ <%%= start_form_tag :action => '<%= @form_action %><%= @suffix %>' %>
2
+ <%%= hidden_field '<%= @singular_name %>', 'id' %>
3
+ <%= all_input_tags(@model_instance, @singular_name, {}) %>
4
+ <input type="submit" value="<%= @form_action.to_s.capitalize %>" />
5
+ <%%= end_form_tag %>
@@ -1,15 +1,16 @@
1
- require File.dirname(__FILE__) + '/../test_helper'
2
- require '<%= @controller_name %>_controller'
1
+ require File.dirname(__FILE__) + '<%= '/..' * controller_class_nesting_depth %>/../test_helper'
2
+ require '<%= controller_file_path %>_controller'
3
3
 
4
4
  # Re-raise errors caught by the controller.
5
- class <%= @controller_class_name %>Controller; def rescue_action(e) raise e end; end
5
+ class <%= controller_class_name %>Controller; def rescue_action(e) raise e end; end
6
6
 
7
- class <%= @controller_class_name %>ControllerTest < Test::Unit::TestCase
7
+ class <%= controller_class_name %>ControllerTest < Test::Unit::TestCase
8
8
  fixtures :<%= table_name %>
9
9
 
10
10
  def setup
11
- @controller = <%= @controller_class_name %>Controller.new
12
- @request, @response = ActionController::TestRequest.new, ActionController::TestResponse.new
11
+ @controller = <%= controller_class_name %>Controller.new
12
+ @request = ActionController::TestRequest.new
13
+ @response = ActionController::TestResponse.new
13
14
  end
14
15
 
15
16
  <% for action in unscaffolded_actions -%>
@@ -0,0 +1,2 @@
1
+ module <%= controller_class_name %>Helper
2
+ end
@@ -1,6 +1,6 @@
1
1
  <html>
2
2
  <head>
3
- <title>Scaffolding: <%%= controller.controller_name %>#<%%= controller.action_name %></title>
3
+ <title><%= controller_class_name %>: <%%= controller.action_name %></title>
4
4
  <link href="/stylesheets/scaffold.css" rel="stylesheet" type="text/css" />
5
5
  </head>
6
6
  <body>
@@ -24,30 +24,30 @@ a:hover { color: #fff; background-color:#000; }
24
24
 
25
25
  #ErrorExplanation {
26
26
  width: 400px;
27
- border: 2px solid #red;
28
- padding: 7px;
29
- padding-bottom: 12px;
30
- margin-bottom: 20px;
31
- background-color: #f0f0f0;
27
+ border: 2px solid #red;
28
+ padding: 7px;
29
+ padding-bottom: 12px;
30
+ margin-bottom: 20px;
31
+ background-color: #f0f0f0;
32
32
  }
33
33
 
34
34
  #ErrorExplanation h2 {
35
- text-align: left;
36
- font-weight: bold;
37
- padding: 5px 5px 5px 15px;
38
- font-size: 12px;
39
- margin: -7px;
40
- background-color: #c00;
41
- color: #fff;
35
+ text-align: left;
36
+ font-weight: bold;
37
+ padding: 5px 5px 5px 15px;
38
+ font-size: 12px;
39
+ margin: -7px;
40
+ background-color: #c00;
41
+ color: #fff;
42
42
  }
43
43
 
44
44
  #ErrorExplanation p {
45
- color: #333;
46
- margin-bottom: 0;
47
- padding: 5px;
45
+ color: #333;
46
+ margin-bottom: 0;
47
+ padding: 5px;
48
48
  }
49
49
 
50
50
  #ErrorExplanation ul li {
51
- font-size: 12px;
52
- list-style: square;
51
+ font-size: 12px;
52
+ list-style: square;
53
53
  }
@@ -1,7 +1,7 @@
1
1
  <h1>Editing <%= singular_name %></h1>
2
2
 
3
3
  <%%= error_messages_for '<%= singular_name %>' %>
4
- <%%= form '<%= singular_name %>', :action => 'update<%= suffix %>' %>
4
+ <%= template_for_inclusion %>
5
5
 
6
6
  <%%= link_to 'Show', :action => 'show<%= suffix %>', :id => @<%= singular_name %>.id %> |
7
7
  <%%= link_to 'Back', :action => 'list<%= suffix %>' %>
@@ -10,7 +10,7 @@
10
10
  <%% for <%= singular_name %> in @<%= plural_name %> %>
11
11
  <tr>
12
12
  <%% for column in <%= class_name %>.content_columns %>
13
- <td><%%=h <%= singular_name %>[column.name] %></td>
13
+ <td><%%=h <%= singular_name %>.send(column.name) %></td>
14
14
  <%% end %>
15
15
  <td><%%= link_to 'Show', :action => 'show<%= suffix %>', :id => <%= singular_name %>.id %></td>
16
16
  <td><%%= link_to 'Edit', :action => 'edit<%= suffix %>', :id => <%= singular_name %>.id %></td>
@@ -1,6 +1,6 @@
1
1
  <h1>New <%= @singular_name %></h1>
2
2
 
3
3
  <%%= error_messages_for '<%= singular_name %>' %>
4
- <%%= form '<%= singular_name %>', :action => 'create<%= suffix %>' %>
4
+ <%= template_for_inclusion %>
5
5
 
6
6
  <%%= link_to 'Back', :action => 'list<%= suffix %>' %>
@@ -0,0 +1,200 @@
1
+ require File.dirname(__FILE__) + '/spec'
2
+
3
+ class Object
4
+ class << self
5
+ # Lookup missing generators using const_missing. This allows any
6
+ # generator to reference another without having to know its location:
7
+ # RubyGems, ~/.rails/generators, and RAILS_ROOT/script/generators.
8
+ def lookup_missing_generator(class_id)
9
+ if md = /(.+)Generator$/.match(class_id.to_s)
10
+ name = md.captures.first.demodulize.underscore
11
+ Rails::Generator::Base.lookup(name).klass
12
+ else
13
+ const_missing_before_generators(class_id)
14
+ end
15
+ end
16
+
17
+ unless respond_to?(:const_missing_before_generators)
18
+ alias_method :const_missing_before_generators, :const_missing
19
+ alias_method :const_missing, :lookup_missing_generator
20
+ end
21
+ end
22
+ end
23
+
24
+ # User home directory lookup adapted from RubyGems.
25
+ def Dir.user_home
26
+ if ENV['HOME']
27
+ ENV['HOME']
28
+ elsif ENV['USERPROFILE']
29
+ ENV['USERPROFILE']
30
+ elsif ENV['HOMEDRIVE'] and ENV['HOMEPATH']
31
+ "#{ENV['HOMEDRIVE']}:#{ENV['HOMEPATH']}"
32
+ else
33
+ File.expand_path '~'
34
+ end
35
+ end
36
+
37
+
38
+ module Rails
39
+ module Generator
40
+
41
+ # Generator lookup is managed by a list of sources which return specs
42
+ # describing where to find and how to create generators. This module
43
+ # provides class methods for manipulating the source list and looking up
44
+ # generator specs, and an #instance wrapper for quickly instantiating
45
+ # generators by name.
46
+ #
47
+ # A spec is not a generator: it's a description of where to find
48
+ # the generator and how to create it. A source is anything that
49
+ # yields generators from #each. PathSource and GemSource are provided.
50
+ module Lookup
51
+ def self.append_features(base)
52
+ super
53
+ base.extend(ClassMethods)
54
+ base.use_component_sources!
55
+ end
56
+
57
+ # Convenience method to instantiate another generator.
58
+ def instance(generator_name, args, runtime_options = {})
59
+ self.class.instance(generator_name, args, runtime_options)
60
+ end
61
+
62
+ module ClassMethods
63
+ # The list of sources where we look, in order, for generators.
64
+ def sources
65
+ read_inheritable_attribute(:sources) or use_component_sources!
66
+ end
67
+
68
+ # Add a source to the end of the list.
69
+ def append_sources(*args)
70
+ sources.concat(args.flatten)
71
+ invalidate_cache!
72
+ end
73
+
74
+ # Add a source to the beginning of the list.
75
+ def prepend_sources(*args)
76
+ write_inheritable_array(:sources, args.flatten + sources)
77
+ invalidate_cache!
78
+ end
79
+
80
+ # Reset the source list.
81
+ def reset_sources
82
+ write_inheritable_attribute(:sources, [])
83
+ invalidate_cache!
84
+ end
85
+
86
+ # Use application generators (app, ?).
87
+ def use_application_sources!
88
+ reset_sources
89
+ sources << PathSource.new(:builtin, "#{File.dirname(__FILE__)}/generators/applications")
90
+ end
91
+
92
+ # Use component generators (model, controller, etc).
93
+ # 1. Rails application. If RAILS_ROOT is defined we know we're
94
+ # generating in the context of a Rails application, so search
95
+ # RAILS_ROOT/script/generators.
96
+ # 2. User home directory. Search ~/.rails/generators.
97
+ # 3. RubyGems. Search for gems named *_generator.
98
+ # 4. Builtins. Model, controller, mailer, scaffold.
99
+ def use_component_sources!
100
+ reset_sources
101
+ sources << PathSource.new(:app, "#{::RAILS_ROOT}/script/generators") if defined? ::RAILS_ROOT
102
+ sources << PathSource.new(:user, "#{Dir.user_home}/.rails/generators")
103
+ sources << GemSource.new if Object.const_defined?(:Gem)
104
+ sources << PathSource.new(:builtin, "#{File.dirname(__FILE__)}/generators/components")
105
+ end
106
+
107
+ # Lookup knows how to find generators' Specs from a list of Sources.
108
+ # Searches the sources, in order, for the first matching name.
109
+ def lookup(generator_name)
110
+ @found ||= {}
111
+ generator_name = generator_name.to_s.downcase
112
+ @found[generator_name] ||= cache.find { |spec|
113
+ spec.name == generator_name
114
+ } or raise GeneratorError, "Couldn't find '#{generator_name}' generator"
115
+ end
116
+
117
+ # Convenience method to lookup and instantiate a generator.
118
+ def instance(generator_name, args = [], runtime_options = {})
119
+ lookup(generator_name).klass.new(args, full_options(runtime_options))
120
+ end
121
+
122
+ private
123
+ # Lookup and cache every generator from the source list.
124
+ def cache
125
+ @cache ||= sources.inject([]) { |cache, source| cache + source.map }
126
+ end
127
+
128
+ # Clear the cache whenever the source list changes.
129
+ def invalidate_cache!
130
+ @cache = nil
131
+ end
132
+ end
133
+ end
134
+
135
+ # Sources enumerate (yield from #each) generator specs which describe
136
+ # where to find and how to create generators. Enumerable is mixed in so,
137
+ # for example, source.collect will retrieve every generator.
138
+ # Sources may be assigned a label to distinguish them.
139
+ class Source
140
+ include Enumerable
141
+
142
+ attr_reader :label
143
+ def initialize(label)
144
+ @label = label
145
+ end
146
+
147
+ # The each method must be implemented in subclasses.
148
+ # The base implementation raises an error.
149
+ def each
150
+ raise NotImplementedError
151
+ end
152
+
153
+ # Return a convenient sorted list of all generator names.
154
+ def names
155
+ map { |spec| spec.name }.sort
156
+ end
157
+ end
158
+
159
+
160
+ # PathSource looks for generators in a filesystem directory.
161
+ class PathSource < Source
162
+ attr_reader :path
163
+
164
+ def initialize(label, path)
165
+ super label
166
+ @path = path
167
+ end
168
+
169
+ # Yield each eligible subdirectory.
170
+ def each
171
+ Dir["#{path}/[a-z]*"].each do |dir|
172
+ if File.directory?(dir)
173
+ yield Spec.new(File.basename(dir), dir, label)
174
+ end
175
+ end
176
+ end
177
+ end
178
+
179
+
180
+ # GemSource hits the mines to quarry for generators. The latest versions
181
+ # of gems named *_generator are selected.
182
+ class GemSource < Source
183
+ def initialize
184
+ super :RubyGems
185
+ end
186
+
187
+ # Yield latest versions of generator gems.
188
+ def each
189
+ Gem::cache.search(/_generator$/).inject({}) { |latest, gem|
190
+ hem = latest[gem.name]
191
+ latest[gem.name] = gem if hem.nil? or gem.version > hem.version
192
+ latest
193
+ }.values.each { |gem|
194
+ yield Spec.new(gem.name.sub(/_generator$/, ''), gem.full_gem_path, label)
195
+ }
196
+ end
197
+ end
198
+
199
+ end
200
+ end
@@ -0,0 +1,53 @@
1
+ module Rails
2
+ module Generator
3
+
4
+ # Manifest captures the actions a generator performs. Instantiate
5
+ # a manifest with an optional target object, hammer it with actions,
6
+ # then replay or rewind on the object of your choice.
7
+ #
8
+ # Example:
9
+ # manifest = Manifest.new { |m|
10
+ # m.make_directory '/foo'
11
+ # m.create_file '/foo/bar.txt'
12
+ # }
13
+ # manifest.replay(creator)
14
+ # manifest.rewind(destroyer)
15
+ class Manifest
16
+ attr_reader :target
17
+
18
+ # Take a default action target. Yield self if block given.
19
+ def initialize(target = nil)
20
+ @target, @actions = target, []
21
+ yield self if block_given?
22
+ end
23
+
24
+ # Record an action.
25
+ def method_missing(action, *args, &block)
26
+ @actions << [action, args, block]
27
+ end
28
+
29
+ # Replay recorded actions.
30
+ def replay(target = nil)
31
+ send_actions(target || @target, @actions)
32
+ end
33
+
34
+ # Rewind recorded actions.
35
+ def rewind(target = nil)
36
+ send_actions(target || @target, @actions.reverse)
37
+ end
38
+
39
+ # Erase recorded actions.
40
+ def erase
41
+ @actions = []
42
+ end
43
+
44
+ private
45
+ def send_actions(target, actions)
46
+ actions.each do |method, args, block|
47
+ target.send(method, *args, &block)
48
+ end
49
+ end
50
+ end
51
+
52
+ end
53
+ end
@@ -0,0 +1,134 @@
1
+ require 'optparse'
2
+
3
+ module Rails
4
+ module Generator
5
+ module Options
6
+ def self.append_features(base)
7
+ super
8
+ base.extend(ClassMethods)
9
+ class << base
10
+ if respond_to?(:inherited)
11
+ alias_method :inherited_without_options, :inherited
12
+ end
13
+ alias_method :inherited, :inherited_with_options
14
+ end
15
+ end
16
+
17
+ module ClassMethods
18
+ def inherited_with_options(sub)
19
+ inherited_without_options(sub) if respond_to?(:inherited_without_options)
20
+ sub.extend(Rails::Generator::Options::ClassMethods)
21
+ end
22
+
23
+ def mandatory_options(options = nil)
24
+ if options
25
+ write_inheritable_attribute(:mandatory_options, options)
26
+ else
27
+ read_inheritable_attribute(:mandatory_options) or write_inheritable_attribute(:mandatory_options, {})
28
+ end
29
+ end
30
+
31
+ def default_options(options = nil)
32
+ if options
33
+ write_inheritable_attribute(:default_options, options)
34
+ else
35
+ read_inheritable_attribute(:default_options) or write_inheritable_attribute(:default_options, {})
36
+ end
37
+ end
38
+
39
+ # Merge together our class options. In increasing precedence:
40
+ # default_options (class default options)
41
+ # runtime_options (provided as argument)
42
+ # mandatory_options (class mandatory options)
43
+ def full_options(runtime_options = {})
44
+ default_options.merge(runtime_options).merge(mandatory_options)
45
+ end
46
+
47
+ end
48
+
49
+ # Each instance has an options hash that's populated by #parse.
50
+ def options
51
+ @options ||= {}
52
+ end
53
+ attr_writer :options
54
+
55
+ protected
56
+ # Convenient access to class mandatory options.
57
+ def mandatory_options
58
+ self.class.mandatory_options
59
+ end
60
+
61
+ # Convenient access to class default options.
62
+ def default_options
63
+ self.class.default_options
64
+ end
65
+
66
+ # Merge together our instance options. In increasing precedence:
67
+ # default_options (class default options)
68
+ # options (instance options)
69
+ # runtime_options (provided as argument)
70
+ # mandatory_options (class mandatory options)
71
+ def full_options(runtime_options = {})
72
+ self.class.full_options(options.merge(runtime_options))
73
+ end
74
+
75
+ # Parse arguments into the options hash. Classes may customize
76
+ # parsing behavior by overriding these methods:
77
+ # #banner Usage: ./script/generate [options]
78
+ # #add_options! Options:
79
+ # some options..
80
+ # #add_general_options! General Options:
81
+ # general options..
82
+ def parse!(args, runtime_options = {})
83
+ self.options = {}
84
+
85
+ @option_parser = OptionParser.new do |opt|
86
+ opt.banner = banner
87
+ add_options!(opt)
88
+ add_general_options!(opt)
89
+ opt.parse!(args)
90
+ end
91
+
92
+ return args
93
+ ensure
94
+ self.options = full_options(runtime_options)
95
+ end
96
+
97
+ # Raise a usage error. Override usage_message to provide a blurb
98
+ # after the option parser summary.
99
+ def usage
100
+ raise UsageError, "#{@option_parser}\n#{usage_message}"
101
+ end
102
+
103
+ def usage_message
104
+ ''
105
+ end
106
+
107
+ # Override with your own usage banner.
108
+ def banner
109
+ "Usage: #{$0} [options]"
110
+ end
111
+
112
+ # Override to add your options to the parser:
113
+ # def add_options!(opt)
114
+ # opt.on('-v', '--verbose') { |value| options[:verbose] = value }
115
+ # end
116
+ def add_options!(opt)
117
+ end
118
+
119
+ # Adds general options like -h and --quiet. Usually don't override.
120
+ def add_general_options!(opt)
121
+ opt.separator ''
122
+ opt.separator 'General Options:'
123
+
124
+ opt.on('-p', '--pretend', 'Run but do not make any changes.') { |options[:pretend]| }
125
+ opt.on('-f', '--force', 'Overwrite files that already exist.') { options[:collision] = :force }
126
+ opt.on('-s', '--skip', 'Skip files that already exist.') { options[:collision] = :skip }
127
+ opt.on('-q', '--quiet', 'Keep is like a secret with /dev/null.') { |options[:quiet]| }
128
+ opt.on('-t', '--backtrace', 'Debugging: show backtrace on errors.') { |options[:backtrace]| }
129
+ opt.on('-h', '--help', 'Show this help message.') { |options[:help]| }
130
+ end
131
+
132
+ end
133
+ end
134
+ end