rails 1.0.0 → 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.

Files changed (177) hide show
  1. data/CHANGELOG +1020 -10
  2. data/MIT-LICENSE +1 -1
  3. data/README +110 -60
  4. data/Rakefile +74 -139
  5. data/bin/about +1 -1
  6. data/bin/console +1 -1
  7. data/bin/destroy +1 -1
  8. data/bin/generate +1 -1
  9. data/bin/performance/request +3 -0
  10. data/bin/plugin +1 -1
  11. data/bin/process/{spinner → inspector} +1 -1
  12. data/bin/rails +10 -12
  13. data/bin/runner +1 -1
  14. data/bin/server +1 -1
  15. data/{lib/rails_info.rb → builtin/rails_info/rails/info.rb} +33 -14
  16. data/builtin/rails_info/rails/info_controller.rb +9 -0
  17. data/builtin/rails_info/rails/info_helper.rb +2 -0
  18. data/builtin/rails_info/rails_info_controller.rb +2 -0
  19. data/configs/apache.conf +1 -1
  20. data/configs/databases/frontbase.yml +28 -0
  21. data/configs/databases/mysql.yml +54 -0
  22. data/configs/databases/oracle.yml +39 -0
  23. data/configs/databases/postgresql.yml +48 -0
  24. data/configs/databases/sqlite2.yml +16 -0
  25. data/configs/databases/sqlite3.yml +19 -0
  26. data/configs/initializers/inflections.rb +10 -0
  27. data/configs/initializers/mime_types.rb +5 -0
  28. data/configs/lighttpd.conf +29 -15
  29. data/configs/routes.rb +27 -11
  30. data/doc/README_FOR_APP +1 -1
  31. data/environments/boot.rb +103 -14
  32. data/environments/development.rb +5 -6
  33. data/environments/environment.rb +36 -30
  34. data/environments/production.rb +2 -3
  35. data/environments/test.rb +5 -2
  36. data/fresh_rakefile +2 -2
  37. data/helpers/application.rb +8 -2
  38. data/helpers/test_helper.rb +10 -0
  39. data/html/404.html +27 -5
  40. data/html/422.html +30 -0
  41. data/html/500.html +27 -5
  42. data/html/index.html +6 -6
  43. data/html/javascripts/application.js +2 -0
  44. data/html/javascripts/controls.js +532 -319
  45. data/html/javascripts/dragdrop.js +521 -133
  46. data/html/javascripts/effects.js +708 -442
  47. data/html/javascripts/prototype.js +3393 -953
  48. data/html/robots.txt +5 -1
  49. data/lib/code_statistics.rb +2 -2
  50. data/lib/commands/console.rb +18 -9
  51. data/lib/commands/performance/profiler.rb +25 -9
  52. data/lib/commands/performance/request.rb +6 -0
  53. data/lib/commands/plugin.rb +196 -96
  54. data/lib/commands/process/inspector.rb +68 -0
  55. data/lib/commands/process/reaper.rb +90 -71
  56. data/lib/commands/process/spawner.rb +188 -21
  57. data/lib/commands/process/spinner.rb +3 -3
  58. data/lib/commands/runner.rb +28 -7
  59. data/lib/commands/server.rb +20 -9
  60. data/lib/commands/servers/base.rb +31 -0
  61. data/lib/commands/servers/lighttpd.rb +60 -26
  62. data/lib/commands/servers/mongrel.rb +69 -0
  63. data/lib/commands/servers/webrick.rb +18 -11
  64. data/lib/console_app.rb +30 -0
  65. data/lib/console_sandbox.rb +2 -2
  66. data/lib/console_with_helpers.rb +26 -0
  67. data/lib/dispatcher.rb +3 -78
  68. data/lib/fcgi_handler.rb +98 -64
  69. data/lib/initializer.rb +323 -194
  70. data/lib/rails/plugin/loader.rb +150 -0
  71. data/lib/rails/plugin/locator.rb +78 -0
  72. data/lib/rails/plugin.rb +84 -0
  73. data/lib/{rails_version.rb → rails/version.rb} +1 -1
  74. data/lib/rails_generator/base.rb +85 -25
  75. data/lib/rails_generator/commands.rb +122 -40
  76. data/lib/rails_generator/generated_attribute.rb +42 -0
  77. data/lib/rails_generator/generators/applications/app/USAGE +0 -7
  78. data/lib/rails_generator/generators/applications/app/app_generator.rb +67 -28
  79. data/lib/rails_generator/generators/components/controller/USAGE +11 -12
  80. data/lib/rails_generator/generators/components/controller/controller_generator.rb +2 -3
  81. data/lib/rails_generator/generators/components/controller/templates/functional_test.rb +1 -11
  82. data/lib/rails_generator/generators/components/controller/templates/{view.rhtml → view.html.erb} +0 -0
  83. data/lib/rails_generator/generators/components/integration_test/USAGE +8 -0
  84. data/lib/rails_generator/generators/components/integration_test/integration_test_generator.rb +16 -0
  85. data/lib/rails_generator/generators/components/integration_test/templates/integration_test.rb +10 -0
  86. data/lib/rails_generator/generators/components/mailer/USAGE +9 -11
  87. data/lib/rails_generator/generators/components/mailer/mailer_generator.rb +10 -8
  88. data/lib/rails_generator/generators/components/mailer/templates/fixture.erb +3 -0
  89. data/lib/rails_generator/generators/components/mailer/templates/fixture.rhtml +0 -3
  90. data/lib/rails_generator/generators/components/mailer/templates/unit_test.rb +9 -25
  91. data/lib/rails_generator/generators/components/mailer/templates/view.erb +3 -0
  92. data/lib/rails_generator/generators/components/mailer/templates/view.rhtml +0 -3
  93. data/lib/rails_generator/generators/components/migration/USAGE +23 -8
  94. data/lib/rails_generator/generators/components/migration/migration_generator.rb +15 -2
  95. data/lib/rails_generator/generators/components/migration/templates/migration.rb +7 -3
  96. data/lib/rails_generator/generators/components/model/USAGE +21 -11
  97. data/lib/rails_generator/generators/components/model/model_generator.rb +28 -1
  98. data/lib/rails_generator/generators/components/model/templates/fixtures.yml +18 -4
  99. data/lib/rails_generator/generators/components/model/templates/migration.rb +16 -0
  100. data/lib/rails_generator/generators/components/model/templates/unit_test.rb +2 -4
  101. data/lib/rails_generator/generators/components/observer/USAGE +13 -0
  102. data/lib/rails_generator/generators/components/observer/observer_generator.rb +16 -0
  103. data/lib/rails_generator/generators/components/observer/templates/observer.rb +2 -0
  104. data/lib/rails_generator/generators/components/observer/templates/unit_test.rb +8 -0
  105. data/lib/rails_generator/generators/components/plugin/USAGE +10 -18
  106. data/lib/rails_generator/generators/components/plugin/plugin_generator.rb +6 -0
  107. data/lib/rails_generator/generators/components/plugin/templates/MIT-LICENSE +20 -0
  108. data/lib/rails_generator/generators/components/plugin/templates/README +10 -1
  109. data/lib/rails_generator/generators/components/plugin/templates/Rakefile +1 -1
  110. data/lib/rails_generator/generators/components/plugin/templates/USAGE +1 -1
  111. data/lib/rails_generator/generators/components/plugin/templates/init.rb +1 -1
  112. data/lib/rails_generator/generators/components/plugin/templates/install.rb +1 -0
  113. data/lib/rails_generator/generators/components/plugin/templates/plugin.rb +1 -1
  114. data/lib/rails_generator/generators/components/plugin/templates/tasks.rake +1 -1
  115. data/lib/rails_generator/generators/components/plugin/templates/uninstall.rb +1 -0
  116. data/lib/rails_generator/generators/components/resource/USAGE +23 -0
  117. data/lib/rails_generator/generators/components/resource/resource_generator.rb +74 -0
  118. data/lib/rails_generator/generators/components/resource/templates/controller.rb +2 -0
  119. data/lib/rails_generator/generators/components/resource/templates/functional_test.rb +8 -0
  120. data/lib/rails_generator/generators/components/resource/templates/helper.rb +2 -0
  121. data/lib/rails_generator/generators/components/scaffold/USAGE +24 -31
  122. data/lib/rails_generator/generators/components/scaffold/scaffold_generator.rb +45 -137
  123. data/lib/rails_generator/generators/components/scaffold/templates/controller.rb +65 -34
  124. data/lib/rails_generator/generators/components/scaffold/templates/functional_test.rb +23 -76
  125. data/lib/rails_generator/generators/components/scaffold/templates/layout.html.erb +17 -0
  126. data/lib/rails_generator/generators/components/scaffold/templates/style.css +5 -5
  127. data/lib/rails_generator/generators/components/scaffold/templates/view_edit.html.erb +19 -0
  128. data/lib/rails_generator/generators/components/scaffold/templates/view_index.html.erb +24 -0
  129. data/lib/rails_generator/generators/components/scaffold/templates/view_new.html.erb +18 -0
  130. data/lib/rails_generator/generators/components/scaffold/templates/view_show.html.erb +10 -0
  131. data/lib/rails_generator/generators/components/session_migration/USAGE +6 -11
  132. data/lib/rails_generator/generators/components/session_migration/session_migration_generator.rb +7 -1
  133. data/lib/rails_generator/generators/components/session_migration/templates/migration.rb +8 -7
  134. data/lib/rails_generator/lookup.rb +46 -12
  135. data/lib/rails_generator/options.rb +11 -8
  136. data/lib/rails_generator/scripts/destroy.rb +23 -0
  137. data/lib/rails_generator/scripts.rb +7 -4
  138. data/lib/rails_generator/secret_key_generator.rb +160 -0
  139. data/lib/rails_generator/spec.rb +1 -1
  140. data/lib/rails_generator.rb +1 -1
  141. data/lib/railties_path.rb +1 -1
  142. data/lib/ruby_version_check.rb +17 -0
  143. data/lib/source_annotation_extractor.rb +62 -0
  144. data/lib/tasks/annotations.rake +23 -0
  145. data/lib/tasks/databases.rake +328 -133
  146. data/lib/tasks/documentation.rake +72 -68
  147. data/lib/tasks/framework.rake +99 -58
  148. data/lib/tasks/log.rake +9 -0
  149. data/lib/tasks/misc.rake +2 -17
  150. data/lib/tasks/rails.rb +2 -2
  151. data/lib/tasks/routes.rake +17 -0
  152. data/lib/tasks/statistics.rake +10 -8
  153. data/lib/tasks/testing.rake +99 -31
  154. data/lib/tasks/tmp.rake +37 -0
  155. data/lib/test_help.rb +8 -5
  156. data/lib/webrick_server.rb +11 -16
  157. metadata +312 -272
  158. data/bin/breakpointer +0 -3
  159. data/builtin/controllers/rails_info_controller.rb +0 -11
  160. data/configs/database.yml +0 -85
  161. data/lib/binding_of_caller.rb +0 -85
  162. data/lib/breakpoint.rb +0 -523
  163. data/lib/breakpoint_client.rb +0 -196
  164. data/lib/commands/breakpointer.rb +0 -1
  165. data/lib/rails_generator/generators/components/scaffold/templates/form.rhtml +0 -3
  166. data/lib/rails_generator/generators/components/scaffold/templates/form_scaffolding.rhtml +0 -1
  167. data/lib/rails_generator/generators/components/scaffold/templates/layout.rhtml +0 -13
  168. data/lib/rails_generator/generators/components/scaffold/templates/view_edit.rhtml +0 -9
  169. data/lib/rails_generator/generators/components/scaffold/templates/view_list.rhtml +0 -27
  170. data/lib/rails_generator/generators/components/scaffold/templates/view_new.rhtml +0 -8
  171. data/lib/rails_generator/generators/components/scaffold/templates/view_show.rhtml +0 -8
  172. data/lib/rails_generator/generators/components/web_service/USAGE +0 -28
  173. data/lib/rails_generator/generators/components/web_service/templates/api_definition.rb +0 -5
  174. data/lib/rails_generator/generators/components/web_service/templates/controller.rb +0 -8
  175. data/lib/rails_generator/generators/components/web_service/templates/functional_test.rb +0 -19
  176. data/lib/rails_generator/generators/components/web_service/web_service_generator.rb +0 -29
  177. data/lib/tasks/javascripts.rake +0 -6
@@ -0,0 +1,150 @@
1
+ require "rails/plugin"
2
+
3
+ module Rails
4
+ class Plugin
5
+ class Loader
6
+ attr_reader :initializer
7
+
8
+ # Creates a new Plugin::Loader instance, associated with the given
9
+ # Rails::Initializer. This default implementation automatically locates
10
+ # all plugins, and adds all plugin load paths, when it is created. The plugins
11
+ # are then fully loaded (init.rb is evaluated) when load_plugins is called.
12
+ #
13
+ # It is the loader's responsibility to ensure that only the plugins specified
14
+ # in the configuration are actually loaded, and that the order defined
15
+ # is respected.
16
+ def initialize(initializer)
17
+ @initializer = initializer
18
+ end
19
+
20
+ # Returns the plugins to be loaded, in the order they should be loaded.
21
+ def plugins
22
+ @plugins ||= all_plugins.select { |plugin| should_load?(plugin) }.sort { |p1, p2| order_plugins(p1, p2) }
23
+ end
24
+
25
+ # Returns all the plugins that could be found by the current locators.
26
+ def all_plugins
27
+ @all_plugins ||= locate_plugins
28
+ @all_plugins
29
+ end
30
+
31
+ def load_plugins
32
+ plugins.each do |plugin|
33
+ plugin.load(initializer)
34
+ register_plugin_as_loaded(plugin)
35
+ end
36
+ ensure_all_registered_plugins_are_loaded!
37
+ end
38
+
39
+ # Adds the load paths for every plugin into the $LOAD_PATH. Plugin load paths are
40
+ # added *after* the application's <tt>lib</tt> directory, to ensure that an application
41
+ # can always override code within a plugin.
42
+ #
43
+ # Plugin load paths are also added to Dependencies.load_paths, and Dependencies.load_once_paths.
44
+ def add_plugin_load_paths
45
+ plugins.each do |plugin|
46
+ plugin.load_paths.each do |path|
47
+ $LOAD_PATH.insert(application_lib_index + 1, path)
48
+ Dependencies.load_paths << path
49
+ Dependencies.load_once_paths << path
50
+ end
51
+ end
52
+ $LOAD_PATH.uniq!
53
+ end
54
+
55
+ protected
56
+
57
+ # The locate_plugins method uses each class in config.plugin_locators to
58
+ # find the set of all plugins available to this Rails application.
59
+ def locate_plugins
60
+ configuration.plugin_locators.map { |locator|
61
+ locator.new(initializer).plugins
62
+ }.flatten
63
+ # TODO: sorting based on config.plugins
64
+ end
65
+
66
+ def register_plugin_as_loaded(plugin)
67
+ initializer.loaded_plugins << plugin
68
+ end
69
+
70
+ def configuration
71
+ initializer.configuration
72
+ end
73
+
74
+ def should_load?(plugin)
75
+ # uses Plugin#name and Plugin#valid?
76
+ enabled?(plugin) && plugin.valid?
77
+ end
78
+
79
+ def order_plugins(plugin_a, plugin_b)
80
+ if !explicit_plugin_loading_order?
81
+ plugin_a <=> plugin_b
82
+ else
83
+ if !explicitly_enabled?(plugin_a) && !explicitly_enabled?(plugin_b)
84
+ plugin_a <=> plugin_b
85
+ else
86
+ effective_order_of(plugin_a) <=> effective_order_of(plugin_b)
87
+ end
88
+ end
89
+ end
90
+
91
+ def effective_order_of(plugin)
92
+ if explicitly_enabled?(plugin)
93
+ registered_plugin_names.index(plugin.name)
94
+ else
95
+ registered_plugin_names.index('all')
96
+ end
97
+ end
98
+
99
+ def application_lib_index
100
+ $LOAD_PATH.index(File.join(RAILS_ROOT, 'lib')) || 0
101
+ end
102
+
103
+ def enabled?(plugin)
104
+ !explicit_plugin_loading_order? || registered?(plugin)
105
+ end
106
+
107
+ def explicit_plugin_loading_order?
108
+ !registered_plugin_names.nil?
109
+ end
110
+
111
+ def registered?(plugin)
112
+ explicit_plugin_loading_order? && registered_plugins_names_plugin?(plugin)
113
+ end
114
+
115
+ def explicitly_enabled?(plugin)
116
+ !explicit_plugin_loading_order? || explicitly_registered?(plugin)
117
+ end
118
+
119
+ def explicitly_registered?(plugin)
120
+ explicit_plugin_loading_order? && registered_plugin_names.include?(plugin.name)
121
+ end
122
+
123
+ def registered_plugins_names_plugin?(plugin)
124
+ registered_plugin_names.include?(plugin.name) || registered_plugin_names.include?('all')
125
+ end
126
+
127
+ # The plugins that have been explicitly listed with config.plugins. If this list is nil
128
+ # then it means the client does not care which plugins or in what order they are loaded,
129
+ # so we load all in alphabetical order. If it is an empty array, we load no plugins, if it is
130
+ # non empty, we load the named plugins in the order specified.
131
+ def registered_plugin_names
132
+ configuration.plugins ? configuration.plugins.map(&:to_s) : nil
133
+ end
134
+
135
+ def loaded?(plugin_name)
136
+ initializer.loaded_plugins.detect { |plugin| plugin.name == plugin_name.to_s }
137
+ end
138
+
139
+ def ensure_all_registered_plugins_are_loaded!
140
+ if explicit_plugin_loading_order?
141
+ if configuration.plugins.detect {|plugin| plugin != :all && !loaded?(plugin) }
142
+ missing_plugins = configuration.plugins - (plugins + [:all])
143
+ raise LoadError, "Could not locate the following plugins: #{missing_plugins.to_sentence}"
144
+ end
145
+ end
146
+ end
147
+
148
+ end
149
+ end
150
+ end
@@ -0,0 +1,78 @@
1
+ module Rails
2
+ class Plugin
3
+
4
+ # The Plugin::Locator class should be subclasses to provide custom plugin-finding
5
+ # abilities to Rails (i.e. loading plugins from Gems, etc). Each subclass should implement
6
+ # the <tt>located_plugins</tt> method, which return an array of Plugin objects that have been found.
7
+ class Locator
8
+ include Enumerable
9
+
10
+ attr_reader :initializer
11
+
12
+ def initialize(initializer)
13
+ @initializer = initializer
14
+ end
15
+
16
+ # This method should return all the plugins which this Plugin::Locator can find
17
+ # These will then be used by the current Plugin::Loader, which is responsible for actually
18
+ # loading the plugins themselves
19
+ def plugins
20
+ raise "The `plugins' method must be defined by concrete subclasses of #{self.class}"
21
+ end
22
+
23
+ def each(&block)
24
+ plugins.each(&block)
25
+ end
26
+
27
+ def plugin_names
28
+ plugins.map(&:name)
29
+ end
30
+ end
31
+
32
+ # The Rails::Plugin::FileSystemLocator will try to locate plugins by examining the directories
33
+ # the the paths given in configuration.plugin_paths. Any plugins that can be found are returned
34
+ # in a list.
35
+ #
36
+ # The criteria for a valid plugin in this case is found in Rails::Plugin#valid?, although
37
+ # other subclasses of Rails::Plugin::Locator can of course use different conditions.
38
+ class FileSystemLocator < Locator
39
+
40
+ # Returns all the plugins which can be loaded in the filesystem, under the paths given
41
+ # by configuration.plugin_paths.
42
+ def plugins
43
+ initializer.configuration.plugin_paths.flatten.inject([]) do |plugins, path|
44
+ plugins.concat locate_plugins_under(path)
45
+ plugins
46
+ end.flatten
47
+ end
48
+
49
+ private
50
+
51
+ # Attempts to create a plugin from the given path. If the created plugin is valid?
52
+ # (see Rails::Plugin#valid?) then the plugin instance is returned; otherwise nil.
53
+ def create_plugin(path)
54
+ plugin = Rails::Plugin.new(path)
55
+ plugin.valid? ? plugin : nil
56
+ end
57
+
58
+ # This starts at the base path looking for valid plugins (see Rails::Plugin#valid?).
59
+ # Since plugins can be nested arbitrarily deep within an unspecified number of intermediary
60
+ # directories, this method runs recursively until it finds a plugin directory, e.g.
61
+ #
62
+ # locate_plugins_under('vendor/plugins/acts/acts_as_chunky_bacon')
63
+ # => <Rails::Plugin name: 'acts_as_chunky_bacon' ... >
64
+ #
65
+ def locate_plugins_under(base_path)
66
+ Dir.glob(File.join(base_path, '*')).inject([]) do |plugins, path|
67
+ if plugin = create_plugin(path)
68
+ plugins << plugin
69
+ elsif File.directory?(path)
70
+ plugins.concat locate_plugins_under(path)
71
+ end
72
+ plugins
73
+ end
74
+ end
75
+
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,84 @@
1
+ module Rails
2
+
3
+ # The Plugin class should be an object which provides the following methods:
4
+ #
5
+ # * +name+ - used during initialisation to order the plugin (based on name and
6
+ # the contents of <tt>config.plugins</tt>)
7
+ # * +valid?+ - returns true if this plugin can be loaded
8
+ # * +load_paths+ - each path within the returned array will be added to the $LOAD_PATH
9
+ # * +load+ - finally 'load' the plugin.
10
+ #
11
+ # These methods are expected by the Rails::Plugin::Locator and Rails::Plugin::Loader classes.
12
+ # The default implementation returns the <tt>lib</tt> directory as its </tt>load_paths</tt>,
13
+ # and evaluates <tt>init.rb</tt> when <tt>load</tt> is called.
14
+ class Plugin
15
+ include Comparable
16
+
17
+ attr_reader :directory, :name
18
+
19
+ def initialize(directory)
20
+ @directory = directory
21
+ @name = File.basename(@directory) rescue nil
22
+ @loaded = false
23
+ end
24
+
25
+ def valid?
26
+ File.directory?(directory) && (has_lib_directory? || has_init_file?)
27
+ end
28
+
29
+ # Returns a list of paths this plugin wishes to make available in $LOAD_PATH
30
+ def load_paths
31
+ report_nonexistant_or_empty_plugin! unless valid?
32
+ has_lib_directory? ? [lib_path] : []
33
+ end
34
+
35
+ # Evaluates a plugin's init.rb file
36
+ def load(initializer)
37
+ return if loaded?
38
+ report_nonexistant_or_empty_plugin! unless valid?
39
+ evaluate_init_rb(initializer)
40
+ @loaded = true
41
+ end
42
+
43
+ def loaded?
44
+ @loaded
45
+ end
46
+
47
+ def <=>(other_plugin)
48
+ name <=> other_plugin.name
49
+ end
50
+
51
+ private
52
+
53
+ def report_nonexistant_or_empty_plugin!
54
+ raise LoadError, "Can not find the plugin named: #{name}"
55
+ end
56
+
57
+ def lib_path
58
+ File.join(directory, 'lib')
59
+ end
60
+
61
+ def init_path
62
+ File.join(directory, 'init.rb')
63
+ end
64
+
65
+ def has_lib_directory?
66
+ File.directory?(lib_path)
67
+ end
68
+
69
+ def has_init_file?
70
+ File.file?(init_path)
71
+ end
72
+
73
+ def evaluate_init_rb(initializer)
74
+ if has_init_file?
75
+ silence_warnings do
76
+ # Allow plugins to reference the current configuration object
77
+ config = initializer.configuration
78
+
79
+ eval(IO.read(init_path), binding, init_path)
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
@@ -1,6 +1,6 @@
1
1
  module Rails
2
2
  module VERSION #:nodoc:
3
- MAJOR = 1
3
+ MAJOR = 2
4
4
  MINOR = 0
5
5
  TINY = 0
6
6
 
@@ -1,20 +1,50 @@
1
1
  require File.dirname(__FILE__) + '/options'
2
2
  require File.dirname(__FILE__) + '/manifest'
3
3
  require File.dirname(__FILE__) + '/spec'
4
+ require File.dirname(__FILE__) + '/generated_attribute'
4
5
 
5
- # Rails::Generator is a code generation platform tailored for the Rails
6
- # web application framework. Generators are easily invoked within Rails
7
- # applications to add and remove components such as models and controllers.
8
- # New generators are easy to create and may be distributed as RubyGems or
9
- # tarballs for inclusion system-wide, per-user, or per-application.
10
- #
11
- # Generators may subclass other generators to provide variations that
12
- # require little or no new logic but replace the template files.
13
- # The postback generator is an example: it subclasses the scaffold
14
- # generator and just replaces the code templates with its own.
15
- #
16
- # Now go forth and multiply^Wgenerate.
17
6
  module Rails
7
+ # Rails::Generator is a code generation platform tailored for the Rails
8
+ # web application framework. Generators are easily invoked within Rails
9
+ # applications to add and remove components such as models and controllers.
10
+ # New generators are easy to create and may be distributed as RubyGems,
11
+ # tarballs, or Rails plugins for inclusion system-wide, per-user,
12
+ # or per-application.
13
+ #
14
+ # For actual examples see the rails_generator/generators directory in the
15
+ # Rails source (or the +railties+ directory if you have frozen the Rails
16
+ # source in your application).
17
+ #
18
+ # Generators may subclass other generators to provide variations that
19
+ # require little or no new logic but replace the template files.
20
+ #
21
+ # For a RubyGem, put your generator class and templates in the +lib+
22
+ # directory. For a Rails plugin, make a +generators+ directory at the
23
+ # root of your plugin.
24
+ #
25
+ # The layout of generator files can be seen in the built-in
26
+ # +controller+ generator:
27
+ #
28
+ # generators/
29
+ # components/
30
+ # controller/
31
+ # controller_generator.rb
32
+ # templates/
33
+ # controller.rb
34
+ # functional_test.rb
35
+ # helper.rb
36
+ # view.html.erb
37
+ #
38
+ # The directory name (+controller+) matches the name of the generator file
39
+ # (controller_generator.rb) and class (+ControllerGenerator+). The files
40
+ # that will be copied or used as templates are stored in the +templates+
41
+ # directory.
42
+ #
43
+ # The filenames of the templates don't matter, but choose something that
44
+ # will be self-explanatory since you will be referencing these in the
45
+ # +manifest+ method inside your generator subclass.
46
+ #
47
+ #
18
48
  module Generator
19
49
  class GeneratorError < StandardError; end
20
50
  class UsageError < GeneratorError; end
@@ -22,27 +52,36 @@ module Rails
22
52
 
23
53
  # The base code generator is bare-bones. It sets up the source and
24
54
  # destination paths and tells the logger whether to keep its trap shut.
25
- # You're probably looking for NamedBase, a subclass meant for generating
26
- # "named" components such as models, controllers, and mailers.
55
+ #
56
+ # It's useful for copying files such as stylesheets, images, or
57
+ # javascripts.
58
+ #
59
+ # For more comprehensive template-based passive code generation with
60
+ # arguments, you'll want Rails::Generator::NamedBase.
27
61
  #
28
62
  # Generators create a manifest of the actions they perform then hand
29
- # the manifest to a command which replay the actions to do the heavy
30
- # lifting. Create, destroy, and list commands are included. Since a
63
+ # the manifest to a command which replays the actions to do the heavy
64
+ # lifting (such as checking for existing files or creating directories
65
+ # if needed). Create, destroy, and list commands are included. Since a
31
66
  # single manifest may be used by any command, creating new generators is
32
67
  # as simple as writing some code templates and declaring what you'd like
33
68
  # to do with them.
34
69
  #
35
70
  # The manifest method must be implemented by subclasses, returning a
36
- # Rails::Generator::Manifest. The record method is provided as a
71
+ # Rails::Generator::Manifest. The +record+ method is provided as a
37
72
  # convenience for manifest creation. Example:
38
- # class EliteGenerator < Rails::Generator::Base
73
+ #
74
+ # class StylesheetGenerator < Rails::Generator::Base
39
75
  # def manifest
40
76
  # record do |m|
41
- # m.do(some)
42
- # m.things(in) { here }
77
+ # m.directory('public/stylesheets')
78
+ # m.file('application.css', 'public/stylesheets/application.css')
43
79
  # end
44
80
  # end
45
81
  # end
82
+ #
83
+ # See Rails::Generator::Commands::Create for a list of methods available
84
+ # to the manifest.
46
85
  class Base
47
86
  include Options
48
87
 
@@ -78,7 +117,7 @@ module Rails
78
117
  usage if options[:help]
79
118
  end
80
119
 
81
- # Generators must provide a manifest. Use the record method to create
120
+ # Generators must provide a manifest. Use the +record+ method to create
82
121
  # a new manifest and record your generator's actions.
83
122
  def manifest
84
123
  raise NotImplementedError, "No manifest for '#{spec.name}' generator."
@@ -136,13 +175,25 @@ module Rails
136
175
  # The base generator for named components: models, controllers, mailers,
137
176
  # etc. The target name is taken as the first argument and inflected to
138
177
  # singular, plural, class, file, and table forms for your convenience.
139
- # The remaining arguments are aliased to actions for controller and
140
- # mailer convenience.
178
+ # The remaining arguments are aliased to +actions+ as an array for
179
+ # controller and mailer convenience.
180
+ #
181
+ # Several useful local variables and methods are populated in the
182
+ # +initialize+ method. See below for a list of Attributes and
183
+ # External Aliases available to both the manifest and to all templates.
141
184
  #
142
185
  # If no name is provided, the generator raises a usage error with content
143
186
  # optionally read from the USAGE file in the generator's base path.
144
187
  #
145
- # See Rails::Generator::Base for a discussion of Manifests and Commands.
188
+ # For example, the +controller+ generator takes the first argument as
189
+ # the name of the class and subsequent arguments as the names of
190
+ # actions to be generated:
191
+ #
192
+ # ./script/generate controller Article index new create
193
+ #
194
+ # See Rails::Generator::Base for a discussion of manifests,
195
+ # Rails::Generator::Commands::Create for methods available to the manifest,
196
+ # and Rails::Generator for a general discussion of generators.
146
197
  class NamedBase < Base
147
198
  attr_reader :name, :class_name, :singular_name, :plural_name, :table_name
148
199
  attr_reader :class_path, :file_path, :class_nesting, :class_nesting_depth
@@ -165,16 +216,25 @@ module Rails
165
216
  def banner
166
217
  "Usage: #{$0} #{spec.name} #{spec.name.camelize}Name [options]"
167
218
  end
219
+
220
+ def attributes
221
+ @attributes ||= @args.collect do |attribute|
222
+ Rails::Generator::GeneratedAttribute.new(*attribute.split(":"))
223
+ end
224
+ end
225
+
168
226
 
169
227
  private
170
228
  def assign_names!(name)
171
229
  @name = name
172
230
  base_name, @class_path, @file_path, @class_nesting, @class_nesting_depth = extract_modules(@name)
173
231
  @class_name_without_nesting, @singular_name, @plural_name = inflect_names(base_name)
174
- @table_name = ActiveRecord::Base.pluralize_table_names ? plural_name : singular_name
232
+ @table_name = (!defined?(ActiveRecord::Base) || ActiveRecord::Base.pluralize_table_names) ? plural_name : singular_name
233
+ @table_name.gsub! '/', '_'
175
234
  if @class_nesting.empty?
176
235
  @class_name = @class_name_without_nesting
177
236
  else
237
+ @table_name = @class_nesting.underscore << "_" << @table_name
178
238
  @class_name = "#{@class_nesting}::#{@class_name_without_nesting}"
179
239
  end
180
240
  end