lib/hanami/application.rb in hanami-2.0.0.alpha2 vs lib/hanami/application.rb in hanami-2.0.0.alpha3

- old
+ new

@@ -1,13 +1,16 @@ # frozen_string_literal: true require "dry/system/container" +require "dry/system/loader/autoloading" require "hanami/configuration" require "pathname" require "rack" +require "zeitwerk" require_relative "slice" require_relative "application/autoloader/inflector_adapter" +require_relative "application/routes" require_relative "application/settings" module Hanami # Hanami application class # @@ -50,25 +53,25 @@ alias config configuration def init # rubocop:disable Metrics/MethodLength return self if inited? - configuration.finalize + configuration.finalize! + @autoloader = Zeitwerk::Loader.new + autoloader.inflector = Autoloader::InflectorAdapter.new(inflector) + load_settings @container = prepare_container @deps_module = prepare_deps_module load_slices slices.values.each(&:init) slices.freeze - if configuration.autoloader - configuration.autoloader.inflector = Autoloader::InflectorAdapter.new(inflector) - configuration.autoloader.setup - end + autoloader.setup load_routes @inited = true self @@ -76,10 +79,16 @@ def inited? @inited end + def autoloader + raise "Application not init'ed" unless defined?(@autoloader) + + @autoloader + end + def container raise "Application not init'ed" unless defined?(@container) @container end @@ -149,46 +158,35 @@ def booted? @booted end - def settings(&block) # rubocop:disable Metrics/MethodLength - if block - @_settings = Application::Settings.build( - configuration.settings_loader, - configuration.settings_loader_options, - &block - ) - elsif instance_variable_defined?(:@_settings) - @_settings - else - # Load settings lazily so they can be used to configure the - # Hanami::Application subclass (before the application has inited) - load_settings - @_settings ||= nil - end + def shutdown + container.shutdown! end - def routes(&block) - @_mutex.synchronize do - if block.nil? - raise "Hanami.application.routes not configured" unless defined?(@_routes) + def settings + @_settings ||= load_settings + end - @_routes - else - @_routes = block - end + def routes + @_mutex.synchronize do + @_routes ||= load_routes end end MODULE_DELIMITER = "::" private_constant :MODULE_DELIMITER def namespace inflector.constantize(name.split(MODULE_DELIMITER)[0..-2].join(MODULE_DELIMITER)) end + def namespace_name + namespace.name + end + def namespace_path inflector.underscore(namespace) end def application_name @@ -254,25 +252,23 @@ config.bootable_dirs = [ "config/boot", Pathname(__dir__).join("application/container/boot").realpath, ] - if configuration.autoloader - require "dry/system/loader/autoloading" - config.component_dirs.loader = Dry::System::Loader::Autoloading - config.component_dirs.add_to_load_path = false - end + config.component_dirs.loader = Dry::System::Loader::Autoloading + config.component_dirs.add_to_load_path = false + end - if root.join("lib").directory? - config.component_dirs.add "lib" do |dir| - dir.default_namespace = application_name.to_s - end - - configuration.autoloader&.push_dir(root.join("lib")) - 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) end + # Add lib/ to to the $LOAD_PATH so other files there (outside the app namespace) + # are require-able + container.add_to_load_path!("lib") if root.join("lib").directory? + container end # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength def define_deps_module @@ -315,17 +311,26 @@ ) end # rubocop:enable Metrics/AbcSize, Metrics/MethodLength def load_routes - require File.join(configuration.root, configuration.router.routes) + require File.join(configuration.root, configuration.router.routes_path) + routes_class = autodiscover_application_constant(configuration.router.routes_class_name) + routes_class.routes rescue LoadError # rubocop:disable Lint/SuppressedException end def load_settings prepare_base_load_path require File.join(configuration.root, configuration.settings_path) - rescue LoadError # rubocop:disable Lint/SuppressedException + settings_class = autodiscover_application_constant(configuration.settings_class_name) + settings_class.new(configuration.settings_store) + rescue LoadError + Settings.new + end + + def autodiscover_application_constant(constants) + inflector.constantize([namespace_name, *constants].join(MODULE_DELIMITER)) end end # rubocop:enable Metrics/ModuleLength # Application instance interface