lib/eac_ruby_utils/root_module_setup.rb
# frozen_string_literal: true require 'active_support/inflector' require 'eac_ruby_utils/patches/module/require_sub' require 'zeitwerk' module EacRubyUtils class RootModuleSetup require_sub __FILE__, require_mode: :kernel DEFAULT_NAMESPACE = ::Object LIB_DIRECTORY_BASENAME = 'lib' class << self # @param root_module_file [String] def perform(root_module_file, &block) new(root_module_file, &block).perform end end attr_reader :block, :root_module_file # @param root_module_file [String] def initialize(root_module_file, &block) self.root_module_file = root_module_file self.block = block end # @return [Module, nil] def extension_for dirname = ::File.dirname(relative_root_module_file) return nil if ['.', '/', ''].include?(dirname) require dirname ::ActiveSupport::Inflector.constantize(dirname.camelize) end # @return [Zeitwerk::GemLoader] def loader @loader ||= ::Zeitwerk::Registry.loader_for_gem( root_module_file, namespace: namespace, warn_on_extra_files: true ) end # @return [Module] def namespace extension_for || DEFAULT_NAMESPACE end # @return [void] def perform perform_block perform_zeitwerk end # @return [String] def relative_root_module_file count = 0 current = ::File.basename(root_module_file, '.*') dirname = ::File.dirname(root_module_file) loop do ibr if dirname == '/' break current if ::File.basename(dirname) == LIB_DIRECTORY_BASENAME current = ::File.join(::File.basename(dirname), current) dirname = ::File.dirname(dirname) count += 1 end end # @return [String] def root_module_directory ::File.expand_path(::File.basename(root_module_file, '.*'), ::File.dirname(root_module_file)) end protected attr_writer :block, :root_module_file def perform_block instance_eval(&block) if block end # @return [void] def perform_zeitwerk loader.setup end end end