rails 2.3.18 → 3.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.
- data/bin/rails +8 -20
- metadata +74 -251
- data/CHANGELOG +0 -2193
- data/MIT-LICENSE +0 -20
- data/README +0 -243
- data/Rakefile +0 -365
- data/bin/about +0 -4
- data/bin/console +0 -3
- data/bin/dbconsole +0 -3
- data/bin/destroy +0 -3
- data/bin/generate +0 -3
- data/bin/performance/benchmarker +0 -3
- data/bin/performance/profiler +0 -3
- data/bin/plugin +0 -3
- data/bin/runner +0 -3
- data/bin/server +0 -3
- data/builtin/rails_info/rails/info.rb +0 -131
- data/builtin/rails_info/rails/info_controller.rb +0 -9
- data/builtin/rails_info/rails/info_helper.rb +0 -2
- data/builtin/rails_info/rails_info_controller.rb +0 -2
- data/configs/databases/frontbase.yml +0 -28
- data/configs/databases/ibm_db.yml +0 -62
- data/configs/databases/mysql.yml +0 -60
- data/configs/databases/oracle.yml +0 -39
- data/configs/databases/postgresql.yml +0 -51
- data/configs/databases/sqlite2.yml +0 -19
- data/configs/databases/sqlite3.yml +0 -22
- data/configs/empty.log +0 -0
- data/configs/initializers/backtrace_silencers.rb +0 -7
- data/configs/initializers/cookie_verification_secret.rb +0 -7
- data/configs/initializers/inflections.rb +0 -10
- data/configs/initializers/mime_types.rb +0 -5
- data/configs/initializers/new_rails_defaults.rb +0 -21
- data/configs/initializers/session_store.rb +0 -15
- data/configs/locales/en.yml +0 -5
- data/configs/routes.rb +0 -43
- data/configs/seeds.rb +0 -7
- data/dispatches/config.ru +0 -7
- data/dispatches/dispatch.fcgi +0 -24
- data/dispatches/dispatch.rb +0 -10
- data/dispatches/gateway.cgi +0 -97
- data/doc/README_FOR_APP +0 -2
- data/environments/boot.rb +0 -114
- data/environments/development.rb +0 -17
- data/environments/environment.rb +0 -41
- data/environments/production.rb +0 -28
- data/environments/test.rb +0 -28
- data/fresh_rakefile +0 -10
- data/helpers/application_controller.rb +0 -10
- data/helpers/application_helper.rb +0 -3
- data/helpers/performance_test.rb +0 -9
- data/helpers/test_helper.rb +0 -38
- data/html/404.html +0 -30
- data/html/422.html +0 -30
- data/html/500.html +0 -30
- data/html/favicon.ico +0 -0
- data/html/images/rails.png +0 -0
- data/html/index.html +0 -275
- data/html/javascripts/application.js +0 -2
- data/html/javascripts/controls.js +0 -963
- data/html/javascripts/dragdrop.js +0 -973
- data/html/javascripts/effects.js +0 -1128
- data/html/javascripts/prototype.js +0 -4320
- data/html/robots.txt +0 -5
- data/lib/code_statistics.rb +0 -107
- data/lib/commands.rb +0 -17
- data/lib/commands/about.rb +0 -3
- data/lib/commands/console.rb +0 -45
- data/lib/commands/dbconsole.rb +0 -87
- data/lib/commands/destroy.rb +0 -6
- data/lib/commands/generate.rb +0 -6
- data/lib/commands/ncgi/listener +0 -86
- data/lib/commands/ncgi/tracker +0 -69
- data/lib/commands/performance/benchmarker.rb +0 -24
- data/lib/commands/performance/profiler.rb +0 -50
- data/lib/commands/plugin.rb +0 -968
- data/lib/commands/runner.rb +0 -54
- data/lib/commands/server.rb +0 -114
- data/lib/commands/update.rb +0 -4
- data/lib/console_app.rb +0 -30
- data/lib/console_sandbox.rb +0 -6
- data/lib/console_with_helpers.rb +0 -5
- data/lib/dispatcher.rb +0 -24
- data/lib/fcgi_handler.rb +0 -239
- data/lib/initializer.rb +0 -1152
- data/lib/performance_test_help.rb +0 -5
- data/lib/rails/backtrace_cleaner.rb +0 -54
- data/lib/rails/gem_builder.rb +0 -21
- data/lib/rails/gem_dependency.rb +0 -317
- data/lib/rails/plugin.rb +0 -179
- data/lib/rails/plugin/loader.rb +0 -198
- data/lib/rails/plugin/locator.rb +0 -100
- data/lib/rails/rack.rb +0 -8
- data/lib/rails/rack/debugger.rb +0 -23
- data/lib/rails/rack/log_tailer.rb +0 -35
- data/lib/rails/rack/metal.rb +0 -51
- data/lib/rails/rack/static.rb +0 -46
- data/lib/rails/vendor_gem_source_index.rb +0 -140
- data/lib/rails/version.rb +0 -9
- data/lib/rails_generator.rb +0 -46
- data/lib/rails_generator/base.rb +0 -266
- data/lib/rails_generator/commands.rb +0 -621
- data/lib/rails_generator/generated_attribute.rb +0 -47
- data/lib/rails_generator/generators/applications/app/USAGE +0 -9
- data/lib/rails_generator/generators/applications/app/app_generator.rb +0 -266
- data/lib/rails_generator/generators/applications/app/scm/git.rb +0 -18
- data/lib/rails_generator/generators/applications/app/scm/scm.rb +0 -8
- data/lib/rails_generator/generators/applications/app/scm/svn.rb +0 -7
- data/lib/rails_generator/generators/applications/app/template_runner.rb +0 -401
- data/lib/rails_generator/generators/components/controller/USAGE +0 -30
- data/lib/rails_generator/generators/components/controller/controller_generator.rb +0 -43
- data/lib/rails_generator/generators/components/controller/templates/controller.rb +0 -7
- data/lib/rails_generator/generators/components/controller/templates/functional_test.rb +0 -8
- data/lib/rails_generator/generators/components/controller/templates/helper.rb +0 -2
- data/lib/rails_generator/generators/components/controller/templates/helper_test.rb +0 -4
- data/lib/rails_generator/generators/components/controller/templates/view.html.erb +0 -2
- data/lib/rails_generator/generators/components/helper/USAGE +0 -24
- data/lib/rails_generator/generators/components/helper/helper_generator.rb +0 -25
- data/lib/rails_generator/generators/components/helper/templates/helper.rb +0 -2
- data/lib/rails_generator/generators/components/helper/templates/helper_test.rb +0 -4
- data/lib/rails_generator/generators/components/integration_test/USAGE +0 -8
- data/lib/rails_generator/generators/components/integration_test/integration_test_generator.rb +0 -16
- data/lib/rails_generator/generators/components/integration_test/templates/integration_test.rb +0 -10
- data/lib/rails_generator/generators/components/mailer/USAGE +0 -16
- data/lib/rails_generator/generators/components/mailer/mailer_generator.rb +0 -30
- data/lib/rails_generator/generators/components/mailer/templates/fixture.erb +0 -3
- data/lib/rails_generator/generators/components/mailer/templates/fixture.rhtml +0 -0
- data/lib/rails_generator/generators/components/mailer/templates/mailer.rb +0 -15
- data/lib/rails_generator/generators/components/mailer/templates/unit_test.rb +0 -20
- data/lib/rails_generator/generators/components/mailer/templates/view.erb +0 -3
- data/lib/rails_generator/generators/components/mailer/templates/view.rhtml +0 -0
- data/lib/rails_generator/generators/components/metal/USAGE +0 -8
- data/lib/rails_generator/generators/components/metal/metal_generator.rb +0 -8
- data/lib/rails_generator/generators/components/metal/templates/metal.rb +0 -12
- data/lib/rails_generator/generators/components/migration/USAGE +0 -29
- data/lib/rails_generator/generators/components/migration/migration_generator.rb +0 -20
- data/lib/rails_generator/generators/components/migration/templates/migration.rb +0 -11
- data/lib/rails_generator/generators/components/model/USAGE +0 -27
- data/lib/rails_generator/generators/components/model/model_generator.rb +0 -52
- data/lib/rails_generator/generators/components/model/templates/fixtures.yml +0 -23
- data/lib/rails_generator/generators/components/model/templates/migration.rb +0 -16
- data/lib/rails_generator/generators/components/model/templates/model.rb +0 -5
- data/lib/rails_generator/generators/components/model/templates/unit_test.rb +0 -8
- data/lib/rails_generator/generators/components/observer/USAGE +0 -13
- data/lib/rails_generator/generators/components/observer/observer_generator.rb +0 -16
- data/lib/rails_generator/generators/components/observer/templates/observer.rb +0 -2
- data/lib/rails_generator/generators/components/observer/templates/unit_test.rb +0 -8
- data/lib/rails_generator/generators/components/performance_test/USAGE +0 -8
- data/lib/rails_generator/generators/components/performance_test/performance_test_generator.rb +0 -16
- data/lib/rails_generator/generators/components/performance_test/templates/performance_test.rb +0 -9
- data/lib/rails_generator/generators/components/plugin/USAGE +0 -25
- data/lib/rails_generator/generators/components/plugin/plugin_generator.rb +0 -39
- data/lib/rails_generator/generators/components/plugin/templates/MIT-LICENSE +0 -20
- data/lib/rails_generator/generators/components/plugin/templates/README +0 -13
- data/lib/rails_generator/generators/components/plugin/templates/Rakefile +0 -23
- data/lib/rails_generator/generators/components/plugin/templates/USAGE +0 -8
- data/lib/rails_generator/generators/components/plugin/templates/generator.rb +0 -8
- data/lib/rails_generator/generators/components/plugin/templates/init.rb +0 -1
- data/lib/rails_generator/generators/components/plugin/templates/install.rb +0 -1
- data/lib/rails_generator/generators/components/plugin/templates/plugin.rb +0 -1
- data/lib/rails_generator/generators/components/plugin/templates/tasks.rake +0 -4
- data/lib/rails_generator/generators/components/plugin/templates/test_helper.rb +0 -4
- data/lib/rails_generator/generators/components/plugin/templates/uninstall.rb +0 -1
- data/lib/rails_generator/generators/components/plugin/templates/unit_test.rb +0 -8
- data/lib/rails_generator/generators/components/resource/USAGE +0 -23
- data/lib/rails_generator/generators/components/resource/resource_generator.rb +0 -76
- data/lib/rails_generator/generators/components/resource/templates/controller.rb +0 -2
- data/lib/rails_generator/generators/components/resource/templates/functional_test.rb +0 -8
- data/lib/rails_generator/generators/components/resource/templates/helper.rb +0 -2
- data/lib/rails_generator/generators/components/resource/templates/helper_test.rb +0 -4
- data/lib/rails_generator/generators/components/scaffold/USAGE +0 -29
- data/lib/rails_generator/generators/components/scaffold/scaffold_generator.rb +0 -103
- data/lib/rails_generator/generators/components/scaffold/templates/controller.rb +0 -83
- data/lib/rails_generator/generators/components/scaffold/templates/functional_test.rb +0 -45
- data/lib/rails_generator/generators/components/scaffold/templates/helper.rb +0 -2
- data/lib/rails_generator/generators/components/scaffold/templates/helper_test.rb +0 -4
- data/lib/rails_generator/generators/components/scaffold/templates/layout.html.erb +0 -17
- data/lib/rails_generator/generators/components/scaffold/templates/style.css +0 -54
- data/lib/rails_generator/generators/components/scaffold/templates/view_edit.html.erb +0 -18
- data/lib/rails_generator/generators/components/scaffold/templates/view_index.html.erb +0 -24
- data/lib/rails_generator/generators/components/scaffold/templates/view_new.html.erb +0 -17
- data/lib/rails_generator/generators/components/scaffold/templates/view_show.html.erb +0 -10
- data/lib/rails_generator/generators/components/session_migration/USAGE +0 -10
- data/lib/rails_generator/generators/components/session_migration/session_migration_generator.rb +0 -18
- data/lib/rails_generator/generators/components/session_migration/templates/migration.rb +0 -16
- data/lib/rails_generator/lookup.rb +0 -249
- data/lib/rails_generator/manifest.rb +0 -53
- data/lib/rails_generator/options.rb +0 -150
- data/lib/rails_generator/scripts.rb +0 -89
- data/lib/rails_generator/scripts/destroy.rb +0 -29
- data/lib/rails_generator/scripts/generate.rb +0 -7
- data/lib/rails_generator/scripts/update.rb +0 -12
- data/lib/rails_generator/secret_key_generator.rb +0 -24
- data/lib/rails_generator/simple_logger.rb +0 -46
- data/lib/rails_generator/spec.rb +0 -44
- data/lib/railties_path.rb +0 -1
- data/lib/ruby_version_check.rb +0 -17
- data/lib/rubyprof_ext.rb +0 -35
- data/lib/source_annotation_extractor.rb +0 -102
- data/lib/tasks/annotations.rake +0 -20
- data/lib/tasks/databases.rake +0 -436
- data/lib/tasks/documentation.rake +0 -93
- data/lib/tasks/framework.rake +0 -146
- data/lib/tasks/gems.rake +0 -78
- data/lib/tasks/log.rake +0 -9
- data/lib/tasks/middleware.rake +0 -7
- data/lib/tasks/misc.rake +0 -63
- data/lib/tasks/rails.rb +0 -14
- data/lib/tasks/routes.rake +0 -18
- data/lib/tasks/statistics.rake +0 -17
- data/lib/tasks/testing.rake +0 -139
- data/lib/tasks/tmp.rake +0 -37
- data/lib/test_help.rb +0 -38
- data/lib/webrick_server.rb +0 -156
- data/railties.gemspec +0 -22
@@ -1,621 +0,0 @@
|
|
1
|
-
require 'delegate'
|
2
|
-
require 'optparse'
|
3
|
-
require 'fileutils'
|
4
|
-
require 'tempfile'
|
5
|
-
require 'erb'
|
6
|
-
|
7
|
-
module Rails
|
8
|
-
module Generator
|
9
|
-
module Commands
|
10
|
-
# Here's a convenient way to get a handle on generator commands.
|
11
|
-
# Command.instance('destroy', my_generator) instantiates a Destroy
|
12
|
-
# delegate of my_generator ready to do your dirty work.
|
13
|
-
def self.instance(command, generator)
|
14
|
-
const_get(command.to_s.camelize).new(generator)
|
15
|
-
end
|
16
|
-
|
17
|
-
# Even more convenient access to commands. Include Commands in
|
18
|
-
# the generator Base class to get a nice #command instance method
|
19
|
-
# which returns a delegate for the requested command.
|
20
|
-
def self.included(base)
|
21
|
-
base.send(:define_method, :command) do |command|
|
22
|
-
Commands.instance(command, self)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
|
27
|
-
# Generator commands delegate Rails::Generator::Base and implement
|
28
|
-
# a standard set of actions. Their behavior is defined by the way
|
29
|
-
# they respond to these actions: Create brings life; Destroy brings
|
30
|
-
# death; List passively observes.
|
31
|
-
#
|
32
|
-
# Commands are invoked by replaying (or rewinding) the generator's
|
33
|
-
# manifest of actions. See Rails::Generator::Manifest and
|
34
|
-
# Rails::Generator::Base#manifest method that generator subclasses
|
35
|
-
# are required to override.
|
36
|
-
#
|
37
|
-
# Commands allows generators to "plug in" invocation behavior, which
|
38
|
-
# corresponds to the GoF Strategy pattern.
|
39
|
-
class Base < DelegateClass(Rails::Generator::Base)
|
40
|
-
# Replay action manifest. RewindBase subclass rewinds manifest.
|
41
|
-
def invoke!
|
42
|
-
manifest.replay(self)
|
43
|
-
after_generate
|
44
|
-
end
|
45
|
-
|
46
|
-
def dependency(generator_name, args, runtime_options = {})
|
47
|
-
logger.dependency(generator_name) do
|
48
|
-
self.class.new(instance(generator_name, args, full_options(runtime_options))).invoke!
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
# Does nothing for all commands except Create.
|
53
|
-
def class_collisions(*class_names)
|
54
|
-
end
|
55
|
-
|
56
|
-
# Does nothing for all commands except Create.
|
57
|
-
def readme(*args)
|
58
|
-
end
|
59
|
-
|
60
|
-
protected
|
61
|
-
def current_migration_number
|
62
|
-
Dir.glob("#{RAILS_ROOT}/#{@migration_directory}/[0-9]*_*.rb").inject(0) do |max, file_path|
|
63
|
-
n = File.basename(file_path).split('_', 2).first.to_i
|
64
|
-
if n > max then n else max end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
def next_migration_number
|
69
|
-
current_migration_number + 1
|
70
|
-
end
|
71
|
-
|
72
|
-
def migration_directory(relative_path)
|
73
|
-
directory(@migration_directory = relative_path)
|
74
|
-
end
|
75
|
-
|
76
|
-
def existing_migrations(file_name)
|
77
|
-
Dir.glob("#{@migration_directory}/[0-9]*_*.rb").grep(/[0-9]+_#{file_name}.rb$/)
|
78
|
-
end
|
79
|
-
|
80
|
-
def migration_exists?(file_name)
|
81
|
-
not existing_migrations(file_name).empty?
|
82
|
-
end
|
83
|
-
|
84
|
-
def next_migration_string(padding = 3)
|
85
|
-
if ActiveRecord::Base.timestamped_migrations
|
86
|
-
Time.now.utc.strftime("%Y%m%d%H%M%S")
|
87
|
-
else
|
88
|
-
"%.#{padding}d" % next_migration_number
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
def gsub_file(relative_destination, regexp, *args, &block)
|
93
|
-
path = destination_path(relative_destination)
|
94
|
-
content = File.read(path).gsub(regexp, *args, &block)
|
95
|
-
File.open(path, 'wb') { |file| file.write(content) }
|
96
|
-
end
|
97
|
-
|
98
|
-
private
|
99
|
-
# Ask the user interactively whether to force collision.
|
100
|
-
def force_file_collision?(destination, src, dst, file_options = {}, &block)
|
101
|
-
$stdout.print "overwrite #{destination}? (enter \"h\" for help) [Ynaqdh] "
|
102
|
-
case $stdin.gets.chomp
|
103
|
-
when /\Ad\z/i
|
104
|
-
Tempfile.open(File.basename(destination), File.dirname(dst)) do |temp|
|
105
|
-
temp.write render_file(src, file_options, &block)
|
106
|
-
temp.rewind
|
107
|
-
$stdout.puts `#{diff_cmd} "#{dst}" "#{temp.path}"`
|
108
|
-
end
|
109
|
-
puts "retrying"
|
110
|
-
raise 'retry diff'
|
111
|
-
when /\Aa\z/i
|
112
|
-
$stdout.puts "forcing #{spec.name}"
|
113
|
-
options[:collision] = :force
|
114
|
-
when /\Aq\z/i
|
115
|
-
$stdout.puts "aborting #{spec.name}"
|
116
|
-
raise SystemExit
|
117
|
-
when /\An\z/i then :skip
|
118
|
-
when /\Ay\z/i then :force
|
119
|
-
else
|
120
|
-
$stdout.puts <<-HELP
|
121
|
-
Y - yes, overwrite
|
122
|
-
n - no, do not overwrite
|
123
|
-
a - all, overwrite this and all others
|
124
|
-
q - quit, abort
|
125
|
-
d - diff, show the differences between the old and the new
|
126
|
-
h - help, show this help
|
127
|
-
HELP
|
128
|
-
raise 'retry'
|
129
|
-
end
|
130
|
-
rescue
|
131
|
-
retry
|
132
|
-
end
|
133
|
-
|
134
|
-
def diff_cmd
|
135
|
-
ENV['RAILS_DIFF'] || 'diff -u'
|
136
|
-
end
|
137
|
-
|
138
|
-
def render_template_part(template_options)
|
139
|
-
# Getting Sandbox to evaluate part template in it
|
140
|
-
part_binding = template_options[:sandbox].call.sandbox_binding
|
141
|
-
part_rel_path = template_options[:insert]
|
142
|
-
part_path = source_path(part_rel_path)
|
143
|
-
|
144
|
-
# Render inner template within Sandbox binding
|
145
|
-
rendered_part = ERB.new(File.readlines(part_path).join, nil, '-').result(part_binding)
|
146
|
-
begin_mark = template_part_mark(template_options[:begin_mark], template_options[:mark_id])
|
147
|
-
end_mark = template_part_mark(template_options[:end_mark], template_options[:mark_id])
|
148
|
-
begin_mark + rendered_part + end_mark
|
149
|
-
end
|
150
|
-
|
151
|
-
def template_part_mark(name, id)
|
152
|
-
"<!--[#{name}:#{id}]-->\n"
|
153
|
-
end
|
154
|
-
end
|
155
|
-
|
156
|
-
# Base class for commands which handle generator actions in reverse, such as Destroy.
|
157
|
-
class RewindBase < Base
|
158
|
-
# Rewind action manifest.
|
159
|
-
def invoke!
|
160
|
-
manifest.rewind(self)
|
161
|
-
end
|
162
|
-
end
|
163
|
-
|
164
|
-
|
165
|
-
# Create is the premier generator command. It copies files, creates
|
166
|
-
# directories, renders templates, and more.
|
167
|
-
class Create < Base
|
168
|
-
|
169
|
-
# Check whether the given class names are already taken by
|
170
|
-
# Ruby or Rails. In the future, expand to check other namespaces
|
171
|
-
# such as the rest of the user's app.
|
172
|
-
def class_collisions(*class_names)
|
173
|
-
path = class_names.shift
|
174
|
-
class_names.flatten.each do |class_name|
|
175
|
-
# Convert to string to allow symbol arguments.
|
176
|
-
class_name = class_name.to_s
|
177
|
-
|
178
|
-
# Skip empty strings.
|
179
|
-
next if class_name.strip.empty?
|
180
|
-
|
181
|
-
# Split the class from its module nesting.
|
182
|
-
nesting = class_name.split('::')
|
183
|
-
name = nesting.pop
|
184
|
-
|
185
|
-
# Hack to limit const_defined? to non-inherited on 1.9.
|
186
|
-
extra = []
|
187
|
-
extra << false unless Object.method(:const_defined?).arity == 1
|
188
|
-
|
189
|
-
# Extract the last Module in the nesting.
|
190
|
-
last = nesting.inject(Object) { |last, nest|
|
191
|
-
break unless last.const_defined?(nest, *extra)
|
192
|
-
last.const_get(nest)
|
193
|
-
}
|
194
|
-
|
195
|
-
# If the last Module exists, check whether the given
|
196
|
-
# class exists and raise a collision if so.
|
197
|
-
if last and last.const_defined?(name.camelize, *extra)
|
198
|
-
raise_class_collision(class_name)
|
199
|
-
end
|
200
|
-
end
|
201
|
-
end
|
202
|
-
|
203
|
-
# Copy a file from source to destination with collision checking.
|
204
|
-
#
|
205
|
-
# The file_options hash accepts :chmod and :shebang and :collision options.
|
206
|
-
# :chmod sets the permissions of the destination file:
|
207
|
-
# file 'config/empty.log', 'log/test.log', :chmod => 0664
|
208
|
-
# :shebang sets the #!/usr/bin/ruby line for scripts
|
209
|
-
# file 'bin/generate.rb', 'script/generate', :chmod => 0755, :shebang => '/usr/bin/env ruby'
|
210
|
-
# :collision sets the collision option only for the destination file:
|
211
|
-
# file 'settings/server.yml', 'config/server.yml', :collision => :skip
|
212
|
-
#
|
213
|
-
# Collisions are handled by checking whether the destination file
|
214
|
-
# exists and either skipping the file, forcing overwrite, or asking
|
215
|
-
# the user what to do.
|
216
|
-
def file(relative_source, relative_destination, file_options = {}, &block)
|
217
|
-
# Determine full paths for source and destination files.
|
218
|
-
source = source_path(relative_source)
|
219
|
-
destination = destination_path(relative_destination)
|
220
|
-
destination_exists = File.exist?(destination)
|
221
|
-
|
222
|
-
# If source and destination are identical then we're done.
|
223
|
-
if destination_exists and identical?(source, destination, &block)
|
224
|
-
return logger.identical(relative_destination)
|
225
|
-
end
|
226
|
-
|
227
|
-
# Check for and resolve file collisions.
|
228
|
-
if destination_exists
|
229
|
-
|
230
|
-
# Make a choice whether to overwrite the file. :force and
|
231
|
-
# :skip already have their mind made up, but give :ask a shot.
|
232
|
-
choice = case (file_options[:collision] || options[:collision]).to_sym #|| :ask
|
233
|
-
when :ask then force_file_collision?(relative_destination, source, destination, file_options, &block)
|
234
|
-
when :force then :force
|
235
|
-
when :skip then :skip
|
236
|
-
else raise "Invalid collision option: #{options[:collision].inspect}"
|
237
|
-
end
|
238
|
-
|
239
|
-
# Take action based on our choice. Bail out if we chose to
|
240
|
-
# skip the file; otherwise, log our transgression and continue.
|
241
|
-
case choice
|
242
|
-
when :force then logger.force(relative_destination)
|
243
|
-
when :skip then return(logger.skip(relative_destination))
|
244
|
-
else raise "Invalid collision choice: #{choice}.inspect"
|
245
|
-
end
|
246
|
-
|
247
|
-
# File doesn't exist so log its unbesmirched creation.
|
248
|
-
else
|
249
|
-
logger.create relative_destination
|
250
|
-
end
|
251
|
-
|
252
|
-
# If we're pretending, back off now.
|
253
|
-
return if options[:pretend]
|
254
|
-
|
255
|
-
# Write destination file with optional shebang. Yield for content
|
256
|
-
# if block given so templaters may render the source file. If a
|
257
|
-
# shebang is requested, replace the existing shebang or insert a
|
258
|
-
# new one.
|
259
|
-
File.open(destination, 'wb') do |dest|
|
260
|
-
dest.write render_file(source, file_options, &block)
|
261
|
-
end
|
262
|
-
|
263
|
-
# Optionally change permissions.
|
264
|
-
if file_options[:chmod]
|
265
|
-
FileUtils.chmod(file_options[:chmod], destination)
|
266
|
-
end
|
267
|
-
|
268
|
-
# Optionally add file to subversion or git
|
269
|
-
system("svn add #{destination}") if options[:svn]
|
270
|
-
system("git add -v #{relative_destination}") if options[:git]
|
271
|
-
end
|
272
|
-
|
273
|
-
# Checks if the source and the destination file are identical. If
|
274
|
-
# passed a block then the source file is a template that needs to first
|
275
|
-
# be evaluated before being compared to the destination.
|
276
|
-
def identical?(source, destination, &block)
|
277
|
-
return false if File.directory? destination
|
278
|
-
source = block_given? ? File.open(source) {|sf| yield(sf)} : IO.read(source)
|
279
|
-
destination = IO.read(destination)
|
280
|
-
source == destination
|
281
|
-
end
|
282
|
-
|
283
|
-
# Generate a file for a Rails application using an ERuby template.
|
284
|
-
# Looks up and evaluates a template by name and writes the result.
|
285
|
-
#
|
286
|
-
# The ERB template uses explicit trim mode to best control the
|
287
|
-
# proliferation of whitespace in generated code. <%- trims leading
|
288
|
-
# whitespace; -%> trims trailing whitespace including one newline.
|
289
|
-
#
|
290
|
-
# A hash of template options may be passed as the last argument.
|
291
|
-
# The options accepted by the file are accepted as well as :assigns,
|
292
|
-
# a hash of variable bindings. Example:
|
293
|
-
# template 'foo', 'bar', :assigns => { :action => 'view' }
|
294
|
-
#
|
295
|
-
# Template is implemented in terms of file. It calls file with a
|
296
|
-
# block which takes a file handle and returns its rendered contents.
|
297
|
-
def template(relative_source, relative_destination, template_options = {})
|
298
|
-
file(relative_source, relative_destination, template_options) do |file|
|
299
|
-
# Evaluate any assignments in a temporary, throwaway binding.
|
300
|
-
vars = template_options[:assigns] || {}
|
301
|
-
b = template_options[:binding] || binding
|
302
|
-
vars.each { |k,v| eval "#{k} = vars[:#{k}] || vars['#{k}']", b }
|
303
|
-
|
304
|
-
# Render the source file with the temporary binding.
|
305
|
-
ERB.new(file.read, nil, '-').result(b)
|
306
|
-
end
|
307
|
-
end
|
308
|
-
|
309
|
-
def complex_template(relative_source, relative_destination, template_options = {})
|
310
|
-
options = template_options.dup
|
311
|
-
options[:assigns] ||= {}
|
312
|
-
options[:assigns]['template_for_inclusion'] = render_template_part(template_options)
|
313
|
-
template(relative_source, relative_destination, options)
|
314
|
-
end
|
315
|
-
|
316
|
-
# Create a directory including any missing parent directories.
|
317
|
-
# Always skips directories which exist.
|
318
|
-
def directory(relative_path)
|
319
|
-
path = destination_path(relative_path)
|
320
|
-
if File.exist?(path)
|
321
|
-
logger.exists relative_path
|
322
|
-
else
|
323
|
-
logger.create relative_path
|
324
|
-
unless options[:pretend]
|
325
|
-
FileUtils.mkdir_p(path)
|
326
|
-
# git doesn't require adding the paths, adding the files later will
|
327
|
-
# automatically do a path add.
|
328
|
-
|
329
|
-
# Subversion doesn't do path adds, so we need to add
|
330
|
-
# each directory individually.
|
331
|
-
# So stack up the directory tree and add the paths to
|
332
|
-
# subversion in order without recursion.
|
333
|
-
if options[:svn]
|
334
|
-
stack = [relative_path]
|
335
|
-
until File.dirname(stack.last) == stack.last # dirname('.') == '.'
|
336
|
-
stack.push File.dirname(stack.last)
|
337
|
-
end
|
338
|
-
stack.reverse_each do |rel_path|
|
339
|
-
svn_path = destination_path(rel_path)
|
340
|
-
system("svn add -N #{svn_path}") unless File.directory?(File.join(svn_path, '.svn'))
|
341
|
-
end
|
342
|
-
end
|
343
|
-
end
|
344
|
-
end
|
345
|
-
end
|
346
|
-
|
347
|
-
# Display a README.
|
348
|
-
def readme(*relative_sources)
|
349
|
-
relative_sources.flatten.each do |relative_source|
|
350
|
-
logger.readme relative_source
|
351
|
-
puts File.read(source_path(relative_source)) unless options[:pretend]
|
352
|
-
end
|
353
|
-
end
|
354
|
-
|
355
|
-
# When creating a migration, it knows to find the first available file in db/migrate and use the migration.rb template.
|
356
|
-
def migration_template(relative_source, relative_destination, template_options = {})
|
357
|
-
migration_directory relative_destination
|
358
|
-
migration_file_name = template_options[:migration_file_name] || file_name
|
359
|
-
raise "Another migration is already named #{migration_file_name}: #{existing_migrations(migration_file_name).first}" if migration_exists?(migration_file_name)
|
360
|
-
template(relative_source, "#{relative_destination}/#{next_migration_string}_#{migration_file_name}.rb", template_options)
|
361
|
-
end
|
362
|
-
|
363
|
-
def route_resources(*resources)
|
364
|
-
resource_list = resources.map { |r| r.to_sym.inspect }.join(', ')
|
365
|
-
sentinel = 'ActionController::Routing::Routes.draw do |map|'
|
366
|
-
|
367
|
-
logger.route "map.resources #{resource_list}"
|
368
|
-
unless options[:pretend]
|
369
|
-
gsub_file 'config/routes.rb', /(#{Regexp.escape(sentinel)})/mi do |match|
|
370
|
-
"#{match}\n map.resources #{resource_list}\n"
|
371
|
-
end
|
372
|
-
end
|
373
|
-
end
|
374
|
-
|
375
|
-
private
|
376
|
-
def render_file(path, options = {})
|
377
|
-
File.open(path, 'rb') do |file|
|
378
|
-
if block_given?
|
379
|
-
yield file
|
380
|
-
else
|
381
|
-
content = ''
|
382
|
-
if shebang = options[:shebang]
|
383
|
-
content << "#!#{shebang}\n"
|
384
|
-
if line = file.gets
|
385
|
-
content << "line\n" if line !~ /^#!/
|
386
|
-
end
|
387
|
-
end
|
388
|
-
content << file.read
|
389
|
-
end
|
390
|
-
end
|
391
|
-
end
|
392
|
-
|
393
|
-
# Raise a usage error with an informative WordNet suggestion.
|
394
|
-
# Thanks to Florian Gross (flgr).
|
395
|
-
def raise_class_collision(class_name)
|
396
|
-
message = <<end_message
|
397
|
-
The name '#{class_name}' is either already used in your application or reserved by Ruby on Rails.
|
398
|
-
Please choose an alternative and run this generator again.
|
399
|
-
end_message
|
400
|
-
if suggest = find_synonyms(class_name)
|
401
|
-
if suggest.any?
|
402
|
-
message << "\n Suggestions: \n\n"
|
403
|
-
message << suggest.join("\n")
|
404
|
-
end
|
405
|
-
end
|
406
|
-
raise UsageError, message
|
407
|
-
end
|
408
|
-
|
409
|
-
SYNONYM_LOOKUP_URI = "http://wordnet.princeton.edu/perl/webwn?s=%s"
|
410
|
-
|
411
|
-
# Look up synonyms on WordNet. Thanks to Florian Gross (flgr).
|
412
|
-
def find_synonyms(word)
|
413
|
-
require 'open-uri'
|
414
|
-
require 'timeout'
|
415
|
-
timeout(5) do
|
416
|
-
open(SYNONYM_LOOKUP_URI % word) do |stream|
|
417
|
-
# Grab words linked to dictionary entries as possible synonyms
|
418
|
-
data = stream.read.gsub(" ", " ").scan(/<a href="webwn.*?">([\w ]*?)<\/a>/s).uniq
|
419
|
-
end
|
420
|
-
end
|
421
|
-
rescue Exception
|
422
|
-
return nil
|
423
|
-
end
|
424
|
-
end
|
425
|
-
|
426
|
-
|
427
|
-
# Undo the actions performed by a generator. Rewind the action
|
428
|
-
# manifest and attempt to completely erase the results of each action.
|
429
|
-
class Destroy < RewindBase
|
430
|
-
# Remove a file if it exists and is a file.
|
431
|
-
def file(relative_source, relative_destination, file_options = {})
|
432
|
-
destination = destination_path(relative_destination)
|
433
|
-
if File.exist?(destination)
|
434
|
-
logger.rm relative_destination
|
435
|
-
unless options[:pretend]
|
436
|
-
if options[:svn]
|
437
|
-
# If the file has been marked to be added
|
438
|
-
# but has not yet been checked in, revert and delete
|
439
|
-
if options[:svn][relative_destination]
|
440
|
-
system("svn revert #{destination}")
|
441
|
-
FileUtils.rm(destination)
|
442
|
-
else
|
443
|
-
# If the directory is not in the status list, it
|
444
|
-
# has no modifications so we can simply remove it
|
445
|
-
system("svn rm #{destination}")
|
446
|
-
end
|
447
|
-
elsif options[:git]
|
448
|
-
if options[:git][:new][relative_destination]
|
449
|
-
# file has been added, but not committed
|
450
|
-
system("git reset HEAD #{relative_destination}")
|
451
|
-
FileUtils.rm(destination)
|
452
|
-
elsif options[:git][:modified][relative_destination]
|
453
|
-
# file is committed and modified
|
454
|
-
system("git rm -f #{relative_destination}")
|
455
|
-
else
|
456
|
-
# If the directory is not in the status list, it
|
457
|
-
# has no modifications so we can simply remove it
|
458
|
-
system("git rm #{relative_destination}")
|
459
|
-
end
|
460
|
-
else
|
461
|
-
FileUtils.rm(destination)
|
462
|
-
end
|
463
|
-
end
|
464
|
-
else
|
465
|
-
logger.missing relative_destination
|
466
|
-
return
|
467
|
-
end
|
468
|
-
end
|
469
|
-
|
470
|
-
# Templates are deleted just like files and the actions take the
|
471
|
-
# same parameters, so simply alias the file method.
|
472
|
-
alias_method :template, :file
|
473
|
-
|
474
|
-
# Remove each directory in the given path from right to left.
|
475
|
-
# Remove each subdirectory if it exists and is a directory.
|
476
|
-
def directory(relative_path)
|
477
|
-
parts = relative_path.split('/')
|
478
|
-
until parts.empty?
|
479
|
-
partial = File.join(parts)
|
480
|
-
path = destination_path(partial)
|
481
|
-
if File.exist?(path)
|
482
|
-
if Dir[File.join(path, '*')].empty?
|
483
|
-
logger.rmdir partial
|
484
|
-
unless options[:pretend]
|
485
|
-
if options[:svn]
|
486
|
-
# If the directory has been marked to be added
|
487
|
-
# but has not yet been checked in, revert and delete
|
488
|
-
if options[:svn][relative_path]
|
489
|
-
system("svn revert #{path}")
|
490
|
-
FileUtils.rmdir(path)
|
491
|
-
else
|
492
|
-
# If the directory is not in the status list, it
|
493
|
-
# has no modifications so we can simply remove it
|
494
|
-
system("svn rm #{path}")
|
495
|
-
end
|
496
|
-
# I don't think git needs to remove directories?..
|
497
|
-
# or maybe they have special consideration...
|
498
|
-
else
|
499
|
-
FileUtils.rmdir(path)
|
500
|
-
end
|
501
|
-
end
|
502
|
-
else
|
503
|
-
logger.notempty partial
|
504
|
-
end
|
505
|
-
else
|
506
|
-
logger.missing partial
|
507
|
-
end
|
508
|
-
parts.pop
|
509
|
-
end
|
510
|
-
end
|
511
|
-
|
512
|
-
def complex_template(*args)
|
513
|
-
# nothing should be done here
|
514
|
-
end
|
515
|
-
|
516
|
-
# When deleting a migration, it knows to delete every file named "[0-9]*_#{file_name}".
|
517
|
-
def migration_template(relative_source, relative_destination, template_options = {})
|
518
|
-
migration_directory relative_destination
|
519
|
-
|
520
|
-
migration_file_name = template_options[:migration_file_name] || file_name
|
521
|
-
unless migration_exists?(migration_file_name)
|
522
|
-
puts "There is no migration named #{migration_file_name}"
|
523
|
-
return
|
524
|
-
end
|
525
|
-
|
526
|
-
|
527
|
-
existing_migrations(migration_file_name).each do |file_path|
|
528
|
-
file(relative_source, file_path, template_options)
|
529
|
-
end
|
530
|
-
end
|
531
|
-
|
532
|
-
def route_resources(*resources)
|
533
|
-
resource_list = resources.map { |r| r.to_sym.inspect }.join(', ')
|
534
|
-
look_for = "\n map.resources #{resource_list}\n"
|
535
|
-
logger.route "map.resources #{resource_list}"
|
536
|
-
gsub_file 'config/routes.rb', /(#{look_for})/mi, ''
|
537
|
-
end
|
538
|
-
end
|
539
|
-
|
540
|
-
|
541
|
-
# List a generator's action manifest.
|
542
|
-
class List < Base
|
543
|
-
def dependency(generator_name, args, options = {})
|
544
|
-
logger.dependency "#{generator_name}(#{args.join(', ')}, #{options.inspect})"
|
545
|
-
end
|
546
|
-
|
547
|
-
def class_collisions(*class_names)
|
548
|
-
logger.class_collisions class_names.join(', ')
|
549
|
-
end
|
550
|
-
|
551
|
-
def file(relative_source, relative_destination, options = {})
|
552
|
-
logger.file relative_destination
|
553
|
-
end
|
554
|
-
|
555
|
-
def template(relative_source, relative_destination, options = {})
|
556
|
-
logger.template relative_destination
|
557
|
-
end
|
558
|
-
|
559
|
-
def complex_template(relative_source, relative_destination, options = {})
|
560
|
-
logger.template "#{options[:insert]} inside #{relative_destination}"
|
561
|
-
end
|
562
|
-
|
563
|
-
def directory(relative_path)
|
564
|
-
logger.directory "#{destination_path(relative_path)}/"
|
565
|
-
end
|
566
|
-
|
567
|
-
def readme(*args)
|
568
|
-
logger.readme args.join(', ')
|
569
|
-
end
|
570
|
-
|
571
|
-
def migration_template(relative_source, relative_destination, options = {})
|
572
|
-
migration_directory relative_destination
|
573
|
-
logger.migration_template file_name
|
574
|
-
end
|
575
|
-
|
576
|
-
def route_resources(*resources)
|
577
|
-
resource_list = resources.map { |r| r.to_sym.inspect }.join(', ')
|
578
|
-
logger.route "map.resources #{resource_list}"
|
579
|
-
end
|
580
|
-
end
|
581
|
-
|
582
|
-
# Update generator's action manifest.
|
583
|
-
class Update < Create
|
584
|
-
def file(relative_source, relative_destination, options = {})
|
585
|
-
# logger.file relative_destination
|
586
|
-
end
|
587
|
-
|
588
|
-
def template(relative_source, relative_destination, options = {})
|
589
|
-
# logger.template relative_destination
|
590
|
-
end
|
591
|
-
|
592
|
-
def complex_template(relative_source, relative_destination, template_options = {})
|
593
|
-
|
594
|
-
begin
|
595
|
-
dest_file = destination_path(relative_destination)
|
596
|
-
source_to_update = File.readlines(dest_file).join
|
597
|
-
rescue Errno::ENOENT
|
598
|
-
logger.missing relative_destination
|
599
|
-
return
|
600
|
-
end
|
601
|
-
|
602
|
-
logger.refreshing "#{template_options[:insert].gsub(/\.erb/,'')} inside #{relative_destination}"
|
603
|
-
|
604
|
-
begin_mark = Regexp.quote(template_part_mark(template_options[:begin_mark], template_options[:mark_id]))
|
605
|
-
end_mark = Regexp.quote(template_part_mark(template_options[:end_mark], template_options[:mark_id]))
|
606
|
-
|
607
|
-
# Refreshing inner part of the template with freshly rendered part.
|
608
|
-
rendered_part = render_template_part(template_options)
|
609
|
-
source_to_update.gsub!(/#{begin_mark}.*?#{end_mark}/m, rendered_part)
|
610
|
-
|
611
|
-
File.open(dest_file, 'w') { |file| file.write(source_to_update) }
|
612
|
-
end
|
613
|
-
|
614
|
-
def directory(relative_path)
|
615
|
-
# logger.directory "#{destination_path(relative_path)}/"
|
616
|
-
end
|
617
|
-
end
|
618
|
-
|
619
|
-
end
|
620
|
-
end
|
621
|
-
end
|