railties 7.0.8.7 → 7.1.5.1

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 (168) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +723 -215
  3. data/MIT-LICENSE +1 -1
  4. data/RDOC_MAIN.md +99 -0
  5. data/README.rdoc +4 -4
  6. data/lib/minitest/rails_plugin.rb +63 -0
  7. data/lib/rails/api/task.rb +35 -4
  8. data/lib/rails/app_updater.rb +14 -2
  9. data/lib/rails/application/bootstrap.rb +23 -4
  10. data/lib/rails/application/configuration.rb +190 -69
  11. data/lib/rails/application/default_middleware_stack.rb +8 -2
  12. data/lib/rails/application/dummy_config.rb +19 -0
  13. data/lib/rails/application/finisher.rb +43 -33
  14. data/lib/rails/application.rb +141 -33
  15. data/lib/rails/backtrace_cleaner.rb +5 -3
  16. data/lib/rails/cli.rb +5 -2
  17. data/lib/rails/command/actions.rb +10 -12
  18. data/lib/rails/command/base.rb +55 -53
  19. data/lib/rails/command/environment_argument.rb +32 -16
  20. data/lib/rails/command/helpers/editor.rb +17 -12
  21. data/lib/rails/command.rb +84 -33
  22. data/lib/rails/commands/about/about_command.rb +14 -0
  23. data/lib/rails/commands/application/application_command.rb +2 -0
  24. data/lib/rails/commands/console/console_command.rb +14 -14
  25. data/lib/rails/commands/credentials/USAGE +53 -55
  26. data/lib/rails/commands/credentials/credentials_command/diffing.rb +5 -3
  27. data/lib/rails/commands/credentials/credentials_command.rb +64 -70
  28. data/lib/rails/commands/db/system/change/change_command.rb +2 -1
  29. data/lib/rails/commands/dbconsole/dbconsole_command.rb +25 -115
  30. data/lib/rails/commands/destroy/destroy_command.rb +3 -2
  31. data/lib/rails/commands/dev/dev_command.rb +1 -6
  32. data/lib/rails/commands/encrypted/USAGE +15 -20
  33. data/lib/rails/commands/encrypted/encrypted_command.rb +46 -35
  34. data/lib/rails/commands/gem_help/USAGE +16 -0
  35. data/lib/rails/commands/gem_help/gem_help_command.rb +13 -0
  36. data/lib/rails/commands/generate/generate_command.rb +2 -2
  37. data/lib/rails/commands/help/USAGE +13 -13
  38. data/lib/rails/commands/help/help_command.rb +21 -2
  39. data/lib/rails/commands/initializers/initializers_command.rb +1 -4
  40. data/lib/rails/commands/middleware/middleware_command.rb +17 -0
  41. data/lib/rails/commands/new/new_command.rb +2 -0
  42. data/lib/rails/commands/notes/notes_command.rb +2 -1
  43. data/lib/rails/commands/plugin/plugin_command.rb +2 -0
  44. data/lib/rails/commands/rake/rake_command.rb +25 -22
  45. data/lib/rails/commands/restart/restart_command.rb +14 -0
  46. data/lib/rails/commands/routes/routes_command.rb +13 -1
  47. data/lib/rails/commands/runner/USAGE +14 -12
  48. data/lib/rails/commands/runner/runner_command.rb +32 -20
  49. data/lib/rails/commands/secret/secret_command.rb +13 -0
  50. data/lib/rails/commands/secrets/USAGE +44 -49
  51. data/lib/rails/commands/secrets/secrets_command.rb +20 -38
  52. data/lib/rails/commands/server/server_command.rb +33 -32
  53. data/lib/rails/commands/test/USAGE +14 -0
  54. data/lib/rails/commands/test/test_command.rb +56 -14
  55. data/lib/rails/commands/unused_routes/unused_routes_command.rb +75 -0
  56. data/lib/rails/commands/version/version_command.rb +1 -0
  57. data/lib/rails/configuration.rb +5 -5
  58. data/lib/rails/console/app.rb +1 -4
  59. data/lib/rails/deprecator.rb +7 -0
  60. data/lib/rails/engine/configuration.rb +50 -6
  61. data/lib/rails/engine.rb +49 -21
  62. data/lib/rails/gem_version.rb +4 -4
  63. data/lib/rails/generators/actions.rb +6 -15
  64. data/lib/rails/generators/active_model.rb +28 -14
  65. data/lib/rails/generators/app_base.rb +355 -82
  66. data/lib/rails/generators/app_name.rb +3 -14
  67. data/lib/rails/generators/base.rb +17 -9
  68. data/lib/rails/generators/database.rb +40 -2
  69. data/lib/rails/generators/erb/mailer/templates/layout.html.erb.tt +1 -1
  70. data/lib/rails/generators/generated_attribute.rb +12 -0
  71. data/lib/rails/generators/migration.rb +4 -5
  72. data/lib/rails/generators/model_helpers.rb +2 -1
  73. data/lib/rails/generators/rails/app/USAGE +22 -6
  74. data/lib/rails/generators/rails/app/app_generator.rb +85 -64
  75. data/lib/rails/generators/rails/app/templates/Dockerfile.tt +103 -0
  76. data/lib/rails/generators/rails/app/templates/Gemfile.tt +9 -11
  77. data/lib/rails/generators/rails/app/templates/app/views/layouts/mailer.html.erb.tt +1 -1
  78. data/lib/rails/generators/rails/app/templates/bin/setup.tt +10 -1
  79. data/lib/rails/generators/rails/app/templates/config/application.rb.tt +6 -17
  80. data/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml.tt +4 -4
  81. data/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml.tt +3 -3
  82. data/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml.tt +4 -6
  83. data/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml.tt +3 -3
  84. data/lib/rails/generators/rails/app/templates/config/databases/trilogy.yml.tt +59 -0
  85. data/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt +12 -2
  86. data/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +32 -28
  87. data/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt +13 -9
  88. data/lib/rails/generators/rails/app/templates/config/initializers/assets.rb.tt +2 -0
  89. data/lib/rails/generators/rails/app/templates/config/initializers/content_security_policy.rb.tt +2 -2
  90. data/lib/rails/generators/rails/app/templates/config/initializers/cors.rb.tt +1 -1
  91. data/lib/rails/generators/rails/app/templates/config/initializers/filter_parameter_logging.rb.tt +3 -3
  92. data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_7_1.rb.tt +280 -0
  93. data/lib/rails/generators/rails/app/templates/config/initializers/permissions_policy.rb.tt +11 -9
  94. data/lib/rails/generators/rails/app/templates/config/locales/en.yml +11 -13
  95. data/lib/rails/generators/rails/app/templates/config/puma.rb.tt +21 -20
  96. data/lib/rails/generators/rails/app/templates/config/routes.rb.tt +5 -1
  97. data/lib/rails/generators/rails/app/templates/db/seeds.rb.tt +6 -4
  98. data/lib/rails/generators/rails/app/templates/docker-entrypoint.tt +10 -0
  99. data/lib/rails/generators/rails/app/templates/dockerignore.tt +43 -0
  100. data/lib/rails/generators/rails/app/templates/gitignore.tt +4 -8
  101. data/lib/rails/generators/rails/app/templates/node-version.tt +1 -0
  102. data/lib/rails/generators/rails/app/templates/test/channels/application_cable/connection_test.rb.tt +10 -8
  103. data/lib/rails/generators/rails/app/templates/test/test_helper.rb.tt +9 -7
  104. data/lib/rails/generators/rails/application_record/application_record_generator.rb +4 -0
  105. data/lib/rails/generators/rails/benchmark/benchmark_generator.rb +2 -1
  106. data/lib/rails/generators/rails/controller/USAGE +12 -4
  107. data/lib/rails/generators/rails/controller/controller_generator.rb +5 -0
  108. data/lib/rails/generators/rails/controller/templates/controller.rb.tt +1 -1
  109. data/lib/rails/generators/rails/credentials/credentials_generator.rb +29 -24
  110. data/lib/rails/generators/rails/credentials/templates/credentials.yml.tt +8 -0
  111. data/lib/rails/generators/rails/db/system/change/change_generator.rb +30 -0
  112. data/lib/rails/generators/rails/encryption_key_file/encryption_key_file_generator.rb +1 -2
  113. data/lib/rails/generators/rails/migration/USAGE +21 -11
  114. data/lib/rails/generators/rails/model/model_generator.rb +4 -0
  115. data/lib/rails/generators/rails/plugin/USAGE +17 -6
  116. data/lib/rails/generators/rails/plugin/plugin_generator.rb +5 -15
  117. data/lib/rails/generators/rails/plugin/templates/Gemfile.tt +2 -2
  118. data/lib/rails/generators/rails/plugin/templates/MIT-LICENSE.tt +1 -1
  119. data/lib/rails/generators/rails/plugin/templates/bin/rails.tt +1 -17
  120. data/lib/rails/generators/rails/plugin/templates/gitignore.tt +0 -2
  121. data/lib/rails/generators/rails/plugin/templates/test/test_helper.rb.tt +4 -4
  122. data/lib/rails/generators/rails/resource/resource_generator.rb +6 -0
  123. data/lib/rails/generators/rails/scaffold/scaffold_generator.rb +2 -1
  124. data/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb +1 -1
  125. data/lib/rails/generators/test_case.rb +2 -2
  126. data/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb +1 -1
  127. data/lib/rails/generators/testing/{behaviour.rb → behavior.rb} +4 -1
  128. data/lib/rails/generators.rb +6 -14
  129. data/lib/rails/health_controller.rb +55 -0
  130. data/lib/rails/info.rb +1 -1
  131. data/lib/rails/info_controller.rb +33 -11
  132. data/lib/rails/mailers_controller.rb +15 -5
  133. data/lib/rails/paths.rb +13 -10
  134. data/lib/rails/rack/logger.rb +15 -12
  135. data/lib/rails/rackup/server.rb +15 -0
  136. data/lib/rails/railtie/configuration.rb +14 -1
  137. data/lib/rails/railtie.rb +31 -31
  138. data/lib/rails/ruby_version_check.rb +2 -0
  139. data/lib/rails/source_annotation_extractor.rb +67 -18
  140. data/lib/rails/tasks/engine.rake +8 -8
  141. data/lib/rails/tasks/framework.rake +4 -10
  142. data/lib/rails/tasks/log.rake +1 -1
  143. data/lib/rails/tasks/misc.rake +3 -14
  144. data/lib/rails/tasks/statistics.rake +5 -4
  145. data/lib/rails/tasks/tmp.rake +5 -5
  146. data/lib/rails/tasks/zeitwerk.rake +15 -35
  147. data/lib/rails/tasks.rb +0 -2
  148. data/lib/rails/templates/rails/mailers/email.html.erb +32 -0
  149. data/lib/rails/templates/rails/mailers/index.html.erb +14 -7
  150. data/lib/rails/templates/rails/mailers/mailer.html.erb +11 -5
  151. data/lib/rails/templates/rails/welcome/index.html.erb +1 -0
  152. data/lib/rails/test_help.rb +9 -14
  153. data/lib/rails/test_unit/line_filtering.rb +1 -1
  154. data/lib/rails/test_unit/reporter.rb +6 -2
  155. data/lib/rails/test_unit/runner.rb +36 -18
  156. data/lib/rails/test_unit/test_parser.rb +88 -0
  157. data/lib/rails/test_unit/testing.rake +13 -33
  158. data/lib/rails/testing/maintain_test_schema.rb +16 -0
  159. data/lib/rails/version.rb +1 -1
  160. data/lib/rails/zeitwerk_checker.rb +15 -0
  161. data/lib/rails.rb +15 -15
  162. metadata +64 -27
  163. data/RDOC_MAIN.rdoc +0 -97
  164. data/lib/rails/application/dummy_erb_compiler.rb +0 -18
  165. data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_7_0.rb.tt +0 -143
  166. data/lib/rails/generators/rails/model/USAGE +0 -113
  167. data/lib/rails/tasks/middleware.rake +0 -9
  168. data/lib/rails/tasks/restart.rake +0 -9
@@ -7,49 +7,54 @@ require "active_support/encrypted_configuration"
7
7
  module Rails
8
8
  module Generators
9
9
  class CredentialsGenerator < Base # :nodoc:
10
+ argument :content_path, default: "config/credentials.yml.enc"
11
+ argument :key_path, default: "config/master.key"
12
+ class_option :skip_secret_key_base, type: :boolean
13
+
10
14
  def add_credentials_file
11
- unless credentials.content_path.exist?
12
- template = credentials_template
15
+ in_root do
16
+ return if File.exist?(content_path)
13
17
 
14
- say "Adding #{credentials.content_path} to store encrypted credentials."
18
+ say "Adding #{content_path} to store encrypted credentials."
15
19
  say ""
20
+
21
+ content = render_template_to_encrypted_file
22
+
16
23
  say "The following content has been encrypted with the Rails master key:"
17
24
  say ""
18
- say template, :on_green
25
+ say content, :on_green
19
26
  say ""
20
-
21
- add_credentials_file_silently(template)
22
-
23
27
  say "You can edit encrypted credentials with `bin/rails credentials:edit`."
24
28
  say ""
25
29
  end
26
30
  end
27
31
 
28
- def add_credentials_file_silently(template = nil)
29
- unless credentials.content_path.exist?
30
- credentials.write(credentials_template)
31
- end
32
- end
33
-
34
32
  private
35
- def credentials
33
+ def encrypted_file
36
34
  ActiveSupport::EncryptedConfiguration.new(
37
- config_path: "config/credentials.yml.enc",
38
- key_path: "config/master.key",
35
+ config_path: content_path,
36
+ key_path: key_path,
39
37
  env_key: "RAILS_MASTER_KEY",
40
38
  raise_if_missing_key: true
41
39
  )
42
40
  end
43
41
 
44
- def credentials_template
45
- <<~YAML
46
- # aws:
47
- # access_key_id: 123
48
- # secret_access_key: 345
42
+ def secret_key_base
43
+ @secret_key_base ||= SecureRandom.hex(64)
44
+ end
45
+
46
+ def render_template_to_encrypted_file
47
+ empty_directory File.dirname(content_path)
48
+
49
+ content = nil
50
+
51
+ encrypted_file.change do |tmp_path|
52
+ template("credentials.yml", tmp_path, force: true, verbose: false) do |rendered|
53
+ content = rendered
54
+ end
55
+ end
49
56
 
50
- # Used as the base secret for all MessageVerifiers in Rails, including the one protecting cookies.
51
- secret_key_base: #{SecureRandom.hex(64)}
52
- YAML
57
+ content
53
58
  end
54
59
  end
55
60
  end
@@ -0,0 +1,8 @@
1
+ # aws:
2
+ # access_key_id: 123
3
+ # secret_access_key: 345
4
+ <% unless options.skip_secret_key_base? -%>
5
+
6
+ # Used as the base secret for all MessageVerifiers in Rails, including the one protecting cookies.
7
+ secret_key_base: <%= secret_key_base %>
8
+ <% end -%>
@@ -40,16 +40,46 @@ module Rails
40
40
  gsub_file("Gemfile", gem_entry_regex_for(name), gem_entry_for(name, *version))
41
41
  end
42
42
 
43
+ def edit_dockerfile
44
+ dockerfile_path = File.expand_path("Dockerfile", destination_root)
45
+ return unless File.exist?(dockerfile_path)
46
+
47
+ build_name = docker_for_database_build
48
+ deploy_name = docker_for_database_deploy
49
+ if build_name
50
+ gsub_file("Dockerfile", all_docker_builds_regex, build_name)
51
+ end
52
+ if deploy_name
53
+ gsub_file("Dockerfile", all_docker_deploys_regex, deploy_name)
54
+ end
55
+ end
56
+
43
57
  private
44
58
  def all_database_gems
45
59
  DATABASES.map { |database| gem_for_database(database) }
46
60
  end
47
61
 
62
+ def all_docker_builds
63
+ DATABASES.map { |database| docker_for_database_build(database).nil? ? nil : docker_for_database_build(database) }.compact!
64
+ end
65
+
66
+ def all_docker_deploys
67
+ DATABASES.map { |database| docker_for_database_deploy(database).nil? ? nil : docker_for_database_deploy(database) }.compact!
68
+ end
69
+
48
70
  def all_database_gems_regex
49
71
  all_database_gem_names = all_database_gems.map(&:first)
50
72
  /(\b#{all_database_gem_names.join('\b|\b')}\b)/
51
73
  end
52
74
 
75
+ def all_docker_builds_regex
76
+ /(\b#{all_docker_builds.join('\b|\b')}\b)/
77
+ end
78
+
79
+ def all_docker_deploys_regex
80
+ /(\b#{all_docker_deploys.join('\b|\b')}\b)/
81
+ end
82
+
53
83
  def gem_entry_regex_for(gem_name)
54
84
  /^gem.*\b#{gem_name}\b.*/
55
85
  end
@@ -26,8 +26,7 @@ module Rails
26
26
  end
27
27
 
28
28
  def add_key_file_silently(key_path, key = nil)
29
- create_file key_path, key || ActiveSupport::EncryptedFile.generate_key
30
- key_path.chmod 0600
29
+ create_file key_path, key || ActiveSupport::EncryptedFile.generate_key, perm: 0600
31
30
  end
32
31
 
33
32
  def ignore_key_file(key_path, ignore: key_ignore(key_path))
@@ -5,31 +5,41 @@ Description:
5
5
  A migration class is generated in db/migrate prefixed by a timestamp of the current date and time.
6
6
 
7
7
  You can name your migration in either of these formats to generate add/remove
8
- column lines from supplied attributes: AddColumnsToTable or RemoveColumnsFromTable
8
+ column lines from supplied attributes: add_{columns}_to_{table} or remove_{columns}_from_{table}.
9
9
 
10
- Example:
11
- `bin/rails generate migration AddSslFlag`
10
+ A migration name containing JoinTable will generate join tables for use with
11
+ has_and_belongs_to_many associations.
12
+
13
+ You can also name your migration create_{table} along with any attributes to generate a regular table.
14
+
15
+ Examples:
16
+ `bin/rails generate migration add_ssl_flag`
12
17
 
13
18
  If the current date is May 14, 2008 and the current time 09:09:12, this creates the AddSslFlag migration
14
19
  db/migrate/20080514090912_add_ssl_flag.rb
15
20
 
16
- `bin/rails generate migration AddTitleBodyToPost title:string body:text published:boolean`
21
+ `bin/rails generate migration add_title_body_published_to_post title:string body:text published:boolean`
17
22
 
18
- This will create the AddTitleBodyToPost in db/migrate/20080514090912_add_title_body_to_post.rb with this in the Change migration:
23
+ This will create db/migrate/20080514090912_add_title_body_published_to_post.rb with this in the migration:
19
24
 
20
25
  add_column :posts, :title, :string
21
26
  add_column :posts, :body, :text
22
27
  add_column :posts, :published, :boolean
23
28
 
24
- Migration names containing JoinTable will generate join tables for use with
25
- has_and_belongs_to_many associations.
29
+ `bin/rails generate migration create_media_join_table artists musics:uniq`
26
30
 
27
- Example:
28
- `bin/rails g migration CreateMediaJoinTable artists musics:uniq`
29
-
30
- will create the migration
31
+ This will create a join table migration:
31
32
 
32
33
  create_join_table :artists, :musics do |t|
33
34
  # t.index [:artist_id, :music_id]
34
35
  t.index [:music_id, :artist_id], unique: true
35
36
  end
37
+
38
+ `bin/rails generate migration create_users email:string`
39
+
40
+ This will create the migration:
41
+
42
+ create_table :users do |t|
43
+ t.string :email
44
+ t.timestamps
45
+ end
@@ -9,6 +9,10 @@ module Rails
9
9
 
10
10
  argument :attributes, type: :array, default: [], banner: "field[:type][:index] field[:type][:index]"
11
11
  hook_for :orm, required: true, desc: "ORM to be invoked"
12
+
13
+ class << self
14
+ delegate(:desc, to: :orm_generator)
15
+ end
12
16
  end
13
17
  end
14
18
  end
@@ -1,10 +1,21 @@
1
1
  Description:
2
- The 'rails plugin new' command creates a skeleton for developing any
3
- kind of Rails extension with ability to run tests using dummy Rails
4
- application.
2
+ The `rails plugin new` command creates a Rails plugin with the ability
3
+ to run tests using a dummy Rails application. A plugin is a gem with
4
+ either a railtie or an engine.
5
5
 
6
- Example:
7
- rails plugin new ~/Code/Ruby/blog
6
+ Examples:
7
+ `rails plugin new ~/Code/Ruby/blog`
8
8
 
9
- This generates a skeletal Rails plugin in ~/Code/Ruby/blog.
9
+ This generates a Rails railtie gem in ~/Code/Ruby/blog.
10
10
  See the README in the newly created plugin to get going.
11
+
12
+ `rails plugin new blog --full`
13
+
14
+ This generates a full Rails engine gem in ./blog. The `--mountable`
15
+ option may also be used to generate a mountable, namespace-isolated
16
+ engine with assets and layouts.
17
+
18
+ `rails plugin new blog --mountable --skip-asset-pipeline`
19
+
20
+ This generates a mountable Rails engine gem at ./blog without an asset
21
+ pipeline. Any part of Rails can be skipped during plugin generation.
@@ -28,14 +28,14 @@ module Rails
28
28
 
29
29
  empty_directory_with_keep_file "app/models/concerns"
30
30
  empty_directory_with_keep_file "app/controllers/concerns"
31
- remove_dir "app/mailers" if skip_action_mailer?
31
+ remove_dir "app/mailers" if options[:skip_action_mailer]
32
32
  remove_dir "app/jobs" if options[:skip_active_job]
33
33
  elsif full?
34
34
  empty_directory_with_keep_file "app/models"
35
35
  empty_directory_with_keep_file "app/controllers"
36
36
  empty_directory_with_keep_file "app/models/concerns"
37
37
  empty_directory_with_keep_file "app/controllers/concerns"
38
- empty_directory_with_keep_file "app/mailers" unless skip_action_mailer?
38
+ empty_directory_with_keep_file "app/mailers" unless options[:skip_action_mailer]
39
39
  empty_directory_with_keep_file "app/jobs" unless options[:skip_active_job]
40
40
 
41
41
  unless api?
@@ -68,10 +68,7 @@ module Rails
68
68
 
69
69
  def version_control
70
70
  if !options[:skip_git] && !options[:pretend]
71
- run "git init", capture: options[:quiet], abort_on_failure: false
72
- if user_default_branch.strip.empty?
73
- `git symbolic-ref HEAD refs/heads/main`
74
- end
71
+ run git_init_command, capture: options[:quiet], abort_on_failure: false
75
72
  end
76
73
  end
77
74
 
@@ -127,10 +124,6 @@ module Rails
127
124
  def test_dummy_config
128
125
  template "rails/boot.rb", "#{dummy_path}/config/boot.rb", force: true
129
126
 
130
- insert_into_file "#{dummy_path}/config/application.rb", <<~RUBY, after: /^Bundler\.require.+\n/
131
- require #{namespaced_name.inspect}
132
- RUBY
133
-
134
127
  if mountable?
135
128
  template "rails/routes.rb", "#{dummy_path}/config/routes.rb", force: true
136
129
  end
@@ -191,11 +184,6 @@ module Rails
191
184
  append_file gemfile_in_app_path, entry
192
185
  end
193
186
  end
194
-
195
- private
196
- def user_default_branch
197
- @user_default_branch ||= `git config init.defaultbranch`
198
- end
199
187
  end
200
188
 
201
189
  module Generators
@@ -226,12 +214,14 @@ module Rails
226
214
  def initialize(*args)
227
215
  @dummy_path = nil
228
216
  super
217
+ imply_options
229
218
 
230
219
  if !engine? || !with_dummy_app?
231
220
  self.options = options.merge(skip_asset_pipeline: true).freeze
232
221
  end
233
222
  end
234
223
 
224
+ public_task :report_implied_options
235
225
  public_task :set_default_accessors!
236
226
  public_task :create_root
237
227
 
@@ -13,7 +13,7 @@ gemspec
13
13
  # Start debugger with binding.b [https://github.com/ruby/debug]
14
14
  # gem "debug", ">= 1.0.0"
15
15
  <% end -%>
16
- <% if RUBY_PLATFORM.match?(/bccwin|cygwin|emx|mingw|mswin|wince|java/) -%>
16
+ <% if RUBY_PLATFORM.match?(/mingw|mswin|java/) -%>
17
17
 
18
- gem "tzinfo-data", platforms: %i[ mingw mswin x64_mingw jruby ]
18
+ gem "tzinfo-data", platforms: %i[ <%= bundler_windows_platforms %> jruby ]
19
19
  <% end -%>
@@ -1,4 +1,4 @@
1
- Copyright <%= Date.today.year %> <%= author %>
1
+ Copyright <%= author %>
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
@@ -11,21 +11,5 @@ APP_PATH = File.expand_path("../<%= dummy_path -%>/config/application", __dir__)
11
11
  ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
12
12
  require "bundler/setup" if File.exist?(ENV["BUNDLE_GEMFILE"])
13
13
 
14
- <% if include_all_railties? -%>
15
- require "rails/all"
16
- <% else -%>
17
- require "rails"
18
- # Pick the frameworks you want:
19
- require "active_model/railtie"
20
- <%= comment_if :skip_active_job %>require "active_job/railtie"
21
- <%= comment_if :skip_active_record %>require "active_record/railtie"
22
- <%= comment_if :skip_active_storage %>require "active_storage/engine"
23
- require "action_controller/railtie"
24
- <%= comment_if :skip_action_mailer %>require "action_mailer/railtie"
25
- <%= comment_if :skip_action_mailbox %>require "action_mailbox/engine"
26
- <%= comment_if :skip_action_text %>require "action_text/engine"
27
- require "action_view/railtie"
28
- <%= comment_if :skip_action_cable %>require "action_cable/engine"
29
- <%= comment_if :skip_test %>require "rails/test_unit/railtie"
30
- <% end -%>
14
+ <%= rails_require_statement %>
31
15
  require "rails/engine/commands"
@@ -9,8 +9,6 @@
9
9
  /<%= dummy_path %>/db/*.sqlite3-*
10
10
  <% end -%>
11
11
  /<%= dummy_path %>/log/*.log
12
- <% unless skip_active_storage? -%>
13
12
  /<%= dummy_path %>/storage/
14
- <% end -%>
15
13
  /<%= dummy_path %>/tmp/
16
14
  <% end -%>
@@ -12,10 +12,10 @@ require "rails/test_help"
12
12
 
13
13
  <% unless options[:skip_active_record] -%>
14
14
  # Load fixtures from the engine
15
- if ActiveSupport::TestCase.respond_to?(:fixture_path=)
16
- ActiveSupport::TestCase.fixture_path = File.expand_path("fixtures", __dir__)
17
- ActionDispatch::IntegrationTest.fixture_path = ActiveSupport::TestCase.fixture_path
18
- ActiveSupport::TestCase.file_fixture_path = ActiveSupport::TestCase.fixture_path + "/files"
15
+ if ActiveSupport::TestCase.respond_to?(:fixture_paths=)
16
+ ActiveSupport::TestCase.fixture_paths = [File.expand_path("fixtures", __dir__)]
17
+ ActionDispatch::IntegrationTest.fixture_paths = ActiveSupport::TestCase.fixture_paths
18
+ ActiveSupport::TestCase.file_fixture_path = File.expand_path("fixtures", __dir__) + "/files"
19
19
  ActiveSupport::TestCase.fixtures :all
20
20
  end
21
21
  <% end -%>
@@ -16,6 +16,12 @@ module Rails
16
16
  desc: "Actions for the resource controller"
17
17
 
18
18
  hook_for :resource_route, required: true
19
+
20
+ class << self
21
+ def desc(description = nil)
22
+ ERB.new(File.read(usage_path)).result(binding)
23
+ end
24
+ end
19
25
  end
20
26
  end
21
27
  end
@@ -8,7 +8,8 @@ module Rails
8
8
  remove_hook_for :resource_controller
9
9
  remove_class_option :actions
10
10
 
11
- class_option :api, type: :boolean
11
+ class_option :api, type: :boolean,
12
+ desc: "Generate API-only controller and tests, with no view templates"
12
13
  class_option :resource_route, type: :boolean
13
14
 
14
15
  hook_for :scaffold_controller, required: true
@@ -13,7 +13,7 @@ module Rails
13
13
  class_option :orm, banner: "NAME", type: :string, required: true,
14
14
  desc: "ORM to generate the controller for"
15
15
  class_option :api, type: :boolean,
16
- desc: "Generates API controller"
16
+ desc: "Generate API controller"
17
17
 
18
18
  class_option :skip_routes, type: :boolean, desc: "Don't add routes to config/routes.rb."
19
19
 
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "rails/generators"
4
- require "rails/generators/testing/behaviour"
4
+ require "rails/generators/testing/behavior"
5
5
  require "rails/generators/testing/setup_and_teardown"
6
6
  require "rails/generators/testing/assertions"
7
7
  require "fileutils"
@@ -28,7 +28,7 @@ module Rails
28
28
  # setup :prepare_destination
29
29
  # end
30
30
  class TestCase < ActiveSupport::TestCase
31
- include Rails::Generators::Testing::Behaviour
31
+ include Rails::Generators::Testing::Behavior
32
32
  include Rails::Generators::Testing::SetupAndTeardown
33
33
  include Rails::Generators::Testing::Assertions
34
34
  include FileUtils
@@ -11,7 +11,7 @@ module TestUnit # :nodoc:
11
11
  check_class_collision suffix: "ControllerTest"
12
12
 
13
13
  class_option :api, type: :boolean,
14
- desc: "Generates API functional tests"
14
+ desc: "Generate API functional tests"
15
15
 
16
16
  class_option :system_tests, type: :string,
17
17
  desc: "Skip system test files"
@@ -11,7 +11,7 @@ require "rails/generators"
11
11
  module Rails
12
12
  module Generators
13
13
  module Testing
14
- module Behaviour
14
+ module Behavior
15
15
  extend ActiveSupport::Concern
16
16
  include ActiveSupport::Testing::Stream
17
17
 
@@ -107,6 +107,9 @@ module Rails
107
107
  Dir.glob("#{dirname}/[0-9]*_*.rb").grep(/\d+_#{file_name}.rb$/).first
108
108
  end
109
109
  end
110
+
111
+ include ActiveSupport::Deprecation::DeprecatedConstantAccessor
112
+ deprecate_constant "Behaviour", "Rails::Generators::Testing::Behavior", deprecator: Rails.deprecator
110
113
  end
111
114
  end
112
115
  end
@@ -1,8 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- activesupport_path = File.expand_path("../../../activesupport/lib", __dir__)
4
- $:.unshift(activesupport_path) if File.directory?(activesupport_path) && !$:.include?(activesupport_path)
5
-
6
3
  require "thor/group"
7
4
  require "rails/command"
8
5
 
@@ -33,7 +30,7 @@ module Rails
33
30
  rails: {
34
31
  actions: "-a",
35
32
  orm: "-o",
36
- javascripts: "-j",
33
+ javascripts: ["-j", "--js"],
37
34
  resource_controller: "-c",
38
35
  scaffold_controller: "-c",
39
36
  stylesheets: "-y",
@@ -93,7 +90,7 @@ module Rails
93
90
  end
94
91
 
95
92
  # Hold configured generators fallbacks. If a plugin developer wants a
96
- # generator group to fallback to another group in case of missing generators,
93
+ # generator group to fall back to another group in case of missing generators,
97
94
  # they can add a fallback.
98
95
  #
99
96
  # For example, shoulda is considered a test_framework and is an extension
@@ -166,7 +163,8 @@ module Rails
166
163
 
167
164
  # Show help message with available generators.
168
165
  def help(command = "generate")
169
- puts "Usage: rails #{command} GENERATOR [args] [options]"
166
+ puts "Usage:"
167
+ puts " bin/rails #{command} GENERATOR [args] [options]"
170
168
  puts
171
169
  puts "General options:"
172
170
  puts " -h, [--help] # Print generator's options and usage"
@@ -264,16 +262,10 @@ module Rails
264
262
  run_after_generate_callback if config[:behavior] == :invoke
265
263
  else
266
264
  options = sorted_groups.flat_map(&:last)
267
- error = Command::Base::CorrectableError.new("Could not find generator '#{namespace}'.", namespace, options)
268
-
269
- if error.respond_to?(:detailed_message)
270
- formatted_message = error.detailed_message
271
- else
272
- formatted_message = error.message
273
- end
265
+ error = Command::CorrectableNameError.new("Could not find generator '#{namespace}'.", namespace, options)
274
266
 
275
267
  puts <<~MSG
276
- #{formatted_message}
268
+ #{error.detailed_message}
277
269
  Run `bin/rails generate --help` for more options.
278
270
  MSG
279
271
  end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rails
4
+ # Built-in Health Check Endpoint
5
+ #
6
+ # \Rails also comes with a built-in health check endpoint that is reachable at
7
+ # the +/up+ path. This endpoint will return a 200 status code if the app has
8
+ # booted with no exceptions, and a 500 status code otherwise.
9
+ #
10
+ # In production, many applications are required to report their status upstream,
11
+ # whether it's to an uptime monitor that will page an engineer when things go
12
+ # wrong, or a load balancer or Kubernetes controller used to determine a pod's
13
+ # health. This health check is designed to be a one-size fits all that will work
14
+ # in many situations.
15
+ #
16
+ # While any newly generated \Rails applications will have the health check at
17
+ # +/up+, you can configure the path to be anything you'd like in your
18
+ # <tt>"config/routes.rb"</tt>:
19
+ #
20
+ # Rails.application.routes.draw do
21
+ # get "healthz" => "rails/health#show", as: :rails_health_check
22
+ # end
23
+ #
24
+ # The health check will now be accessible via the +/healthz+ path.
25
+ #
26
+ # NOTE: This endpoint does not reflect the status of all of your application's
27
+ # dependencies, such as the database or redis cluster. Replace
28
+ # <tt>"rails/health#show"</tt> with your own controller action if you have
29
+ # application specific needs.
30
+ #
31
+ # Think carefully about what you want to check as it can lead to situations
32
+ # where your application is being restarted due to a third-party service going
33
+ # bad. Ideally, you should design your application to handle those outages
34
+ # gracefully.
35
+ class HealthController < ActionController::Base
36
+ rescue_from(Exception) { render_down }
37
+
38
+ def show
39
+ render_up
40
+ end
41
+
42
+ private
43
+ def render_up
44
+ render html: html_status(color: "green")
45
+ end
46
+
47
+ def render_down
48
+ render html: html_status(color: "red"), status: 500
49
+ end
50
+
51
+ def html_status(color:)
52
+ %(<!DOCTYPE html><html><body style="background-color: #{color}"></body></html>).html_safe
53
+ end
54
+ end
55
+ end
data/lib/rails/info.rb CHANGED
@@ -4,7 +4,7 @@ require "cgi"
4
4
 
5
5
  module Rails
6
6
  # This module helps build the runtime properties that are displayed in
7
- # Rails::InfoController responses. These include the active Rails version,
7
+ # Rails::InfoController responses. These include the active \Rails version,
8
8
  # Ruby version, Rack version, and so on.
9
9
  module Info
10
10
  mattr_accessor :properties, default: []
@@ -4,9 +4,11 @@ require "rails/application_controller"
4
4
  require "action_dispatch/routing/inspector"
5
5
 
6
6
  class Rails::InfoController < Rails::ApplicationController # :nodoc:
7
- prepend_view_path ActionDispatch::DebugView::RESCUES_TEMPLATE_PATH
7
+ prepend_view_path ActionDispatch::DebugView::RESCUES_TEMPLATE_PATHS
8
8
  layout -> { request.xhr? ? false : "application" }
9
9
 
10
+ RFC2396_PARSER = defined?(URI::RFC2396_PARSER) ? URI::RFC2396_PARSER : URI::RFC2396_Parser.new
11
+
10
12
  before_action :require_local!
11
13
 
12
14
  def index
@@ -19,12 +21,12 @@ class Rails::InfoController < Rails::ApplicationController # :nodoc:
19
21
  end
20
22
 
21
23
  def routes
22
- if path = params[:path]
23
- path = URI::DEFAULT_PARSER.escape path
24
- normalized_path = with_leading_slash path
24
+ if query = params[:query]
25
+ query = RFC2396_PARSER.escape query
26
+
25
27
  render json: {
26
- exact: match_route { |it| it.match normalized_path },
27
- fuzzy: match_route { |it| it.spec.to_s.match path }
28
+ exact: matching_routes(query: query, exact_match: true),
29
+ fuzzy: matching_routes(query: query, exact_match: false)
28
30
  }
29
31
  else
30
32
  @routes_inspector = ActionDispatch::Routing::RoutesInspector.new(_routes.routes)
@@ -33,11 +35,31 @@ class Rails::InfoController < Rails::ApplicationController # :nodoc:
33
35
  end
34
36
 
35
37
  private
36
- def match_route
37
- _routes.routes.filter_map { |route| route.path.spec.to_s if yield route.path }
38
- end
38
+ def matching_routes(query:, exact_match:)
39
+ return [] if query.blank?
40
+
41
+ normalized_path = ("/" + query).squeeze("/")
42
+ query_without_url_or_path_suffix = query.gsub(/(\w)(_path$)/, '\1').gsub(/(\w)(_url$)/, '\1')
43
+
44
+ _routes.routes.filter_map do |route|
45
+ route_wrapper = ActionDispatch::Routing::RouteWrapper.new(route)
46
+
47
+ if exact_match
48
+ match = route.path.match(normalized_path)
49
+ match ||= (query_without_url_or_path_suffix === route_wrapper.name)
50
+ else
51
+ match = route_wrapper.path.match(query)
52
+ match ||= route_wrapper.name.include?(query_without_url_or_path_suffix)
53
+ end
54
+
55
+ match ||= (query === route_wrapper.verb)
56
+
57
+ unless match
58
+ controller_action = RFC2396_PARSER.escape(route_wrapper.reqs)
59
+ match = exact_match ? (query === controller_action) : controller_action.include?(query)
60
+ end
39
61
 
40
- def with_leading_slash(path)
41
- ("/" + path).squeeze("/")
62
+ route_wrapper.path if match
63
+ end
42
64
  end
43
65
  end