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