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.

Files changed (215) hide show
  1. data/bin/rails +8 -20
  2. metadata +74 -251
  3. data/CHANGELOG +0 -2193
  4. data/MIT-LICENSE +0 -20
  5. data/README +0 -243
  6. data/Rakefile +0 -365
  7. data/bin/about +0 -4
  8. data/bin/console +0 -3
  9. data/bin/dbconsole +0 -3
  10. data/bin/destroy +0 -3
  11. data/bin/generate +0 -3
  12. data/bin/performance/benchmarker +0 -3
  13. data/bin/performance/profiler +0 -3
  14. data/bin/plugin +0 -3
  15. data/bin/runner +0 -3
  16. data/bin/server +0 -3
  17. data/builtin/rails_info/rails/info.rb +0 -131
  18. data/builtin/rails_info/rails/info_controller.rb +0 -9
  19. data/builtin/rails_info/rails/info_helper.rb +0 -2
  20. data/builtin/rails_info/rails_info_controller.rb +0 -2
  21. data/configs/databases/frontbase.yml +0 -28
  22. data/configs/databases/ibm_db.yml +0 -62
  23. data/configs/databases/mysql.yml +0 -60
  24. data/configs/databases/oracle.yml +0 -39
  25. data/configs/databases/postgresql.yml +0 -51
  26. data/configs/databases/sqlite2.yml +0 -19
  27. data/configs/databases/sqlite3.yml +0 -22
  28. data/configs/empty.log +0 -0
  29. data/configs/initializers/backtrace_silencers.rb +0 -7
  30. data/configs/initializers/cookie_verification_secret.rb +0 -7
  31. data/configs/initializers/inflections.rb +0 -10
  32. data/configs/initializers/mime_types.rb +0 -5
  33. data/configs/initializers/new_rails_defaults.rb +0 -21
  34. data/configs/initializers/session_store.rb +0 -15
  35. data/configs/locales/en.yml +0 -5
  36. data/configs/routes.rb +0 -43
  37. data/configs/seeds.rb +0 -7
  38. data/dispatches/config.ru +0 -7
  39. data/dispatches/dispatch.fcgi +0 -24
  40. data/dispatches/dispatch.rb +0 -10
  41. data/dispatches/gateway.cgi +0 -97
  42. data/doc/README_FOR_APP +0 -2
  43. data/environments/boot.rb +0 -114
  44. data/environments/development.rb +0 -17
  45. data/environments/environment.rb +0 -41
  46. data/environments/production.rb +0 -28
  47. data/environments/test.rb +0 -28
  48. data/fresh_rakefile +0 -10
  49. data/helpers/application_controller.rb +0 -10
  50. data/helpers/application_helper.rb +0 -3
  51. data/helpers/performance_test.rb +0 -9
  52. data/helpers/test_helper.rb +0 -38
  53. data/html/404.html +0 -30
  54. data/html/422.html +0 -30
  55. data/html/500.html +0 -30
  56. data/html/favicon.ico +0 -0
  57. data/html/images/rails.png +0 -0
  58. data/html/index.html +0 -275
  59. data/html/javascripts/application.js +0 -2
  60. data/html/javascripts/controls.js +0 -963
  61. data/html/javascripts/dragdrop.js +0 -973
  62. data/html/javascripts/effects.js +0 -1128
  63. data/html/javascripts/prototype.js +0 -4320
  64. data/html/robots.txt +0 -5
  65. data/lib/code_statistics.rb +0 -107
  66. data/lib/commands.rb +0 -17
  67. data/lib/commands/about.rb +0 -3
  68. data/lib/commands/console.rb +0 -45
  69. data/lib/commands/dbconsole.rb +0 -87
  70. data/lib/commands/destroy.rb +0 -6
  71. data/lib/commands/generate.rb +0 -6
  72. data/lib/commands/ncgi/listener +0 -86
  73. data/lib/commands/ncgi/tracker +0 -69
  74. data/lib/commands/performance/benchmarker.rb +0 -24
  75. data/lib/commands/performance/profiler.rb +0 -50
  76. data/lib/commands/plugin.rb +0 -968
  77. data/lib/commands/runner.rb +0 -54
  78. data/lib/commands/server.rb +0 -114
  79. data/lib/commands/update.rb +0 -4
  80. data/lib/console_app.rb +0 -30
  81. data/lib/console_sandbox.rb +0 -6
  82. data/lib/console_with_helpers.rb +0 -5
  83. data/lib/dispatcher.rb +0 -24
  84. data/lib/fcgi_handler.rb +0 -239
  85. data/lib/initializer.rb +0 -1152
  86. data/lib/performance_test_help.rb +0 -5
  87. data/lib/rails/backtrace_cleaner.rb +0 -54
  88. data/lib/rails/gem_builder.rb +0 -21
  89. data/lib/rails/gem_dependency.rb +0 -317
  90. data/lib/rails/plugin.rb +0 -179
  91. data/lib/rails/plugin/loader.rb +0 -198
  92. data/lib/rails/plugin/locator.rb +0 -100
  93. data/lib/rails/rack.rb +0 -8
  94. data/lib/rails/rack/debugger.rb +0 -23
  95. data/lib/rails/rack/log_tailer.rb +0 -35
  96. data/lib/rails/rack/metal.rb +0 -51
  97. data/lib/rails/rack/static.rb +0 -46
  98. data/lib/rails/vendor_gem_source_index.rb +0 -140
  99. data/lib/rails/version.rb +0 -9
  100. data/lib/rails_generator.rb +0 -46
  101. data/lib/rails_generator/base.rb +0 -266
  102. data/lib/rails_generator/commands.rb +0 -621
  103. data/lib/rails_generator/generated_attribute.rb +0 -47
  104. data/lib/rails_generator/generators/applications/app/USAGE +0 -9
  105. data/lib/rails_generator/generators/applications/app/app_generator.rb +0 -266
  106. data/lib/rails_generator/generators/applications/app/scm/git.rb +0 -18
  107. data/lib/rails_generator/generators/applications/app/scm/scm.rb +0 -8
  108. data/lib/rails_generator/generators/applications/app/scm/svn.rb +0 -7
  109. data/lib/rails_generator/generators/applications/app/template_runner.rb +0 -401
  110. data/lib/rails_generator/generators/components/controller/USAGE +0 -30
  111. data/lib/rails_generator/generators/components/controller/controller_generator.rb +0 -43
  112. data/lib/rails_generator/generators/components/controller/templates/controller.rb +0 -7
  113. data/lib/rails_generator/generators/components/controller/templates/functional_test.rb +0 -8
  114. data/lib/rails_generator/generators/components/controller/templates/helper.rb +0 -2
  115. data/lib/rails_generator/generators/components/controller/templates/helper_test.rb +0 -4
  116. data/lib/rails_generator/generators/components/controller/templates/view.html.erb +0 -2
  117. data/lib/rails_generator/generators/components/helper/USAGE +0 -24
  118. data/lib/rails_generator/generators/components/helper/helper_generator.rb +0 -25
  119. data/lib/rails_generator/generators/components/helper/templates/helper.rb +0 -2
  120. data/lib/rails_generator/generators/components/helper/templates/helper_test.rb +0 -4
  121. data/lib/rails_generator/generators/components/integration_test/USAGE +0 -8
  122. data/lib/rails_generator/generators/components/integration_test/integration_test_generator.rb +0 -16
  123. data/lib/rails_generator/generators/components/integration_test/templates/integration_test.rb +0 -10
  124. data/lib/rails_generator/generators/components/mailer/USAGE +0 -16
  125. data/lib/rails_generator/generators/components/mailer/mailer_generator.rb +0 -30
  126. data/lib/rails_generator/generators/components/mailer/templates/fixture.erb +0 -3
  127. data/lib/rails_generator/generators/components/mailer/templates/fixture.rhtml +0 -0
  128. data/lib/rails_generator/generators/components/mailer/templates/mailer.rb +0 -15
  129. data/lib/rails_generator/generators/components/mailer/templates/unit_test.rb +0 -20
  130. data/lib/rails_generator/generators/components/mailer/templates/view.erb +0 -3
  131. data/lib/rails_generator/generators/components/mailer/templates/view.rhtml +0 -0
  132. data/lib/rails_generator/generators/components/metal/USAGE +0 -8
  133. data/lib/rails_generator/generators/components/metal/metal_generator.rb +0 -8
  134. data/lib/rails_generator/generators/components/metal/templates/metal.rb +0 -12
  135. data/lib/rails_generator/generators/components/migration/USAGE +0 -29
  136. data/lib/rails_generator/generators/components/migration/migration_generator.rb +0 -20
  137. data/lib/rails_generator/generators/components/migration/templates/migration.rb +0 -11
  138. data/lib/rails_generator/generators/components/model/USAGE +0 -27
  139. data/lib/rails_generator/generators/components/model/model_generator.rb +0 -52
  140. data/lib/rails_generator/generators/components/model/templates/fixtures.yml +0 -23
  141. data/lib/rails_generator/generators/components/model/templates/migration.rb +0 -16
  142. data/lib/rails_generator/generators/components/model/templates/model.rb +0 -5
  143. data/lib/rails_generator/generators/components/model/templates/unit_test.rb +0 -8
  144. data/lib/rails_generator/generators/components/observer/USAGE +0 -13
  145. data/lib/rails_generator/generators/components/observer/observer_generator.rb +0 -16
  146. data/lib/rails_generator/generators/components/observer/templates/observer.rb +0 -2
  147. data/lib/rails_generator/generators/components/observer/templates/unit_test.rb +0 -8
  148. data/lib/rails_generator/generators/components/performance_test/USAGE +0 -8
  149. data/lib/rails_generator/generators/components/performance_test/performance_test_generator.rb +0 -16
  150. data/lib/rails_generator/generators/components/performance_test/templates/performance_test.rb +0 -9
  151. data/lib/rails_generator/generators/components/plugin/USAGE +0 -25
  152. data/lib/rails_generator/generators/components/plugin/plugin_generator.rb +0 -39
  153. data/lib/rails_generator/generators/components/plugin/templates/MIT-LICENSE +0 -20
  154. data/lib/rails_generator/generators/components/plugin/templates/README +0 -13
  155. data/lib/rails_generator/generators/components/plugin/templates/Rakefile +0 -23
  156. data/lib/rails_generator/generators/components/plugin/templates/USAGE +0 -8
  157. data/lib/rails_generator/generators/components/plugin/templates/generator.rb +0 -8
  158. data/lib/rails_generator/generators/components/plugin/templates/init.rb +0 -1
  159. data/lib/rails_generator/generators/components/plugin/templates/install.rb +0 -1
  160. data/lib/rails_generator/generators/components/plugin/templates/plugin.rb +0 -1
  161. data/lib/rails_generator/generators/components/plugin/templates/tasks.rake +0 -4
  162. data/lib/rails_generator/generators/components/plugin/templates/test_helper.rb +0 -4
  163. data/lib/rails_generator/generators/components/plugin/templates/uninstall.rb +0 -1
  164. data/lib/rails_generator/generators/components/plugin/templates/unit_test.rb +0 -8
  165. data/lib/rails_generator/generators/components/resource/USAGE +0 -23
  166. data/lib/rails_generator/generators/components/resource/resource_generator.rb +0 -76
  167. data/lib/rails_generator/generators/components/resource/templates/controller.rb +0 -2
  168. data/lib/rails_generator/generators/components/resource/templates/functional_test.rb +0 -8
  169. data/lib/rails_generator/generators/components/resource/templates/helper.rb +0 -2
  170. data/lib/rails_generator/generators/components/resource/templates/helper_test.rb +0 -4
  171. data/lib/rails_generator/generators/components/scaffold/USAGE +0 -29
  172. data/lib/rails_generator/generators/components/scaffold/scaffold_generator.rb +0 -103
  173. data/lib/rails_generator/generators/components/scaffold/templates/controller.rb +0 -83
  174. data/lib/rails_generator/generators/components/scaffold/templates/functional_test.rb +0 -45
  175. data/lib/rails_generator/generators/components/scaffold/templates/helper.rb +0 -2
  176. data/lib/rails_generator/generators/components/scaffold/templates/helper_test.rb +0 -4
  177. data/lib/rails_generator/generators/components/scaffold/templates/layout.html.erb +0 -17
  178. data/lib/rails_generator/generators/components/scaffold/templates/style.css +0 -54
  179. data/lib/rails_generator/generators/components/scaffold/templates/view_edit.html.erb +0 -18
  180. data/lib/rails_generator/generators/components/scaffold/templates/view_index.html.erb +0 -24
  181. data/lib/rails_generator/generators/components/scaffold/templates/view_new.html.erb +0 -17
  182. data/lib/rails_generator/generators/components/scaffold/templates/view_show.html.erb +0 -10
  183. data/lib/rails_generator/generators/components/session_migration/USAGE +0 -10
  184. data/lib/rails_generator/generators/components/session_migration/session_migration_generator.rb +0 -18
  185. data/lib/rails_generator/generators/components/session_migration/templates/migration.rb +0 -16
  186. data/lib/rails_generator/lookup.rb +0 -249
  187. data/lib/rails_generator/manifest.rb +0 -53
  188. data/lib/rails_generator/options.rb +0 -150
  189. data/lib/rails_generator/scripts.rb +0 -89
  190. data/lib/rails_generator/scripts/destroy.rb +0 -29
  191. data/lib/rails_generator/scripts/generate.rb +0 -7
  192. data/lib/rails_generator/scripts/update.rb +0 -12
  193. data/lib/rails_generator/secret_key_generator.rb +0 -24
  194. data/lib/rails_generator/simple_logger.rb +0 -46
  195. data/lib/rails_generator/spec.rb +0 -44
  196. data/lib/railties_path.rb +0 -1
  197. data/lib/ruby_version_check.rb +0 -17
  198. data/lib/rubyprof_ext.rb +0 -35
  199. data/lib/source_annotation_extractor.rb +0 -102
  200. data/lib/tasks/annotations.rake +0 -20
  201. data/lib/tasks/databases.rake +0 -436
  202. data/lib/tasks/documentation.rake +0 -93
  203. data/lib/tasks/framework.rake +0 -146
  204. data/lib/tasks/gems.rake +0 -78
  205. data/lib/tasks/log.rake +0 -9
  206. data/lib/tasks/middleware.rake +0 -7
  207. data/lib/tasks/misc.rake +0 -63
  208. data/lib/tasks/rails.rb +0 -14
  209. data/lib/tasks/routes.rake +0 -18
  210. data/lib/tasks/statistics.rake +0 -17
  211. data/lib/tasks/testing.rake +0 -139
  212. data/lib/tasks/tmp.rake +0 -37
  213. data/lib/test_help.rb +0 -38
  214. data/lib/webrick_server.rb +0 -156
  215. 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("&nbsp;", " ").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