lib/hanami/application.rb in hanami-2.0.0.alpha5 vs lib/hanami/application.rb in hanami-2.0.0.alpha6

- old
+ new

@@ -5,21 +5,21 @@ require "hanami/configuration" require "pathname" require "rack" require "zeitwerk" require_relative "slice" -require_relative "application/autoloader/inflector_adapter" module Hanami # Hanami application class # # @since 2.0.0 class Application @_mutex = Mutex.new class << self def inherited(klass) + super @_mutex.synchronize do klass.class_eval do @_mutex = Mutex.new @_configuration = Hanami::Configuration.new(application_name: name, env: Hanami.env) @@ -37,47 +37,50 @@ # # rubocop:disable Metrics/ModuleLength module ClassMethods def self.extended(klass) klass.class_eval do - @inited = @booted = false + @prepared = @booted = false end end def configuration @_configuration end - alias config configuration + alias_method :config, :configuration - def init # rubocop:disable Metrics/MethodLength - return self if inited? + def prepare(provider_name = nil) + if provider_name + container.prepare(provider_name) + return self + end + return self if prepared? + configuration.finalize! - @autoloader = Zeitwerk::Loader.new - autoloader.inflector = Autoloader::InflectorAdapter.new(inflector) - load_settings + @autoloader = Zeitwerk::Loader.new @container = prepare_container @deps_module = prepare_deps_module load_slices - slices.values.each(&:init) + slices.each_value(&:prepare) slices.freeze - autoloader.setup + @autoloader.setup - @inited = true + @prepared = true self end def boot(&block) return self if booted? - init + prepare container.finalize!(&block) slices.values.each(&:boot) @@ -87,38 +90,38 @@ def shutdown container.shutdown! end - def inited? - @inited + def prepared? + @prepared end def booted? @booted end def autoloader - raise "Application not init'ed" unless defined?(@autoloader) + raise "Application not yet prepared" unless defined?(@autoloader) @autoloader end def container - raise "Application not init'ed" unless defined?(@container) + raise "Application not yet prepared" unless defined?(@container) @container end def deps - raise "Application not init'ed" unless defined?(@deps_module) + raise "Application not yet prepared" unless defined?(@deps_module) @deps_module end def router - raise "Application not init'ed" unless inited? + raise "Application not yet prepared" unless prepared? @_mutex.synchronize do @_router ||= load_router end end @@ -137,40 +140,36 @@ slice = Slice.new(self, name: name, **slice_args) slice.namespace.const_set :Slice, slice if slice.namespace # rubocop:disable Style/SafeNavigation slices[name.to_sym] = slice end - def register(*args, **opts, &block) - container.register(*args, **opts, &block) + def register(...) + container.register(...) end - def register_bootable(*args, **opts, &block) - container.boot(*args, **opts, &block) + def register_provider(...) + container.register_provider(...) end - def init_bootable(*args) - container.init(*args) + def start(...) + container.start(...) end - def start_bootable(*args) - container.start(*args) + def key?(...) + container.key?(...) end - def key?(*args) - container.key?(*args) - end - def keys container.keys end - def [](*args) - container[*args] + def [](...) + container.[](...) end - def resolve(*args) - container.resolve(*args) + def resolve(...) + container.resolve(...) end def settings @_settings ||= load_settings end @@ -199,11 +198,11 @@ configuration.inflector end # @api private def component_provider(component) - raise "Hanami.application must be inited before detecting providers" unless inited? + raise "Hanami.application must be prepared before detecting providers" unless prepared? # [Admin, Main, MyApp] or [MyApp::Admin, MyApp::Main, MyApp] providers = slices.values + [self] component_class = component.is_a?(Class) ? component : component.class @@ -219,58 +218,51 @@ def prepare_base_load_path base_path = File.join(root, "lib") $LOAD_PATH.unshift base_path unless $LOAD_PATH.include?(base_path) end + # rubocop:disable Metrics/AbcSize def prepare_container - define_container.tap do |container| - configure_container container - end - end + container = + begin + require "#{application_name}/container" + namespace.const_get :Container + rescue LoadError, NameError + namespace.const_set :Container, Class.new(Dry::System::Container) + end - def prepare_deps_module - define_deps_module - end - - def define_container - require "#{application_name}/container" - namespace.const_get :Container - rescue LoadError, NameError - namespace.const_set :Container, Class.new(Dry::System::Container) - end - - # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength - def configure_container(container) container.use :env, inferrer: -> { Hanami.env } + container.use :zeitwerk, loader: autoloader, run_setup: false, eager_load: false container.use :notifications - container.configure do |config| - config.inflector = configuration.inflector + container.config.root = configuration.root + container.config.inflector = configuration.inflector - config.root = configuration.root - config.bootable_dirs = [ - "config/boot", - Pathname(__dir__).join("application/container/boot").realpath, - ] + container.config.provider_dirs = [ + "config/providers", + Pathname(__dir__).join("application/container/providers").realpath, + ] - config.component_dirs.loader = Dry::System::Loader::Autoloading - config.component_dirs.add_to_load_path = false - end - # Autoload classes defined in lib/[app_namespace]/ if root.join("lib", namespace_path).directory? - autoloader.push_dir(root.join("lib", namespace_path), namespace: namespace) + container.autoloader.push_dir(root.join("lib", namespace_path), namespace: namespace) end - # Add lib/ to to the $LOAD_PATH so other files there (outside the app namespace) - # are require-able + # Add lib/ to to the $LOAD_PATH so any files there (outside the app namespace) can + # be required container.add_to_load_path!("lib") if root.join("lib").directory? + container.configured! + container end - # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength + # rubocop:enable Metrics/AbcSize + def prepare_deps_module + define_deps_module + end + def define_deps_module require "#{application_name}/deps" namespace.const_get :Deps rescue LoadError, NameError namespace.const_set :Deps, container.injector @@ -284,11 +276,10 @@ def slices_path File.join(root, config.slices_dir) end - # rubocop:disable Metrics/AbcSize, Metrics/MethodLength def load_slice(slice_path) slice_path = Pathname(slice_path) slice_name = slice_path.relative_path_from(Pathname(slices_path)).to_s slice_const_name = inflector.camelize(slice_name) @@ -306,10 +297,9 @@ slice_name, namespace: slice_module, root: slice_path.realpath ) end - # rubocop:enable Metrics/AbcSize, Metrics/MethodLength def load_settings require_relative "application/settings" prepare_base_load_path