rails 1.0.0 → 2.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 (177) hide show
  1. data/CHANGELOG +1020 -10
  2. data/MIT-LICENSE +1 -1
  3. data/README +110 -60
  4. data/Rakefile +74 -139
  5. data/bin/about +1 -1
  6. data/bin/console +1 -1
  7. data/bin/destroy +1 -1
  8. data/bin/generate +1 -1
  9. data/bin/performance/request +3 -0
  10. data/bin/plugin +1 -1
  11. data/bin/process/{spinner → inspector} +1 -1
  12. data/bin/rails +10 -12
  13. data/bin/runner +1 -1
  14. data/bin/server +1 -1
  15. data/{lib/rails_info.rb → builtin/rails_info/rails/info.rb} +33 -14
  16. data/builtin/rails_info/rails/info_controller.rb +9 -0
  17. data/builtin/rails_info/rails/info_helper.rb +2 -0
  18. data/builtin/rails_info/rails_info_controller.rb +2 -0
  19. data/configs/apache.conf +1 -1
  20. data/configs/databases/frontbase.yml +28 -0
  21. data/configs/databases/mysql.yml +54 -0
  22. data/configs/databases/oracle.yml +39 -0
  23. data/configs/databases/postgresql.yml +48 -0
  24. data/configs/databases/sqlite2.yml +16 -0
  25. data/configs/databases/sqlite3.yml +19 -0
  26. data/configs/initializers/inflections.rb +10 -0
  27. data/configs/initializers/mime_types.rb +5 -0
  28. data/configs/lighttpd.conf +29 -15
  29. data/configs/routes.rb +27 -11
  30. data/doc/README_FOR_APP +1 -1
  31. data/environments/boot.rb +103 -14
  32. data/environments/development.rb +5 -6
  33. data/environments/environment.rb +36 -30
  34. data/environments/production.rb +2 -3
  35. data/environments/test.rb +5 -2
  36. data/fresh_rakefile +2 -2
  37. data/helpers/application.rb +8 -2
  38. data/helpers/test_helper.rb +10 -0
  39. data/html/404.html +27 -5
  40. data/html/422.html +30 -0
  41. data/html/500.html +27 -5
  42. data/html/index.html +6 -6
  43. data/html/javascripts/application.js +2 -0
  44. data/html/javascripts/controls.js +532 -319
  45. data/html/javascripts/dragdrop.js +521 -133
  46. data/html/javascripts/effects.js +708 -442
  47. data/html/javascripts/prototype.js +3393 -953
  48. data/html/robots.txt +5 -1
  49. data/lib/code_statistics.rb +2 -2
  50. data/lib/commands/console.rb +18 -9
  51. data/lib/commands/performance/profiler.rb +25 -9
  52. data/lib/commands/performance/request.rb +6 -0
  53. data/lib/commands/plugin.rb +196 -96
  54. data/lib/commands/process/inspector.rb +68 -0
  55. data/lib/commands/process/reaper.rb +90 -71
  56. data/lib/commands/process/spawner.rb +188 -21
  57. data/lib/commands/process/spinner.rb +3 -3
  58. data/lib/commands/runner.rb +28 -7
  59. data/lib/commands/server.rb +20 -9
  60. data/lib/commands/servers/base.rb +31 -0
  61. data/lib/commands/servers/lighttpd.rb +60 -26
  62. data/lib/commands/servers/mongrel.rb +69 -0
  63. data/lib/commands/servers/webrick.rb +18 -11
  64. data/lib/console_app.rb +30 -0
  65. data/lib/console_sandbox.rb +2 -2
  66. data/lib/console_with_helpers.rb +26 -0
  67. data/lib/dispatcher.rb +3 -78
  68. data/lib/fcgi_handler.rb +98 -64
  69. data/lib/initializer.rb +323 -194
  70. data/lib/rails/plugin/loader.rb +150 -0
  71. data/lib/rails/plugin/locator.rb +78 -0
  72. data/lib/rails/plugin.rb +84 -0
  73. data/lib/{rails_version.rb → rails/version.rb} +1 -1
  74. data/lib/rails_generator/base.rb +85 -25
  75. data/lib/rails_generator/commands.rb +122 -40
  76. data/lib/rails_generator/generated_attribute.rb +42 -0
  77. data/lib/rails_generator/generators/applications/app/USAGE +0 -7
  78. data/lib/rails_generator/generators/applications/app/app_generator.rb +67 -28
  79. data/lib/rails_generator/generators/components/controller/USAGE +11 -12
  80. data/lib/rails_generator/generators/components/controller/controller_generator.rb +2 -3
  81. data/lib/rails_generator/generators/components/controller/templates/functional_test.rb +1 -11
  82. data/lib/rails_generator/generators/components/controller/templates/{view.rhtml → view.html.erb} +0 -0
  83. data/lib/rails_generator/generators/components/integration_test/USAGE +8 -0
  84. data/lib/rails_generator/generators/components/integration_test/integration_test_generator.rb +16 -0
  85. data/lib/rails_generator/generators/components/integration_test/templates/integration_test.rb +10 -0
  86. data/lib/rails_generator/generators/components/mailer/USAGE +9 -11
  87. data/lib/rails_generator/generators/components/mailer/mailer_generator.rb +10 -8
  88. data/lib/rails_generator/generators/components/mailer/templates/fixture.erb +3 -0
  89. data/lib/rails_generator/generators/components/mailer/templates/fixture.rhtml +0 -3
  90. data/lib/rails_generator/generators/components/mailer/templates/unit_test.rb +9 -25
  91. data/lib/rails_generator/generators/components/mailer/templates/view.erb +3 -0
  92. data/lib/rails_generator/generators/components/mailer/templates/view.rhtml +0 -3
  93. data/lib/rails_generator/generators/components/migration/USAGE +23 -8
  94. data/lib/rails_generator/generators/components/migration/migration_generator.rb +15 -2
  95. data/lib/rails_generator/generators/components/migration/templates/migration.rb +7 -3
  96. data/lib/rails_generator/generators/components/model/USAGE +21 -11
  97. data/lib/rails_generator/generators/components/model/model_generator.rb +28 -1
  98. data/lib/rails_generator/generators/components/model/templates/fixtures.yml +18 -4
  99. data/lib/rails_generator/generators/components/model/templates/migration.rb +16 -0
  100. data/lib/rails_generator/generators/components/model/templates/unit_test.rb +2 -4
  101. data/lib/rails_generator/generators/components/observer/USAGE +13 -0
  102. data/lib/rails_generator/generators/components/observer/observer_generator.rb +16 -0
  103. data/lib/rails_generator/generators/components/observer/templates/observer.rb +2 -0
  104. data/lib/rails_generator/generators/components/observer/templates/unit_test.rb +8 -0
  105. data/lib/rails_generator/generators/components/plugin/USAGE +10 -18
  106. data/lib/rails_generator/generators/components/plugin/plugin_generator.rb +6 -0
  107. data/lib/rails_generator/generators/components/plugin/templates/MIT-LICENSE +20 -0
  108. data/lib/rails_generator/generators/components/plugin/templates/README +10 -1
  109. data/lib/rails_generator/generators/components/plugin/templates/Rakefile +1 -1
  110. data/lib/rails_generator/generators/components/plugin/templates/USAGE +1 -1
  111. data/lib/rails_generator/generators/components/plugin/templates/init.rb +1 -1
  112. data/lib/rails_generator/generators/components/plugin/templates/install.rb +1 -0
  113. data/lib/rails_generator/generators/components/plugin/templates/plugin.rb +1 -1
  114. data/lib/rails_generator/generators/components/plugin/templates/tasks.rake +1 -1
  115. data/lib/rails_generator/generators/components/plugin/templates/uninstall.rb +1 -0
  116. data/lib/rails_generator/generators/components/resource/USAGE +23 -0
  117. data/lib/rails_generator/generators/components/resource/resource_generator.rb +74 -0
  118. data/lib/rails_generator/generators/components/resource/templates/controller.rb +2 -0
  119. data/lib/rails_generator/generators/components/resource/templates/functional_test.rb +8 -0
  120. data/lib/rails_generator/generators/components/resource/templates/helper.rb +2 -0
  121. data/lib/rails_generator/generators/components/scaffold/USAGE +24 -31
  122. data/lib/rails_generator/generators/components/scaffold/scaffold_generator.rb +45 -137
  123. data/lib/rails_generator/generators/components/scaffold/templates/controller.rb +65 -34
  124. data/lib/rails_generator/generators/components/scaffold/templates/functional_test.rb +23 -76
  125. data/lib/rails_generator/generators/components/scaffold/templates/layout.html.erb +17 -0
  126. data/lib/rails_generator/generators/components/scaffold/templates/style.css +5 -5
  127. data/lib/rails_generator/generators/components/scaffold/templates/view_edit.html.erb +19 -0
  128. data/lib/rails_generator/generators/components/scaffold/templates/view_index.html.erb +24 -0
  129. data/lib/rails_generator/generators/components/scaffold/templates/view_new.html.erb +18 -0
  130. data/lib/rails_generator/generators/components/scaffold/templates/view_show.html.erb +10 -0
  131. data/lib/rails_generator/generators/components/session_migration/USAGE +6 -11
  132. data/lib/rails_generator/generators/components/session_migration/session_migration_generator.rb +7 -1
  133. data/lib/rails_generator/generators/components/session_migration/templates/migration.rb +8 -7
  134. data/lib/rails_generator/lookup.rb +46 -12
  135. data/lib/rails_generator/options.rb +11 -8
  136. data/lib/rails_generator/scripts/destroy.rb +23 -0
  137. data/lib/rails_generator/scripts.rb +7 -4
  138. data/lib/rails_generator/secret_key_generator.rb +160 -0
  139. data/lib/rails_generator/spec.rb +1 -1
  140. data/lib/rails_generator.rb +1 -1
  141. data/lib/railties_path.rb +1 -1
  142. data/lib/ruby_version_check.rb +17 -0
  143. data/lib/source_annotation_extractor.rb +62 -0
  144. data/lib/tasks/annotations.rake +23 -0
  145. data/lib/tasks/databases.rake +328 -133
  146. data/lib/tasks/documentation.rake +72 -68
  147. data/lib/tasks/framework.rake +99 -58
  148. data/lib/tasks/log.rake +9 -0
  149. data/lib/tasks/misc.rake +2 -17
  150. data/lib/tasks/rails.rb +2 -2
  151. data/lib/tasks/routes.rake +17 -0
  152. data/lib/tasks/statistics.rake +10 -8
  153. data/lib/tasks/testing.rake +99 -31
  154. data/lib/tasks/tmp.rake +37 -0
  155. data/lib/test_help.rb +8 -5
  156. data/lib/webrick_server.rb +11 -16
  157. metadata +312 -272
  158. data/bin/breakpointer +0 -3
  159. data/builtin/controllers/rails_info_controller.rb +0 -11
  160. data/configs/database.yml +0 -85
  161. data/lib/binding_of_caller.rb +0 -85
  162. data/lib/breakpoint.rb +0 -523
  163. data/lib/breakpoint_client.rb +0 -196
  164. data/lib/commands/breakpointer.rb +0 -1
  165. data/lib/rails_generator/generators/components/scaffold/templates/form.rhtml +0 -3
  166. data/lib/rails_generator/generators/components/scaffold/templates/form_scaffolding.rhtml +0 -1
  167. data/lib/rails_generator/generators/components/scaffold/templates/layout.rhtml +0 -13
  168. data/lib/rails_generator/generators/components/scaffold/templates/view_edit.rhtml +0 -9
  169. data/lib/rails_generator/generators/components/scaffold/templates/view_list.rhtml +0 -27
  170. data/lib/rails_generator/generators/components/scaffold/templates/view_new.rhtml +0 -8
  171. data/lib/rails_generator/generators/components/scaffold/templates/view_show.rhtml +0 -8
  172. data/lib/rails_generator/generators/components/web_service/USAGE +0 -28
  173. data/lib/rails_generator/generators/components/web_service/templates/api_definition.rb +0 -5
  174. data/lib/rails_generator/generators/components/web_service/templates/controller.rb +0 -8
  175. data/lib/rails_generator/generators/components/web_service/templates/functional_test.rb +0 -19
  176. data/lib/rails_generator/generators/components/web_service/web_service_generator.rb +0 -29
  177. data/lib/tasks/javascripts.rake +0 -6
@@ -0,0 +1,10 @@
1
+ <% for attribute in attributes -%>
2
+ <p>
3
+ <b><%= attribute.column.human_name %>:</b>
4
+ <%%=h @<%= singular_name %>.<%= attribute.name %> %>
5
+ </p>
6
+
7
+ <% end -%>
8
+
9
+ <%%= link_to 'Edit', edit_<%= singular_name %>_path(@<%= singular_name %>) %> |
10
+ <%%= link_to 'Back', <%= plural_name %>_path %>
@@ -1,15 +1,10 @@
1
1
  Description:
2
- The session table migration generator creates a migration for adding a session table
3
- used by CGI::Session::ActiveRecordStore.
4
-
5
- The generator takes a migration name as its argument. The migration name may be
6
- given in CamelCase or under_score.
7
-
8
- The generator creates a migration class in db/migrate prefixed by its number
9
- in the queue.
2
+ Creates a migration to add the sessions table used by the Active Record
3
+ session store. Pass the migration name, either CamelCased or under_scored,
4
+ as an argument.
10
5
 
11
6
  Example:
12
- ./script/generate session_migration AddSessionTable
7
+ `./script/generate session_migration CreateSessionTable`
13
8
 
14
- With 4 existing migrations, this will create an AddSessionTable migration in the
15
- file db/migrate/5_add_session_table.rb
9
+ With 4 existing migrations, this creates the AddSessionTable migration
10
+ in db/migrate/005_add_session_table.rb
@@ -6,7 +6,13 @@ class SessionMigrationGenerator < Rails::Generator::NamedBase
6
6
 
7
7
  def manifest
8
8
  record do |m|
9
- m.migration_template 'migration.rb', 'db/migrate'
9
+ m.migration_template 'migration.rb', 'db/migrate',
10
+ :assigns => { :session_table_name => default_session_table_name }
10
11
  end
11
12
  end
13
+
14
+ protected
15
+ def default_session_table_name
16
+ ActiveRecord::Base.pluralize_table_names ? 'session'.pluralize : 'session'
17
+ end
12
18
  end
@@ -1,15 +1,16 @@
1
1
  class <%= class_name %> < ActiveRecord::Migration
2
2
  def self.up
3
- create_table :sessions do |t|
4
- t.column :session_id, :string
5
- t.column :data, :text
6
- t.column :updated_at, :datetime
3
+ create_table :<%= session_table_name %> do |t|
4
+ t.string :session_id, :null => false
5
+ t.text :data
6
+ t.timestamps
7
7
  end
8
-
9
- add_index :sessions, :session_id
8
+
9
+ add_index :<%= session_table_name %>, :session_id
10
+ add_index :<%= session_table_name %>, :updated_at
10
11
  end
11
12
 
12
13
  def self.down
13
- drop_table :sessions
14
+ drop_table :<%= session_table_name %>
14
15
  end
15
16
  end
@@ -46,10 +46,9 @@ module Rails
46
46
  #
47
47
  # A spec is not a generator: it's a description of where to find
48
48
  # the generator and how to create it. A source is anything that
49
- # yields generators from #each. PathSource and GemSource are provided.
49
+ # yields generators from #each. PathSource and GemGeneratorSource are provided.
50
50
  module Lookup
51
- def self.append_features(base)
52
- super
51
+ def self.included(base)
53
52
  base.extend(ClassMethods)
54
53
  base.use_component_sources!
55
54
  end
@@ -93,18 +92,26 @@ module Rails
93
92
  # 1. Rails application. If RAILS_ROOT is defined we know we're
94
93
  # generating in the context of a Rails application, so search
95
94
  # RAILS_ROOT/generators.
96
- # 2. User home directory. Search ~/.rails/generators.
97
- # 3. RubyGems. Search for gems named *_generator.
98
- # 4. Builtins. Model, controller, mailer, scaffold.
95
+ # 2. Look in plugins, either for generators/ or rails_generators/
96
+ # directories within each plugin
97
+ # 3. User home directory. Search ~/.rails/generators.
98
+ # 4. RubyGems. Search for gems named *_generator, and look for
99
+ # generators within any RubyGem's
100
+ # /rails_generators/<generator_name>_generator.rb file.
101
+ # 5. Builtins. Model, controller, mailer, scaffold, and so on.
99
102
  def use_component_sources!
100
103
  reset_sources
101
104
  if defined? ::RAILS_ROOT
102
105
  sources << PathSource.new(:lib, "#{::RAILS_ROOT}/lib/generators")
103
106
  sources << PathSource.new(:vendor, "#{::RAILS_ROOT}/vendor/generators")
104
- sources << PathSource.new(:plugins, "#{::RAILS_ROOT}/vendor/plugins/**/generators")
107
+ sources << PathSource.new(:plugins, "#{::RAILS_ROOT}/vendor/plugins/*/**/generators")
108
+ sources << PathSource.new(:plugins, "#{::RAILS_ROOT}/vendor/plugins/*/**/rails_generators")
105
109
  end
106
110
  sources << PathSource.new(:user, "#{Dir.user_home}/.rails/generators")
107
- sources << GemSource.new if Object.const_defined?(:Gem)
111
+ if Object.const_defined?(:Gem)
112
+ sources << GemGeneratorSource.new
113
+ sources << GemPathSource.new
114
+ end
108
115
  sources << PathSource.new(:builtin, "#{File.dirname(__FILE__)}/generators/components")
109
116
  end
110
117
 
@@ -186,14 +193,15 @@ module Rails
186
193
  end
187
194
  end
188
195
 
189
-
190
- # GemSource hits the mines to quarry for generators. The latest versions
191
- # of gems named *_generator are selected.
192
- class GemSource < Source
196
+ class AbstractGemSource < Source
193
197
  def initialize
194
198
  super :RubyGems
195
199
  end
200
+ end
196
201
 
202
+ # GemGeneratorSource hits the mines to quarry for generators. The latest versions
203
+ # of gems named *_generator are selected.
204
+ class GemGeneratorSource < AbstractGemSource
197
205
  # Yield latest versions of generator gems.
198
206
  def each
199
207
  Gem::cache.search(/_generator$/).inject({}) { |latest, gem|
@@ -206,5 +214,31 @@ module Rails
206
214
  end
207
215
  end
208
216
 
217
+ # GemPathSource looks for generators within any RubyGem's /rails_generators/<generator_name>_generator.rb file.
218
+ class GemPathSource < AbstractGemSource
219
+ # Yield each generator within rails_generator subdirectories.
220
+ def each
221
+ generator_full_paths.each do |generator|
222
+ yield Spec.new(File.basename(generator).sub(/_generator.rb$/, ''), File.dirname(generator), label)
223
+ end
224
+ end
225
+
226
+ private
227
+ def generator_full_paths
228
+ @generator_full_paths ||=
229
+ Gem::cache.inject({}) do |latest, name_gem|
230
+ name, gem = name_gem
231
+ hem = latest[gem.name]
232
+ latest[gem.name] = gem if hem.nil? or gem.version > hem.version
233
+ latest
234
+ end.values.inject([]) do |mem, gem|
235
+ Dir[gem.full_gem_path + '/{rails_,}generators/**/*_generator.rb'].each do |generator|
236
+ mem << generator
237
+ end
238
+ mem
239
+ end
240
+ end
241
+ end
242
+
209
243
  end
210
244
  end
@@ -3,8 +3,7 @@ require 'optparse'
3
3
  module Rails
4
4
  module Generator
5
5
  module Options
6
- def self.append_features(base)
7
- super
6
+ def self.included(base)
8
7
  base.extend(ClassMethods)
9
8
  class << base
10
9
  if respond_to?(:inherited)
@@ -96,8 +95,8 @@ module Rails
96
95
 
97
96
  # Raise a usage error. Override usage_message to provide a blurb
98
97
  # after the option parser summary.
99
- def usage
100
- raise UsageError, "#{@option_parser}\n#{usage_message}"
98
+ def usage(message = usage_message)
99
+ raise UsageError, "#{@option_parser}\n#{message}"
101
100
  end
102
101
 
103
102
  def usage_message
@@ -118,15 +117,19 @@ module Rails
118
117
 
119
118
  # Adds general options like -h and --quiet. Usually don't override.
120
119
  def add_general_options!(opt)
120
+ opt.separator ''
121
+ opt.separator 'Rails Info:'
122
+ opt.on('-v', '--version', 'Show the Rails version number and quit.')
123
+ opt.on('-h', '--help', 'Show this help message and quit.') { |v| options[:help] = v }
124
+
121
125
  opt.separator ''
122
126
  opt.separator 'General Options:'
123
127
 
124
- opt.on('-p', '--pretend', 'Run but do not make any changes.') { |options[:pretend]| }
128
+ opt.on('-p', '--pretend', 'Run but do not make any changes.') { |v| options[:pretend] = v }
125
129
  opt.on('-f', '--force', 'Overwrite files that already exist.') { options[:collision] = :force }
126
130
  opt.on('-s', '--skip', 'Skip files that already exist.') { options[:collision] = :skip }
127
- opt.on('-q', '--quiet', 'Suppress normal output.') { |options[:quiet]| }
128
- opt.on('-t', '--backtrace', 'Debugging: show backtrace on errors.') { |options[:backtrace]| }
129
- opt.on('-h', '--help', 'Show this help message.') { |options[:help]| }
131
+ opt.on('-q', '--quiet', 'Suppress normal output.') { |v| options[:quiet] = v }
132
+ opt.on('-t', '--backtrace', 'Debugging: show backtrace on errors.') { |v| options[:backtrace] = v }
130
133
  opt.on('-c', '--svn', 'Modify files with subversion. (Note: svn must be in path)') do
131
134
  options[:svn] = `svn status`.inject({}) do |opt, e|
132
135
  opt[e.chomp[7..-1]] = true
@@ -3,5 +3,28 @@ require File.dirname(__FILE__) + '/../scripts'
3
3
  module Rails::Generator::Scripts
4
4
  class Destroy < Base
5
5
  mandatory_options :command => :destroy
6
+
7
+ protected
8
+ def usage_message
9
+ usage = "\nInstalled Generators\n"
10
+ Rails::Generator::Base.sources.each do |source|
11
+ label = source.label.to_s.capitalize
12
+ names = source.names
13
+ usage << " #{label}: #{names.join(', ')}\n" unless names.empty?
14
+ end
15
+
16
+ usage << <<end_blurb
17
+
18
+ This script will destroy all files created by the corresponding
19
+ script/generate command. For instance, script/destroy migration CreatePost
20
+ will delete the appropriate ###_create_post.rb file in db/migrate, while
21
+ script/destroy scaffold Post will delete the posts controller and
22
+ views, post model and migration, all associated tests, and the map.resources
23
+ :posts line in config/routes.rb.
24
+
25
+ For instructions on finding new generators, run script/generate
26
+ end_blurb
27
+ return usage
28
+ end
6
29
  end
7
30
  end
@@ -38,14 +38,17 @@ module Rails
38
38
  protected
39
39
  # Override with your own script usage banner.
40
40
  def banner
41
- "Usage: #{$0} [options] generator [args]"
41
+ "Usage: #{$0} generator [options] [args]"
42
42
  end
43
43
 
44
44
  def usage_message
45
45
  usage = "\nInstalled Generators\n"
46
- Rails::Generator::Base.sources.each do |source|
46
+ Rails::Generator::Base.sources.inject({}) do |mem, source|
47
47
  label = source.label.to_s.capitalize
48
- names = source.names
48
+ mem[label] ||= []
49
+ mem[label] |= source.names
50
+ mem
51
+ end.each_pair do |label, names|
49
52
  usage << " #{label}: #{names.join(', ')}\n" unless names.empty?
50
53
  end
51
54
 
@@ -59,7 +62,7 @@ end_blurb
59
62
 
60
63
  if Object.const_defined?(:RAILS_ROOT)
61
64
  usage << <<end_blurb
62
- or to #{File.expand_path(RAILS_ROOT)}/generators/login
65
+ or to #{File.expand_path(RAILS_ROOT)}/lib/generators/login
63
66
  to use with this app only.
64
67
  end_blurb
65
68
  end
@@ -0,0 +1,160 @@
1
+ # A class for creating random secret keys. This class will do its best to create a
2
+ # random secret key that's as secure as possible, using whatever methods are
3
+ # available on the current platform. For example:
4
+ #
5
+ # generator = Rails::SecretKeyGenerator("some unique identifier, such as the application name")
6
+ # generator.generate_secret # => "f3f1be90053fa851... (some long string)"
7
+
8
+ module Rails
9
+ class SecretKeyGenerator
10
+ GENERATORS = [ :secure_random, :win32_api, :urandom, :openssl, :prng ].freeze
11
+
12
+ def initialize(identifier)
13
+ @identifier = identifier
14
+ end
15
+
16
+ # Generate a random secret key with the best possible method available on
17
+ # the current platform.
18
+ def generate_secret
19
+ generator = GENERATORS.find do |g|
20
+ self.class.send("supports_#{g}?")
21
+ end
22
+ send("generate_secret_with_#{generator}")
23
+ end
24
+
25
+ # Generate a random secret key by using the Win32 API. Raises LoadError
26
+ # if the current platform cannot make use of the Win32 API. Raises
27
+ # SystemCallError if some other error occured.
28
+ def generate_secret_with_win32_api
29
+ # Following code is based on David Garamond's GUID library for Ruby.
30
+ require 'Win32API'
31
+
32
+ crypt_acquire_context = Win32API.new("advapi32", "CryptAcquireContext",
33
+ 'PPPII', 'L')
34
+ crypt_gen_random = Win32API.new("advapi32", "CryptGenRandom",
35
+ 'LIP', 'L')
36
+ crypt_release_context = Win32API.new("advapi32", "CryptReleaseContext",
37
+ 'LI', 'L')
38
+ prov_rsa_full = 1
39
+ crypt_verifycontext = 0xF0000000
40
+
41
+ hProvStr = " " * 4
42
+ if crypt_acquire_context.call(hProvStr, nil, nil, prov_rsa_full,
43
+ crypt_verifycontext) == 0
44
+ raise SystemCallError, "CryptAcquireContext failed: #{lastWin32ErrorMessage}"
45
+ end
46
+ hProv, = hProvStr.unpack('L')
47
+ bytes = " " * 64
48
+ if crypt_gen_random.call(hProv, bytes.size, bytes) == 0
49
+ raise SystemCallError, "CryptGenRandom failed: #{lastWin32ErrorMessage}"
50
+ end
51
+ if crypt_release_context.call(hProv, 0) == 0
52
+ raise SystemCallError, "CryptReleaseContext failed: #{lastWin32ErrorMessage}"
53
+ end
54
+ bytes.unpack("H*")[0]
55
+ end
56
+
57
+ # Generate a random secret key with Ruby 1.9's SecureRandom module.
58
+ # Raises LoadError if the current Ruby version does not support
59
+ # SecureRandom.
60
+ def generate_secret_with_secure_random
61
+ require 'securerandom'
62
+ return SecureRandom.hex(64)
63
+ end
64
+
65
+ # Generate a random secret key with OpenSSL. If OpenSSL is not
66
+ # already loaded, then this method will attempt to load it.
67
+ # LoadError will be raised if that fails.
68
+ def generate_secret_with_openssl
69
+ require 'openssl'
70
+ if !File.exist?("/dev/urandom")
71
+ # OpenSSL transparently seeds the random number generator with
72
+ # data from /dev/urandom. On platforms where that is not
73
+ # available, such as Windows, we have to provide OpenSSL with
74
+ # our own seed. Unfortunately there's no way to provide a
75
+ # secure seed without OS support, so we'll have to do with
76
+ # rand() and Time.now.usec().
77
+ OpenSSL::Random.seed(rand(0).to_s + Time.now.usec.to_s)
78
+ end
79
+ data = OpenSSL::BN.rand(2048, -1, false).to_s
80
+ return OpenSSL::Digest::SHA512.new(data).hexdigest
81
+ end
82
+
83
+ # Generate a random secret key with /dev/urandom.
84
+ # Raises SystemCallError on failure.
85
+ def generate_secret_with_urandom
86
+ return File.read("/dev/urandom", 64).unpack("H*")[0]
87
+ end
88
+
89
+ # Generate a random secret key with Ruby's pseudo random number generator,
90
+ # as well as some environment information.
91
+ #
92
+ # This is the least cryptographically secure way to generate a secret key,
93
+ # and should be avoided whenever possible.
94
+ def generate_secret_with_prng
95
+ require 'digest/sha2'
96
+ sha = Digest::SHA2.new(512)
97
+ now = Time.now
98
+ sha << now.to_s
99
+ sha << String(now.usec)
100
+ sha << String(rand(0))
101
+ sha << String($$)
102
+ sha << @identifier
103
+ return sha.hexdigest
104
+ end
105
+
106
+ private
107
+ def lastWin32ErrorMessage
108
+ # Following code is based on David Garamond's GUID library for Ruby.
109
+ get_last_error = Win32API.new("kernel32", "GetLastError", '', 'L')
110
+ format_message = Win32API.new("kernel32", "FormatMessageA",
111
+ 'LPLLPLPPPPPPPP', 'L')
112
+ format_message_ignore_inserts = 0x00000200
113
+ format_message_from_system = 0x00001000
114
+
115
+ code = get_last_error.call
116
+ msg = "\0" * 1024
117
+ len = format_message.call(format_message_ignore_inserts +
118
+ format_message_from_system, 0,
119
+ code, 0, msg, 1024, nil, nil,
120
+ nil, nil, nil, nil, nil, nil)
121
+ msg[0, len].tr("\r", '').chomp
122
+ end
123
+
124
+ def self.supports_secure_random?
125
+ begin
126
+ require 'securerandom'
127
+ true
128
+ rescue LoadError
129
+ false
130
+ end
131
+ end
132
+
133
+ def self.supports_win32_api?
134
+ return false unless RUBY_PLATFORM =~ /(:?mswin|mingw)/
135
+ begin
136
+ require 'Win32API'
137
+ true
138
+ rescue LoadError
139
+ false
140
+ end
141
+ end
142
+
143
+ def self.supports_urandom?
144
+ File.exists?('/dev/urandom')
145
+ end
146
+
147
+ def self.supports_openssl?
148
+ begin
149
+ require 'openssl'
150
+ true
151
+ rescue LoadError
152
+ false
153
+ end
154
+ end
155
+
156
+ def self.supports_prng?
157
+ true
158
+ end
159
+ end
160
+ end
@@ -2,7 +2,7 @@ module Rails
2
2
  module Generator
3
3
  # A spec knows where a generator was found and how to instantiate it.
4
4
  # Metadata include the generator's name, its base path, and the source
5
- # which yielded it (PathSource, GemSource, etc.)
5
+ # which yielded it (PathSource, GemPathSource, etc.)
6
6
  class Spec
7
7
  attr_reader :name, :path, :source
8
8
 
@@ -28,7 +28,7 @@ begin
28
28
  require 'active_support'
29
29
  rescue LoadError
30
30
  require 'rubygems'
31
- require_gem 'activesupport'
31
+ gem 'activesupport'
32
32
  end
33
33
 
34
34
  require 'rails_generator/base'
data/lib/railties_path.rb CHANGED
@@ -1 +1 @@
1
- RAILTIES_PATH = File.expand_path(File.join(File.dirname(__FILE__), '..'))
1
+ RAILTIES_PATH = File.join(File.dirname(__FILE__), '..')
@@ -0,0 +1,17 @@
1
+ min_release = "1.8.2 (2004-12-25)"
2
+ ruby_release = "#{RUBY_VERSION} (#{RUBY_RELEASE_DATE})"
3
+ if ruby_release =~ /1\.8\.3/
4
+ abort <<-end_message
5
+
6
+ Rails does not work with Ruby version 1.8.3.
7
+ Please upgrade to version 1.8.4 or downgrade to 1.8.2.
8
+
9
+ end_message
10
+ elsif ruby_release < min_release
11
+ abort <<-end_message
12
+
13
+ Rails requires Ruby version #{min_release} or later.
14
+ You're running #{ruby_release}; please upgrade to continue.
15
+
16
+ end_message
17
+ end
@@ -0,0 +1,62 @@
1
+ class SourceAnnotationExtractor
2
+ class Annotation < Struct.new(:line, :tag, :text)
3
+ def to_s(options={})
4
+ s = "[%3d] " % line
5
+ s << "[#{tag}] " if options[:tag]
6
+ s << text
7
+ end
8
+ end
9
+
10
+ def self.enumerate(tag, options={})
11
+ extractor = new(tag)
12
+ extractor.display(extractor.find, options)
13
+ end
14
+
15
+ attr_reader :tag
16
+
17
+ def initialize(tag)
18
+ @tag = tag
19
+ end
20
+
21
+ def find(dirs=%w(app lib test))
22
+ dirs.inject({}) { |h, dir| h.update(find_in(dir)) }
23
+ end
24
+
25
+ def find_in(dir)
26
+ results = {}
27
+
28
+ Dir.glob("#{dir}/*") do |item|
29
+ next if File.basename(item)[0] == ?.
30
+
31
+ if File.directory?(item)
32
+ results.update(find_in(item))
33
+ elsif item =~ /\.(builder|(r(?:b|xml|js)))$/
34
+ results.update(extract_annotations_from(item, /#\s*(#{tag}):?\s*(.*)$/))
35
+ elsif item =~ /\.(rhtml|erb)$/
36
+ results.update(extract_annotations_from(item, /<%\s*#\s*(#{tag}):?\s*(.*?)\s*%>/))
37
+ end
38
+ end
39
+
40
+ results
41
+ end
42
+
43
+ def extract_annotations_from(file, pattern)
44
+ lineno = 0
45
+ result = File.readlines(file).inject([]) do |list, line|
46
+ lineno += 1
47
+ next list unless line =~ pattern
48
+ list << Annotation.new(lineno, $1, $2)
49
+ end
50
+ result.empty? ? {} : { file => result }
51
+ end
52
+
53
+ def display(results, options={})
54
+ results.keys.sort.each do |file|
55
+ puts "#{file}:"
56
+ results[file].each do |note|
57
+ puts " * #{note.to_s(options)}"
58
+ end
59
+ puts
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,23 @@
1
+ require 'source_annotation_extractor'
2
+
3
+ desc "Enumerate all annotations"
4
+ task :notes do
5
+ SourceAnnotationExtractor.enumerate "OPTIMIZE|FIXME|TODO", :tag => true
6
+ end
7
+
8
+ namespace :notes do
9
+ desc "Enumerate all OPTIMIZE annotations"
10
+ task :optimize do
11
+ SourceAnnotationExtractor.enumerate "OPTIMIZE"
12
+ end
13
+
14
+ desc "Enumerate all FIXME annotations"
15
+ task :fixme do
16
+ SourceAnnotationExtractor.enumerate "FIXME"
17
+ end
18
+
19
+ desc "Enumerate all TODO annotations"
20
+ task :todo do
21
+ SourceAnnotationExtractor.enumerate "TODO"
22
+ end
23
+ end