railties 7.2.3 → 8.0.5
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +168 -256
- data/lib/minitest/rails_plugin.rb +8 -1
- data/lib/rails/application/bootstrap.rb +0 -1
- data/lib/rails/application/configuration.rb +17 -14
- data/lib/rails/application/default_middleware_stack.rb +4 -0
- data/lib/rails/application/finisher.rb +2 -3
- data/lib/rails/application/routes_reloader.rb +17 -3
- data/lib/rails/application.rb +10 -1
- data/lib/rails/application_controller.rb +2 -0
- data/lib/rails/backtrace_cleaner.rb +2 -2
- data/lib/rails/code_statistics.rb +128 -86
- data/lib/rails/code_statistics_calculator.rb +78 -76
- data/lib/rails/command/helpers/editor.rb +1 -1
- data/lib/rails/command.rb +0 -6
- data/lib/rails/commands/app/update_command.rb +5 -9
- data/lib/rails/commands/console/irb_console.rb +3 -6
- data/lib/rails/commands/credentials/USAGE +4 -4
- data/lib/rails/commands/credentials/credentials_command.rb +5 -1
- data/lib/rails/commands/dev/dev_command.rb +1 -1
- data/lib/rails/commands/devcontainer/devcontainer_command.rb +2 -1
- data/lib/rails/commands/stats/stats_command.rb +19 -0
- data/lib/rails/console/methods.rb +5 -21
- data/lib/rails/dev_caching.rb +2 -2
- data/lib/rails/engine/configuration.rb +3 -1
- data/lib/rails/engine/lazy_route_set.rb +111 -0
- data/lib/rails/engine.rb +10 -6
- data/lib/rails/gem_version.rb +3 -3
- data/lib/rails/generators/actions.rb +3 -3
- data/lib/rails/generators/app_base.rb +76 -56
- data/lib/rails/generators/base.rb +0 -4
- data/lib/rails/generators/bundle_helper.rb +34 -0
- data/lib/rails/generators/database.rb +101 -67
- data/lib/rails/generators/erb/authentication/authentication_generator.rb +15 -0
- data/lib/rails/generators/erb/authentication/templates/app/views/passwords/edit.html.erb +9 -0
- data/lib/rails/generators/erb/authentication/templates/app/views/passwords/new.html.erb +8 -0
- data/lib/rails/generators/erb/authentication/templates/app/views/sessions/new.html.erb +11 -0
- data/lib/rails/generators/generated_attribute.rb +16 -11
- data/lib/rails/generators/rails/app/app_generator.rb +30 -30
- data/lib/rails/generators/rails/app/templates/Dockerfile.tt +23 -6
- data/lib/rails/generators/rails/app/templates/Gemfile.tt +27 -12
- data/lib/rails/generators/rails/app/templates/app/assets/stylesheets/application.css.tt +6 -11
- data/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt +10 -3
- data/lib/rails/generators/rails/app/templates/bin/dev.tt +1 -0
- data/lib/rails/generators/rails/app/templates/bin/setup.tt +5 -8
- data/lib/rails/generators/rails/app/templates/bin/thrust.tt +4 -0
- data/lib/rails/generators/rails/app/templates/config/databases/mysql.yml.tt +24 -1
- data/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml.tt +23 -0
- data/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml.tt +50 -0
- data/lib/rails/generators/rails/app/templates/config/databases/trilogy.yml.tt +30 -5
- data/lib/rails/generators/rails/app/templates/config/deploy.yml.tt +128 -0
- data/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt +12 -23
- data/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +31 -51
- data/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt +5 -19
- data/lib/rails/generators/rails/app/templates/config/initializers/assets.rb.tt +0 -7
- data/lib/rails/generators/rails/app/templates/config/initializers/filter_parameter_logging.rb.tt +1 -1
- data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_8_0.rb.tt +30 -0
- data/lib/rails/generators/rails/app/templates/config/puma.rb.tt +11 -2
- data/lib/rails/generators/rails/app/templates/config/routes.rb.tt +3 -3
- data/lib/rails/generators/rails/app/templates/docker-entrypoint.tt +4 -3
- data/lib/rails/generators/rails/app/templates/dockerignore.tt +7 -2
- data/lib/rails/generators/rails/app/templates/github/ci.yml.tt +12 -6
- data/lib/rails/generators/rails/app/templates/gitignore.tt +1 -2
- data/lib/rails/generators/rails/app/templates/kamal-secrets.tt +17 -0
- data/lib/rails/generators/rails/app/templates/public/400.html +114 -0
- data/lib/rails/generators/rails/app/templates/public/404.html +113 -66
- data/lib/rails/generators/rails/app/templates/public/406-unsupported-browser.html +113 -65
- data/lib/rails/generators/rails/app/templates/public/422.html +113 -66
- data/lib/rails/generators/rails/app/templates/public/500.html +113 -65
- data/lib/rails/generators/rails/app/templates/public/icon.png +0 -0
- data/lib/rails/generators/rails/app/templates/public/icon.svg +2 -2
- data/lib/rails/generators/rails/app/templates/ruby-version.tt +1 -1
- data/lib/rails/generators/rails/authentication/USAGE +6 -0
- data/lib/rails/generators/rails/authentication/authentication_generator.rb +60 -0
- data/lib/rails/generators/rails/authentication/templates/app/channels/application_cable/connection.rb.tt +16 -0
- data/lib/rails/generators/rails/authentication/templates/app/controllers/concerns/authentication.rb.tt +52 -0
- data/lib/rails/generators/rails/authentication/templates/app/controllers/passwords_controller.rb.tt +33 -0
- data/lib/rails/generators/rails/authentication/templates/app/controllers/sessions_controller.rb.tt +21 -0
- data/lib/rails/generators/rails/authentication/templates/app/mailers/passwords_mailer.rb.tt +6 -0
- data/lib/rails/generators/rails/authentication/templates/app/models/current.rb.tt +4 -0
- data/lib/rails/generators/rails/authentication/templates/app/models/session.rb.tt +3 -0
- data/lib/rails/generators/rails/authentication/templates/app/models/user.rb.tt +6 -0
- data/lib/rails/generators/rails/authentication/templates/app/views/passwords_mailer/reset.html.erb.tt +4 -0
- data/lib/rails/generators/rails/authentication/templates/app/views/passwords_mailer/reset.text.erb.tt +2 -0
- data/lib/rails/generators/rails/credentials/templates/credentials.yml.tt +4 -0
- data/lib/rails/generators/rails/db/system/change/change_generator.rb +1 -1
- data/lib/rails/generators/rails/devcontainer/devcontainer_generator.rb +12 -2
- data/lib/rails/generators/rails/devcontainer/templates/devcontainer/Dockerfile.tt +1 -1
- data/lib/rails/generators/rails/devcontainer/templates/devcontainer/devcontainer.json.tt +5 -5
- data/lib/rails/generators/rails/plugin/plugin_generator.rb +7 -9
- data/lib/rails/generators/rails/plugin/templates/Gemfile.tt +1 -1
- data/lib/rails/generators/rails/plugin/templates/github/ci.yml.tt +3 -3
- data/lib/rails/generators/rails/scaffold_controller/templates/api_controller.rb.tt +2 -2
- data/lib/rails/generators/rails/scaffold_controller/templates/controller.rb.tt +3 -3
- data/lib/rails/generators/rails/script/USAGE +18 -0
- data/lib/rails/generators/rails/script/script_generator.rb +18 -0
- data/lib/rails/generators/rails/script/templates/script.rb.tt +3 -0
- data/lib/rails/generators/test_unit/authentication/authentication_generator.rb +18 -0
- data/lib/rails/generators/test_unit/authentication/templates/test/fixtures/users.yml.tt +9 -0
- data/lib/rails/generators/test_unit/authentication/templates/test/mailers/previews/passwords_mailer_preview.rb.tt +7 -0
- data/lib/rails/generators/test_unit/authentication/templates/test/models/user_test.rb.tt +7 -0
- data/lib/rails/generators.rb +1 -0
- data/lib/rails/health_controller.rb +2 -0
- data/lib/rails/info.rb +2 -1
- data/lib/rails/info_controller.rb +10 -4
- data/lib/rails/rack/silence_request.rb +33 -0
- data/lib/rails/rack.rb +1 -0
- data/lib/rails/source_annotation_extractor.rb +37 -16
- data/lib/rails/tasks/statistics.rake +13 -28
- data/lib/rails/templates/rails/info/notes.html.erb +65 -0
- data/lib/rails/templates/rails/mailers/email.html.erb +1 -1
- data/lib/rails/test_unit/line_filtering.rb +24 -3
- data/lib/rails/test_unit/reporter.rb +8 -4
- data/lib/rails/test_unit/runner.rb +1 -0
- metadata +46 -37
- data/lib/rails/console/app.rb +0 -8
- data/lib/rails/console/helpers.rb +0 -8
- data/lib/rails/generators/rails/app/templates/app/assets/config/manifest.js.tt +0 -2
- data/lib/rails/generators/rails/app/templates/app/channels/application_cable/channel.rb.tt +0 -4
- data/lib/rails/generators/rails/app/templates/app/channels/application_cable/connection.rb.tt +0 -4
- data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_7_2.rb.tt +0 -70
- data/lib/rails/generators/rails/app/templates/config/initializers/permissions_policy.rb.tt +0 -13
- data/lib/rails/generators/rails/app/templates/test/channels/application_cable/connection_test.rb.tt +0 -13
- data/lib/rails/generators/rails/plugin/templates/rails/dummy_manifest.js.tt +0 -10
- data/lib/rails/generators/rails/plugin/templates/rails/engine_manifest.js.tt +0 -6
- data/lib/rails/generators/rails/plugin/templates/rails/javascripts.js.tt +0 -17
|
@@ -12,6 +12,9 @@ module Rails
|
|
|
12
12
|
|
|
13
13
|
desc "update", "Update configs and some other initially generated files (or use just update:configs or update:bin)"
|
|
14
14
|
def perform
|
|
15
|
+
require_application!
|
|
16
|
+
Rails.application.deprecators.silenced = true
|
|
17
|
+
|
|
15
18
|
configs
|
|
16
19
|
bin
|
|
17
20
|
public_directory
|
|
@@ -71,23 +74,16 @@ module Rails
|
|
|
71
74
|
skip_action_cable: !defined?(ActionCable::Engine),
|
|
72
75
|
skip_brakeman: skip_gem?("brakeman"),
|
|
73
76
|
skip_rubocop: skip_gem?("rubocop"),
|
|
77
|
+
skip_thruster: skip_gem?("thruster"),
|
|
74
78
|
skip_test: !defined?(Rails::TestUnitRailtie),
|
|
75
79
|
skip_system_test: Rails.application.config.generators.system_tests.nil?,
|
|
76
|
-
asset_pipeline: asset_pipeline,
|
|
77
80
|
skip_asset_pipeline: asset_pipeline.nil?,
|
|
78
81
|
skip_bootsnap: !defined?(Bootsnap),
|
|
79
82
|
}.merge(options)
|
|
80
83
|
end
|
|
81
84
|
|
|
82
85
|
def asset_pipeline
|
|
83
|
-
|
|
84
|
-
when defined?(Sprockets::Railtie)
|
|
85
|
-
"sprockets"
|
|
86
|
-
when defined?(Propshaft::Railtie)
|
|
87
|
-
"propshaft"
|
|
88
|
-
else
|
|
89
|
-
nil
|
|
90
|
-
end
|
|
86
|
+
"propshaft" if defined?(Propshaft::Railtie)
|
|
91
87
|
end
|
|
92
88
|
|
|
93
89
|
def skip_gem?(gem_name)
|
|
@@ -6,7 +6,6 @@ require "irb/command"
|
|
|
6
6
|
module Rails
|
|
7
7
|
class Console
|
|
8
8
|
class RailsHelperBase < IRB::HelperMethod::Base
|
|
9
|
-
include ConsoleMethods
|
|
10
9
|
end
|
|
11
10
|
|
|
12
11
|
class ControllerHelper < RailsHelperBase
|
|
@@ -32,6 +31,7 @@ module Rails
|
|
|
32
31
|
|
|
33
32
|
def execute(*)
|
|
34
33
|
app = Rails.application
|
|
34
|
+
app.reload_routes_unless_loaded
|
|
35
35
|
session = ActionDispatch::Integration::Session.new(app)
|
|
36
36
|
|
|
37
37
|
# This makes app.url_for and app.foo_path available in the console
|
|
@@ -87,7 +87,8 @@ module Rails
|
|
|
87
87
|
|
|
88
88
|
env = colorized_env
|
|
89
89
|
prompt_prefix = "%N(#{env})"
|
|
90
|
-
|
|
90
|
+
# Respect user's configured irb name.
|
|
91
|
+
IRB.conf[:IRB_NAME] = @app.name if IRB.conf[:IRB_NAME] == "irb"
|
|
91
92
|
|
|
92
93
|
IRB.conf[:PROMPT][:RAILS_PROMPT] = {
|
|
93
94
|
PROMPT_I: "#{prompt_prefix}> ",
|
|
@@ -107,10 +108,6 @@ module Rails
|
|
|
107
108
|
end
|
|
108
109
|
end
|
|
109
110
|
|
|
110
|
-
# Because some users/libs use Rails::ConsoleMethods to extend Rails console,
|
|
111
|
-
# we still include it for backward compatibility.
|
|
112
|
-
IRB::ExtendCommandBundle.include ConsoleMethods
|
|
113
|
-
|
|
114
111
|
# Respect user's choice of prompt mode.
|
|
115
112
|
IRB.conf[:PROMPT_MODE] = :RAILS_PROMPT if IRB.conf[:PROMPT_MODE] == :DEFAULT
|
|
116
113
|
IRB::Irb.new.run(IRB.conf)
|
|
@@ -38,8 +38,8 @@ Set up Git to Diff Credentials:
|
|
|
38
38
|
Running the command enrolls the project such that all credentials files use the
|
|
39
39
|
"rails_credentials" diff driver in .gitattributes.
|
|
40
40
|
|
|
41
|
-
Additionally since Git requires the driver itself to be set up in a config file
|
|
42
|
-
that isn't tracked Rails automatically ensures it's configured when running
|
|
41
|
+
Additionally, since Git requires the driver itself to be set up in a config file
|
|
42
|
+
that isn't tracked, Rails automatically ensures it's configured when running
|
|
43
43
|
`<%= executable(:edit) %>`.
|
|
44
44
|
|
|
45
45
|
Otherwise each co-worker would have to run enable manually, including on each new
|
|
@@ -48,8 +48,8 @@ Set up Git to Diff Credentials:
|
|
|
48
48
|
To disenroll from this feature, run `<%= executable(:diff) %> --disenroll`.
|
|
49
49
|
|
|
50
50
|
Editing Credentials:
|
|
51
|
-
|
|
52
|
-
contents to edit the encrypted credentials.
|
|
51
|
+
`<%= executable(:edit) %>` will open a temporary file in `$VISUAL` or `$EDITOR`
|
|
52
|
+
with the decrypted contents to edit the encrypted credentials.
|
|
53
53
|
|
|
54
54
|
When the temporary file is next saved the contents are encrypted and written to
|
|
55
55
|
`config/credentials.yml.enc` while the file itself is destroyed to prevent credentials
|
|
@@ -128,7 +128,11 @@ module Rails
|
|
|
128
128
|
end
|
|
129
129
|
|
|
130
130
|
def extract_environment_from_path(path)
|
|
131
|
-
available_environments.find { |env| path.end_with?("#{env}.yml.enc") }
|
|
131
|
+
available_environments.find { |env| path.end_with?("#{env}.yml.enc") } || extract_custom_environment(path)
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def extract_custom_environment(path)
|
|
135
|
+
path =~ %r{config/credentials/(.+)\.yml\.enc} && $1
|
|
132
136
|
end
|
|
133
137
|
end
|
|
134
138
|
end
|
|
@@ -5,7 +5,7 @@ require "rails/dev_caching"
|
|
|
5
5
|
module Rails
|
|
6
6
|
module Command
|
|
7
7
|
class DevCommand < Base # :nodoc:
|
|
8
|
-
desc "cache", "Toggle development mode caching on/off"
|
|
8
|
+
desc "cache", "Toggle Action Controller development mode caching on/off"
|
|
9
9
|
def cache
|
|
10
10
|
Rails::DevCaching.enable_by_file
|
|
11
11
|
end
|
|
@@ -24,9 +24,10 @@ module Rails
|
|
|
24
24
|
app_name: Rails.application.railtie_name.chomp("_application"),
|
|
25
25
|
database: !!defined?(ActiveRecord) && database,
|
|
26
26
|
active_storage: !!defined?(ActiveStorage),
|
|
27
|
-
redis: !!(defined?(ActionCable) || defined?(ActiveJob)),
|
|
27
|
+
redis: !!((defined?(ActionCable) && !defined?(SolidCable)) || (defined?(ActiveJob) && !defined?(SolidQueue))),
|
|
28
28
|
system_test: File.exist?("test/application_system_test_case.rb"),
|
|
29
29
|
node: File.exist?(".node-version"),
|
|
30
|
+
kamal: File.exist?("config/deploy.yml"),
|
|
30
31
|
}
|
|
31
32
|
end
|
|
32
33
|
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Rails
|
|
4
|
+
module Command
|
|
5
|
+
class StatsCommand < Base # :nodoc:
|
|
6
|
+
desc "stats", "Report code statistics (KLOCs, etc) from the application or engine"
|
|
7
|
+
def perform
|
|
8
|
+
require "rails/code_statistics"
|
|
9
|
+
boot_application!
|
|
10
|
+
|
|
11
|
+
stat_directories = Rails::CodeStatistics.directories.map do |name, dir|
|
|
12
|
+
[name, Rails::Command.application_root.join(dir)]
|
|
13
|
+
end.select { |name, dir| File.directory?(dir) }
|
|
14
|
+
|
|
15
|
+
Rails::CodeStatistics.new(*stat_directories).to_s
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -1,23 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
def self.method_added(_method_name)
|
|
11
|
-
raise_deprecation_warning
|
|
12
|
-
super
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def self.raise_deprecation_warning
|
|
16
|
-
Rails.deprecator.warn(<<~MSG, caller_locations(2..2))
|
|
17
|
-
Extending Rails console through `Rails::ConsoleMethods` is deprecated and will be removed in Rails 8.0.
|
|
18
|
-
Please directly use IRB's extension API to add new commands or helpers to the console.
|
|
19
|
-
For more details, please visit: https://github.com/ruby/irb/blob/master/EXTEND_IRB.md
|
|
20
|
-
MSG
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|
|
3
|
+
Rails.deprecator.warn(<<~MSG, caller_locations(0..1))
|
|
4
|
+
`rails/console/methods` has been deprecated and will be removed in Rails 8.1.
|
|
5
|
+
Please directly use IRB's extension API to add new commands or helpers to the console.
|
|
6
|
+
For more details, please visit: https://github.com/ruby/irb/blob/master/EXTEND_IRB.md
|
|
7
|
+
MSG
|
data/lib/rails/dev_caching.rb
CHANGED
|
@@ -12,10 +12,10 @@ module Rails
|
|
|
12
12
|
|
|
13
13
|
if File.exist?(FILE)
|
|
14
14
|
delete_cache_file
|
|
15
|
-
puts "
|
|
15
|
+
puts "Action Controller caching disabled for development mode."
|
|
16
16
|
else
|
|
17
17
|
create_cache_file
|
|
18
|
-
puts "
|
|
18
|
+
puts "Action Controller caching enabled for development mode."
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
FileUtils.touch "tmp/restart.txt"
|
|
@@ -6,7 +6,7 @@ module Rails
|
|
|
6
6
|
class Engine
|
|
7
7
|
class Configuration < ::Rails::Railtie::Configuration
|
|
8
8
|
attr_reader :root
|
|
9
|
-
attr_accessor :middleware, :javascript_path
|
|
9
|
+
attr_accessor :middleware, :javascript_path, :route_set_class, :default_scope
|
|
10
10
|
attr_writer :eager_load_paths, :autoload_once_paths, :autoload_paths
|
|
11
11
|
|
|
12
12
|
# An array of custom autoload paths to be added to the ones defined
|
|
@@ -44,6 +44,8 @@ module Rails
|
|
|
44
44
|
@generators = app_generators.dup
|
|
45
45
|
@middleware = Rails::Configuration::MiddlewareStackProxy.new
|
|
46
46
|
@javascript_path = "javascript"
|
|
47
|
+
@route_set_class = ActionDispatch::Routing::RouteSet
|
|
48
|
+
@default_scope = nil
|
|
47
49
|
|
|
48
50
|
@autoload_paths = []
|
|
49
51
|
@autoload_once_paths = []
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# :markup: markdown
|
|
4
|
+
|
|
5
|
+
require "action_dispatch/routing/route_set"
|
|
6
|
+
|
|
7
|
+
# :enddoc:
|
|
8
|
+
|
|
9
|
+
module Rails
|
|
10
|
+
class Engine
|
|
11
|
+
class LazyRouteSet < ActionDispatch::Routing::RouteSet
|
|
12
|
+
class NamedRouteCollection < ActionDispatch::Routing::RouteSet::NamedRouteCollection
|
|
13
|
+
def route_defined?(name)
|
|
14
|
+
Rails.application&.reload_routes_unless_loaded
|
|
15
|
+
super
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
module ProxyUrlHelpers
|
|
20
|
+
def url_for(options)
|
|
21
|
+
Rails.application&.reload_routes_unless_loaded
|
|
22
|
+
super
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def full_url_for(options)
|
|
26
|
+
Rails.application&.reload_routes_unless_loaded
|
|
27
|
+
super
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def route_for(name, *args)
|
|
31
|
+
Rails.application&.reload_routes_unless_loaded
|
|
32
|
+
super
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def optimize_routes_generation?
|
|
36
|
+
Rails.application&.reload_routes_unless_loaded
|
|
37
|
+
super
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def initialize(config = DEFAULT_CONFIG)
|
|
42
|
+
super
|
|
43
|
+
self.named_routes = NamedRouteCollection.new
|
|
44
|
+
named_routes.url_helpers_module.prepend(method_missing_module)
|
|
45
|
+
named_routes.path_helpers_module.prepend(method_missing_module)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def generate_extras(options, recall = {})
|
|
49
|
+
Rails.application&.reload_routes_unless_loaded
|
|
50
|
+
|
|
51
|
+
super(options, recall)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def generate_url_helpers(supports_path)
|
|
55
|
+
super.tap { |mod| mod.singleton_class.prepend(ProxyUrlHelpers) }
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def call(req)
|
|
59
|
+
Rails.application&.reload_routes_unless_loaded
|
|
60
|
+
super
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def polymorphic_mappings
|
|
64
|
+
Rails.application&.reload_routes_unless_loaded
|
|
65
|
+
super
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def draw(&block)
|
|
69
|
+
Rails.application&.reload_routes_unless_loaded
|
|
70
|
+
super
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def recognize_path(path, environment = {})
|
|
74
|
+
Rails.application&.reload_routes_unless_loaded
|
|
75
|
+
super
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def recognize_path_with_request(...)
|
|
79
|
+
Rails.application&.reload_routes_unless_loaded
|
|
80
|
+
super
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def routes
|
|
84
|
+
Rails.application&.reload_routes_unless_loaded
|
|
85
|
+
super
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
private
|
|
89
|
+
def method_missing_module
|
|
90
|
+
@method_missing_module ||= Module.new do
|
|
91
|
+
private
|
|
92
|
+
def method_missing(...)
|
|
93
|
+
if Rails.application&.reload_routes_unless_loaded
|
|
94
|
+
public_send(...)
|
|
95
|
+
else
|
|
96
|
+
super
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def respond_to_missing?(...)
|
|
101
|
+
if Rails.application&.reload_routes_unless_loaded
|
|
102
|
+
respond_to?(...)
|
|
103
|
+
else
|
|
104
|
+
super
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
data/lib/rails/engine.rb
CHANGED
|
@@ -6,7 +6,6 @@ require "active_support/callbacks"
|
|
|
6
6
|
require "active_support/core_ext/module/delegation"
|
|
7
7
|
require "active_support/core_ext/object/try"
|
|
8
8
|
require "pathname"
|
|
9
|
-
require "thread"
|
|
10
9
|
|
|
11
10
|
module Rails
|
|
12
11
|
# +Rails::Engine+ allows you to wrap a specific \Rails application or subset of
|
|
@@ -246,7 +245,7 @@ module Rails
|
|
|
246
245
|
# polymorphic_url(MyEngine::Article.new)
|
|
247
246
|
# # => "articles_path" # not "my_engine_articles_path"
|
|
248
247
|
#
|
|
249
|
-
#
|
|
248
|
+
# form_with(model: MyEngine::Article.new) do
|
|
250
249
|
# text_field :title # => <input type="text" name="article[title]" id="article_title" />
|
|
251
250
|
# end
|
|
252
251
|
#
|
|
@@ -295,7 +294,7 @@ module Rails
|
|
|
295
294
|
# All you need to do is pass the helper as the first element in array with
|
|
296
295
|
# attributes for URL:
|
|
297
296
|
#
|
|
298
|
-
#
|
|
297
|
+
# form_with(model: [my_engine, @user])
|
|
299
298
|
#
|
|
300
299
|
# This code will use <tt>my_engine.user_path(@user)</tt> to generate the proper route.
|
|
301
300
|
#
|
|
@@ -349,6 +348,7 @@ module Rails
|
|
|
349
348
|
# config.railties_order = [Blog::Engine, :main_app, :all]
|
|
350
349
|
class Engine < Railtie
|
|
351
350
|
autoload :Configuration, "rails/engine/configuration"
|
|
351
|
+
autoload :LazyRouteSet, "rails/engine/lazy_route_set"
|
|
352
352
|
|
|
353
353
|
class << self
|
|
354
354
|
attr_accessor :called_from, :isolated
|
|
@@ -385,7 +385,8 @@ module Rails
|
|
|
385
385
|
def isolate_namespace(mod)
|
|
386
386
|
engine_name(generate_railtie_name(mod.name))
|
|
387
387
|
|
|
388
|
-
|
|
388
|
+
config.default_scope = { module: ActiveSupport::Inflector.underscore(mod.name) }
|
|
389
|
+
|
|
389
390
|
self.isolated = true
|
|
390
391
|
|
|
391
392
|
unless mod.respond_to?(:railtie_namespace)
|
|
@@ -451,7 +452,6 @@ module Rails
|
|
|
451
452
|
# Load console and invoke the registered hooks.
|
|
452
453
|
# Check Rails::Railtie.console for more info.
|
|
453
454
|
def load_console(app = self)
|
|
454
|
-
require "rails/console/methods"
|
|
455
455
|
run_console_blocks(app)
|
|
456
456
|
self
|
|
457
457
|
end
|
|
@@ -543,7 +543,7 @@ module Rails
|
|
|
543
543
|
# Defines the routes for this engine. If a block is given to
|
|
544
544
|
# routes, it is appended to the engine.
|
|
545
545
|
def routes(&block)
|
|
546
|
-
@routes ||=
|
|
546
|
+
@routes ||= config.route_set_class.new_with_config(config)
|
|
547
547
|
@routes.append(&block) if block_given?
|
|
548
548
|
@routes
|
|
549
549
|
end
|
|
@@ -588,6 +588,10 @@ module Rails
|
|
|
588
588
|
config.eager_load_paths.freeze
|
|
589
589
|
end
|
|
590
590
|
|
|
591
|
+
initializer :make_routes_lazy, before: :bootstrap_hook do |app|
|
|
592
|
+
config.route_set_class = LazyRouteSet if Rails.env.local?
|
|
593
|
+
end
|
|
594
|
+
|
|
591
595
|
initializer :add_routing_paths do |app|
|
|
592
596
|
routing_paths = paths["config/routes.rb"].existent
|
|
593
597
|
external_paths = self.paths["config/routes"].paths
|
data/lib/rails/gem_version.rb
CHANGED
|
@@ -520,9 +520,9 @@ module Rails
|
|
|
520
520
|
|
|
521
521
|
def route_namespace_pattern(namespace)
|
|
522
522
|
namespace.each_with_index.reverse_each.reduce(nil) do |pattern, (name, i)|
|
|
523
|
-
|
|
524
|
-
blank_or_indented_line = "^[ ]*\n|^#{
|
|
525
|
-
"(?:(?:#{blank_or_indented_line})*?^(#{
|
|
523
|
+
cumulative_margin = "\\#{i + 1}[ ]{2}"
|
|
524
|
+
blank_or_indented_line = "^[ ]*\n|^#{cumulative_margin}.*\n"
|
|
525
|
+
"(?:(?:#{blank_or_indented_line})*?^(#{cumulative_margin})namespace :#{name} do\n#{pattern})?"
|
|
526
526
|
end.then do |pattern|
|
|
527
527
|
/^([ ]*).+\.routes\.draw do[ ]*\n#{pattern}/
|
|
528
528
|
end
|
|
@@ -7,19 +7,20 @@ require "open-uri"
|
|
|
7
7
|
require "tsort"
|
|
8
8
|
require "uri"
|
|
9
9
|
require "rails/generators"
|
|
10
|
+
require "rails/generators/bundle_helper"
|
|
10
11
|
require "active_support/core_ext/array/extract_options"
|
|
11
12
|
|
|
12
13
|
module Rails
|
|
13
14
|
module Generators
|
|
14
15
|
class AppBase < Base # :nodoc:
|
|
15
16
|
include AppName
|
|
17
|
+
include BundleHelper
|
|
16
18
|
|
|
17
19
|
NODE_LTS_VERSION = "20.11.1"
|
|
18
20
|
BUN_VERSION = "1.0.1"
|
|
19
21
|
|
|
20
22
|
JAVASCRIPT_OPTIONS = %w( importmap bun webpack esbuild rollup )
|
|
21
23
|
CSS_OPTIONS = %w( tailwind bootstrap bulma postcss sass )
|
|
22
|
-
ASSET_PIPELINE_OPTIONS = %w( none sprockets propshaft )
|
|
23
24
|
|
|
24
25
|
attr_accessor :rails_template
|
|
25
26
|
add_shebang_option!
|
|
@@ -74,10 +75,6 @@ module Rails
|
|
|
74
75
|
|
|
75
76
|
class_option :skip_asset_pipeline, type: :boolean, aliases: "-A", default: nil
|
|
76
77
|
|
|
77
|
-
class_option :asset_pipeline, type: :string, aliases: "-a", default: "sprockets",
|
|
78
|
-
enum: ASSET_PIPELINE_OPTIONS,
|
|
79
|
-
desc: "Choose your asset pipeline"
|
|
80
|
-
|
|
81
78
|
class_option :skip_javascript, type: :boolean, aliases: ["-J", "--skip-js"], default: (true if name == "plugin"),
|
|
82
79
|
desc: "Skip JavaScript files"
|
|
83
80
|
|
|
@@ -99,6 +96,9 @@ module Rails
|
|
|
99
96
|
class_option :skip_dev_gems, type: :boolean, default: nil,
|
|
100
97
|
desc: "Skip development gems (e.g., web-console)"
|
|
101
98
|
|
|
99
|
+
class_option :skip_thruster, type: :boolean, default: nil,
|
|
100
|
+
desc: "Skip Thruster setup"
|
|
101
|
+
|
|
102
102
|
class_option :skip_rubocop, type: :boolean, default: nil,
|
|
103
103
|
desc: "Skip RuboCop setup"
|
|
104
104
|
|
|
@@ -108,10 +108,16 @@ module Rails
|
|
|
108
108
|
class_option :skip_ci, type: :boolean, default: nil,
|
|
109
109
|
desc: "Skip GitHub CI files"
|
|
110
110
|
|
|
111
|
+
class_option :skip_kamal, type: :boolean, default: nil,
|
|
112
|
+
desc: "Skip Kamal setup"
|
|
113
|
+
|
|
114
|
+
class_option :skip_solid, type: :boolean, default: nil,
|
|
115
|
+
desc: "Skip Solid Cache, Queue, and Cable setup"
|
|
116
|
+
|
|
111
117
|
class_option :dev, type: :boolean, default: nil,
|
|
112
118
|
desc: "Set up the #{name} with Gemfile pointing to your Rails checkout"
|
|
113
119
|
|
|
114
|
-
class_option :devcontainer, type: :boolean, default:
|
|
120
|
+
class_option :devcontainer, type: :boolean, default: nil,
|
|
115
121
|
desc: "Generate devcontainer files"
|
|
116
122
|
|
|
117
123
|
class_option :edge, type: :boolean, default: nil,
|
|
@@ -197,7 +203,7 @@ module Rails
|
|
|
197
203
|
|
|
198
204
|
OPTION_IMPLICATIONS = { # :nodoc:
|
|
199
205
|
skip_active_job: [:skip_action_mailer, :skip_active_storage],
|
|
200
|
-
skip_active_record: [:skip_active_storage],
|
|
206
|
+
skip_active_record: [:skip_active_storage, :skip_solid],
|
|
201
207
|
skip_active_storage: [:skip_action_mailbox, :skip_action_text],
|
|
202
208
|
skip_javascript: [:skip_hotwire],
|
|
203
209
|
}
|
|
@@ -287,12 +293,7 @@ module Rails
|
|
|
287
293
|
end
|
|
288
294
|
|
|
289
295
|
def asset_pipeline_gemfile_entry
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
if options[:asset_pipeline] == "sprockets"
|
|
293
|
-
GemfileEntry.floats "sprockets-rails",
|
|
294
|
-
"The original asset pipeline for Rails [https://github.com/rails/sprockets-rails]"
|
|
295
|
-
elsif options[:asset_pipeline] == "propshaft"
|
|
296
|
+
unless skip_asset_pipeline?
|
|
296
297
|
GemfileEntry.floats "propshaft", "The modern asset pipeline for Rails [https://github.com/rails/propshaft]"
|
|
297
298
|
end
|
|
298
299
|
end
|
|
@@ -386,12 +387,8 @@ module Rails
|
|
|
386
387
|
options[:skip_asset_pipeline]
|
|
387
388
|
end
|
|
388
389
|
|
|
389
|
-
def
|
|
390
|
-
|
|
391
|
-
end
|
|
392
|
-
|
|
393
|
-
def skip_propshaft?
|
|
394
|
-
skip_asset_pipeline? || options[:asset_pipeline] != "propshaft"
|
|
390
|
+
def skip_thruster?
|
|
391
|
+
options[:skip_thruster]
|
|
395
392
|
end
|
|
396
393
|
|
|
397
394
|
def skip_rubocop?
|
|
@@ -414,6 +411,14 @@ module Rails
|
|
|
414
411
|
options[:devcontainer]
|
|
415
412
|
end
|
|
416
413
|
|
|
414
|
+
def skip_kamal?
|
|
415
|
+
options[:skip_kamal]
|
|
416
|
+
end
|
|
417
|
+
|
|
418
|
+
def skip_solid?
|
|
419
|
+
options[:skip_solid]
|
|
420
|
+
end
|
|
421
|
+
|
|
417
422
|
class GemfileEntry < Struct.new(:name, :version, :comment, :options, :commented_out)
|
|
418
423
|
def initialize(name, version, comment, options = {}, commented_out = false)
|
|
419
424
|
super
|
|
@@ -536,6 +541,11 @@ module Rails
|
|
|
536
541
|
"latest"
|
|
537
542
|
end
|
|
538
543
|
|
|
544
|
+
def yarn_through_corepack?
|
|
545
|
+
true if dockerfile_yarn_version == "latest"
|
|
546
|
+
dockerfile_yarn_version >= "2"
|
|
547
|
+
end
|
|
548
|
+
|
|
539
549
|
def dockerfile_bun_version
|
|
540
550
|
using_bun? and `bun --version`[/\d+\.\d+\.\d+/]
|
|
541
551
|
rescue
|
|
@@ -572,7 +582,7 @@ module Rails
|
|
|
572
582
|
end
|
|
573
583
|
|
|
574
584
|
def dockerfile_base_packages
|
|
575
|
-
# Add curl to work with the default
|
|
585
|
+
# Add curl to work with the default health check strategy in Kamal
|
|
576
586
|
packages = ["curl"]
|
|
577
587
|
|
|
578
588
|
# ActiveRecord databases
|
|
@@ -606,6 +616,14 @@ module Rails
|
|
|
606
616
|
packages.compact.sort
|
|
607
617
|
end
|
|
608
618
|
|
|
619
|
+
def ci_packages
|
|
620
|
+
if depends_on_system_test?
|
|
621
|
+
dockerfile_build_packages << "google-chrome-stable"
|
|
622
|
+
else
|
|
623
|
+
dockerfile_build_packages
|
|
624
|
+
end
|
|
625
|
+
end
|
|
626
|
+
|
|
609
627
|
def css_gemfile_entry
|
|
610
628
|
return if options[:api]
|
|
611
629
|
return unless options[:css]
|
|
@@ -620,35 +638,9 @@ module Rails
|
|
|
620
638
|
end
|
|
621
639
|
|
|
622
640
|
def cable_gemfile_entry
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
GemfileEntry.new("redis", ">= 4.0.1", comment, {}, true)
|
|
627
|
-
end
|
|
628
|
-
|
|
629
|
-
def bundle_command(command, env = {})
|
|
630
|
-
say_status :run, "bundle #{command}"
|
|
631
|
-
|
|
632
|
-
# We are going to shell out rather than invoking Bundler::CLI.new(command)
|
|
633
|
-
# because `rails new` loads the Thor gem and on the other hand bundler uses
|
|
634
|
-
# its own vendored Thor, which could be a different version. Running both
|
|
635
|
-
# things in the same process is a recipe for a night with paracetamol.
|
|
636
|
-
#
|
|
637
|
-
# Thanks to James Tucker for the Gem tricks involved in this call.
|
|
638
|
-
_bundle_command = Gem.bin_path("bundler", "bundle")
|
|
639
|
-
|
|
640
|
-
require "bundler"
|
|
641
|
-
Bundler.with_original_env do
|
|
642
|
-
exec_bundle_command(_bundle_command, command, env)
|
|
643
|
-
end
|
|
644
|
-
end
|
|
645
|
-
|
|
646
|
-
def exec_bundle_command(bundle_command, command, env)
|
|
647
|
-
full_command = %Q["#{Gem.ruby}" "#{bundle_command}" #{command}]
|
|
648
|
-
if options[:quiet]
|
|
649
|
-
system(env, full_command, out: File::NULL)
|
|
650
|
-
else
|
|
651
|
-
system(env, full_command)
|
|
641
|
+
if !options[:skip_action_cable] && options[:skip_solid]
|
|
642
|
+
comment = "Use Redis adapter to run Action Cable in production"
|
|
643
|
+
GemfileEntry.new("redis", ">= 4.0.1", comment, {}, true)
|
|
652
644
|
end
|
|
653
645
|
end
|
|
654
646
|
|
|
@@ -656,10 +648,6 @@ module Rails
|
|
|
656
648
|
!(options[:skip_bundle] || options[:pretend])
|
|
657
649
|
end
|
|
658
650
|
|
|
659
|
-
def bundler_windows_platforms
|
|
660
|
-
Gem.rubygems_version >= Gem::Version.new("3.3.22") ? "windows" : "mswin mswin64 mingw x64_mingw"
|
|
661
|
-
end
|
|
662
|
-
|
|
663
651
|
def depends_on_system_test?
|
|
664
652
|
!(options[:skip_system_test] || options[:skip_test] || options[:api])
|
|
665
653
|
end
|
|
@@ -721,6 +709,25 @@ module Rails
|
|
|
721
709
|
end
|
|
722
710
|
end
|
|
723
711
|
|
|
712
|
+
def run_kamal
|
|
713
|
+
return if options[:skip_kamal] || !bundle_install?
|
|
714
|
+
|
|
715
|
+
bundle_command "binstubs kamal"
|
|
716
|
+
bundle_command "exec kamal init"
|
|
717
|
+
|
|
718
|
+
template "kamal-secrets.tt", ".kamal/secrets", force: true
|
|
719
|
+
template "config/deploy.yml", force: true
|
|
720
|
+
end
|
|
721
|
+
|
|
722
|
+
def run_solid
|
|
723
|
+
return if skip_solid? || !bundle_install?
|
|
724
|
+
|
|
725
|
+
commands = "solid_cache:install solid_queue:install"
|
|
726
|
+
commands += " solid_cable:install" unless skip_action_cable?
|
|
727
|
+
|
|
728
|
+
rails_command commands
|
|
729
|
+
end
|
|
730
|
+
|
|
724
731
|
def add_bundler_platforms
|
|
725
732
|
if bundle_install? && !jruby?
|
|
726
733
|
# The vast majority of Rails apps will be deployed on `x86_64-linux`.
|
|
@@ -731,14 +738,27 @@ module Rails
|
|
|
731
738
|
end
|
|
732
739
|
end
|
|
733
740
|
|
|
741
|
+
def generate_bundler_binstub
|
|
742
|
+
if bundle_install?
|
|
743
|
+
bundle_command("binstubs bundler")
|
|
744
|
+
end
|
|
745
|
+
end
|
|
746
|
+
|
|
734
747
|
def jruby?
|
|
735
748
|
defined?(JRUBY_VERSION)
|
|
736
749
|
end
|
|
737
750
|
|
|
738
|
-
def
|
|
739
|
-
if
|
|
740
|
-
|
|
751
|
+
def version_manager_ruby_version
|
|
752
|
+
return ENV["RBENV_VERSION"] if ENV["RBENV_VERSION"]
|
|
753
|
+
return ENV["rvm_ruby_string"] if ENV["rvm_ruby_string"]
|
|
754
|
+
|
|
755
|
+
version = if RUBY_ENGINE == "ruby"
|
|
756
|
+
Gem.ruby_version.to_s.sub(/\.([a-zA-Z])/, '-\1')
|
|
757
|
+
else
|
|
758
|
+
RUBY_ENGINE_VERSION
|
|
741
759
|
end
|
|
760
|
+
|
|
761
|
+
"#{RUBY_ENGINE}-#{version}"
|
|
742
762
|
end
|
|
743
763
|
|
|
744
764
|
def empty_directory_with_keep_file(destination, config = {})
|