Generate config.autoload_lib(...) for new apps

This commit is contained in:
Xavier Noria 2023-08-25 09:22:25 +02:00
parent 20af938f39
commit b16adcd4e4
6 changed files with 53 additions and 14 deletions

@ -71,6 +71,16 @@ class Railtie < Rails::Railtie # :nodoc:
initializer "action_mailer.set_autoload_paths", before: :set_autoload_paths do |app|
options = app.config.action_mailer
app.config.paths["test/mailers/previews"].concat(options.preview_paths)
# Preview paths configuration needs a pass.
#
# config.paths is cached as soon as it is accessed. Therefore, mutating
# paths["test/mailers/previews"] does not guarantee config.autoload_paths
# is going to include them.
#
# If config.paths was accessed before, config.autoload_paths is going to
# have whatever paths["test/mailers/previews"] had when cached.
app.config.autoload_paths.concat(options.preview_paths)
end
initializer "action_mailer.compile_config_methods" do

@ -1,3 +1,13 @@
* `config/application.rb` now includes
```ruby
config.autoload_lib(ignore: %w(assets tasks))
```
In practice, this means that new 7.1 applications autoload from `lib` out of the box.
*Xavier Noria*
* Add an option to start rails console in sandbox mode by default
`sandbox_by_default` option is added to start rails console in sandbox

@ -50,6 +50,9 @@ def paths
paths.add "app/mailers", eager_load: true
paths.add "app/views"
# If you add more lib subdirectories here that should not be managed
# by the main autoloader, please update the config.autoload_lib call
# in the template that generates config/application.rb accordingly.
paths.add "lib", load_path: true
paths.add "lib/assets", glob: "*"
paths.add "lib/tasks", glob: "**/*.rake"

@ -15,6 +15,9 @@ module <%= app_const_base %>
config.load_defaults Rails::VERSION::STRING.to_f
<%- end -%>
# Please, see https://guides.rubyonrails.org/autoloading_and_reloading_constants.html#config-autoload-lib-ignore.
config.autoload_lib(ignore: %w(assets tasks))
# Configuration for the application, engines, and railties goes here.
#
# These settings can be overridden in specific environments using the files

@ -2119,8 +2119,10 @@ def index
end
end
test "autoload paths will exclude the configured javascript_path" do
add_to_config "config.javascript_path = 'webpack'"
test "autoload paths do not include custom config.javascript_paths" do
# The config.javascript_path assignment has to be in place before
# config.paths is accessed, since their compilation uses the value.
add_to_top_of_config "config.javascript_path = 'webpack'"
app_dir("app/webpack")
app "development"
@ -2148,10 +2150,10 @@ def index
assert_empty Rails.configuration.paths.load_paths - $LOAD_PATH
end
test "autoload paths are not added to $LOAD_PATH by default" do
test "autoload paths are not added to $LOAD_PATH by default, except for lib" do
app "development"
assert_empty ActiveSupport::Dependencies.autoload_paths & $LOAD_PATH
assert_equal ["#{app_path}/lib"], ActiveSupport::Dependencies.autoload_paths & $LOAD_PATH
# Precondition, ensure we are testing something next.
assert_not_empty Rails.configuration.paths.load_paths
@ -2170,6 +2172,23 @@ def index
assert_includes $LOAD_PATH, lib
end
test "config.autoload_lib(...) is generated by default" do
app_file "lib/x.rb", "X = true"
app_file "lib/m/x.rb", "M::X = true"
app_file "lib/assets/x.rb", "Assets::X = true"
app_file "lib/tasks/x.rb", "Tasks::X = true"
app "development"
assert_includes Rails.application.config.autoload_paths, "#{app_path}/lib"
assert_includes Rails.application.config.eager_load_paths, "#{app_path}/lib"
assert X
assert M::X
assert_raises(NameError) { Assets }
assert_raises(NameError) { Tasks }
end
test "autoload paths can be set in the config file of the environment" do
app_dir "custom_autoload_path"
app_dir "custom_autoload_once_path"
@ -2197,6 +2216,7 @@ def index
app_file "lib/tasks/x.rb", "Tasks::X = true"
app_file "lib/generators/x.rb", "Generators::X = true"
remove_from_config "config\\.#{method_name}.*"
add_to_config "config.#{method_name}(ignore: %w(tasks generators))"
app "development"
@ -2215,6 +2235,7 @@ def index
app_file "lib/x.rb", "X = true"
app_file "lib/tasks/x.rb", "Tasks::X = true"
remove_from_config "config\\.#{method_name}.*"
add_to_config "config.#{method_name}(ignore: [])"
app "development"
@ -2232,6 +2253,7 @@ def index
app_file "lib/x.rb", "X = true"
app_file "lib/tasks/x.rb", "Tasks::X = true"
remove_from_config "config\\.#{method_name}.*"
add_to_config "config.#{method_name}(ignore: 'tasks')"
app "development"
@ -2249,6 +2271,7 @@ def index
app_file "lib/x.rb", "X = true"
app_file "lib/tasks/x.rb", "Tasks::X = true"
remove_from_config "config\\.#{method_name}.*"
add_to_config "config.#{method_name}(ignore: nil)"
app "development"

@ -234,27 +234,17 @@ module ZeitwerkIntegrationTestExtras; end
$zeitwerk_integration_test_user = false
app_file "app/models/user.rb", "class User; end; $zeitwerk_integration_test_user = true"
$zeitwerk_integration_test_lib = false
app_dir "lib"
app_file "lib/webhook_hacks.rb", "WebhookHacks = 1; $zeitwerk_integration_test_lib = true"
$zeitwerk_integration_test_extras = false
app_dir "extras"
app_file "extras/websocket_hacks.rb", "WebsocketHacks = 1; $zeitwerk_integration_test_extras = true"
add_to_config "config.autoload_paths << '#{app_path}/lib'"
add_to_config "config.autoload_once_paths << '#{app_path}/extras'"
boot("production")
assert $zeitwerk_integration_test_user
assert_not $zeitwerk_integration_test_lib
assert_not $zeitwerk_integration_test_extras
assert WebhookHacks
assert WebsocketHacks
assert $zeitwerk_integration_test_lib
assert $zeitwerk_integration_test_extras
end