DEV: Print a warning and restart server when editing non-autoloaded files (#13037)

DEV: Print a warning and restart server when editing non-autoloaded files (#13037)

This commit adds a listener on (almost) all .rb files in the repository. When a change occurs, it checks whether Zeitwerk is responsible for autoloading it. If not, a warning will be printed to the console and the server will be automatically restarted. Optionally, you can pass the AUTO_RESTART=0 environment variable to prevent auto-restart.

diff --git a/config/initializers/000-development_reload_warnings.rb b/config/initializers/000-development_reload_warnings.rb
new file mode 100644
index 0000000..4381eac
--- /dev/null
+++ b/config/initializers/000-development_reload_warnings.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+# Development helper which prints a warning when you edit a non-autoloaded ruby file.
+# These include initializers, middleware, plugin.rb files, and more.
+# Launch the server with AUTO_RESTART=0 to disable automatic restarts.
+if Rails.env.development? && !Rails.configuration.cache_classes
+  paths = [
+    *Dir["#{Rails.root}/app/*"].reject { |path| path.end_with? "/assets" },
+    "#{Rails.root}/config",
+    "#{Rails.root}/lib",
+    "#{Rails.root}/plugins"
+  ]
+
+  Listen.to(*paths, only: /\.rb$/) do |modified, added, removed|
+    auto_restart = ENV["AUTO_RESTART"] != "0"
+
+    files = modified + added + removed
+
+    not_autoloaded = files.filter_map do |file|
+      autoloaded = Rails.autoloaders.main.autoloads.key? file
+      Pathname.new(file).relative_path_from(Rails.root) if !autoloaded
+    end
+
+    if not_autoloaded.length > 0
+      message = auto_restart ? "Restarting server..." : "Server restart required. Automate this by setting AUTO_RESTART=1."
+      STDERR.puts "[DEV]: Edited files which are not autoloaded. #{message}"
+      STDERR.puts not_autoloaded.map { |path| "- #{path}".indent(7) }.join("\n")
+      Process.kill("USR2", Process.ppid) if auto_restart
+    end
+  end.start
+end

GitHub sha: b65af119

This commit appears in #13037 which was approved by eviltrout. It was merged by davidtaylorhq.