From b65af1193dbf1f017b788bfa65f992fc5dd8d6e8 Mon Sep 17 00:00:00 2001 From: David Taylor Date: Wed, 12 May 2021 10:32:45 +0100 Subject: [PATCH] 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. --- .../000-development_reload_warnings.rb | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 config/initializers/000-development_reload_warnings.rb diff --git a/config/initializers/000-development_reload_warnings.rb b/config/initializers/000-development_reload_warnings.rb new file mode 100644 index 00000000000..4381eacc166 --- /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