railties 3.0.0.beta3 → 3.0.0.beta4
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +5 -0
- data/README +118 -123
- data/guides/source/3_0_release_notes.textile +13 -11
- data/guides/source/action_controller_overview.textile +2 -2
- data/guides/source/action_mailer_basics.textile +70 -26
- data/guides/source/action_view_overview.textile +1 -1
- data/guides/source/active_record_basics.textile +9 -1
- data/guides/source/active_record_querying.textile +2 -2
- data/guides/source/active_support_core_extensions.textile +377 -9
- data/guides/source/activerecord_validations_callbacks.textile +98 -55
- data/guides/source/association_basics.textile +1 -1
- data/guides/source/caching_with_rails.textile +1 -1
- data/guides/source/command_line.textile +23 -23
- data/guides/source/configuring.textile +1 -3
- data/guides/source/contribute.textile +27 -28
- data/guides/source/credits.html.erb +4 -4
- data/guides/source/debugging_rails_applications.textile +2 -2
- data/guides/source/form_helpers.textile +7 -6
- data/guides/source/generators.textile +19 -29
- data/guides/source/getting_started.textile +106 -49
- data/guides/source/i18n.textile +27 -27
- data/guides/source/index.html.erb +18 -8
- data/guides/source/initialization.textile +140 -514
- data/guides/source/layout.html.erb +6 -4
- data/guides/source/layouts_and_rendering.textile +5 -5
- data/guides/source/migrations.textile +7 -3
- data/guides/source/nested_model_forms.textile +2 -2
- data/guides/source/performance_testing.textile +11 -12
- data/guides/source/plugins.textile +30 -30
- data/guides/source/rails_application_templates.textile +3 -3
- data/guides/source/rails_on_rack.textile +3 -66
- data/guides/source/routing.textile +10 -4
- data/guides/source/security.textile +1 -1
- data/guides/source/testing.textile +55 -52
- data/guides/w3c_validator.rb +67 -0
- data/lib/rails.rb +1 -0
- data/lib/rails/application.rb +49 -13
- data/lib/rails/application/bootstrap.rb +7 -6
- data/lib/rails/application/configuration.rb +24 -47
- data/lib/rails/application/finisher.rb +8 -3
- data/lib/rails/backtrace_cleaner.rb +11 -12
- data/lib/rails/commands.rb +54 -54
- data/lib/rails/commands/application.rb +7 -2
- data/lib/rails/commands/{performance/benchmarker.rb → benchmarker.rb} +0 -0
- data/lib/rails/commands/dbconsole.rb +4 -3
- data/lib/rails/commands/destroy.rb +1 -0
- data/lib/rails/commands/generate.rb +1 -0
- data/lib/rails/commands/{performance/profiler.rb → profiler.rb} +0 -0
- data/lib/rails/commands/runner.rb +4 -2
- data/lib/rails/configuration.rb +36 -0
- data/lib/rails/engine.rb +24 -24
- data/lib/rails/engine/configuration.rb +0 -1
- data/lib/rails/generators.rb +48 -10
- data/lib/rails/generators/actions.rb +5 -3
- data/lib/rails/generators/base.rb +23 -17
- data/lib/rails/generators/erb/scaffold/templates/_form.html.erb +9 -8
- data/lib/rails/generators/erb/scaffold/templates/show.html.erb +1 -1
- data/lib/rails/generators/generated_attribute.rb +7 -6
- data/lib/rails/generators/rails/app/USAGE +2 -2
- data/lib/rails/generators/rails/app/app_generator.rb +242 -97
- data/lib/rails/generators/rails/app/templates/Gemfile +3 -0
- data/lib/rails/generators/rails/app/templates/README +167 -130
- data/lib/rails/generators/rails/app/templates/Rakefile +0 -3
- data/lib/rails/generators/rails/app/templates/config/boot.rb +9 -2
- data/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml +5 -5
- data/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +4 -0
- data/lib/rails/generators/rails/app/templates/script/rails +2 -5
- data/lib/rails/generators/rails/generator/templates/%file_name%_generator.rb.tt +1 -3
- data/lib/rails/generators/rails/stylesheets/templates/scaffold.css +5 -9
- data/lib/rails/generators/test_case.rb +12 -0
- data/lib/rails/generators/test_unit/integration/templates/integration_test.rb +1 -1
- data/lib/rails/generators/test_unit/performance/templates/performance_test.rb +1 -1
- data/lib/rails/info.rb +0 -33
- data/lib/rails/log_subscriber.rb +13 -6
- data/lib/rails/rack/logger.rb +4 -3
- data/lib/rails/railtie.rb +4 -0
- data/lib/rails/railtie/configuration.rb +21 -4
- data/lib/rails/tasks/documentation.rake +2 -0
- data/lib/rails/tasks/framework.rake +22 -0
- data/lib/rails/tasks/middleware.rake +1 -1
- data/lib/rails/tasks/routes.rake +5 -1
- data/lib/rails/test_help.rb +3 -1
- data/lib/rails/test_unit/testing.rake +3 -1
- data/lib/rails/version.rb +1 -1
- metadata +12 -19
- data/lib/rails/application/metal_loader.rb +0 -50
- data/lib/rails/dispatcher.rb +0 -24
- data/lib/rails/generators/rails/mailer/USAGE +0 -15
- data/lib/rails/generators/rails/mailer/mailer_generator.rb +0 -14
- data/lib/rails/generators/rails/mailer/templates/mailer.rb +0 -16
- data/lib/rails/generators/rails/metal/USAGE +0 -8
- data/lib/rails/generators/rails/metal/metal_generator.rb +0 -11
- data/lib/rails/generators/rails/metal/templates/metal.rb +0 -12
data/lib/rails/engine.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'rails/railtie'
|
2
2
|
require 'active_support/core_ext/module/delegation'
|
3
3
|
require 'pathname'
|
4
|
+
require 'rbconfig'
|
4
5
|
|
5
6
|
module Rails
|
6
7
|
# Rails::Engine allows you to wrap a specific Rails application and share it accross
|
@@ -24,7 +25,7 @@ module Rails
|
|
24
25
|
# end
|
25
26
|
#
|
26
27
|
# Then ensure that this file is loaded at the top of your config/application.rb (or in
|
27
|
-
# your Gemfile) and it will automatically load models, controllers
|
28
|
+
# your Gemfile) and it will automatically load models, controllers and helpers
|
28
29
|
# inside app, load routes at "config/routes.rb", load locales at "config/locales/*",
|
29
30
|
# load tasks at "lib/tasks/*".
|
30
31
|
#
|
@@ -41,10 +42,10 @@ module Rails
|
|
41
42
|
# config.load_paths << File.expand_path("../lib/some/path", __FILE__)
|
42
43
|
#
|
43
44
|
# initializer "my_engine.add_middleware" do |app|
|
44
|
-
# app.
|
45
|
+
# app.middleware.use MyEngine::Middleware
|
45
46
|
# end
|
46
47
|
# end
|
47
|
-
#
|
48
|
+
#
|
48
49
|
# == Paths
|
49
50
|
#
|
50
51
|
# Since Rails 3.0, both your Application and Engines do not have hardcoded paths.
|
@@ -72,7 +73,6 @@ module Rails
|
|
72
73
|
# paths.app.controllers = "app/controllers"
|
73
74
|
# paths.app.helpers = "app/helpers"
|
74
75
|
# paths.app.models = "app/models"
|
75
|
-
# paths.app.metals = "app/metal"
|
76
76
|
# paths.app.views = "app/views"
|
77
77
|
# paths.lib = "lib"
|
78
78
|
# paths.lib.tasks = "lib/tasks"
|
@@ -119,20 +119,29 @@ module Rails
|
|
119
119
|
root = File.exist?("#{root_path}/#{flag}") ? root_path : default
|
120
120
|
raise "Could not find root path for #{self}" unless root
|
121
121
|
|
122
|
-
|
122
|
+
Config::CONFIG['host_os'] =~ /mswin|mingw/ ?
|
123
123
|
Pathname.new(root).expand_path : Pathname.new(root).realpath
|
124
124
|
end
|
125
125
|
end
|
126
126
|
|
127
|
-
delegate :
|
127
|
+
delegate :paths, :root, :to => :config
|
128
128
|
|
129
129
|
def load_tasks
|
130
130
|
super
|
131
131
|
config.paths.lib.tasks.to_a.sort.each { |ext| load(ext) }
|
132
132
|
end
|
133
133
|
|
134
|
+
def eager_load!
|
135
|
+
config.eager_load_paths.each do |load_path|
|
136
|
+
matcher = /\A#{Regexp.escape(load_path)}\/(.*)\.rb\Z/
|
137
|
+
Dir.glob("#{load_path}/**/*.rb").sort.each do |file|
|
138
|
+
require_dependency file.sub(matcher, '\1')
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
134
143
|
# Add configured load paths to ruby load paths and remove duplicates.
|
135
|
-
initializer :set_load_path, :before => :
|
144
|
+
initializer :set_load_path, :before => :bootstrap_hook do
|
136
145
|
config.load_paths.reverse_each do |path|
|
137
146
|
$LOAD_PATH.unshift(path) if File.directory?(path)
|
138
147
|
end
|
@@ -141,7 +150,10 @@ module Rails
|
|
141
150
|
|
142
151
|
# Set the paths from which Rails will automatically load source files,
|
143
152
|
# and the load_once paths.
|
144
|
-
|
153
|
+
#
|
154
|
+
# This needs to be an initializer, since it needs to run once
|
155
|
+
# per engine and get the engine as a block parameter
|
156
|
+
initializer :set_autoload_paths, :before => :bootstrap_hook do |app|
|
145
157
|
ActiveSupport::Dependencies.load_paths.unshift(*config.load_paths)
|
146
158
|
|
147
159
|
if reloadable?(app)
|
@@ -166,7 +178,7 @@ module Rails
|
|
166
178
|
paths.app.controllers.to_a.each do |load_path|
|
167
179
|
load_path = File.expand_path(load_path)
|
168
180
|
Dir["#{load_path}/*/**/*_controller.rb"].collect do |path|
|
169
|
-
namespace = File.dirname(path).sub(/#{load_path}\/?/, '')
|
181
|
+
namespace = File.dirname(path).sub(/#{Regexp.escape(load_path)}\/?/, '')
|
170
182
|
app.routes.controller_namespaces << namespace unless namespace.empty?
|
171
183
|
end
|
172
184
|
end
|
@@ -189,27 +201,15 @@ module Rails
|
|
189
201
|
end
|
190
202
|
end
|
191
203
|
|
192
|
-
initializer :add_metals do |app|
|
193
|
-
app.metal_loader.paths.unshift(*paths.app.metals.to_a)
|
194
|
-
end
|
195
|
-
|
196
204
|
initializer :load_config_initializers do
|
197
205
|
paths.config.initializers.to_a.sort.each do |initializer|
|
198
206
|
load(initializer)
|
199
207
|
end
|
200
208
|
end
|
201
209
|
|
202
|
-
initializer :
|
203
|
-
|
204
|
-
|
205
|
-
if app.config.cache_classes
|
206
|
-
config.eager_load_paths.each do |load_path|
|
207
|
-
matcher = /\A#{Regexp.escape(load_path)}\/(.*)\.rb\Z/
|
208
|
-
Dir.glob("#{load_path}/**/*.rb").sort.each do |file|
|
209
|
-
require_dependency file.sub(matcher, '\1')
|
210
|
-
end
|
211
|
-
end
|
212
|
-
end
|
210
|
+
initializer :engines_blank_point do
|
211
|
+
# We need this initializer so all extra initializers added in engines are
|
212
|
+
# consistently executed after all the initializers above across all engines.
|
213
213
|
end
|
214
214
|
|
215
215
|
protected
|
@@ -19,7 +19,6 @@ module Rails
|
|
19
19
|
paths.app.helpers "app/helpers", :eager_load => true
|
20
20
|
paths.app.models "app/models", :eager_load => true
|
21
21
|
paths.app.mailers "app/mailers", :eager_load => true
|
22
|
-
paths.app.metals "app/metal", :eager_load => true
|
23
22
|
paths.app.views "app/views"
|
24
23
|
paths.lib "lib", :load_path => true
|
25
24
|
paths.lib.tasks "lib/tasks", :glob => "**/*.rake"
|
data/lib/rails/generators.rb
CHANGED
@@ -68,6 +68,7 @@ module Rails
|
|
68
68
|
options.deep_merge! config.options
|
69
69
|
fallbacks.merge! config.fallbacks
|
70
70
|
templates_path.concat config.templates
|
71
|
+
templates_path.uniq!
|
71
72
|
end
|
72
73
|
|
73
74
|
def self.templates_path
|
@@ -166,6 +167,42 @@ module Rails
|
|
166
167
|
end
|
167
168
|
end
|
168
169
|
|
170
|
+
def self.hidden_namespaces
|
171
|
+
@hidden_namespaces ||= begin
|
172
|
+
orm = options[:rails][:orm]
|
173
|
+
test = options[:rails][:test_framework]
|
174
|
+
template = options[:rails][:template_engine]
|
175
|
+
|
176
|
+
[
|
177
|
+
"rails",
|
178
|
+
"#{orm}:migration",
|
179
|
+
"#{orm}:model",
|
180
|
+
"#{orm}:observer",
|
181
|
+
"#{orm}:session_migration",
|
182
|
+
"#{test}:controller",
|
183
|
+
"#{test}:helper",
|
184
|
+
"#{test}:integration",
|
185
|
+
"#{test}:mailer",
|
186
|
+
"#{test}:model",
|
187
|
+
"#{test}:observer",
|
188
|
+
"#{test}:scaffold",
|
189
|
+
"#{test}:view",
|
190
|
+
"#{test}:performance",
|
191
|
+
"#{test}:plugin",
|
192
|
+
"#{template}:controller",
|
193
|
+
"#{template}:scaffold",
|
194
|
+
"#{template}:mailer"
|
195
|
+
]
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
class << self
|
200
|
+
def hide_namespaces(*namespaces)
|
201
|
+
hidden_namespaces.concat(namespaces)
|
202
|
+
end
|
203
|
+
alias hide_namespace hide_namespaces
|
204
|
+
end
|
205
|
+
|
169
206
|
# Show help message with available generators.
|
170
207
|
def self.help(command = 'generate')
|
171
208
|
lookup!
|
@@ -197,9 +234,7 @@ module Rails
|
|
197
234
|
rails.delete("app")
|
198
235
|
print_list("rails", rails)
|
199
236
|
|
200
|
-
groups.delete(
|
201
|
-
groups.delete("test_unit") if options[:rails][:test_framework] == :test_unit
|
202
|
-
groups.delete("erb") if options[:rails][:template_engine] == :erb
|
237
|
+
hidden_namespaces.each {|n| groups.delete(n.to_s) }
|
203
238
|
|
204
239
|
groups.sort.each { |b, n| print_list(b, n) }
|
205
240
|
end
|
@@ -208,9 +243,17 @@ module Rails
|
|
208
243
|
|
209
244
|
# Prints a list of generators.
|
210
245
|
def self.print_list(base, namespaces) #:nodoc:
|
246
|
+
namespaces = namespaces.reject do |n|
|
247
|
+
hidden_namespaces.include?(n)
|
248
|
+
end
|
249
|
+
|
211
250
|
return if namespaces.empty?
|
212
251
|
puts "#{base.camelize}:"
|
213
|
-
|
252
|
+
|
253
|
+
namespaces.each do |namespace|
|
254
|
+
puts(" #{namespace}")
|
255
|
+
end
|
256
|
+
|
214
257
|
puts
|
215
258
|
end
|
216
259
|
|
@@ -290,10 +333,5 @@ module Rails
|
|
290
333
|
paths.uniq!
|
291
334
|
paths
|
292
335
|
end
|
293
|
-
|
294
336
|
end
|
295
|
-
end
|
296
|
-
|
297
|
-
# If the application was already defined, configure generators,
|
298
|
-
# otherwise you have to configure it by hand.
|
299
|
-
Rails::Generators.configure! if Rails.respond_to?(:application) && Rails.application
|
337
|
+
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'open-uri'
|
2
2
|
require 'active_support/deprecation'
|
3
|
+
require 'rbconfig'
|
3
4
|
|
4
5
|
module Rails
|
5
6
|
module Generators
|
@@ -53,7 +54,8 @@ module Rails
|
|
53
54
|
name, version = args
|
54
55
|
|
55
56
|
# Deal with deprecated options
|
56
|
-
{ :env => :
|
57
|
+
{ :env => :group, :only => :group,
|
58
|
+
:lib => :require, :require_as => :require }.each do |old, new|
|
57
59
|
next unless options[old]
|
58
60
|
options[new] = options.delete(old)
|
59
61
|
ActiveSupport::Deprecation.warn "#{old.inspect} option in gem is deprecated, use #{new.inspect} instead"
|
@@ -240,7 +242,7 @@ module Rails
|
|
240
242
|
def rake(command, options={})
|
241
243
|
log :rake, command
|
242
244
|
env = options[:env] || 'development'
|
243
|
-
sudo = options[:sudo] &&
|
245
|
+
sudo = options[:sudo] && Config::CONFIG['host_os'] !~ /mswin|mingw/ ? 'sudo ' : ''
|
244
246
|
in_root { run("#{sudo}#{extify(:rake)} #{command} RAILS_ENV=#{env}", :verbose => false) }
|
245
247
|
end
|
246
248
|
|
@@ -307,7 +309,7 @@ module Rails
|
|
307
309
|
# Add an extension to the given name based on the platform.
|
308
310
|
#
|
309
311
|
def extify(name)
|
310
|
-
if
|
312
|
+
if Config::CONFIG['host_os'] =~ /mswin|mingw/
|
311
313
|
"#{name}.bat"
|
312
314
|
else
|
313
315
|
name
|
@@ -20,24 +20,19 @@ module Rails
|
|
20
20
|
|
21
21
|
add_runtime_options!
|
22
22
|
|
23
|
-
#
|
24
|
-
|
25
|
-
|
26
|
-
@
|
27
|
-
if base_name && generator_name
|
28
|
-
File.expand_path(File.join(base_name, generator_name, 'templates'), File.dirname(__FILE__))
|
29
|
-
end
|
30
|
-
end
|
23
|
+
# Returns the source root for this generator using default_source_root as default.
|
24
|
+
def self.source_root(path=nil)
|
25
|
+
@_source_root = path if path
|
26
|
+
@_source_root ||= default_source_root
|
31
27
|
end
|
32
28
|
|
33
29
|
# Tries to get the description from a USAGE file one folder above the source
|
34
30
|
# root otherwise uses a default description.
|
35
|
-
#
|
36
31
|
def self.desc(description=nil)
|
37
32
|
return super if description
|
38
|
-
usage = File.expand_path(
|
33
|
+
usage = source_root && File.expand_path("../USAGE", source_root)
|
39
34
|
|
40
|
-
@desc ||= if File.exist?(usage)
|
35
|
+
@desc ||= if usage && File.exist?(usage)
|
41
36
|
File.read(usage)
|
42
37
|
else
|
43
38
|
"Description:\n Create #{base_name.humanize.downcase} files for #{generator_name} generator."
|
@@ -47,7 +42,6 @@ module Rails
|
|
47
42
|
# Convenience method to get the namespace from the class name. It's the
|
48
43
|
# same as Thor default except that the Generator at the end of the class
|
49
44
|
# is removed.
|
50
|
-
#
|
51
45
|
def self.namespace(name=nil)
|
52
46
|
return super if name
|
53
47
|
@namespace ||= super.sub(/_generator$/, '').sub(/:generators:/, ':')
|
@@ -200,7 +194,6 @@ module Rails
|
|
200
194
|
end
|
201
195
|
|
202
196
|
# Make class option aware of Rails::Generators.options and Rails::Generators.aliases.
|
203
|
-
#
|
204
197
|
def self.class_option(name, options={}) #:nodoc:
|
205
198
|
options[:desc] = "Indicates when to generate #{name.to_s.humanize.downcase}" unless options.key?(:desc)
|
206
199
|
options[:aliases] = default_aliases_for_option(name, options)
|
@@ -208,14 +201,27 @@ module Rails
|
|
208
201
|
super(name, options)
|
209
202
|
end
|
210
203
|
|
204
|
+
# Returns the default source root for a given generator. This is used internally
|
205
|
+
# by rails to set its generators source root. If you want to customize your source
|
206
|
+
# root, you should use source_root.
|
207
|
+
def self.default_source_root
|
208
|
+
return unless base_name && generator_name
|
209
|
+
path = File.expand_path(File.join(base_name, generator_name, 'templates'), base_root)
|
210
|
+
path if File.exists?(path)
|
211
|
+
end
|
212
|
+
|
213
|
+
# Returns the base root for a common set of generators. This is used to dynamically
|
214
|
+
# guess the default source root.
|
215
|
+
def self.base_root
|
216
|
+
File.dirname(__FILE__)
|
217
|
+
end
|
218
|
+
|
211
219
|
# Cache source root and add lib/generators/base/generator/templates to
|
212
220
|
# source paths.
|
213
|
-
#
|
214
221
|
def self.inherited(base) #:nodoc:
|
215
222
|
super
|
216
223
|
|
217
|
-
#
|
218
|
-
# and can point to wrong directions when inside an specified directory.
|
224
|
+
# Invoke source_root so the default_source_root is set.
|
219
225
|
base.source_root
|
220
226
|
|
221
227
|
if base.name && base.name !~ /Base$/
|
@@ -282,7 +288,7 @@ module Rails
|
|
282
288
|
end
|
283
289
|
|
284
290
|
# Removes the namespaces and get the generator name. For example,
|
285
|
-
# Rails::Generators::
|
291
|
+
# Rails::Generators::ModelGenerator will return "model" as generator name.
|
286
292
|
#
|
287
293
|
def self.generator_name
|
288
294
|
@generator_name ||= begin
|
@@ -1,13 +1,14 @@
|
|
1
1
|
<%%= form_for(@<%= singular_name %>) do |f| %>
|
2
2
|
<%% if @<%= singular_name %>.errors.any? %>
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
3
|
+
<div id="error_explanation">
|
4
|
+
<h2><%%= pluralize(@<%= singular_name %>.errors.count, "error") %> prohibited this <%= singular_name %> from being saved:</h2>
|
5
|
+
|
6
|
+
<ul>
|
7
|
+
<%% @<%= singular_name %>.errors.full_messages.each do |msg| %>
|
8
|
+
<li><%%= msg %></li>
|
9
|
+
<%% end %>
|
10
|
+
</ul>
|
11
|
+
</div>
|
11
12
|
<%% end %>
|
12
13
|
|
13
14
|
<% for attribute in attributes -%>
|
@@ -9,12 +9,13 @@ module Rails
|
|
9
9
|
|
10
10
|
def field_type
|
11
11
|
@field_type ||= case type
|
12
|
-
when :integer, :float, :decimal
|
13
|
-
when :
|
14
|
-
when :
|
15
|
-
when :
|
16
|
-
when :
|
17
|
-
when :
|
12
|
+
when :integer, :float, :decimal then :text_field
|
13
|
+
when :time then :time_select
|
14
|
+
when :datetime, :timestamp then :datetime_select
|
15
|
+
when :date then :date_select
|
16
|
+
when :string then :text_field
|
17
|
+
when :text then :text_area
|
18
|
+
when :boolean then :check_box
|
18
19
|
else
|
19
20
|
:text_field
|
20
21
|
end
|
@@ -1,9 +1,9 @@
|
|
1
1
|
Description:
|
2
|
-
The 'rails' command creates a new Rails application with a default
|
2
|
+
The 'rails new' command creates a new Rails application with a default
|
3
3
|
directory structure and configuration at the path you specify.
|
4
4
|
|
5
5
|
Example:
|
6
|
-
rails ~/Code/Ruby/weblog
|
6
|
+
rails new ~/Code/Ruby/weblog
|
7
7
|
|
8
8
|
This generates a skeletal Rails installation in ~/Code/Ruby/weblog.
|
9
9
|
See the README in the newly created application to get going.
|
@@ -1,87 +1,62 @@
|
|
1
1
|
require 'digest/md5'
|
2
2
|
require 'active_support/secure_random'
|
3
3
|
require 'rails/version' unless defined?(Rails::VERSION)
|
4
|
+
require 'rbconfig'
|
5
|
+
require 'open-uri'
|
6
|
+
require 'uri'
|
4
7
|
|
5
|
-
module Rails
|
6
|
-
|
7
|
-
|
8
|
-
RAILS_DEV_PATH = File.expand_path("../../../../../..", File.dirname(__FILE__))
|
8
|
+
module Rails
|
9
|
+
module ActionMethods
|
10
|
+
attr_reader :options
|
9
11
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
class AppGenerator < Base
|
15
|
-
DATABASES = %w( mysql oracle postgresql sqlite3 frontbase ibm_db )
|
16
|
-
|
17
|
-
attr_accessor :rails_template
|
18
|
-
add_shebang_option!
|
19
|
-
|
20
|
-
argument :app_path, :type => :string
|
21
|
-
|
22
|
-
class_option :database, :type => :string, :aliases => "-d", :default => "sqlite3",
|
23
|
-
:desc => "Preconfigure for selected database (options: #{DATABASES.join('/')})"
|
24
|
-
|
25
|
-
class_option :template, :type => :string, :aliases => "-m",
|
26
|
-
:desc => "Path to an application template (can be a filesystem path or URL)."
|
27
|
-
|
28
|
-
class_option :dev, :type => :boolean, :default => false,
|
29
|
-
:desc => "Setup the application with Gemfile pointing to your Rails checkout"
|
30
|
-
|
31
|
-
class_option :edge, :type => :boolean, :default => false,
|
32
|
-
:desc => "Setup the application with Gemfile pointing to Rails repository"
|
33
|
-
|
34
|
-
class_option :skip_gemfile, :type => :boolean, :default => false,
|
35
|
-
:desc => "Don't create a Gemfile"
|
36
|
-
|
37
|
-
class_option :skip_activerecord, :type => :boolean, :aliases => "-O", :default => false,
|
38
|
-
:desc => "Skip ActiveRecord files"
|
39
|
-
|
40
|
-
class_option :skip_testunit, :type => :boolean, :aliases => "-T", :default => false,
|
41
|
-
:desc => "Skip TestUnit files"
|
42
|
-
|
43
|
-
class_option :skip_prototype, :type => :boolean, :aliases => "-J", :default => false,
|
44
|
-
:desc => "Skip Prototype files"
|
45
|
-
|
46
|
-
class_option :skip_git, :type => :boolean, :aliases => "-G", :default => false,
|
47
|
-
:desc => "Skip Git ignores and keeps"
|
48
|
-
|
49
|
-
# Add bin/rails options
|
50
|
-
class_option :version, :type => :boolean, :aliases => "-v", :group => :rails,
|
51
|
-
:desc => "Show Rails version number and quit"
|
12
|
+
def initialize(generator)
|
13
|
+
@generator = generator
|
14
|
+
@options = generator.options
|
15
|
+
end
|
52
16
|
|
53
|
-
|
54
|
-
|
17
|
+
private
|
18
|
+
%w(template copy_file directory empty_directory inside
|
19
|
+
empty_directory_with_gitkeep create_file chmod shebang).each do |method|
|
20
|
+
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
21
|
+
def #{method}(*args, &block)
|
22
|
+
@generator.send(:#{method}, *args, &block)
|
23
|
+
end
|
24
|
+
RUBY
|
25
|
+
end
|
55
26
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
27
|
+
# TODO: Remove once this is fully in place
|
28
|
+
def method_missing(meth, *args, &block)
|
29
|
+
STDERR.puts "Calling #{meth} with #{args.inspect} with #{block}"
|
30
|
+
@generator.send(meth, *args, &block)
|
60
31
|
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class AppBuilder
|
35
|
+
def rakefile
|
36
|
+
template "Rakefile"
|
61
37
|
end
|
62
38
|
|
63
|
-
def
|
64
|
-
|
65
|
-
|
39
|
+
def readme
|
40
|
+
copy_file "README"
|
41
|
+
end
|
66
42
|
|
67
|
-
|
68
|
-
|
69
|
-
FileUtils.cd(destination_root)
|
43
|
+
def gemfile
|
44
|
+
template "Gemfile"
|
70
45
|
end
|
71
46
|
|
72
|
-
def
|
73
|
-
copy_file "README"
|
74
|
-
copy_file "gitignore", ".gitignore" unless options[:skip_git]
|
75
|
-
template "Rakefile"
|
47
|
+
def configru
|
76
48
|
template "config.ru"
|
77
|
-
template "Gemfile" unless options[:skip_gemfile]
|
78
49
|
end
|
79
50
|
|
80
|
-
def
|
51
|
+
def gitignore
|
52
|
+
copy_file "gitignore", ".gitignore"
|
53
|
+
end
|
54
|
+
|
55
|
+
def app
|
81
56
|
directory 'app'
|
82
57
|
end
|
83
58
|
|
84
|
-
def
|
59
|
+
def config
|
85
60
|
empty_directory "config"
|
86
61
|
|
87
62
|
inside "config" do
|
@@ -95,29 +70,24 @@ module Rails::Generators
|
|
95
70
|
end
|
96
71
|
end
|
97
72
|
|
98
|
-
def
|
99
|
-
template "config/
|
100
|
-
end
|
101
|
-
|
102
|
-
def create_activerecord_files
|
103
|
-
return if options[:skip_activerecord]
|
104
|
-
template "config/databases/#{options[:database]}.yml", "config/database.yml"
|
73
|
+
def database_yml
|
74
|
+
template "config/databases/#{@options[:database]}.yml", "config/database.yml"
|
105
75
|
end
|
106
76
|
|
107
|
-
def
|
77
|
+
def db
|
108
78
|
directory "db"
|
109
79
|
end
|
110
80
|
|
111
|
-
def
|
81
|
+
def doc
|
112
82
|
directory "doc"
|
113
83
|
end
|
114
84
|
|
115
|
-
def
|
85
|
+
def lib
|
116
86
|
empty_directory "lib"
|
117
87
|
empty_directory_with_gitkeep "lib/tasks"
|
118
88
|
end
|
119
89
|
|
120
|
-
def
|
90
|
+
def log
|
121
91
|
empty_directory "log"
|
122
92
|
|
123
93
|
inside "log" do
|
@@ -128,19 +98,19 @@ module Rails::Generators
|
|
128
98
|
end
|
129
99
|
end
|
130
100
|
|
131
|
-
def
|
132
|
-
directory "public", "public", :recursive => false
|
101
|
+
def public_directory
|
102
|
+
directory "public", "public", :recursive => false
|
133
103
|
end
|
134
104
|
|
135
|
-
def
|
105
|
+
def images
|
136
106
|
directory "public/images"
|
137
107
|
end
|
138
108
|
|
139
|
-
def
|
109
|
+
def stylesheets
|
140
110
|
empty_directory_with_gitkeep "public/stylesheets"
|
141
111
|
end
|
142
112
|
|
143
|
-
def
|
113
|
+
def javascripts
|
144
114
|
unless options[:skip_prototype]
|
145
115
|
directory "public/javascripts"
|
146
116
|
else
|
@@ -148,19 +118,18 @@ module Rails::Generators
|
|
148
118
|
end
|
149
119
|
end
|
150
120
|
|
151
|
-
def
|
121
|
+
def script
|
152
122
|
directory "script" do |content|
|
153
123
|
"#{shebang}\n" + content
|
154
124
|
end
|
155
125
|
chmod "script", 0755, :verbose => false
|
156
126
|
end
|
157
127
|
|
158
|
-
def
|
159
|
-
return if options[:skip_testunit]
|
128
|
+
def test
|
160
129
|
directory "test"
|
161
130
|
end
|
162
131
|
|
163
|
-
def
|
132
|
+
def tmp
|
164
133
|
empty_directory "tmp"
|
165
134
|
|
166
135
|
inside "tmp" do
|
@@ -170,25 +139,200 @@ module Rails::Generators
|
|
170
139
|
end
|
171
140
|
end
|
172
141
|
|
173
|
-
def
|
142
|
+
def vendor_plugins
|
174
143
|
empty_directory_with_gitkeep "vendor/plugins"
|
175
144
|
end
|
145
|
+
end
|
176
146
|
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
end
|
147
|
+
module Generators
|
148
|
+
# We need to store the RAILS_DEV_PATH in a constant, otherwise the path
|
149
|
+
# can change in Ruby 1.8.7 when we FileUtils.cd.
|
150
|
+
RAILS_DEV_PATH = File.expand_path("../../../../../..", File.dirname(__FILE__))
|
182
151
|
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
152
|
+
RESERVED_NAMES = %w[application destroy benchmarker profiler
|
153
|
+
plugin runner test]
|
154
|
+
|
155
|
+
class AppGenerator < Base
|
156
|
+
DATABASES = %w( mysql oracle postgresql sqlite3 frontbase ibm_db )
|
157
|
+
|
158
|
+
attr_accessor :rails_template
|
159
|
+
add_shebang_option!
|
160
|
+
|
161
|
+
argument :app_path, :type => :string
|
162
|
+
|
163
|
+
class_option :database, :type => :string, :aliases => "-d", :default => "sqlite3",
|
164
|
+
:desc => "Preconfigure for selected database (options: #{DATABASES.join('/')})"
|
165
|
+
|
166
|
+
class_option :builder, :type => :string, :aliases => "-b",
|
167
|
+
:desc => "Path to an application builder (can be a filesystem path or URL)"
|
168
|
+
|
169
|
+
class_option :template, :type => :string, :aliases => "-m",
|
170
|
+
:desc => "Path to an application template (can be a filesystem path or URL)."
|
171
|
+
|
172
|
+
class_option :dev, :type => :boolean, :default => false,
|
173
|
+
:desc => "Setup the application with Gemfile pointing to your Rails checkout"
|
174
|
+
|
175
|
+
class_option :edge, :type => :boolean, :default => false,
|
176
|
+
:desc => "Setup the application with Gemfile pointing to Rails repository"
|
177
|
+
|
178
|
+
class_option :skip_gemfile, :type => :boolean, :default => false,
|
179
|
+
:desc => "Don't create a Gemfile"
|
180
|
+
|
181
|
+
class_option :skip_activerecord, :type => :boolean, :aliases => "-O", :default => false,
|
182
|
+
:desc => "Skip ActiveRecord files"
|
183
|
+
|
184
|
+
class_option :skip_testunit, :type => :boolean, :aliases => "-T", :default => false,
|
185
|
+
:desc => "Skip TestUnit files"
|
186
|
+
|
187
|
+
class_option :skip_prototype, :type => :boolean, :aliases => "-J", :default => false,
|
188
|
+
:desc => "Skip Prototype files"
|
189
|
+
|
190
|
+
class_option :skip_git, :type => :boolean, :aliases => "-G", :default => false,
|
191
|
+
:desc => "Skip Git ignores and keeps"
|
192
|
+
|
193
|
+
# Add bin/rails options
|
194
|
+
class_option :version, :type => :boolean, :aliases => "-v", :group => :rails,
|
195
|
+
:desc => "Show Rails version number and quit"
|
196
|
+
|
197
|
+
class_option :help, :type => :boolean, :aliases => "-h", :group => :rails,
|
198
|
+
:desc => "Show this help message and quit"
|
199
|
+
|
200
|
+
def initialize(*args)
|
201
|
+
raise Error, "Options should be given after the application name. For details run: rails --help" if args[0].blank?
|
202
|
+
|
203
|
+
@original_wd = Dir.pwd
|
204
|
+
|
205
|
+
super
|
206
|
+
|
207
|
+
if !options[:skip_activerecord] && !DATABASES.include?(options[:database])
|
208
|
+
raise Error, "Invalid value for --database option. Supported for preconfiguration are: #{DATABASES.join(", ")}."
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
def create_root
|
213
|
+
self.destination_root = File.expand_path(app_path, destination_root)
|
214
|
+
valid_app_const?
|
215
|
+
|
216
|
+
empty_directory '.'
|
217
|
+
set_default_accessors!
|
218
|
+
FileUtils.cd(destination_root)
|
219
|
+
end
|
220
|
+
|
221
|
+
def create_root_files
|
222
|
+
build(:readme)
|
223
|
+
build(:rakefile)
|
224
|
+
build(:configru)
|
225
|
+
build(:gitignore) unless options[:skip_git]
|
226
|
+
build(:gemfile) unless options[:skip_gemfile]
|
227
|
+
end
|
228
|
+
|
229
|
+
def create_app_files
|
230
|
+
build(:app)
|
231
|
+
end
|
232
|
+
|
233
|
+
def create_config_files
|
234
|
+
build(:config)
|
235
|
+
end
|
236
|
+
|
237
|
+
def create_boot_file
|
238
|
+
template "config/boot.rb"
|
239
|
+
end
|
240
|
+
|
241
|
+
def create_activerecord_files
|
242
|
+
return if options[:skip_activerecord]
|
243
|
+
build(:database_yml)
|
244
|
+
end
|
245
|
+
|
246
|
+
def create_db_files
|
247
|
+
build(:db)
|
248
|
+
end
|
249
|
+
|
250
|
+
def create_doc_files
|
251
|
+
build(:doc)
|
252
|
+
end
|
253
|
+
|
254
|
+
def create_lib_files
|
255
|
+
build(:lib)
|
256
|
+
end
|
257
|
+
|
258
|
+
def create_log_files
|
259
|
+
build(:log)
|
260
|
+
end
|
261
|
+
|
262
|
+
def create_public_files
|
263
|
+
build(:public_directory)
|
264
|
+
end
|
265
|
+
|
266
|
+
def create_public_image_files
|
267
|
+
build(:images)
|
268
|
+
end
|
269
|
+
|
270
|
+
def create_public_stylesheets_files
|
271
|
+
build(:stylesheets)
|
272
|
+
end
|
273
|
+
|
274
|
+
def create_prototype_files
|
275
|
+
build(:javascripts)
|
276
|
+
end
|
277
|
+
|
278
|
+
def create_script_files
|
279
|
+
build(:script)
|
280
|
+
end
|
281
|
+
|
282
|
+
def create_test_files
|
283
|
+
build(:test) unless options[:skip_testunit]
|
284
|
+
end
|
285
|
+
|
286
|
+
def create_tmp_files
|
287
|
+
build(:tmp)
|
288
|
+
end
|
289
|
+
|
290
|
+
def create_vendor_files
|
291
|
+
build(:vendor_plugins)
|
292
|
+
end
|
293
|
+
|
294
|
+
def finish_template
|
295
|
+
build(:leftovers)
|
296
|
+
end
|
297
|
+
|
298
|
+
def apply_rails_template
|
299
|
+
apply rails_template if rails_template
|
300
|
+
rescue Thor::Error, LoadError, Errno::ENOENT => e
|
301
|
+
raise Error, "The template [#{rails_template}] could not be loaded. Error: #{e}"
|
302
|
+
end
|
303
|
+
|
304
|
+
def bundle_if_dev_or_edge
|
305
|
+
bundle_command = File.basename(Thor::Util.ruby_command).sub(/ruby/, 'bundle')
|
306
|
+
run "#{bundle_command} install" if dev_or_edge?
|
307
|
+
end
|
187
308
|
|
188
309
|
protected
|
189
310
|
|
190
311
|
def self.banner
|
191
|
-
"rails #{self.arguments.map(&:usage).join(' ')} [options]"
|
312
|
+
"rails new #{self.arguments.map(&:usage).join(' ')} [options]"
|
313
|
+
end
|
314
|
+
|
315
|
+
def builder
|
316
|
+
@builder ||= begin
|
317
|
+
if path = options[:builder]
|
318
|
+
if URI(path).is_a?(URI::HTTP)
|
319
|
+
contents = open(path, "Accept" => "application/x-thor-template") {|io| io.read }
|
320
|
+
else
|
321
|
+
contents = open(File.expand_path(path, @original_wd)) {|io| io.read }
|
322
|
+
end
|
323
|
+
|
324
|
+
prok = eval("proc { #{contents} }", TOPLEVEL_BINDING, path, 1)
|
325
|
+
instance_eval(&prok)
|
326
|
+
end
|
327
|
+
|
328
|
+
builder_class = defined?(::AppBuilder) ? ::AppBuilder : Rails::AppBuilder
|
329
|
+
builder_class.send(:include, ActionMethods)
|
330
|
+
builder_class.new(self)
|
331
|
+
end
|
332
|
+
end
|
333
|
+
|
334
|
+
def build(meth, *args)
|
335
|
+
builder.send(meth, *args) if builder.respond_to?(meth)
|
192
336
|
end
|
193
337
|
|
194
338
|
def set_default_accessors!
|
@@ -265,12 +409,13 @@ module Rails::Generators
|
|
265
409
|
"/opt/local/var/run/mysql4/mysqld.sock", # mac + darwinports + mysql4
|
266
410
|
"/opt/local/var/run/mysql5/mysqld.sock", # mac + darwinports + mysql5
|
267
411
|
"/opt/lampp/var/mysql/mysql.sock" # xampp for linux
|
268
|
-
].find { |f| File.exist?(f) } unless
|
412
|
+
].find { |f| File.exist?(f) } unless Config::CONFIG['host_os'] =~ /mswin|mingw/
|
269
413
|
end
|
270
414
|
|
271
415
|
def empty_directory_with_gitkeep(destination, config = {})
|
272
416
|
empty_directory(destination, config)
|
273
417
|
create_file("#{destination}/.gitkeep") unless options[:skip_git]
|
274
418
|
end
|
419
|
+
end
|
275
420
|
end
|
276
421
|
end
|