railties 7.1.0 → 7.2.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +203 -650
- data/lib/minitest/rails_plugin.rb +5 -2
- data/lib/rails/all.rb +1 -3
- data/lib/rails/api/task.rb +6 -4
- data/lib/rails/application/bootstrap.rb +11 -8
- data/lib/rails/application/configuration.rb +80 -36
- data/lib/rails/application/dummy_config.rb +2 -2
- data/lib/rails/application/finisher.rb +10 -0
- data/lib/rails/application.rb +29 -76
- data/lib/rails/backtrace_cleaner.rb +18 -3
- data/lib/rails/cli.rb +0 -1
- data/lib/rails/command.rb +1 -1
- data/lib/rails/commands/app/update_command.rb +102 -0
- data/lib/rails/commands/boot/boot_command.rb +14 -0
- data/lib/rails/commands/console/console_command.rb +2 -21
- data/lib/rails/commands/console/irb_console.rb +146 -0
- data/lib/rails/commands/credentials/USAGE +1 -1
- data/lib/rails/commands/credentials/credentials_command.rb +2 -2
- data/lib/rails/commands/dbconsole/dbconsole_command.rb +21 -30
- data/lib/rails/commands/devcontainer/devcontainer_command.rb +39 -0
- data/lib/rails/commands/rake/rake_command.rb +1 -1
- data/lib/rails/commands/runner/runner_command.rb +14 -3
- data/lib/rails/commands/server/server_command.rb +5 -3
- data/lib/rails/commands/test/test_command.rb +2 -0
- data/lib/rails/configuration.rb +10 -1
- data/lib/rails/console/app.rb +5 -32
- data/lib/rails/console/helpers.rb +5 -16
- data/lib/rails/console/methods.rb +23 -0
- data/lib/rails/engine/configuration.rb +45 -6
- data/lib/rails/engine.rb +24 -17
- data/lib/rails/gem_version.rb +3 -3
- data/lib/rails/generators/active_model.rb +26 -12
- data/lib/rails/generators/app_base.rb +80 -61
- data/lib/rails/generators/base.rb +9 -5
- data/lib/rails/generators/database.rb +227 -69
- data/lib/rails/generators/erb/scaffold/templates/edit.html.erb.tt +2 -0
- data/lib/rails/generators/erb/scaffold/templates/index.html.erb.tt +2 -0
- data/lib/rails/generators/erb/scaffold/templates/new.html.erb.tt +2 -0
- data/lib/rails/generators/generated_attribute.rb +26 -1
- data/lib/rails/generators/migration.rb +3 -3
- data/lib/rails/generators/rails/app/app_generator.rb +57 -32
- data/lib/rails/generators/rails/app/templates/Dockerfile.tt +23 -16
- data/lib/rails/generators/rails/app/templates/Gemfile.tt +17 -17
- data/lib/rails/generators/rails/app/templates/app/controllers/application_controller.rb.tt +4 -0
- data/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt +8 -1
- data/lib/rails/generators/rails/app/templates/app/views/pwa/manifest.json.erb.tt +22 -0
- data/lib/rails/generators/rails/app/templates/app/views/pwa/service-worker.js +26 -0
- data/lib/rails/generators/rails/app/templates/bin/brakeman.tt +6 -0
- data/lib/rails/generators/rails/app/templates/bin/rubocop.tt +7 -0
- data/lib/rails/generators/rails/app/templates/bin/setup.tt +6 -2
- data/lib/rails/generators/rails/app/templates/config/application.rb.tt +1 -1
- data/lib/rails/generators/rails/app/templates/config/databases/mysql.yml.tt +3 -3
- data/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml.tt +11 -4
- data/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml.tt +8 -1
- data/lib/rails/generators/rails/app/templates/config/databases/trilogy.yml.tt +3 -3
- data/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt +14 -7
- data/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +14 -6
- data/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt +10 -7
- data/lib/rails/generators/rails/app/templates/config/initializers/assets.rb.tt +1 -1
- data/lib/rails/generators/rails/app/templates/config/initializers/filter_parameter_logging.rb.tt +3 -3
- data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_7_2.rb.tt +70 -0
- data/lib/rails/generators/rails/app/templates/config/puma.rb.tt +25 -26
- data/lib/rails/generators/rails/app/templates/config/routes.rb.tt +6 -0
- data/lib/rails/generators/rails/app/templates/docker-entrypoint.tt +5 -0
- data/lib/rails/generators/rails/app/templates/dockerignore.tt +13 -0
- data/lib/rails/generators/rails/app/templates/github/ci.yml.tt +138 -0
- data/lib/rails/generators/rails/app/templates/github/dependabot.yml +12 -0
- data/lib/rails/generators/rails/app/templates/gitignore.tt +3 -3
- data/lib/rails/generators/rails/app/templates/public/406-unsupported-browser.html +66 -0
- data/lib/rails/generators/rails/app/templates/public/icon.png +0 -0
- data/lib/rails/generators/rails/app/templates/public/icon.svg +3 -0
- data/lib/rails/generators/rails/app/templates/rubocop.yml.tt +8 -0
- data/lib/rails/generators/rails/app/templates/test/application_system_test_case.rb.tt +1 -1
- data/lib/rails/generators/rails/controller/controller_generator.rb +1 -1
- data/lib/rails/generators/rails/db/system/change/change_generator.rb +134 -20
- data/lib/rails/generators/rails/devcontainer/devcontainer_generator.rb +166 -0
- data/lib/rails/generators/rails/devcontainer/templates/devcontainer/Dockerfile.tt +3 -0
- data/lib/rails/generators/rails/devcontainer/templates/devcontainer/compose.yaml.tt +47 -0
- data/lib/rails/generators/rails/devcontainer/templates/devcontainer/devcontainer.json.tt +37 -0
- data/lib/rails/generators/rails/migration/migration_generator.rb +4 -0
- data/lib/rails/generators/rails/plugin/plugin_generator.rb +40 -7
- data/lib/rails/generators/rails/plugin/templates/%name%.gemspec.tt +2 -2
- data/lib/rails/generators/rails/plugin/templates/Gemfile.tt +5 -1
- data/lib/rails/generators/rails/plugin/templates/app/views/layouts/%namespaced_name%/application.html.erb.tt +2 -0
- data/lib/rails/generators/rails/plugin/templates/bin/rubocop.tt +7 -0
- data/lib/rails/generators/rails/plugin/templates/github/ci.yml.tt +103 -0
- data/lib/rails/generators/rails/plugin/templates/github/dependabot.yml +12 -0
- data/lib/rails/generators/rails/plugin/templates/rubocop.yml.tt +8 -0
- data/lib/rails/generators/rails/plugin/templates/test/application_system_test_case.rb.tt +1 -1
- data/lib/rails/generators/rails/plugin/templates/test/test_helper.rb.tt +2 -2
- data/lib/rails/generators/test_unit/mailer/templates/functional_test.rb.tt +6 -4
- data/lib/rails/generators/test_unit/mailer/templates/preview.rb.tt +3 -2
- data/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb +15 -1
- data/lib/rails/generators/test_unit/scaffold/templates/api_functional_test.rb.tt +2 -2
- data/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb.tt +2 -2
- data/lib/rails/generators/test_unit/scaffold/templates/system_test.rb.tt +2 -0
- data/lib/rails/generators/test_unit/system/templates/application_system_test_case.rb.tt +1 -1
- data/lib/rails/generators/testing/assertions.rb +20 -0
- data/lib/rails/generators/testing/behavior.rb +7 -6
- data/lib/rails/generators.rb +7 -3
- data/lib/rails/health_controller.rb +2 -2
- data/lib/rails/info.rb +2 -2
- data/lib/rails/info_controller.rb +4 -2
- data/lib/rails/mailers_controller.rb +14 -1
- data/lib/rails/paths.rb +2 -2
- data/lib/rails/pwa_controller.rb +15 -0
- data/lib/rails/rack/logger.rb +15 -7
- data/lib/rails/railtie/configurable.rb +2 -2
- data/lib/rails/railtie.rb +15 -16
- data/lib/rails/tasks/framework.rake +0 -26
- data/lib/rails/tasks/tmp.rake +1 -1
- data/lib/rails/tasks/zeitwerk.rake +14 -34
- data/lib/rails/templates/layouts/application.html.erb +1 -1
- data/lib/rails/templates/rails/mailers/email.html.erb +20 -9
- data/lib/rails/templates/rails/welcome/index.html.erb +4 -2
- data/lib/rails/test_help.rb +2 -4
- data/lib/rails/test_unit/reporter.rb +8 -2
- data/lib/rails/test_unit/runner.rb +26 -2
- data/lib/rails/test_unit/test_parser.rb +45 -0
- data/lib/rails/testing/maintain_test_schema.rb +1 -1
- data/lib/rails/zeitwerk_checker.rb +15 -0
- data/lib/rails.rb +7 -4
- metadata +46 -35
- data/lib/rails/app_updater.rb +0 -40
- data/lib/rails/commands/secrets/USAGE +0 -61
- data/lib/rails/commands/secrets/secrets_command.rb +0 -46
- data/lib/rails/generators/rails/app/templates/config/databases/jdbc.yml.tt +0 -68
- data/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml.tt +0 -54
- data/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml.tt +0 -70
- data/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml.tt +0 -24
- data/lib/rails/generators/rails/app/templates/config/databases/oracle.yml.tt +0 -62
- data/lib/rails/generators/rails/app/templates/config/databases/sqlserver.yml.tt +0 -53
- data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_7_1.rb.tt +0 -223
- data/lib/rails/generators/rails/app/templates/public/apple-touch-icon-precomposed.png +0 -0
- data/lib/rails/generators/rails/app/templates/public/apple-touch-icon.png +0 -0
- data/lib/rails/generators/rails/app/templates/public/favicon.ico +0 -0
- data/lib/rails/ruby_version_check.rb +0 -17
- data/lib/rails/secrets.rb +0 -110
@@ -22,7 +22,7 @@ class <%= controller_class_name %>ControllerTest < ActionDispatch::IntegrationTe
|
|
22
22
|
|
23
23
|
test "should create <%= singular_table_name %>" do
|
24
24
|
assert_difference("<%= class_name %>.count") do
|
25
|
-
post <%= index_helper(type: :url) %>, params: { <%= "#{singular_table_name}:
|
25
|
+
post <%= index_helper(type: :url) %>, params: { <%= "#{singular_table_name}: #{attributes_string}" %> }
|
26
26
|
end
|
27
27
|
|
28
28
|
assert_redirected_to <%= show_helper("#{class_name}.last") %>
|
@@ -39,7 +39,7 @@ class <%= controller_class_name %>ControllerTest < ActionDispatch::IntegrationTe
|
|
39
39
|
end
|
40
40
|
|
41
41
|
test "should update <%= singular_table_name %>" do
|
42
|
-
patch <%= show_helper %>, params: { <%= "#{singular_table_name}:
|
42
|
+
patch <%= show_helper %>, params: { <%= "#{singular_table_name}: #{attributes_string}" %> }
|
43
43
|
assert_redirected_to <%= show_helper %>
|
44
44
|
end
|
45
45
|
|
@@ -35,6 +35,8 @@ class <%= class_name.pluralize %>Test < ApplicationSystemTestCase
|
|
35
35
|
<%- attributes_hash.each do |attr, value| -%>
|
36
36
|
<%- if boolean?(attr) -%>
|
37
37
|
check "<%= attr.humanize %>" if <%= value %>
|
38
|
+
<%- elsif datetime?(attr) || time?(attr) -%>
|
39
|
+
fill_in "<%= attr.humanize %>", with: <%= value %>.to_s
|
38
40
|
<%- else -%>
|
39
41
|
fill_in "<%= attr.humanize %>", with: <%= value %>
|
40
42
|
<%- end -%>
|
@@ -121,6 +121,26 @@ module Rails
|
|
121
121
|
assert_equal(value, create_generated_attribute(attribute_type).default)
|
122
122
|
end
|
123
123
|
end
|
124
|
+
|
125
|
+
# Asserts a given initializer exists. You need to supply a path relative
|
126
|
+
# to the `config/initializers/` directory.
|
127
|
+
#
|
128
|
+
# assert_initializer "mail_interceptors.rb"
|
129
|
+
#
|
130
|
+
# You can also give extra arguments. If the argument is a regexp, it will check if the
|
131
|
+
# regular expression matches the given file content. If it's a string, it compares the
|
132
|
+
# file with the given string:
|
133
|
+
#
|
134
|
+
# assert_initializer "mail_interceptors.rb", /SandboxEmailInterceptor/
|
135
|
+
#
|
136
|
+
# Finally, when a block is given, it yields the file content:
|
137
|
+
#
|
138
|
+
# assert_initializer "mail_interceptors.rb" do |initializer|
|
139
|
+
# assert_match(/SandboxEmailInterceptor/, initializer)
|
140
|
+
# end
|
141
|
+
def assert_initializer(name, *contents, &block)
|
142
|
+
assert_file("config/initializers/#{name}", *contents, &block)
|
143
|
+
end
|
124
144
|
end
|
125
145
|
end
|
126
146
|
end
|
@@ -65,11 +65,15 @@ module Rails
|
|
65
65
|
# You can provide a configuration hash as second argument. This method returns the output
|
66
66
|
# printed by the generator.
|
67
67
|
def run_generator(args = default_arguments, config = {})
|
68
|
-
|
69
|
-
|
70
|
-
args += ["--skip-bootsnap"] unless args.include?("--no-skip-bootsnap") || args.include?("--skip-bootsnap")
|
68
|
+
args += ["--skip-bundle"] unless args.include?("--no-skip-bundle") || args.include?("--dev")
|
69
|
+
args += ["--skip-bootsnap"] unless args.include?("--no-skip-bootsnap") || args.include?("--skip-bootsnap")
|
71
70
|
|
71
|
+
if ENV["RAILS_LOG_TO_STDOUT"] == "true"
|
72
72
|
generator_class.start(args, config.reverse_merge(destination_root: destination_root))
|
73
|
+
else
|
74
|
+
capture(:stdout) do
|
75
|
+
generator_class.start(args, config.reverse_merge(destination_root: destination_root))
|
76
|
+
end
|
73
77
|
end
|
74
78
|
end
|
75
79
|
|
@@ -107,9 +111,6 @@ module Rails
|
|
107
111
|
Dir.glob("#{dirname}/[0-9]*_*.rb").grep(/\d+_#{file_name}.rb$/).first
|
108
112
|
end
|
109
113
|
end
|
110
|
-
|
111
|
-
include ActiveSupport::Deprecation::DeprecatedConstantAccessor
|
112
|
-
deprecate_constant "Behaviour", "Rails::Generators::Testing::Behavior", deprecator: Rails.deprecator
|
113
114
|
end
|
114
115
|
end
|
115
116
|
end
|
data/lib/rails/generators.rb
CHANGED
@@ -60,6 +60,10 @@ module Rails
|
|
60
60
|
}
|
61
61
|
}
|
62
62
|
|
63
|
+
# We need to store the RAILS_DEV_PATH in a constant, otherwise the path
|
64
|
+
# can change when we FileUtils.cd.
|
65
|
+
RAILS_DEV_PATH = File.expand_path("../../..", __dir__) # :nodoc:
|
66
|
+
|
63
67
|
class << self
|
64
68
|
def configure!(config) # :nodoc:
|
65
69
|
api_only! if config.api_only
|
@@ -90,7 +94,7 @@ module Rails
|
|
90
94
|
end
|
91
95
|
|
92
96
|
# Hold configured generators fallbacks. If a plugin developer wants a
|
93
|
-
# generator group to
|
97
|
+
# generator group to fall back to another group in case of missing generators,
|
94
98
|
# they can add a fallback.
|
95
99
|
#
|
96
100
|
# For example, shoulda is considered a test_framework and is an extension
|
@@ -151,7 +155,8 @@ module Rails
|
|
151
155
|
"#{template}:scaffold",
|
152
156
|
"#{template}:mailer",
|
153
157
|
"action_text:install",
|
154
|
-
"action_mailbox:install"
|
158
|
+
"action_mailbox:install",
|
159
|
+
"devcontainer"
|
155
160
|
]
|
156
161
|
end
|
157
162
|
end
|
@@ -202,7 +207,6 @@ module Rails
|
|
202
207
|
rails.map! { |n| n.delete_prefix("rails:") }
|
203
208
|
rails.delete("app")
|
204
209
|
rails.delete("plugin")
|
205
|
-
rails.delete("encrypted_secrets")
|
206
210
|
rails.delete("encrypted_file")
|
207
211
|
rails.delete("encryption_key_file")
|
208
212
|
rails.delete("master_key")
|
@@ -24,7 +24,7 @@ module Rails
|
|
24
24
|
# The health check will now be accessible via the +/healthz+ path.
|
25
25
|
#
|
26
26
|
# NOTE: This endpoint does not reflect the status of all of your application's
|
27
|
-
# dependencies, such as the database or
|
27
|
+
# dependencies, such as the database or Redis cluster. Replace
|
28
28
|
# <tt>"rails/health#show"</tt> with your own controller action if you have
|
29
29
|
# application specific needs.
|
30
30
|
#
|
@@ -49,7 +49,7 @@ module Rails
|
|
49
49
|
end
|
50
50
|
|
51
51
|
def html_status(color:)
|
52
|
-
%(
|
52
|
+
%(<!DOCTYPE html><html><body style="background-color: #{color}"></body></html>).html_safe
|
53
53
|
end
|
54
54
|
end
|
55
55
|
end
|
data/lib/rails/info.rb
CHANGED
@@ -95,11 +95,11 @@ module Rails
|
|
95
95
|
|
96
96
|
# The name of the database adapter for the current environment.
|
97
97
|
property "Database adapter" do
|
98
|
-
ActiveRecord::Base.
|
98
|
+
ActiveRecord::Base.connection_pool.db_config.adapter
|
99
99
|
end
|
100
100
|
|
101
101
|
property "Database schema version" do
|
102
|
-
ActiveRecord::Base.
|
102
|
+
ActiveRecord::Base.connection_pool.migration_context.current_version rescue nil
|
103
103
|
end
|
104
104
|
end
|
105
105
|
end
|
@@ -7,6 +7,8 @@ class Rails::InfoController < Rails::ApplicationController # :nodoc:
|
|
7
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
|
@@ -20,7 +22,7 @@ class Rails::InfoController < Rails::ApplicationController # :nodoc:
|
|
20
22
|
|
21
23
|
def routes
|
22
24
|
if query = params[:query]
|
23
|
-
query =
|
25
|
+
query = RFC2396_PARSER.escape query
|
24
26
|
|
25
27
|
render json: {
|
26
28
|
exact: matching_routes(query: query, exact_match: true),
|
@@ -53,7 +55,7 @@ class Rails::InfoController < Rails::ApplicationController # :nodoc:
|
|
53
55
|
match ||= (query === route_wrapper.verb)
|
54
56
|
|
55
57
|
unless match
|
56
|
-
controller_action =
|
58
|
+
controller_action = RFC2396_PARSER.escape(route_wrapper.reqs)
|
57
59
|
match = exact_match ? (query === controller_action) : controller_action.include?(query)
|
58
60
|
end
|
59
61
|
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "rails/application_controller"
|
4
|
+
require "active_support/core_ext/enumerable"
|
4
5
|
|
5
6
|
class Rails::MailersController < Rails::ApplicationController # :nodoc:
|
6
7
|
prepend_view_path ActionDispatch::DebugView::RESCUES_TEMPLATE_PATHS
|
@@ -9,7 +10,7 @@ class Rails::MailersController < Rails::ApplicationController # :nodoc:
|
|
9
10
|
before_action :find_preview, only: [:preview, :download]
|
10
11
|
before_action :require_local!, unless: :show_previews?
|
11
12
|
|
12
|
-
helper_method :part_query, :locale_query
|
13
|
+
helper_method :attachment_url, :part_query, :locale_query
|
13
14
|
|
14
15
|
content_security_policy(false)
|
15
16
|
|
@@ -38,6 +39,8 @@ class Rails::MailersController < Rails::ApplicationController # :nodoc:
|
|
38
39
|
if @preview.email_exists?(@email_action)
|
39
40
|
@page_title = "Mailer Preview for #{@preview.preview_name}##{@email_action}"
|
40
41
|
@email = @preview.call(@email_action, params)
|
42
|
+
@attachments = attachments_for(@email).reject { |filename, attachment| attachment.inline? }
|
43
|
+
@inline_attachments = attachments_for(@email).select { |filename, attachment| attachment.inline? }
|
41
44
|
|
42
45
|
if params[:part]
|
43
46
|
part_type = Mime::Type.lookup(params[:part])
|
@@ -95,6 +98,16 @@ class Rails::MailersController < Rails::ApplicationController # :nodoc:
|
|
95
98
|
end
|
96
99
|
end
|
97
100
|
|
101
|
+
def attachments_for(email)
|
102
|
+
email.all_parts.to_a.select(&:attachment?).index_by do |attachment|
|
103
|
+
attachment.respond_to?(:original_filename) ? attachment.original_filename : attachment.filename
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def attachment_url(attachment)
|
108
|
+
"data:application/octet-stream;charset=utf-8;base64,#{Base64.encode64(attachment.body.to_s)}"
|
109
|
+
end
|
110
|
+
|
98
111
|
def part_query(mime_type)
|
99
112
|
request.query_parameters.merge(part: mime_type).to_query
|
100
113
|
end
|
data/lib/rails/paths.rb
CHANGED
@@ -105,8 +105,8 @@ module Rails
|
|
105
105
|
private
|
106
106
|
def filter_by(&block)
|
107
107
|
all_paths.find_all(&block).flat_map { |path|
|
108
|
-
paths = path.
|
109
|
-
paths - path.children.flat_map { |p| yield(p) ? [] : p.
|
108
|
+
paths = path.existent_directories
|
109
|
+
paths - path.children.flat_map { |p| yield(p) ? [] : p.existent_directories }
|
110
110
|
}.uniq
|
111
111
|
end
|
112
112
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rails/application_controller"
|
4
|
+
|
5
|
+
class Rails::PwaController < Rails::ApplicationController # :nodoc:
|
6
|
+
skip_forgery_protection
|
7
|
+
|
8
|
+
def service_worker
|
9
|
+
render template: "pwa/service-worker", layout: false
|
10
|
+
end
|
11
|
+
|
12
|
+
def manifest
|
13
|
+
render template: "pwa/manifest", layout: false
|
14
|
+
end
|
15
|
+
end
|
data/lib/rails/rack/logger.rb
CHANGED
@@ -20,22 +20,26 @@ module Rails
|
|
20
20
|
def call(env)
|
21
21
|
request = ActionDispatch::Request.new(env)
|
22
22
|
|
23
|
-
if logger.respond_to?(:
|
24
|
-
logger.
|
23
|
+
env["rails.rack_logger_tag_count"] = if logger.respond_to?(:push_tags)
|
24
|
+
logger.push_tags(*compute_tags(request)).size
|
25
25
|
else
|
26
|
-
|
26
|
+
0
|
27
27
|
end
|
28
|
+
|
29
|
+
call_app(request, env)
|
28
30
|
end
|
29
31
|
|
30
32
|
private
|
31
33
|
def call_app(request, env) # :doc:
|
34
|
+
logger_tag_pop_count = env["rails.rack_logger_tag_count"]
|
35
|
+
|
32
36
|
instrumenter = ActiveSupport::Notifications.instrumenter
|
33
37
|
handle = instrumenter.build_handle("request.action_dispatch", { request: request })
|
34
38
|
handle.start
|
35
39
|
|
36
40
|
logger.info { started_request_message(request) }
|
37
41
|
status, headers, body = response = @app.call(env)
|
38
|
-
body = ::Rack::BodyProxy.new(body,
|
42
|
+
body = ::Rack::BodyProxy.new(body) { finish_request_instrumentation(handle, logger_tag_pop_count) }
|
39
43
|
|
40
44
|
if response.frozen?
|
41
45
|
[status, headers, body]
|
@@ -44,10 +48,8 @@ module Rails
|
|
44
48
|
response
|
45
49
|
end
|
46
50
|
rescue Exception
|
47
|
-
handle
|
51
|
+
finish_request_instrumentation(handle, logger_tag_pop_count)
|
48
52
|
raise
|
49
|
-
ensure
|
50
|
-
ActiveSupport::LogSubscriber.flush_all!
|
51
53
|
end
|
52
54
|
|
53
55
|
# Started GET "/session/new" for 127.0.0.1 at 2012-09-26 14:51:42 -0700
|
@@ -75,6 +77,12 @@ module Rails
|
|
75
77
|
def logger
|
76
78
|
Rails.logger
|
77
79
|
end
|
80
|
+
|
81
|
+
def finish_request_instrumentation(handle, logger_tag_pop_count)
|
82
|
+
handle.finish
|
83
|
+
logger.pop_tags(logger_tag_pop_count) if logger.respond_to?(:pop_tags) && logger_tag_pop_count > 0
|
84
|
+
ActiveSupport::LogSubscriber.flush_all!
|
85
|
+
end
|
78
86
|
end
|
79
87
|
end
|
80
88
|
end
|
data/lib/rails/railtie.rb
CHANGED
@@ -50,8 +50,8 @@ module Rails
|
|
50
50
|
# To add an initialization step to the \Rails boot process from your railtie, just
|
51
51
|
# define the initialization code with the +initializer+ macro:
|
52
52
|
#
|
53
|
-
# class
|
54
|
-
# initializer "
|
53
|
+
# class MyGem::Railtie < Rails::Railtie
|
54
|
+
# initializer "my_gem.configure_rails_initialization" do
|
55
55
|
# # some initialization behavior
|
56
56
|
# end
|
57
57
|
# end
|
@@ -59,9 +59,9 @@ module Rails
|
|
59
59
|
# If specified, the block can also receive the application object, in case you
|
60
60
|
# need to access some application-specific configuration, like middleware:
|
61
61
|
#
|
62
|
-
# class
|
63
|
-
# initializer "
|
64
|
-
# app.middleware.use
|
62
|
+
# class MyGem::Railtie < Rails::Railtie
|
63
|
+
# initializer "my_gem.configure_rails_initialization" do |app|
|
64
|
+
# app.middleware.use MyGem::Middleware
|
65
65
|
# end
|
66
66
|
# end
|
67
67
|
#
|
@@ -74,14 +74,14 @@ module Rails
|
|
74
74
|
# Railties can access a config object which contains configuration shared by all
|
75
75
|
# railties and the application:
|
76
76
|
#
|
77
|
-
# class
|
77
|
+
# class MyGem::Railtie < Rails::Railtie
|
78
78
|
# # Customize the ORM
|
79
|
-
# config.app_generators.orm :
|
79
|
+
# config.app_generators.orm :my_gem_orm
|
80
80
|
#
|
81
81
|
# # Add a to_prepare block which is executed once in production
|
82
82
|
# # and before each request in development.
|
83
83
|
# config.to_prepare do
|
84
|
-
#
|
84
|
+
# MyGem.setup!
|
85
85
|
# end
|
86
86
|
# end
|
87
87
|
#
|
@@ -90,9 +90,9 @@ module Rails
|
|
90
90
|
# If your railtie has Rake tasks, you can tell \Rails to load them through the method
|
91
91
|
# +rake_tasks+:
|
92
92
|
#
|
93
|
-
# class
|
93
|
+
# class MyGem::Railtie < Rails::Railtie
|
94
94
|
# rake_tasks do
|
95
|
-
# load "path/to/
|
95
|
+
# load "path/to/my_gem.tasks"
|
96
96
|
# end
|
97
97
|
# end
|
98
98
|
#
|
@@ -100,9 +100,9 @@ module Rails
|
|
100
100
|
# your generators at a different location, you can specify in your railtie a block which
|
101
101
|
# will load them during normal generators lookup:
|
102
102
|
#
|
103
|
-
# class
|
103
|
+
# class MyGem::Railtie < Rails::Railtie
|
104
104
|
# generators do
|
105
|
-
# require "path/to/
|
105
|
+
# require "path/to/my_gem_generator"
|
106
106
|
# end
|
107
107
|
# end
|
108
108
|
#
|
@@ -120,7 +120,7 @@ module Rails
|
|
120
120
|
# this less confusing for everyone.
|
121
121
|
# It can be used like this:
|
122
122
|
#
|
123
|
-
# class
|
123
|
+
# class MyGem::Railtie < Rails::Railtie
|
124
124
|
# server do
|
125
125
|
# WebpackServer.start
|
126
126
|
# end
|
@@ -221,14 +221,13 @@ module Rails
|
|
221
221
|
|
222
222
|
# If the class method does not have a method, then send the method call
|
223
223
|
# to the Railtie instance.
|
224
|
-
def method_missing(name,
|
224
|
+
def method_missing(name, ...)
|
225
225
|
if !abstract_railtie? && instance.respond_to?(name)
|
226
|
-
instance.public_send(name,
|
226
|
+
instance.public_send(name, ...)
|
227
227
|
else
|
228
228
|
super
|
229
229
|
end
|
230
230
|
end
|
231
|
-
ruby2_keywords(:method_missing)
|
232
231
|
|
233
232
|
# receives an instance variable identifier, set the variable value if is
|
234
233
|
# blank and append given block to value, which will be used later in
|
@@ -1,9 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
namespace :app do
|
4
|
-
desc "Update configs and some other initially generated files (or use just update:configs or update:bin)"
|
5
|
-
task update: [ "update:configs", "update:bin", "update:active_storage", "update:upgrade_guide_info" ]
|
6
|
-
|
7
4
|
desc "Apply the template supplied by LOCATION=(/path/to/template) or URL"
|
8
5
|
task template: :environment do
|
9
6
|
template = ENV["LOCATION"]
|
@@ -34,27 +31,4 @@ namespace :app do
|
|
34
31
|
end
|
35
32
|
end
|
36
33
|
end
|
37
|
-
|
38
|
-
namespace :update do
|
39
|
-
require "rails/app_updater"
|
40
|
-
|
41
|
-
# desc "Update config files from your current rails install"
|
42
|
-
task :configs do
|
43
|
-
Rails::AppUpdater.invoke_from_app_generator :create_boot_file
|
44
|
-
Rails::AppUpdater.invoke_from_app_generator :update_config_files
|
45
|
-
end
|
46
|
-
|
47
|
-
# desc "Add new executables to the application bin/ directory"
|
48
|
-
task :bin do
|
49
|
-
Rails::AppUpdater.invoke_from_app_generator :update_bin_files
|
50
|
-
end
|
51
|
-
|
52
|
-
task :active_storage do
|
53
|
-
Rails::AppUpdater.invoke_from_app_generator :update_active_storage
|
54
|
-
end
|
55
|
-
|
56
|
-
task :upgrade_guide_info do
|
57
|
-
Rails::AppUpdater.invoke_from_app_generator :display_upgrade_guide_info
|
58
|
-
end
|
59
|
-
end
|
60
34
|
end
|
data/lib/rails/tasks/tmp.rake
CHANGED
@@ -1,11 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
puts "Hold on, I am eager loading the application."
|
5
|
-
Zeitwerk::Loader.eager_load_all
|
6
|
-
end
|
3
|
+
require "rails/zeitwerk_checker"
|
7
4
|
|
8
|
-
|
5
|
+
report_unchecked = ->(unchecked) do
|
9
6
|
puts
|
10
7
|
puts <<~EOS
|
11
8
|
WARNING: The following directories will only be checked if you configure
|
@@ -13,7 +10,7 @@ report_not_checked = ->(not_checked) do
|
|
13
10
|
EOS
|
14
11
|
puts
|
15
12
|
|
16
|
-
|
13
|
+
unchecked.each { |dir| puts " #{dir}" }
|
17
14
|
puts
|
18
15
|
|
19
16
|
puts <<~EOS
|
@@ -23,39 +20,22 @@ report_not_checked = ->(not_checked) do
|
|
23
20
|
puts
|
24
21
|
end
|
25
22
|
|
26
|
-
report = ->(not_checked) do
|
27
|
-
if not_checked.any?
|
28
|
-
report_not_checked[not_checked]
|
29
|
-
puts "Otherwise, all is good!"
|
30
|
-
else
|
31
|
-
puts "All is good!"
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
23
|
namespace :zeitwerk do
|
36
24
|
desc "Check project structure for Zeitwerk compatibility"
|
37
25
|
task check: :environment do
|
26
|
+
puts "Hold on, I am eager loading the application."
|
27
|
+
|
38
28
|
begin
|
39
|
-
|
40
|
-
rescue NameError => e
|
41
|
-
|
42
|
-
abort $&.sub(/expected file #{Regexp.escape(Rails.root.to_s)}./, "expected file ")
|
43
|
-
else
|
44
|
-
raise
|
45
|
-
end
|
29
|
+
unchecked = Rails::ZeitwerkChecker.check
|
30
|
+
rescue Zeitwerk::NameError => e
|
31
|
+
abort e.message.sub(/#{Regexp.escape(Rails.root.to_s)}./, "")
|
46
32
|
end
|
47
33
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
end
|
54
|
-
|
55
|
-
not_checked = ActiveSupport::Dependencies.autoload_paths - eager_load_paths
|
56
|
-
not_checked.select! { |dir| Dir.exist?(dir) }
|
57
|
-
not_checked.reject! { |dir| Dir.empty?(dir) }
|
58
|
-
|
59
|
-
report[not_checked]
|
34
|
+
if unchecked.empty?
|
35
|
+
puts "All is good!"
|
36
|
+
else
|
37
|
+
report_unchecked[unchecked]
|
38
|
+
puts "Otherwise, all is good!"
|
39
|
+
end
|
60
40
|
end
|
61
41
|
end
|
@@ -44,6 +44,13 @@
|
|
44
44
|
content: "\00a0"; //
|
45
45
|
}
|
46
46
|
|
47
|
+
th {
|
48
|
+
font-weight: inherit;
|
49
|
+
color: #7f7f7f;
|
50
|
+
text-align: right;
|
51
|
+
white-space: nowrap;
|
52
|
+
}
|
53
|
+
|
47
54
|
iframe {
|
48
55
|
border: 0;
|
49
56
|
width: 100%;
|
@@ -54,14 +61,14 @@
|
|
54
61
|
<body>
|
55
62
|
<header>
|
56
63
|
<dl>
|
57
|
-
<% if
|
64
|
+
<% if Array(@email.from) != Array(@email.smtp_envelope_from) %>
|
58
65
|
<dt>SMTP-From:</dt>
|
59
66
|
<dd id="smtp_from"><%= @email.smtp_envelope_from %></dd>
|
60
67
|
<% end %>
|
61
68
|
|
62
|
-
<% if
|
69
|
+
<% if Set[*@email.to, *@email.cc, *@email.bcc] != Set[*@email.smtp_envelope_to] %>
|
63
70
|
<dt>SMTP-To:</dt>
|
64
|
-
<dd id="smtp_to"><%= @email.smtp_envelope_to %></dd>
|
71
|
+
<dd id="smtp_to"><%= @email.smtp_envelope_to.join(", ") %></dd>
|
65
72
|
<% end %>
|
66
73
|
|
67
74
|
<dt>From:</dt>
|
@@ -86,17 +93,21 @@
|
|
86
93
|
<% end %>
|
87
94
|
|
88
95
|
<dt>Date:</dt>
|
89
|
-
<dd id="date"><%= Time.current.rfc2822 %></dd>
|
96
|
+
<dd id="date"><%= @email.header['date'] || Time.current.rfc2822 %></dd>
|
90
97
|
|
91
98
|
<dt>Subject:</dt>
|
92
99
|
<dd><strong id="subject"><%= @email.subject %></strong></dd>
|
93
100
|
|
94
|
-
<%
|
101
|
+
<% if @attachments.any? || @inline_attachments.any? %>
|
95
102
|
<dt>Attachments:</dt>
|
96
103
|
<dd>
|
97
|
-
<% @
|
98
|
-
|
99
|
-
|
104
|
+
<% @attachments.each do |filename, attachment| %>
|
105
|
+
<%= link_to filename, attachment_url(attachment), download: filename %>
|
106
|
+
<% end %>
|
107
|
+
|
108
|
+
<% if @inline_attachments.any? %>
|
109
|
+
(Inline: <% @inline_attachments.each do |filename, attachment| %>
|
110
|
+
<%= link_to filename, attachment_url(attachment), download: filename %><% end %>)
|
100
111
|
<% end %>
|
101
112
|
</dd>
|
102
113
|
<% end %>
|
@@ -134,7 +145,7 @@
|
|
134
145
|
<table>
|
135
146
|
<% @email.header_fields.each do |field| %>
|
136
147
|
<tr>
|
137
|
-
<
|
148
|
+
<th><%= field.name %>:</th>
|
138
149
|
<td><%= field.value %></td>
|
139
150
|
</tr>
|
140
151
|
<% end %>
|
@@ -1,11 +1,12 @@
|
|
1
|
-
<% ruby_on_rails_logo_favicon_data_uri = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIwcHgiIGhlaWdodD0iMzIwcHgiIHZpZXdCb3g9IjAgMCAzMjAgMzIwIiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPgogICAgPHRpdGxlPkljb248L3RpdGxlPgogICAgPGcgaWQ9Ikljb24iIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPgogICAgICAgIDxnIGlkPSJSdWJ5LU9uLVJhaWxzLUxvZ28iIHRyYW5zZm9ybT0idHJhbnNsYXRlKDUuMDAwMDAwLCAyMC4wMDAwMDApIiBmaWxsPSIjRDgxRTAwIj4KICAgICAgICAgICAgPHBhdGggZD0iTTIxLjkzMzA3MDYsMjg1IEwxNjguMTc1NDI2LDI4NSBDMTQ3Ljk0MDg1OCwxNTAuNjkxNzA2IDE5Ni44ODIzODMsNjYuMzE0MjkwMiAzMTUsMzEuODY3NzUzNiBDMzE1LDIxLjc4NTEyODQgMzE1LDMxLjg2Nzc1MzYgMzE1LDIxLjc4NTEyODQgQzE2MS4yNTI4MywyNC45MTE2Mjc4IDYzLjU2Mzg1MzMsMTEyLjY0OTkxOCAyMS45MzMwNzA2LDI4NSBaIiBpZD0iUGF0aCIvPgogICAgICAgICAgICA8cG9seWdvbiBpZD0iUGF0aCIgcG9pbnRzPSI0MC40MDgyNjQzIDE4NS45MTU3MSAxMi43MzI2NDk0IDE3NC40MDE2NjMgLTEuNDIxMDg1NDdlLTE0IDIwNS40NDI3MSAyOS41NzExOTY2IDIxNi42NDcxMTUiLz4KICAgICAgICAgICAgPHBvbHlnb24gaWQ9IlBhdGgiIHBvaW50cz0iMTgwLjQ3MzEwMiAyNjguMDczNjQzIDIwNC45MzYwMTYgMjc2LjQxMDk2NiAyMDQuOTM2MDE2IDI1NC41MDg2NzMgMTgwLjQ4OTY0NCAyNDQuMzM4MTA3Ii8+CiAgICAgICAgICAgIDxwb2x5Z29uIGlkPSJQYXRoIiBwb2ludHM9IjEwMC41ODk1MTkgOTcuMjI4NzYwNiA3Ni42ODQwMTU2IDc5LjE2ODcwMjEgNTUuMjQ0MDc5MSAxMDAuMTgzMTA1IDgxLjUxNDMyMzkgMTE3LjQzMzcyNSIvPgogICAgICAgICAgICA8cG9seWdvbiBpZD0iUGF0aCIgcG9pbnRzPSIxODQuNTc1Njc5IDE4NC44OTYyOTUgMjA3Ljk1MjAzIDIwMC4yNDY2MSAyMTEuNzI3NzI5IDE4MS4yMDUyNjYgMTg5Ljg2MzY1MyAxNjQuNjg3NDYiLz4KICAgICAgICAgICAgPHBvbHlnb24gaWQ9IlBhdGgiIHBvaW50cz0iMjYxLjczNDAxIDY1Ljg5NTk0NDYgMjY5LjM1NDIzNCA4Mi4zMjk1NCAyODUuMzE4MjU2IDcyLjcwNDg1OTYgMjc4LjMxMDEyOSA1Ni45ODI5ODk1Ii8+CiAgICAgICAgICAgIDxwb2x5Z29uIGlkPSJQYXRoIiBwb2ludHM9IjI2MS45MTM3IDE2LjE4NDU0NzMgMjU1LjU5ODQ3OSA3LjEwNTQyNzM2ZS0xNSAyMzIuNzk2MDIgMy40ODg5NjMyMyAyNDAuNDYzODczIDIwLjAyNTI3MjUiLz4KICAgICAgICAgICAgPHBvbHlnb24gaWQ9IlBhdGgiIHBvaW50cz0iMjExLjkzNDExOSAxMTEuNTgwNjc1IDIyNi43MjI1NDcgMTI3Ljc5MjYwMSAyMzguMDIzOTI1IDExMy45MDM3MTUgMjIzLjQ2ODM3NSA5Ni41NDY4Njg1Ii8+CiAgICAgICAgICAgIDxwb2x5Z29uIGlkPSJQYXRoIiBwb2ludHM9IjE3OS42ODY4NTggMzguNDk1MjIxOCAxNjQuNjQxOTMxIDIwLjAyNTI3MjUgMTM5Ljg0NzYyIDMyLjU1NTI5OTIgMTU2LjYwMTMyNCA1MC45MjE2NzUzIi8+CiAgICAgICAgPC9nPgogICAgPC9nPgo8L3N2Zz4=" %>
|
2
1
|
<!DOCTYPE html>
|
3
2
|
<html>
|
4
3
|
<head>
|
5
4
|
<title>Ruby on Rails <%= Rails.version %></title>
|
6
5
|
<meta charset="utf-8">
|
7
6
|
<meta name="viewport" content="width=device-width">
|
8
|
-
|
7
|
+
|
8
|
+
<link rel="icon" href="/icon.png" type="image/png">
|
9
|
+
<link rel="apple-touch-icon" href="/icon.png" sizes="512x512">
|
9
10
|
|
10
11
|
<style type="text/css">
|
11
12
|
* {
|
@@ -84,6 +85,7 @@
|
|
84
85
|
|
85
86
|
<ul>
|
86
87
|
<li><strong>Rails version:</strong> <%= Rails.version %></li>
|
88
|
+
<li><strong>Rack version:</strong> <%= Rack.release %></li>
|
87
89
|
<li><strong>Ruby version:</strong> <%= RUBY_DESCRIPTION %></li>
|
88
90
|
</ul>
|
89
91
|
</body>
|