From 9f20404dd943b8daa704620fbdb7ebd56cc552c2 Mon Sep 17 00:00:00 2001 From: Tomasz Stolarczyk Date: Thu, 9 Nov 2023 20:22:22 +0100 Subject: [PATCH] Generate event to handlers and handler to events mappings. The script generates two classes: `EventToHandlers` and HandlerToEvents in the Rails `lib` directory so it's easier to see the big picture of all subscriptions. It also helps to navigate between subscriptions and events. Execute the script using following command: bin/rails r script/big_picture.rb --- rails_application/.gitignore | 4 + rails_application/script/big_picture.rb | 107 ++++++++++++++++++++++++ 2 files changed, 111 insertions(+) create mode 100644 rails_application/script/big_picture.rb diff --git a/rails_application/.gitignore b/rails_application/.gitignore index 6d962d3ee..7714eaa69 100644 --- a/rails_application/.gitignore +++ b/rails_application/.gitignore @@ -31,3 +31,7 @@ yarn-debug.log* .ruby-version /app/assets/builds/* !/app/assets/builds/.keep + +# Event to handlers and handler to events mappings generated by big_picture.rb script +/lib/event_to_handlers.rb +/lib/handler_to_events.rb \ No newline at end of file diff --git a/rails_application/script/big_picture.rb b/rails_application/script/big_picture.rb new file mode 100644 index 000000000..77ed0de0a --- /dev/null +++ b/rails_application/script/big_picture.rb @@ -0,0 +1,107 @@ +# frozen_string_literal: true + +class GenerateFiles + EVENT_TO_HANDLERS_FILE = "lib/event_to_handlers.rb" + HANDLER_TO_EVENTS_FILE = "lib/handler_to_events.rb" + + def generate_event_to_handlers + File.open(EVENT_TO_HANDLERS_FILE, "w") do |f| + f.puts event_to_handlers_header + + all_event_types.sort.each do |event_type| + f.puts indent("#{event_type} => [", 6) + + event_store + .subscribers_for(event_type) + .each { |subscription| f.puts indent("#{handler_name(subscription)}, # #{handler_type(subscription)}", 8) } + f.puts indent("],", 6) + end + + f.print footer + end + end + + def generate_handler_to_events + handler_to_events = + all_event_types.each_with_object({}) do |event_type, acc| + event_store + .subscribers_for(event_type) + .each do |subscription| + acc[subscription] ||= [] + acc[subscription] << event_type + end + end + + File.open("lib/handler_to_events.rb", "w") do |f| + f.puts handler_to_events_header + + handler_to_events + .keys + .sort_by { |h| handler_name(h) } + .each do |handler| + f.puts indent("#{handler_name(handler)} => [", 6) + handler_to_events[handler].sort.each { |event_type| f.puts indent("#{event_type},", 8) } + f.puts indent("],", 6) + end + + f.print footer + end + end + + def handler_name(handler) + case handler + when Class + handler.name + when Method + "#{handler.receiver}.method(:#{handler.original_name})" + else + handler.class.name + end + end + + def all_event_types + ::Infra::Event.descendants.map(&:name) + end + + def handler_type(subscription) + subscription.respond_to?(:perform_async) ? "async" : "SYNC" + end + + def event_store + Rails.configuration.event_store + end + + def handler_to_events_header + <<~EOF + class HandlerToEvents + # File autogenerated with script/big_picture.rb + def events + { + EOF + end + + def event_to_handlers_header + <<~EOF + class EventToHandlers + # File autogenerated with script/big_picture.rb + def handlers + { + EOF + end + + def footer + <<~EOF + } + end + end + EOF + end + + def indent(str, spaces) + (" " * spaces) + str + end +end + +script = GenerateFiles.new +script.generate_event_to_handlers +script.generate_handler_to_events