railties 3.0.0.beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (334) hide show
  1. data/CHANGELOG +2201 -0
  2. data/README +286 -0
  3. data/bin/rails +11 -0
  4. data/builtin/rails_info/rails/info.rb +147 -0
  5. data/builtin/rails_info/rails/info_controller.rb +15 -0
  6. data/builtin/rails_info/rails/info_helper.rb +2 -0
  7. data/builtin/routes.rb +3 -0
  8. data/guides/files/javascripts/code_highlighter.js +188 -0
  9. data/guides/files/javascripts/guides.js +7 -0
  10. data/guides/files/javascripts/highlighters.js +90 -0
  11. data/guides/files/stylesheets/main.css +441 -0
  12. data/guides/files/stylesheets/print.css +52 -0
  13. data/guides/files/stylesheets/reset.css +43 -0
  14. data/guides/files/stylesheets/style.css +13 -0
  15. data/guides/files/stylesheets/syntax.css +31 -0
  16. data/guides/images/belongs_to.png +0 -0
  17. data/guides/images/book_icon.gif +0 -0
  18. data/guides/images/bullet.gif +0 -0
  19. data/guides/images/chapters_icon.gif +0 -0
  20. data/guides/images/check_bullet.gif +0 -0
  21. data/guides/images/credits_pic_blank.gif +0 -0
  22. data/guides/images/csrf.png +0 -0
  23. data/guides/images/customized_error_messages.png +0 -0
  24. data/guides/images/error_messages.png +0 -0
  25. data/guides/images/feature_tile.gif +0 -0
  26. data/guides/images/footer_tile.gif +0 -0
  27. data/guides/images/fxn.png +0 -0
  28. data/guides/images/grey_bullet.gif +0 -0
  29. data/guides/images/habtm.png +0 -0
  30. data/guides/images/has_many.png +0 -0
  31. data/guides/images/has_many_through.png +0 -0
  32. data/guides/images/has_one.png +0 -0
  33. data/guides/images/has_one_through.png +0 -0
  34. data/guides/images/header_backdrop.png +0 -0
  35. data/guides/images/header_tile.gif +0 -0
  36. data/guides/images/i18n/demo_localized_pirate.png +0 -0
  37. data/guides/images/i18n/demo_translated_en.png +0 -0
  38. data/guides/images/i18n/demo_translated_pirate.png +0 -0
  39. data/guides/images/i18n/demo_translation_missing.png +0 -0
  40. data/guides/images/i18n/demo_untranslated.png +0 -0
  41. data/guides/images/icons/README +5 -0
  42. data/guides/images/icons/callouts/1.png +0 -0
  43. data/guides/images/icons/callouts/10.png +0 -0
  44. data/guides/images/icons/callouts/11.png +0 -0
  45. data/guides/images/icons/callouts/12.png +0 -0
  46. data/guides/images/icons/callouts/13.png +0 -0
  47. data/guides/images/icons/callouts/14.png +0 -0
  48. data/guides/images/icons/callouts/15.png +0 -0
  49. data/guides/images/icons/callouts/2.png +0 -0
  50. data/guides/images/icons/callouts/3.png +0 -0
  51. data/guides/images/icons/callouts/4.png +0 -0
  52. data/guides/images/icons/callouts/5.png +0 -0
  53. data/guides/images/icons/callouts/6.png +0 -0
  54. data/guides/images/icons/callouts/7.png +0 -0
  55. data/guides/images/icons/callouts/8.png +0 -0
  56. data/guides/images/icons/callouts/9.png +0 -0
  57. data/guides/images/icons/caution.png +0 -0
  58. data/guides/images/icons/example.png +0 -0
  59. data/guides/images/icons/home.png +0 -0
  60. data/guides/images/icons/important.png +0 -0
  61. data/guides/images/icons/next.png +0 -0
  62. data/guides/images/icons/note.png +0 -0
  63. data/guides/images/icons/prev.png +0 -0
  64. data/guides/images/icons/tip.png +0 -0
  65. data/guides/images/icons/up.png +0 -0
  66. data/guides/images/icons/warning.png +0 -0
  67. data/guides/images/nav_arrow.gif +0 -0
  68. data/guides/images/polymorphic.png +0 -0
  69. data/guides/images/posts_index.png +0 -0
  70. data/guides/images/rails_guides_logo.gif +0 -0
  71. data/guides/images/rails_logo_remix.gif +0 -0
  72. data/guides/images/rails_welcome.png +0 -0
  73. data/guides/images/session_fixation.png +0 -0
  74. data/guides/images/tab_grey.gif +0 -0
  75. data/guides/images/tab_info.gif +0 -0
  76. data/guides/images/tab_note.gif +0 -0
  77. data/guides/images/tab_red.gif +0 -0
  78. data/guides/images/tab_yellow.gif +0 -0
  79. data/guides/images/tab_yellow.png +0 -0
  80. data/guides/images/validation_error_messages.png +0 -0
  81. data/guides/rails_guides.rb +44 -0
  82. data/guides/rails_guides/generator.rb +178 -0
  83. data/guides/rails_guides/helpers.rb +34 -0
  84. data/guides/rails_guides/indexer.rb +55 -0
  85. data/guides/rails_guides/levenshtein.rb +31 -0
  86. data/guides/rails_guides/textile_extensions.rb +41 -0
  87. data/guides/source/2_2_release_notes.textile +422 -0
  88. data/guides/source/2_3_release_notes.textile +610 -0
  89. data/guides/source/3_0_release_notes.textile +560 -0
  90. data/guides/source/action_controller_overview.textile +783 -0
  91. data/guides/source/action_mailer_basics.textile +437 -0
  92. data/guides/source/action_view_overview.textile +1481 -0
  93. data/guides/source/active_record_basics.textile +204 -0
  94. data/guides/source/active_record_querying.textile +961 -0
  95. data/guides/source/active_support_core_extensions.textile +1835 -0
  96. data/guides/source/activerecord_validations_callbacks.textile +1127 -0
  97. data/guides/source/ajax_on_rails.textile +342 -0
  98. data/guides/source/association_basics.textile +1816 -0
  99. data/guides/source/caching_with_rails.textile +390 -0
  100. data/guides/source/command_line.textile +589 -0
  101. data/guides/source/configuring.textile +290 -0
  102. data/guides/source/contribute.textile +71 -0
  103. data/guides/source/contributing_to_rails.textile +272 -0
  104. data/guides/source/credits.textile.erb +52 -0
  105. data/guides/source/debugging_rails_applications.textile +709 -0
  106. data/guides/source/form_helpers.textile +768 -0
  107. data/guides/source/generators.textile +378 -0
  108. data/guides/source/getting_started.textile +1310 -0
  109. data/guides/source/i18n.textile +879 -0
  110. data/guides/source/index.textile.erb +124 -0
  111. data/guides/source/layout.html.erb +103 -0
  112. data/guides/source/layouts_and_rendering.textile +979 -0
  113. data/guides/source/migrations.textile +591 -0
  114. data/guides/source/nested_model_forms.textile +222 -0
  115. data/guides/source/performance_testing.textile +531 -0
  116. data/guides/source/plugins.textile +1512 -0
  117. data/guides/source/rails_application_templates.textile +238 -0
  118. data/guides/source/rails_on_rack.textile +306 -0
  119. data/guides/source/routing.textile +903 -0
  120. data/guides/source/security.textile +984 -0
  121. data/guides/source/testing.textile +946 -0
  122. data/lib/generators/erb.rb +8 -0
  123. data/lib/generators/erb/controller/controller_generator.rb +21 -0
  124. data/lib/generators/erb/controller/templates/view.html.erb +2 -0
  125. data/lib/generators/erb/mailer/mailer_generator.rb +20 -0
  126. data/lib/generators/erb/mailer/templates/view.text.erb +3 -0
  127. data/lib/generators/erb/scaffold/scaffold_generator.rb +53 -0
  128. data/lib/generators/erb/scaffold/templates/_form.html.erb +13 -0
  129. data/lib/generators/erb/scaffold/templates/edit.html.erb +6 -0
  130. data/lib/generators/erb/scaffold/templates/index.html.erb +27 -0
  131. data/lib/generators/erb/scaffold/templates/layout.html.erb +16 -0
  132. data/lib/generators/erb/scaffold/templates/new.html.erb +5 -0
  133. data/lib/generators/erb/scaffold/templates/show.html.erb +10 -0
  134. data/lib/generators/rails/app/USAGE +9 -0
  135. data/lib/generators/rails/app/app_generator.rb +262 -0
  136. data/lib/generators/rails/app/templates/Gemfile +34 -0
  137. data/lib/generators/rails/app/templates/README +243 -0
  138. data/lib/generators/rails/app/templates/Rakefile +10 -0
  139. data/lib/generators/rails/app/templates/app/controllers/application_controller.rb +3 -0
  140. data/lib/generators/rails/app/templates/app/helpers/application_helper.rb +2 -0
  141. data/lib/generators/rails/app/templates/app/models/.empty_directory +0 -0
  142. data/lib/generators/rails/app/templates/app/views/layouts/.empty_directory +0 -0
  143. data/lib/generators/rails/app/templates/config.ru +4 -0
  144. data/lib/generators/rails/app/templates/config/application.rb +51 -0
  145. data/lib/generators/rails/app/templates/config/boot.rb +17 -0
  146. data/lib/generators/rails/app/templates/config/databases/frontbase.yml +28 -0
  147. data/lib/generators/rails/app/templates/config/databases/ibm_db.yml +71 -0
  148. data/lib/generators/rails/app/templates/config/databases/mysql.yml +60 -0
  149. data/lib/generators/rails/app/templates/config/databases/oracle.yml +39 -0
  150. data/lib/generators/rails/app/templates/config/databases/postgresql.yml +51 -0
  151. data/lib/generators/rails/app/templates/config/databases/sqlite3.yml +22 -0
  152. data/lib/generators/rails/app/templates/config/environment.rb +5 -0
  153. data/lib/generators/rails/app/templates/config/environments/development.rb.tt +19 -0
  154. data/lib/generators/rails/app/templates/config/environments/production.rb.tt +33 -0
  155. data/lib/generators/rails/app/templates/config/environments/test.rb.tt +29 -0
  156. data/lib/generators/rails/app/templates/config/initializers/backtrace_silencers.rb +7 -0
  157. data/lib/generators/rails/app/templates/config/initializers/cookie_verification_secret.rb.tt +7 -0
  158. data/lib/generators/rails/app/templates/config/initializers/inflections.rb +10 -0
  159. data/lib/generators/rails/app/templates/config/initializers/mime_types.rb +5 -0
  160. data/lib/generators/rails/app/templates/config/initializers/session_store.rb.tt +15 -0
  161. data/lib/generators/rails/app/templates/config/locales/en.yml +5 -0
  162. data/lib/generators/rails/app/templates/config/routes.rb +58 -0
  163. data/lib/generators/rails/app/templates/db/seeds.rb +7 -0
  164. data/lib/generators/rails/app/templates/doc/README_FOR_APP +2 -0
  165. data/lib/generators/rails/app/templates/gitignore +4 -0
  166. data/lib/generators/rails/app/templates/public/404.html +26 -0
  167. data/lib/generators/rails/app/templates/public/422.html +26 -0
  168. data/lib/generators/rails/app/templates/public/500.html +26 -0
  169. data/lib/generators/rails/app/templates/public/favicon.ico +0 -0
  170. data/lib/generators/rails/app/templates/public/images/rails.png +0 -0
  171. data/lib/generators/rails/app/templates/public/index.html +278 -0
  172. data/lib/generators/rails/app/templates/public/javascripts/application.js +2 -0
  173. data/lib/generators/rails/app/templates/public/javascripts/controls.js +963 -0
  174. data/lib/generators/rails/app/templates/public/javascripts/dragdrop.js +973 -0
  175. data/lib/generators/rails/app/templates/public/javascripts/effects.js +1128 -0
  176. data/lib/generators/rails/app/templates/public/javascripts/prototype.js +4320 -0
  177. data/lib/generators/rails/app/templates/public/javascripts/rails.js +110 -0
  178. data/lib/generators/rails/app/templates/public/robots.txt +5 -0
  179. data/lib/generators/rails/app/templates/public/stylesheets/.empty_directory +0 -0
  180. data/lib/generators/rails/app/templates/script/rails +9 -0
  181. data/lib/generators/rails/app/templates/test/fixtures/.empty_directory +0 -0
  182. data/lib/generators/rails/app/templates/test/functional/.empty_directory +0 -0
  183. data/lib/generators/rails/app/templates/test/integration/.empty_directory +0 -0
  184. data/lib/generators/rails/app/templates/test/performance/browsing_test.rb +9 -0
  185. data/lib/generators/rails/app/templates/test/test_helper.rb +13 -0
  186. data/lib/generators/rails/app/templates/test/unit/.empty_directory +0 -0
  187. data/lib/generators/rails/controller/USAGE +18 -0
  188. data/lib/generators/rails/controller/controller_generator.rb +14 -0
  189. data/lib/generators/rails/controller/templates/controller.rb +7 -0
  190. data/lib/generators/rails/generator/USAGE +11 -0
  191. data/lib/generators/rails/generator/generator_generator.rb +25 -0
  192. data/lib/generators/rails/generator/templates/%file_name%_generator.rb.tt +5 -0
  193. data/lib/generators/rails/generator/templates/USAGE.tt +8 -0
  194. data/lib/generators/rails/generator/templates/templates/.empty_directory +0 -0
  195. data/lib/generators/rails/helper/USAGE +17 -0
  196. data/lib/generators/rails/helper/helper_generator.rb +13 -0
  197. data/lib/generators/rails/helper/templates/helper.rb +2 -0
  198. data/lib/generators/rails/integration_test/USAGE +10 -0
  199. data/lib/generators/rails/integration_test/integration_test_generator.rb +7 -0
  200. data/lib/generators/rails/mailer/USAGE +15 -0
  201. data/lib/generators/rails/mailer/mailer_generator.rb +14 -0
  202. data/lib/generators/rails/mailer/templates/mailer.rb +16 -0
  203. data/lib/generators/rails/metal/USAGE +8 -0
  204. data/lib/generators/rails/metal/metal_generator.rb +11 -0
  205. data/lib/generators/rails/metal/templates/metal.rb +12 -0
  206. data/lib/generators/rails/migration/USAGE +29 -0
  207. data/lib/generators/rails/migration/migration_generator.rb +8 -0
  208. data/lib/generators/rails/model/USAGE +30 -0
  209. data/lib/generators/rails/model/model_generator.rb +8 -0
  210. data/lib/generators/rails/model_subclass/model_subclass_generator.rb +12 -0
  211. data/lib/generators/rails/observer/USAGE +12 -0
  212. data/lib/generators/rails/observer/observer_generator.rb +7 -0
  213. data/lib/generators/rails/performance_test/USAGE +10 -0
  214. data/lib/generators/rails/performance_test/performance_test_generator.rb +7 -0
  215. data/lib/generators/rails/plugin/USAGE +13 -0
  216. data/lib/generators/rails/plugin/plugin_generator.rb +47 -0
  217. data/lib/generators/rails/plugin/templates/MIT-LICENSE.tt +20 -0
  218. data/lib/generators/rails/plugin/templates/README.tt +13 -0
  219. data/lib/generators/rails/plugin/templates/Rakefile.tt +10 -0
  220. data/lib/generators/rails/plugin/templates/init.rb +1 -0
  221. data/lib/generators/rails/plugin/templates/install.rb +1 -0
  222. data/lib/generators/rails/plugin/templates/lib/%file_name%.rb.tt +1 -0
  223. data/lib/generators/rails/plugin/templates/lib/tasks/%file_name%_tasks.rake.tt +4 -0
  224. data/lib/generators/rails/plugin/templates/uninstall.rb +1 -0
  225. data/lib/generators/rails/resource/USAGE +23 -0
  226. data/lib/generators/rails/resource/resource_generator.rb +34 -0
  227. data/lib/generators/rails/scaffold/USAGE +29 -0
  228. data/lib/generators/rails/scaffold/scaffold_generator.rb +13 -0
  229. data/lib/generators/rails/scaffold_controller/USAGE +20 -0
  230. data/lib/generators/rails/scaffold_controller/scaffold_controller_generator.rb +27 -0
  231. data/lib/generators/rails/scaffold_controller/templates/controller.rb +85 -0
  232. data/lib/generators/rails/session_migration/USAGE +8 -0
  233. data/lib/generators/rails/session_migration/session_migration_generator.rb +8 -0
  234. data/lib/generators/rails/stylesheets/USAGE +5 -0
  235. data/lib/generators/rails/stylesheets/stylesheets_generator.rb +9 -0
  236. data/lib/generators/rails/stylesheets/templates/scaffold.css +61 -0
  237. data/lib/generators/test_unit.rb +8 -0
  238. data/lib/generators/test_unit/controller/controller_generator.rb +14 -0
  239. data/lib/generators/test_unit/controller/templates/functional_test.rb +8 -0
  240. data/lib/generators/test_unit/helper/helper_generator.rb +13 -0
  241. data/lib/generators/test_unit/helper/templates/helper_test.rb +4 -0
  242. data/lib/generators/test_unit/integration/integration_generator.rb +13 -0
  243. data/lib/generators/test_unit/integration/templates/integration_test.rb +10 -0
  244. data/lib/generators/test_unit/mailer/mailer_generator.rb +21 -0
  245. data/lib/generators/test_unit/mailer/templates/fixture +3 -0
  246. data/lib/generators/test_unit/mailer/templates/functional_test.rb +22 -0
  247. data/lib/generators/test_unit/model/model_generator.rb +24 -0
  248. data/lib/generators/test_unit/model/templates/fixtures.yml +23 -0
  249. data/lib/generators/test_unit/model/templates/unit_test.rb +8 -0
  250. data/lib/generators/test_unit/observer/observer_generator.rb +13 -0
  251. data/lib/generators/test_unit/observer/templates/unit_test.rb +8 -0
  252. data/lib/generators/test_unit/performance/performance_generator.rb +13 -0
  253. data/lib/generators/test_unit/performance/templates/performance_test.rb +9 -0
  254. data/lib/generators/test_unit/plugin/plugin_generator.rb +13 -0
  255. data/lib/generators/test_unit/plugin/templates/%file_name%_test.rb.tt +8 -0
  256. data/lib/generators/test_unit/plugin/templates/test_helper.rb +3 -0
  257. data/lib/generators/test_unit/scaffold/scaffold_generator.rb +18 -0
  258. data/lib/generators/test_unit/scaffold/templates/functional_test.rb +47 -0
  259. data/lib/rails.rb +95 -0
  260. data/lib/rails/all.rb +14 -0
  261. data/lib/rails/application.rb +125 -0
  262. data/lib/rails/application/bootstrap.rb +85 -0
  263. data/lib/rails/application/configurable.rb +19 -0
  264. data/lib/rails/application/configuration.rb +86 -0
  265. data/lib/rails/application/finisher.rb +49 -0
  266. data/lib/rails/application/metal_loader.rb +50 -0
  267. data/lib/rails/application/railties.rb +31 -0
  268. data/lib/rails/application/routes_reloader.rb +46 -0
  269. data/lib/rails/backtrace_cleaner.rb +54 -0
  270. data/lib/rails/code_statistics.rb +107 -0
  271. data/lib/rails/commands.rb +72 -0
  272. data/lib/rails/commands/application.rb +13 -0
  273. data/lib/rails/commands/console.rb +55 -0
  274. data/lib/rails/commands/dbconsole.rb +104 -0
  275. data/lib/rails/commands/destroy.rb +9 -0
  276. data/lib/rails/commands/generate.rb +9 -0
  277. data/lib/rails/commands/performance/benchmarker.rb +23 -0
  278. data/lib/rails/commands/performance/profiler.rb +46 -0
  279. data/lib/rails/commands/plugin.rb +542 -0
  280. data/lib/rails/commands/runner.rb +51 -0
  281. data/lib/rails/commands/server.rb +75 -0
  282. data/lib/rails/commands/update.rb +9 -0
  283. data/lib/rails/configuration.rb +191 -0
  284. data/lib/rails/console/app.rb +33 -0
  285. data/lib/rails/console/helpers.rb +5 -0
  286. data/lib/rails/console/sandbox.rb +6 -0
  287. data/lib/rails/deprecation.rb +62 -0
  288. data/lib/rails/dispatcher.rb +24 -0
  289. data/lib/rails/engine.rb +130 -0
  290. data/lib/rails/engine/configurable.rb +25 -0
  291. data/lib/rails/engine/configuration.rb +49 -0
  292. data/lib/rails/generators.rb +289 -0
  293. data/lib/rails/generators/actions.rb +309 -0
  294. data/lib/rails/generators/active_model.rb +78 -0
  295. data/lib/rails/generators/base.rb +362 -0
  296. data/lib/rails/generators/generated_attribute.rb +48 -0
  297. data/lib/rails/generators/migration.rb +64 -0
  298. data/lib/rails/generators/named_base.rb +95 -0
  299. data/lib/rails/generators/resource_helpers.rb +80 -0
  300. data/lib/rails/generators/test_case.rb +239 -0
  301. data/lib/rails/initializable.rb +97 -0
  302. data/lib/rails/paths.rb +144 -0
  303. data/lib/rails/performance_test_help.rb +3 -0
  304. data/lib/rails/plugin.rb +64 -0
  305. data/lib/rails/rack.rb +8 -0
  306. data/lib/rails/rack/debugger.rb +23 -0
  307. data/lib/rails/rack/log_tailer.rb +33 -0
  308. data/lib/rails/rack/logger.rb +34 -0
  309. data/lib/rails/rack/static.rb +5 -0
  310. data/lib/rails/railtie.rb +74 -0
  311. data/lib/rails/railtie/configurable.rb +23 -0
  312. data/lib/rails/railtie/configuration.rb +9 -0
  313. data/lib/rails/railties_path.rb +1 -0
  314. data/lib/rails/ruby_version_check.rb +10 -0
  315. data/lib/rails/rubyprof_ext.rb +35 -0
  316. data/lib/rails/source_annotation_extractor.rb +102 -0
  317. data/lib/rails/subscriber.rb +108 -0
  318. data/lib/rails/subscriber/test_helper.rb +98 -0
  319. data/lib/rails/tasks.rb +16 -0
  320. data/lib/rails/tasks/annotations.rake +20 -0
  321. data/lib/rails/tasks/documentation.rake +96 -0
  322. data/lib/rails/tasks/framework.rake +69 -0
  323. data/lib/rails/tasks/log.rake +9 -0
  324. data/lib/rails/tasks/middleware.rake +7 -0
  325. data/lib/rails/tasks/misc.rake +71 -0
  326. data/lib/rails/tasks/routes.rake +17 -0
  327. data/lib/rails/tasks/statistics.rake +16 -0
  328. data/lib/rails/tasks/tmp.rake +37 -0
  329. data/lib/rails/test_help.rb +30 -0
  330. data/lib/rails/test_unit/railtie.rb +17 -0
  331. data/lib/rails/test_unit/testing.rake +130 -0
  332. data/lib/rails/version.rb +9 -0
  333. data/lib/rails/webrick_server.rb +156 -0
  334. metadata +427 -0
@@ -0,0 +1,48 @@
1
+ module Rails
2
+ module Generators
3
+ class GeneratedAttribute
4
+ attr_accessor :name, :type
5
+
6
+ def initialize(name, type)
7
+ @name, @type = name, type.to_sym
8
+ end
9
+
10
+ def field_type
11
+ @field_type ||= case type
12
+ when :integer, :float, :decimal then :text_field
13
+ when :datetime, :timestamp, :time then :datetime_select
14
+ when :date then :date_select
15
+ when :string then :text_field
16
+ when :text then :text_area
17
+ when :boolean then :check_box
18
+ else
19
+ :text_field
20
+ end
21
+ end
22
+
23
+ def default
24
+ @default ||= case type
25
+ when :integer then 1
26
+ when :float then 1.5
27
+ when :decimal then "9.99"
28
+ when :datetime, :timestamp, :time then Time.now.to_s(:db)
29
+ when :date then Date.today.to_s(:db)
30
+ when :string then "MyString"
31
+ when :text then "MyText"
32
+ when :boolean then false
33
+ when :references, :belongs_to then nil
34
+ else
35
+ ""
36
+ end
37
+ end
38
+
39
+ def human_name
40
+ name.to_s.humanize
41
+ end
42
+
43
+ def reference?
44
+ [ :references, :belongs_to ].include?(self.type)
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,64 @@
1
+ module Rails
2
+ module Generators
3
+ # Holds common methods for migrations. It assumes that migrations has the
4
+ # [0-9]*_name format and can be used by another frameworks (like Sequel)
5
+ # just by implementing the next migration number method.
6
+ #
7
+ module Migration
8
+ attr_reader :migration_number, :migration_file_name, :migration_class_name
9
+
10
+ def self.included(base) #:nodoc:
11
+ base.extend ClassMethods
12
+ end
13
+
14
+ module ClassMethods
15
+ def migration_lookup_at(dirname) #:nodoc:
16
+ Dir.glob("#{dirname}/[0-9]*_*.rb")
17
+ end
18
+
19
+ def migration_exists?(dirname, file_name) #:nodoc:
20
+ migration_lookup_at(dirname).grep(/\d+_#{file_name}.rb$/).first
21
+ end
22
+
23
+ def current_migration_number(dirname) #:nodoc:
24
+ migration_lookup_at(dirname).collect do |file|
25
+ File.basename(file).split("_").first.to_i
26
+ end.max.to_i
27
+ end
28
+
29
+ def next_migration_number(dirname) #:nodoc:
30
+ raise NotImplementedError
31
+ end
32
+ end
33
+
34
+ # Creates a migration template at the given destination. The difference
35
+ # to the default template method is that the migration number is appended
36
+ # to the destination file name.
37
+ #
38
+ # The migration number, migration file name, migration class name are
39
+ # available as instance variables in the template to be rendered.
40
+ #
41
+ # ==== Examples
42
+ #
43
+ # migration_template "migration.rb", "db/migrate/add_foo_to_bar.rb"
44
+ #
45
+ def migration_template(source, destination=nil, config={})
46
+ destination = File.expand_path(destination || source, self.destination_root)
47
+
48
+ migration_dir = File.dirname(destination)
49
+ @migration_number = self.class.next_migration_number(migration_dir)
50
+ @migration_file_name = File.basename(destination).sub(/\.rb$/, '')
51
+ @migration_class_name = @migration_file_name.camelize
52
+
53
+ destination = self.class.migration_exists?(migration_dir, @migration_file_name)
54
+
55
+ if behavior == :invoke
56
+ raise Error, "Another migration is already named #{@migration_file_name}: #{destination}" if destination
57
+ destination = File.join(migration_dir, "#{@migration_number}_#{@migration_file_name}.rb")
58
+ end
59
+
60
+ template(source, destination, config)
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,95 @@
1
+ require 'rails/generators/base'
2
+ require 'rails/generators/generated_attribute'
3
+
4
+ module Rails
5
+ module Generators
6
+ class NamedBase < Base
7
+ argument :name, :type => :string
8
+
9
+ def initialize(args, *options) #:nodoc:
10
+ # Unfreeze name in case it's given as a frozen string
11
+ args[0] = args[0].dup if args[0].is_a?(String) && args[0].frozen?
12
+ super
13
+ assign_names!(self.name)
14
+ parse_attributes! if respond_to?(:attributes)
15
+ end
16
+
17
+ protected
18
+
19
+ attr_reader :class_path, :file_name
20
+ alias :singular_name :file_name
21
+
22
+ def file_path
23
+ @file_path ||= (class_path + [file_name]).join('/')
24
+ end
25
+
26
+ def class_name
27
+ @class_name ||= (class_path + [file_name]).map!{ |m| m.camelize }.join('::')
28
+ end
29
+
30
+ def plural_name
31
+ @plural_name ||= singular_name.pluralize
32
+ end
33
+
34
+ def i18n_scope
35
+ @i18n_scope ||= file_path.gsub('/', '.')
36
+ end
37
+
38
+ def table_name
39
+ @table_name ||= begin
40
+ base = pluralize_table_names? ? plural_name : singular_name
41
+ (class_path + [base]).join('_')
42
+ end
43
+ end
44
+
45
+ # Tries to retrieve the application name or simple return application.
46
+ def application_name
47
+ if defined?(Rails) && Rails.application
48
+ Rails.application.class.name.split('::').first.underscore
49
+ else
50
+ "application"
51
+ end
52
+ end
53
+
54
+ def assign_names!(name) #:nodoc:
55
+ @class_path = name.include?('/') ? name.split('/') : name.split('::')
56
+ @class_path.map! { |m| m.underscore }
57
+ @file_name = @class_path.pop
58
+ end
59
+
60
+ # Convert attributes array into GeneratedAttribute objects.
61
+ def parse_attributes! #:nodoc:
62
+ self.attributes = (attributes || []).map do |key_value|
63
+ name, type = key_value.split(':')
64
+ Rails::Generators::GeneratedAttribute.new(name, type)
65
+ end
66
+ end
67
+
68
+ def pluralize_table_names?
69
+ !defined?(ActiveRecord::Base) || ActiveRecord::Base.pluralize_table_names
70
+ end
71
+
72
+ # Add a class collisions name to be checked on class initialization. You
73
+ # can supply a hash with a :prefix or :suffix to be tested.
74
+ #
75
+ # ==== Examples
76
+ #
77
+ # check_class_collision :suffix => "Observer"
78
+ #
79
+ # If the generator is invoked with class name Admin, it will check for
80
+ # the presence of "AdminObserver".
81
+ #
82
+ def self.check_class_collision(options={})
83
+ define_method :check_class_collision do
84
+ name = if self.respond_to?(:controller_class_name) # for ScaffoldBase
85
+ controller_class_name
86
+ else
87
+ class_name
88
+ end
89
+
90
+ class_collisions "#{options[:prefix]}#{name}#{options[:suffix]}"
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,80 @@
1
+ require 'rails/generators/active_model'
2
+
3
+ module Rails
4
+ module Generators
5
+ # Deal with controller names on scaffold and add some helpers to deal with
6
+ # ActiveModel.
7
+ #
8
+ module ResourceHelpers
9
+ mattr_accessor :skip_warn
10
+
11
+ def self.included(base) #:nodoc:
12
+ base.class_option :force_plural, :type => :boolean, :desc => "Forces the use of a plural ModelName"
13
+ end
14
+
15
+ # Set controller variables on initialization.
16
+ #
17
+ def initialize(*args) #:nodoc:
18
+ super
19
+
20
+ if name == name.pluralize && !options[:force_plural]
21
+ unless ResourceHelpers.skip_warn
22
+ say "Plural version of the model detected, using singularized version. Override with --force-plural."
23
+ ResourceHelpers.skip_warn = true
24
+ end
25
+ name.replace name.singularize
26
+ assign_names!(name)
27
+ end
28
+
29
+ @controller_name = name.pluralize
30
+ end
31
+
32
+ protected
33
+
34
+ attr_reader :controller_name
35
+
36
+ def controller_class_path
37
+ @class_path
38
+ end
39
+
40
+ def controller_file_name
41
+ @controller_file_name ||= file_name.pluralize
42
+ end
43
+
44
+ def controller_file_path
45
+ @controller_file_path ||= (controller_class_path + [controller_file_name]).join('/')
46
+ end
47
+
48
+ def controller_class_name
49
+ @controller_class_name ||= (controller_class_path + [controller_file_name]).map!{ |m| m.camelize }.join('::')
50
+ end
51
+
52
+ def controller_i18n_scope
53
+ @controller_i18n_scope ||= controller_file_path.gsub('/', '.')
54
+ end
55
+
56
+ # Loads the ORM::Generators::ActiveModel class. This class is responsable
57
+ # to tell scaffold entities how to generate an specific method for the
58
+ # ORM. Check Rails::Generators::ActiveModel for more information.
59
+ def orm_class
60
+ @orm_class ||= begin
61
+ # Raise an error if the class_option :orm was not defined.
62
+ unless self.class.class_options[:orm]
63
+ raise "You need to have :orm as class option to invoke orm_class and orm_instance"
64
+ end
65
+
66
+ begin
67
+ "#{options[:orm].to_s.classify}::Generators::ActiveModel".constantize
68
+ rescue NameError => e
69
+ Rails::Generators::ActiveModel
70
+ end
71
+ end
72
+ end
73
+
74
+ # Initialize ORM::Generators::ActiveModel to access instance methods.
75
+ def orm_instance(name=file_name)
76
+ @orm_instance ||= @orm_class.new(name)
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,239 @@
1
+ require 'active_support/core_ext/class/attribute'
2
+ require 'active_support/core_ext/module/delegation'
3
+ require 'active_support/core_ext/hash/reverse_merge'
4
+ require 'rails/generators'
5
+ require 'fileutils'
6
+
7
+ module Rails
8
+ module Generators
9
+ # Disable color in output. Easier to debug.
10
+ no_color!
11
+
12
+ # This class provides a TestCase for testing generators. To setup, you need
13
+ # just to configure the destination and set which generator is being tested:
14
+ #
15
+ # class AppGeneratorTest < Rails::Generators::TestCase
16
+ # tests AppGenerator
17
+ # destination File.expand_path("../tmp", File.dirname(__FILE__))
18
+ # end
19
+ #
20
+ # If you want to ensure your destination root is clean before running each test,
21
+ # you can set a setup callback:
22
+ #
23
+ # class AppGeneratorTest < Rails::Generators::TestCase
24
+ # tests AppGenerator
25
+ # destination File.expand_path("../tmp", File.dirname(__FILE__))
26
+ # setup :prepare_destination
27
+ # end
28
+ #
29
+ class TestCase < ActiveSupport::TestCase
30
+ include FileUtils
31
+
32
+ class_attribute :destination_root, :current_path, :generator_class, :default_arguments
33
+ delegate :destination_root, :current_path, :generator_class, :default_arguments, :to => :'self.class'
34
+
35
+ # Generators frequently change the current path using +FileUtils.cd+.
36
+ # So we need to store the path at file load and revert back to it after each test.
37
+ self.current_path = File.expand_path(Dir.pwd)
38
+ self.default_arguments = []
39
+
40
+ setup :destination_root_is_set?, :ensure_current_path
41
+ teardown :ensure_current_path
42
+
43
+ # Sets which generator should be tested:
44
+ #
45
+ # tests AppGenerator
46
+ #
47
+ def self.tests(klass)
48
+ self.generator_class = klass
49
+ end
50
+
51
+ # Sets default arguments on generator invocation. This can be overwritten when
52
+ # invoking it.
53
+ #
54
+ # arguments %w(app_name --skip-activerecord)
55
+ #
56
+ def self.arguments(array)
57
+ self.default_arguments = array
58
+ end
59
+
60
+ # Sets the destination of generator files:
61
+ #
62
+ # destination File.expand_path("../tmp", File.dirname(__FILE__))
63
+ #
64
+ def self.destination(path)
65
+ self.destination_root = path
66
+ end
67
+
68
+ # Captures the given stream and returns it:
69
+ #
70
+ # stream = capture(:stdout){ puts "Cool" }
71
+ # stream #=> "Cool\n"
72
+ #
73
+ def capture(stream)
74
+ begin
75
+ stream = stream.to_s
76
+ eval "$#{stream} = StringIO.new"
77
+ yield
78
+ result = eval("$#{stream}").string
79
+ ensure
80
+ eval("$#{stream} = #{stream.upcase}")
81
+ end
82
+
83
+ result
84
+ end
85
+ alias :silence :capture
86
+
87
+ # Asserts a given file exists. You need to supply an absolute path or a path relative
88
+ # to the configured destination:
89
+ #
90
+ # assert_file "config/environment.rb"
91
+ #
92
+ # You can also give extra arguments. If the argument is a regexp, it will check if the
93
+ # regular expression matches the given file content. If it's a string, it compares the
94
+ # file with the given string:
95
+ #
96
+ # assert_file "config/environment.rb", /initialize/
97
+ #
98
+ # Finally, when a block is given, it yields the file content:
99
+ #
100
+ # assert_file "app/controller/products_controller.rb" do |controller|
101
+ # assert_instance_method :index, content do |index|
102
+ # assert_match /Product\.all/, index
103
+ # end
104
+ # end
105
+ #
106
+ def assert_file(relative, *contents)
107
+ absolute = File.expand_path(relative, destination_root)
108
+ assert File.exists?(absolute), "Expected file #{relative.inspect} to exist, but does not"
109
+
110
+ read = File.read(absolute) if block_given? || !contents.empty?
111
+ yield read if block_given?
112
+
113
+ contents.each do |content|
114
+ case content
115
+ when String
116
+ assert_equal content, read
117
+ when Regexp
118
+ assert_match content, read
119
+ end
120
+ end
121
+ end
122
+ alias :assert_directory :assert_file
123
+
124
+ # Asserts a given file does not exist. You need to supply an absolute path or a
125
+ # path relative to the configured destination:
126
+ #
127
+ # assert_no_file "config/random.rb"
128
+ #
129
+ def assert_no_file(relative)
130
+ absolute = File.expand_path(relative, destination_root)
131
+ assert !File.exists?(absolute), "Expected file #{relative.inspect} to not exist, but does"
132
+ end
133
+ alias :assert_no_directory :assert_no_file
134
+
135
+ # Asserts a given file does not exist. You need to supply an absolute path or a
136
+ # path relative to the configured destination:
137
+ #
138
+ # assert_migration "db/migrate/create_products.rb"
139
+ #
140
+ # This method manipulates the given path and tries to find any migration which
141
+ # matches the migration name. For example, the call above is converted to:
142
+ #
143
+ # assert_file "db/migrate/003_create_products.rb"
144
+ #
145
+ # Consequently, assert_migration accepts the same arguments has assert_file.
146
+ #
147
+ def assert_migration(relative, *contents, &block)
148
+ file_name = migration_file_name(relative)
149
+ assert file_name, "Expected migration #{relative} to exist, but was not found"
150
+ assert_file file_name, *contents, &block
151
+ end
152
+
153
+ # Asserts a given migration does not exist. You need to supply an absolute path or a
154
+ # path relative to the configured destination:
155
+ #
156
+ # assert_no_file "config/random.rb"
157
+ #
158
+ def assert_no_migration(relative)
159
+ file_name = migration_file_name(relative)
160
+ assert_nil file_name, "Expected migration #{relative} to not exist, but found #{file_name}"
161
+ end
162
+
163
+ # Asserts the given class method exists in the given content. This method does not detect
164
+ # class methods inside (class << self), only class methods which starts with "self.".
165
+ # When a block is given, it yields the content of the method.
166
+ #
167
+ # assert_migration "db/migrate/create_products.rb" do |migration|
168
+ # assert_class_method :up, migration do |up|
169
+ # assert_match /create_table/, up
170
+ # end
171
+ # end
172
+ #
173
+ def assert_class_method(method, content, &block)
174
+ assert_instance_method "self.#{method}", content, &block
175
+ end
176
+
177
+ # Asserts the given method exists in the given content. When a block is given,
178
+ # it yields the content of the method.
179
+ #
180
+ # assert_file "app/controller/products_controller.rb" do |controller|
181
+ # assert_instance_method :index, content do |index|
182
+ # assert_match /Product\.all/, index
183
+ # end
184
+ # end
185
+ #
186
+ def assert_instance_method(method, content)
187
+ assert content =~ /def #{method}(\(.+\))?(.*?)\n end/m, "Expected to have method #{method}"
188
+ yield $2.strip if block_given?
189
+ end
190
+ alias :assert_method :assert_instance_method
191
+
192
+ # Runs the generator configured for this class. The first argument is an array like
193
+ # command line arguments:
194
+ #
195
+ # class AppGeneratorTest < Rails::Generators::TestCase
196
+ # tests AppGenerator
197
+ # destination File.expand_path("../tmp", File.dirname(__FILE__))
198
+ # teardown :cleanup_destination_root
199
+ #
200
+ # test "database.yml is not created when skipping activerecord" do
201
+ # run_generator %w(myapp --skip-activerecord)
202
+ # assert_no_file "config/database.yml"
203
+ # end
204
+ # end
205
+ #
206
+ # You can provide a configuration hash as second argument. This method returns the output
207
+ # printed by the generator.
208
+ def run_generator(args=self.default_arguments, config={})
209
+ capture(:stdout) { self.generator_class.start(args, config.reverse_merge(:destination_root => destination_root)) }
210
+ end
211
+
212
+ # Instantiate the generator.
213
+ def generator(args=self.default_arguments, options={}, config={})
214
+ @generator ||= self.generator_class.new(args, options, config.reverse_merge(:destination_root => destination_root))
215
+ end
216
+
217
+ protected
218
+
219
+ def destination_root_is_set? #:nodoc:
220
+ raise "You need to configure your Rails::Generators::TestCase destination root." unless destination_root
221
+ end
222
+
223
+ def ensure_current_path #:nodoc:
224
+ cd current_path
225
+ end
226
+
227
+ def prepare_destination
228
+ rm_rf(destination_root)
229
+ mkdir_p(destination_root)
230
+ end
231
+
232
+ def migration_file_name(relative) #:nodoc:
233
+ absolute = File.expand_path(relative, destination_root)
234
+ dirname, file_name = File.dirname(absolute), File.basename(absolute).sub(/\.rb$/, '')
235
+ Dir.glob("#{dirname}/[0-9]*_*.rb").grep(/\d+_#{file_name}.rb$/).first
236
+ end
237
+ end
238
+ end
239
+ end