rails 2.2.3 → 2.3.2

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 (229) hide show
  1. data/CHANGELOG +272 -191
  2. data/MIT-LICENSE +1 -1
  3. data/README +6 -19
  4. data/Rakefile +24 -71
  5. data/bin/rails +1 -0
  6. data/builtin/rails_info/rails/info.rb +12 -8
  7. data/configs/databases/mysql.yml +3 -0
  8. data/configs/initializers/backtrace_silencers.rb +7 -0
  9. data/configs/initializers/new_rails_defaults.rb +2 -0
  10. data/configs/initializers/session_store.rb +15 -0
  11. data/dispatches/config.ru +7 -0
  12. data/doc/README_FOR_APP +2 -5
  13. data/environments/boot.rb +1 -0
  14. data/environments/environment.rb +14 -48
  15. data/environments/production.rb +11 -7
  16. data/environments/test.rb +6 -0
  17. data/helpers/application_controller.rb +10 -0
  18. data/helpers/test_helper.rb +1 -1
  19. data/html/500.html +0 -3
  20. data/html/index.html +1 -0
  21. data/lib/commands/about.rb +1 -1
  22. data/lib/commands/dbconsole.rb +18 -2
  23. data/lib/commands/plugin.rb +4 -3
  24. data/lib/commands/runner.rb +13 -7
  25. data/lib/commands/server.rb +98 -33
  26. data/lib/console_app.rb +4 -4
  27. data/lib/console_with_helpers.rb +2 -23
  28. data/lib/dispatcher.rb +1 -1
  29. data/lib/fcgi_handler.rb +12 -10
  30. data/lib/initializer.rb +108 -41
  31. data/lib/rails/backtrace_cleaner.rb +54 -0
  32. data/lib/rails/gem_dependency.rb +124 -94
  33. data/lib/rails/plugin.rb +49 -6
  34. data/lib/rails/plugin/loader.rb +66 -27
  35. data/lib/rails/plugin/locator.rb +1 -1
  36. data/lib/rails/rack.rb +3 -1
  37. data/lib/rails/rack/debugger.rb +21 -0
  38. data/lib/rails/rack/log_tailer.rb +35 -0
  39. data/lib/rails/rack/metal.rb +51 -0
  40. data/lib/rails/rack/static.rb +15 -4
  41. data/lib/rails/version.rb +2 -2
  42. data/lib/rails_generator/base.rb +3 -0
  43. data/lib/rails_generator/commands.rb +8 -3
  44. data/lib/rails_generator/generators/applications/app/app_generator.rb +210 -136
  45. data/lib/rails_generator/generators/applications/app/scm/git.rb +16 -0
  46. data/lib/rails_generator/generators/applications/app/scm/scm.rb +8 -0
  47. data/lib/rails_generator/generators/applications/app/scm/svn.rb +7 -0
  48. data/lib/rails_generator/generators/applications/app/template_runner.rb +401 -0
  49. data/lib/rails_generator/generators/components/controller/USAGE +12 -11
  50. data/lib/rails_generator/generators/components/controller/controller_generator.rb +7 -1
  51. data/lib/rails_generator/generators/components/controller/templates/helper_test.rb +4 -0
  52. data/lib/rails_generator/generators/components/helper/USAGE +24 -0
  53. data/lib/rails_generator/generators/components/helper/helper_generator.rb +25 -0
  54. data/lib/rails_generator/generators/components/helper/templates/helper.rb +2 -0
  55. data/lib/rails_generator/generators/components/helper/templates/helper_test.rb +4 -0
  56. data/lib/rails_generator/generators/components/metal/USAGE +8 -0
  57. data/lib/rails_generator/generators/components/metal/metal_generator.rb +8 -0
  58. data/lib/rails_generator/generators/components/metal/templates/metal.rb +12 -0
  59. data/lib/rails_generator/generators/components/resource/USAGE +2 -2
  60. data/lib/rails_generator/generators/components/resource/resource_generator.rb +2 -0
  61. data/lib/rails_generator/generators/components/resource/templates/helper_test.rb +4 -0
  62. data/lib/rails_generator/generators/components/scaffold/scaffold_generator.rb +2 -0
  63. data/lib/rails_generator/generators/components/scaffold/templates/controller.rb +1 -1
  64. data/lib/rails_generator/generators/components/scaffold/templates/functional_test.rb +4 -4
  65. data/lib/rails_generator/generators/components/scaffold/templates/helper_test.rb +4 -0
  66. data/lib/rails_generator/generators/components/scaffold/templates/layout.html.erb +1 -1
  67. data/lib/rails_generator/generators/components/scaffold/templates/view_edit.html.erb +2 -2
  68. data/lib/rails_generator/generators/components/scaffold/templates/view_index.html.erb +2 -2
  69. data/lib/rails_generator/generators/components/scaffold/templates/view_new.html.erb +2 -2
  70. data/lib/rails_generator/generators/components/scaffold/templates/view_show.html.erb +1 -1
  71. data/lib/rails_generator/secret_key_generator.rb +2 -0
  72. data/lib/tasks/databases.rake +13 -6
  73. data/lib/tasks/documentation.rake +2 -9
  74. data/lib/tasks/framework.rake +26 -1
  75. data/lib/tasks/gems.rake +33 -48
  76. data/lib/tasks/middleware.rake +7 -0
  77. data/lib/tasks/misc.rake +7 -0
  78. data/lib/tasks/statistics.rake +0 -1
  79. data/lib/tasks/testing.rake +5 -5
  80. data/lib/tasks/tmp.rake +2 -2
  81. data/lib/test_help.rb +16 -8
  82. metadata +92 -159
  83. data/bin/performance/request +0 -3
  84. data/bin/process/inspector +0 -3
  85. data/bin/process/reaper +0 -3
  86. data/bin/process/spawner +0 -3
  87. data/config.ru +0 -17
  88. data/configs/apache.conf +0 -40
  89. data/configs/lighttpd.conf +0 -54
  90. data/doc/guides/html/2_2_release_notes.html +0 -1185
  91. data/doc/guides/html/actioncontroller_basics.html +0 -1270
  92. data/doc/guides/html/activerecord_validations_callbacks.html +0 -749
  93. data/doc/guides/html/association_basics.html +0 -2585
  94. data/doc/guides/html/authors.html +0 -240
  95. data/doc/guides/html/benchmarking_and_profiling.html +0 -1018
  96. data/doc/guides/html/caching_with_rails.html +0 -583
  97. data/doc/guides/html/command_line.html +0 -434
  98. data/doc/guides/html/configuring.html +0 -438
  99. data/doc/guides/html/creating_plugins.html +0 -1594
  100. data/doc/guides/html/debugging_rails_applications.html +0 -1175
  101. data/doc/guides/html/finders.html +0 -1090
  102. data/doc/guides/html/form_helpers.html +0 -638
  103. data/doc/guides/html/getting_started_with_rails.html +0 -2066
  104. data/doc/guides/html/index.html +0 -349
  105. data/doc/guides/html/layouts_and_rendering.html +0 -1406
  106. data/doc/guides/html/migrations.html +0 -921
  107. data/doc/guides/html/routing_outside_in.html +0 -2213
  108. data/doc/guides/html/security.html +0 -1346
  109. data/doc/guides/html/testing_rails_applications.html +0 -1859
  110. data/doc/guides/source/2_2_release_notes.txt +0 -435
  111. data/doc/guides/source/actioncontroller_basics/changelog.txt +0 -5
  112. data/doc/guides/source/actioncontroller_basics/cookies.txt +0 -34
  113. data/doc/guides/source/actioncontroller_basics/csrf.txt +0 -32
  114. data/doc/guides/source/actioncontroller_basics/filters.txt +0 -119
  115. data/doc/guides/source/actioncontroller_basics/http_auth.txt +0 -24
  116. data/doc/guides/source/actioncontroller_basics/index.txt +0 -40
  117. data/doc/guides/source/actioncontroller_basics/introduction.txt +0 -9
  118. data/doc/guides/source/actioncontroller_basics/methods.txt +0 -39
  119. data/doc/guides/source/actioncontroller_basics/parameter_filtering.txt +0 -14
  120. data/doc/guides/source/actioncontroller_basics/params.txt +0 -93
  121. data/doc/guides/source/actioncontroller_basics/request_response_objects.txt +0 -43
  122. data/doc/guides/source/actioncontroller_basics/rescue.txt +0 -67
  123. data/doc/guides/source/actioncontroller_basics/session.txt +0 -187
  124. data/doc/guides/source/actioncontroller_basics/streaming.txt +0 -91
  125. data/doc/guides/source/actioncontroller_basics/verification.txt +0 -40
  126. data/doc/guides/source/active_record_basics.txt +0 -181
  127. data/doc/guides/source/activerecord_validations_callbacks.txt +0 -404
  128. data/doc/guides/source/association_basics.txt +0 -1840
  129. data/doc/guides/source/authors.txt +0 -39
  130. data/doc/guides/source/benchmarking_and_profiling/appendix.txt +0 -95
  131. data/doc/guides/source/benchmarking_and_profiling/digging_deeper.txt +0 -105
  132. data/doc/guides/source/benchmarking_and_profiling/edge_rails_features.txt +0 -185
  133. data/doc/guides/source/benchmarking_and_profiling/gameplan.txt +0 -27
  134. data/doc/guides/source/benchmarking_and_profiling/index.txt +0 -242
  135. data/doc/guides/source/benchmarking_and_profiling/rubyprof.txt +0 -179
  136. data/doc/guides/source/benchmarking_and_profiling/statistics.txt +0 -57
  137. data/doc/guides/source/caching_with_rails.txt +0 -367
  138. data/doc/guides/source/command_line.txt +0 -147
  139. data/doc/guides/source/configuring.txt +0 -225
  140. data/doc/guides/source/creating_plugins/acts_as_yaffle.txt +0 -191
  141. data/doc/guides/source/creating_plugins/appendix.txt +0 -46
  142. data/doc/guides/source/creating_plugins/controllers.txt +0 -59
  143. data/doc/guides/source/creating_plugins/core_ext.txt +0 -123
  144. data/doc/guides/source/creating_plugins/custom_route.txt +0 -69
  145. data/doc/guides/source/creating_plugins/gem.txt +0 -1
  146. data/doc/guides/source/creating_plugins/generator_method.txt +0 -89
  147. data/doc/guides/source/creating_plugins/helpers.txt +0 -51
  148. data/doc/guides/source/creating_plugins/index.txt +0 -52
  149. data/doc/guides/source/creating_plugins/migration_generator.txt +0 -156
  150. data/doc/guides/source/creating_plugins/models.txt +0 -76
  151. data/doc/guides/source/creating_plugins/odds_and_ends.txt +0 -69
  152. data/doc/guides/source/creating_plugins/test_setup.txt +0 -230
  153. data/doc/guides/source/debugging_rails_applications.txt +0 -733
  154. data/doc/guides/source/finders.txt +0 -668
  155. data/doc/guides/source/form_helpers.txt +0 -345
  156. data/doc/guides/source/getting_started_with_rails.txt +0 -1256
  157. data/doc/guides/source/images/belongs_to.png +0 -0
  158. data/doc/guides/source/images/bullet.gif +0 -0
  159. data/doc/guides/source/images/csrf.png +0 -0
  160. data/doc/guides/source/images/habtm.png +0 -0
  161. data/doc/guides/source/images/has_many.png +0 -0
  162. data/doc/guides/source/images/has_many_through.png +0 -0
  163. data/doc/guides/source/images/has_one.png +0 -0
  164. data/doc/guides/source/images/has_one_through.png +0 -0
  165. data/doc/guides/source/images/header_backdrop.png +0 -0
  166. data/doc/guides/source/images/icons/README +0 -5
  167. data/doc/guides/source/images/icons/callouts/1.png +0 -0
  168. data/doc/guides/source/images/icons/callouts/10.png +0 -0
  169. data/doc/guides/source/images/icons/callouts/11.png +0 -0
  170. data/doc/guides/source/images/icons/callouts/12.png +0 -0
  171. data/doc/guides/source/images/icons/callouts/13.png +0 -0
  172. data/doc/guides/source/images/icons/callouts/14.png +0 -0
  173. data/doc/guides/source/images/icons/callouts/15.png +0 -0
  174. data/doc/guides/source/images/icons/callouts/2.png +0 -0
  175. data/doc/guides/source/images/icons/callouts/3.png +0 -0
  176. data/doc/guides/source/images/icons/callouts/4.png +0 -0
  177. data/doc/guides/source/images/icons/callouts/5.png +0 -0
  178. data/doc/guides/source/images/icons/callouts/6.png +0 -0
  179. data/doc/guides/source/images/icons/callouts/7.png +0 -0
  180. data/doc/guides/source/images/icons/callouts/8.png +0 -0
  181. data/doc/guides/source/images/icons/callouts/9.png +0 -0
  182. data/doc/guides/source/images/icons/caution.png +0 -0
  183. data/doc/guides/source/images/icons/example.png +0 -0
  184. data/doc/guides/source/images/icons/home.png +0 -0
  185. data/doc/guides/source/images/icons/important.png +0 -0
  186. data/doc/guides/source/images/icons/next.png +0 -0
  187. data/doc/guides/source/images/icons/note.png +0 -0
  188. data/doc/guides/source/images/icons/prev.png +0 -0
  189. data/doc/guides/source/images/icons/tip.png +0 -0
  190. data/doc/guides/source/images/icons/up.png +0 -0
  191. data/doc/guides/source/images/icons/warning.png +0 -0
  192. data/doc/guides/source/images/polymorphic.png +0 -0
  193. data/doc/guides/source/images/rails_logo_remix.gif +0 -0
  194. data/doc/guides/source/images/ruby_on_rails_by_mike_rundle2.gif +0 -0
  195. data/doc/guides/source/images/session_fixation.png +0 -0
  196. data/doc/guides/source/index.txt +0 -118
  197. data/doc/guides/source/layouts_and_rendering.txt +0 -982
  198. data/doc/guides/source/migrations/anatomy_of_a_migration.txt +0 -85
  199. data/doc/guides/source/migrations/changelog.txt +0 -5
  200. data/doc/guides/source/migrations/creating_a_migration.txt +0 -109
  201. data/doc/guides/source/migrations/foreign_keys.txt +0 -8
  202. data/doc/guides/source/migrations/index.txt +0 -22
  203. data/doc/guides/source/migrations/rakeing_around.txt +0 -111
  204. data/doc/guides/source/migrations/scheming.txt +0 -47
  205. data/doc/guides/source/migrations/using_models_in_migrations.txt +0 -46
  206. data/doc/guides/source/migrations/writing_a_migration.txt +0 -159
  207. data/doc/guides/source/routing_outside_in.txt +0 -986
  208. data/doc/guides/source/security.txt +0 -984
  209. data/doc/guides/source/stylesheets/base.css +0 -358
  210. data/doc/guides/source/stylesheets/forms.css +0 -35
  211. data/doc/guides/source/stylesheets/more.css +0 -82
  212. data/doc/guides/source/templates/guides.html.erb +0 -97
  213. data/doc/guides/source/templates/inline.css +0 -165
  214. data/doc/guides/source/testing_rails_applications.txt +0 -995
  215. data/helpers/application.rb +0 -15
  216. data/lib/commands/performance/request.rb +0 -6
  217. data/lib/commands/process/inspector.rb +0 -68
  218. data/lib/commands/process/reaper.rb +0 -149
  219. data/lib/commands/process/spawner.rb +0 -219
  220. data/lib/commands/process/spinner.rb +0 -57
  221. data/lib/commands/servers/base.rb +0 -31
  222. data/lib/commands/servers/lighttpd.rb +0 -94
  223. data/lib/commands/servers/mongrel.rb +0 -69
  224. data/lib/commands/servers/new_mongrel.rb +0 -16
  225. data/lib/commands/servers/thin.rb +0 -25
  226. data/lib/commands/servers/webrick.rb +0 -66
  227. data/lib/rails/mongrel_server/commands.rb +0 -342
  228. data/lib/rails/mongrel_server/handler.rb +0 -55
  229. data/lib/rails/rack/logger.rb +0 -28
@@ -0,0 +1,16 @@
1
+ module Rails
2
+ class Git < Scm
3
+ def self.clone(repos, branch=nil)
4
+ `git clone #{repos}`
5
+
6
+ if branch
7
+ `cd #{repos.split('/').last}/`
8
+ `git checkout #{branch}`
9
+ end
10
+ end
11
+
12
+ def self.run(command)
13
+ `git #{command}`
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,8 @@
1
+ module Rails
2
+ class Scm
3
+ private
4
+ def self.hash_to_parameters(hash)
5
+ hash.collect { |key, value| "--#{key} #{(value.kind_of?(String) ? value : "")}"}.join(" ")
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,7 @@
1
+ module Rails
2
+ class Svn < Scm
3
+ def self.checkout(repos, branch = nil)
4
+ `svn checkout #{repos}/#{branch || "trunk"}`
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,401 @@
1
+ require File.dirname(__FILE__) + '/scm/scm'
2
+ require File.dirname(__FILE__) + '/scm/git'
3
+ require File.dirname(__FILE__) + '/scm/svn'
4
+
5
+ require 'open-uri'
6
+ require 'fileutils'
7
+
8
+ module Rails
9
+ class TemplateRunner
10
+ attr_reader :root
11
+ attr_writer :logger
12
+
13
+ def initialize(template, root = '') # :nodoc:
14
+ @root = File.expand_path(File.directory?(root) ? root : File.join(Dir.pwd, root))
15
+
16
+ log 'applying', "template: #{template}"
17
+
18
+ load_template(template)
19
+
20
+ log 'applied', "#{template}"
21
+ end
22
+
23
+ def load_template(template)
24
+ begin
25
+ code = open(template).read
26
+ in_root { self.instance_eval(code) }
27
+ rescue LoadError, Errno::ENOENT => e
28
+ raise "The template [#{template}] could not be loaded. Error: #{e}"
29
+ end
30
+ end
31
+
32
+ # Create a new file in the Rails project folder. Specify the
33
+ # relative path from RAILS_ROOT. Data is the return value of a block
34
+ # or a data string.
35
+ #
36
+ # ==== Examples
37
+ #
38
+ # file("lib/fun_party.rb") do
39
+ # hostname = ask("What is the virtual hostname I should use?")
40
+ # "vhost.name = #{hostname}"
41
+ # end
42
+ #
43
+ # file("config/apach.conf", "your apache config")
44
+ #
45
+ def file(filename, data = nil, log_action = true, &block)
46
+ log 'file', filename if log_action
47
+ dir, file = [File.dirname(filename), File.basename(filename)]
48
+
49
+ inside(dir) do
50
+ File.open(file, "w") do |f|
51
+ if block_given?
52
+ f.write(block.call)
53
+ else
54
+ f.write(data)
55
+ end
56
+ end
57
+ end
58
+ end
59
+
60
+ # Install a plugin. You must provide either a Subversion url or Git url.
61
+ # For a Git-hosted plugin, you can specify if it should be added as a submodule instead of cloned.
62
+ #
63
+ # ==== Examples
64
+ #
65
+ # plugin 'restful-authentication', :git => 'git://github.com/technoweenie/restful-authentication.git'
66
+ # plugin 'restful-authentication', :git => 'git://github.com/technoweenie/restful-authentication.git', :submodule => true
67
+ # plugin 'restful-authentication', :svn => 'svn://svnhub.com/technoweenie/restful-authentication/trunk'
68
+ #
69
+ def plugin(name, options)
70
+ log 'plugin', name
71
+
72
+ if options[:git] && options[:submodule]
73
+ in_root do
74
+ Git.run("submodule add #{options[:git]} vendor/plugins/#{name}")
75
+ end
76
+ elsif options[:git] || options[:svn]
77
+ in_root do
78
+ run_ruby_script("script/plugin install #{options[:svn] || options[:git]}", false)
79
+ end
80
+ else
81
+ log "! no git or svn provided for #{name}. skipping..."
82
+ end
83
+ end
84
+
85
+ # Adds an entry into config/environment.rb for the supplied gem :
86
+ def gem(name, options = {})
87
+ log 'gem', name
88
+ env = options.delete(:env)
89
+
90
+ gems_code = "config.gem '#{name}'"
91
+
92
+ if options.any?
93
+ opts = options.inject([]) {|result, h| result << [":#{h[0]} => #{h[1].inspect.gsub('"',"'")}"] }.sort.join(", ")
94
+ gems_code << ", #{opts}"
95
+ end
96
+
97
+ environment gems_code, :env => env
98
+ end
99
+
100
+ # Adds a line inside the Initializer block for config/environment.rb. Used by #gem
101
+ # If options :env is specified, the line is appended to the corresponding
102
+ # file in config/environments/#{env}.rb
103
+ def environment(data = nil, options = {}, &block)
104
+ sentinel = 'Rails::Initializer.run do |config|'
105
+
106
+ data = block.call if !data && block_given?
107
+
108
+ in_root do
109
+ if options[:env].nil?
110
+ gsub_file 'config/environment.rb', /(#{Regexp.escape(sentinel)})/mi do |match|
111
+ "#{match}\n " << data
112
+ end
113
+ else
114
+ Array.wrap(options[:env]).each do|env|
115
+ append_file "config/environments/#{env}.rb", "\n#{data}"
116
+ end
117
+ end
118
+ end
119
+ end
120
+
121
+ # Run a command in git.
122
+ #
123
+ # ==== Examples
124
+ #
125
+ # git :init
126
+ # git :add => "this.file that.rb"
127
+ # git :add => "onefile.rb", :rm => "badfile.cxx"
128
+ #
129
+ def git(command = {})
130
+ in_root do
131
+ if command.is_a?(Symbol)
132
+ log 'running', "git #{command}"
133
+ Git.run(command.to_s)
134
+ else
135
+ command.each do |command, options|
136
+ log 'running', "git #{command} #{options}"
137
+ Git.run("#{command} #{options}")
138
+ end
139
+ end
140
+ end
141
+ end
142
+
143
+ # Create a new file in the vendor/ directory. Code can be specified
144
+ # in a block or a data string can be given.
145
+ #
146
+ # ==== Examples
147
+ #
148
+ # vendor("sekrit.rb") do
149
+ # sekrit_salt = "#{Time.now}--#{3.years.ago}--#{rand}--"
150
+ # "salt = '#{sekrit_salt}'"
151
+ # end
152
+ #
153
+ # vendor("foreign.rb", "# Foreign code is fun")
154
+ #
155
+ def vendor(filename, data = nil, &block)
156
+ log 'vendoring', filename
157
+ file("vendor/#{filename}", data, false, &block)
158
+ end
159
+
160
+ # Create a new file in the lib/ directory. Code can be specified
161
+ # in a block or a data string can be given.
162
+ #
163
+ # ==== Examples
164
+ #
165
+ # lib("crypto.rb") do
166
+ # "crypted_special_value = '#{rand}--#{Time.now}--#{rand(1337)}--'"
167
+ # end
168
+ #
169
+ # lib("foreign.rb", "# Foreign code is fun")
170
+ #
171
+ def lib(filename, data = nil, &block)
172
+ log 'lib', filename
173
+ file("lib/#{filename}", data, false, &block)
174
+ end
175
+
176
+ # Create a new Rakefile with the provided code (either in a block or a string).
177
+ #
178
+ # ==== Examples
179
+ #
180
+ # rakefile("bootstrap.rake") do
181
+ # project = ask("What is the UNIX name of your project?")
182
+ #
183
+ # <<-TASK
184
+ # namespace :#{project} do
185
+ # task :bootstrap do
186
+ # puts "i like boots!"
187
+ # end
188
+ # end
189
+ # TASK
190
+ # end
191
+ #
192
+ # rakefile("seed.rake", "puts 'im plantin ur seedz'")
193
+ #
194
+ def rakefile(filename, data = nil, &block)
195
+ log 'rakefile', filename
196
+ file("lib/tasks/#{filename}", data, false, &block)
197
+ end
198
+
199
+ # Create a new initializer with the provided code (either in a block or a string).
200
+ #
201
+ # ==== Examples
202
+ #
203
+ # initializer("globals.rb") do
204
+ # data = ""
205
+ #
206
+ # ['MY_WORK', 'ADMINS', 'BEST_COMPANY_EVAR'].each do
207
+ # data << "#{const} = :entp"
208
+ # end
209
+ #
210
+ # data
211
+ # end
212
+ #
213
+ # initializer("api.rb", "API_KEY = '123456'")
214
+ #
215
+ def initializer(filename, data = nil, &block)
216
+ log 'initializer', filename
217
+ file("config/initializers/#{filename}", data, false, &block)
218
+ end
219
+
220
+ # Generate something using a generator from Rails or a plugin.
221
+ # The second parameter is the argument string that is passed to
222
+ # the generator or an Array that is joined.
223
+ #
224
+ # ==== Example
225
+ #
226
+ # generate(:authenticated, "user session")
227
+ #
228
+ def generate(what, *args)
229
+ log 'generating', what
230
+ argument = args.map(&:to_s).flatten.join(" ")
231
+
232
+ in_root { run_ruby_script("script/generate #{what} #{argument}", false) }
233
+ end
234
+
235
+ # Executes a command
236
+ #
237
+ # ==== Example
238
+ #
239
+ # inside('vendor') do
240
+ # run('ln -s ~/edge rails)
241
+ # end
242
+ #
243
+ def run(command, log_action = true)
244
+ log 'executing', "#{command} from #{Dir.pwd}" if log_action
245
+ `#{command}`
246
+ end
247
+
248
+ # Executes a ruby script (taking into account WIN32 platform quirks)
249
+ def run_ruby_script(command, log_action = true)
250
+ ruby_command = RUBY_PLATFORM=~ /win32/ ? 'ruby ' : ''
251
+ run("#{ruby_command}#{command}", log_action)
252
+ end
253
+
254
+ # Runs the supplied rake task
255
+ #
256
+ # ==== Example
257
+ #
258
+ # rake("db:migrate")
259
+ # rake("db:migrate", :env => "production")
260
+ # rake("gems:install", :sudo => true)
261
+ #
262
+ def rake(command, options = {})
263
+ log 'rake', command
264
+ env = options[:env] || 'development'
265
+ sudo = options[:sudo] ? 'sudo ' : ''
266
+ in_root { run("#{sudo}rake #{command} RAILS_ENV=#{env}", false) }
267
+ end
268
+
269
+ # Just run the capify command in root
270
+ #
271
+ # ==== Example
272
+ #
273
+ # capify!
274
+ #
275
+ def capify!
276
+ log 'capifying'
277
+ in_root { run('capify .', false) }
278
+ end
279
+
280
+ # Add Rails to /vendor/rails
281
+ #
282
+ # ==== Example
283
+ #
284
+ # freeze!
285
+ #
286
+ def freeze!(args = {})
287
+ log 'vendor', 'rails edge'
288
+ in_root { run('rake rails:freeze:edge', false) }
289
+ end
290
+
291
+ # Make an entry in Rails routing file conifg/routes.rb
292
+ #
293
+ # === Example
294
+ #
295
+ # route "map.root :controller => :welcome"
296
+ #
297
+ def route(routing_code)
298
+ log 'route', routing_code
299
+ sentinel = 'ActionController::Routing::Routes.draw do |map|'
300
+
301
+ in_root do
302
+ gsub_file 'config/routes.rb', /(#{Regexp.escape(sentinel)})/mi do |match|
303
+ "#{match}\n #{routing_code}\n"
304
+ end
305
+ end
306
+ end
307
+
308
+ protected
309
+
310
+ # Get a user's input
311
+ #
312
+ # ==== Example
313
+ #
314
+ # answer = ask("Should I freeze the latest Rails?")
315
+ # freeze! if ask("Should I freeze the latest Rails?") == "yes"
316
+ #
317
+ def ask(string)
318
+ log '', string
319
+ STDIN.gets.strip
320
+ end
321
+
322
+ # Do something in the root of the Rails application or
323
+ # a provided subfolder; the full path is yielded to the block you provide.
324
+ # The path is set back to the previous path when the method exits.
325
+ def inside(dir = '', &block)
326
+ folder = File.join(root, dir)
327
+ FileUtils.mkdir_p(folder) unless File.exist?(folder)
328
+ FileUtils.cd(folder) { block.arity == 1 ? yield(folder) : yield }
329
+ end
330
+
331
+ def in_root
332
+ FileUtils.cd(root) { yield }
333
+ end
334
+
335
+ # Helper to test if the user says yes(y)?
336
+ #
337
+ # ==== Example
338
+ #
339
+ # freeze! if yes?("Should I freeze the latest Rails?")
340
+ #
341
+ def yes?(question)
342
+ answer = ask(question).downcase
343
+ answer == "y" || answer == "yes"
344
+ end
345
+
346
+ # Helper to test if the user does NOT say yes(y)?
347
+ #
348
+ # ==== Example
349
+ #
350
+ # capify! if no?("Will you be using vlad to deploy your application?")
351
+ #
352
+ def no?(question)
353
+ !yes?(question)
354
+ end
355
+
356
+ # Run a regular expression replacement on a file
357
+ #
358
+ # ==== Example
359
+ #
360
+ # gsub_file 'app/controllers/application_controller.rb', /#\s*(filter_parameter_logging :password)/, '\1'
361
+ #
362
+ def gsub_file(relative_destination, regexp, *args, &block)
363
+ path = destination_path(relative_destination)
364
+ content = File.read(path).gsub(regexp, *args, &block)
365
+ File.open(path, 'wb') { |file| file.write(content) }
366
+ end
367
+
368
+ # Append text to a file
369
+ #
370
+ # ==== Example
371
+ #
372
+ # append_file 'config/environments/test.rb', 'config.gem "rspec"'
373
+ #
374
+ def append_file(relative_destination, data)
375
+ path = destination_path(relative_destination)
376
+ File.open(path, 'ab') { |file| file.write(data) }
377
+ end
378
+
379
+ def destination_path(relative_destination)
380
+ File.join(root, relative_destination)
381
+ end
382
+
383
+ def log(action, message = '')
384
+ logger.log(action, message)
385
+ end
386
+
387
+ def logger
388
+ @logger ||= Rails::Generator::Base.logger
389
+ end
390
+
391
+ def logger
392
+ @logger ||= if defined?(Rails::Generator::Base)
393
+ Rails::Generator::Base.logger
394
+ else
395
+ require 'rails_generator/simple_logger'
396
+ Rails::Generator::SimpleLogger.new(STDOUT)
397
+ end
398
+ end
399
+
400
+ end
401
+ end
@@ -6,24 +6,25 @@ Description:
6
6
  path like 'parent_module/controller_name'.
7
7
 
8
8
  This generates a controller class in app/controllers, view templates in
9
- app/views/controller_name, a helper class in app/helpers, and a functional
10
- test suite in test/functional.
9
+ app/views/controller_name, a helper class in app/helpers, a functional
10
+ test suite in test/functional and a helper test suite in test/unit/helpers.
11
11
 
12
12
  Example:
13
13
  `./script/generate controller CreditCard open debit credit close`
14
14
 
15
15
  Credit card controller with URLs like /credit_card/debit.
16
- Controller: app/controllers/credit_card_controller.rb
17
- Views: app/views/credit_card/debit.html.erb [...]
18
- Helper: app/helpers/credit_card_helper.rb
19
- Test: test/functional/credit_card_controller_test.rb
16
+ Controller: app/controllers/credit_card_controller.rb
17
+ Functional Test: test/functional/credit_card_controller_test.rb
18
+ Views: app/views/credit_card/debit.html.erb [...]
19
+ Helper: app/helpers/credit_card_helper.rb
20
+ Helper Test: test/unit/helpers/credit_card_helper_test.rb
20
21
 
21
22
  Modules Example:
22
23
  `./script/generate controller 'admin/credit_card' suspend late_fee`
23
24
 
24
25
  Credit card admin controller with URLs /admin/credit_card/suspend.
25
- Controller: app/controllers/admin/credit_card_controller.rb
26
- Views: app/views/admin/credit_card/debit.html.erb [...]
27
- Helper: app/helpers/admin/credit_card_helper.rb
28
- Test: test/functional/admin/credit_card_controller_test.rb
29
-
26
+ Controller: app/controllers/admin/credit_card_controller.rb
27
+ Functional Test: test/functional/admin/credit_card_controller_test.rb
28
+ Views: app/views/admin/credit_card/debit.html.erb [...]
29
+ Helper: app/helpers/admin/credit_card_helper.rb
30
+ Helper Test: test/unit/helpers/admin/credit_card_helper_test.rb