lib/dry/system/booter.rb in dry-system-0.7.3 vs lib/dry/system/booter.rb in dry-system-0.8.0

- old
+ new

@@ -1,7 +1,9 @@ +require 'dry/system/components/bootable' require 'dry/system/errors' require 'dry/system/lifecycle' +require 'dry/system/booter/component_registry' module Dry module System # Default booter implementation # @@ -11,96 +13,126 @@ # # @api private class Booter attr_reader :path - attr_reader :finalizers - attr_reader :booted + attr_reader :components + # @api private def initialize(path) @path = path - @booted = {} - @finalizers = {} + @booted = [] + @components = ComponentRegistry.new end # @api private - def []=(name, fn) - @finalizers[name] = fn + def register_component(component) + components.register(component) self end # @api private + def load_component(path) + identifier = Pathname(path).basename('.rb').to_s.to_sym + + unless components.exists?(identifier) + require path + end + + self + end + + # @api private def finalize! - Dir[boot_files].each do |path| - start(File.basename(path, '.rb').to_sym) + boot_files.each do |path| + load_component(path) end + + components.each do |component| + start(component) + end + freeze end # @api private - def init(name) - Kernel.require(path.join(name.to_s)) + def init(name_or_component) + with_component(name_or_component) do |component| + call(component) do + component.init + yield if block_given? + end - call(name) do |lifecycle| - lifecycle.(:init) - yield(lifecycle) if block_given? + self end - - self end # @api private - def start(name) - check_component_identifier(name) + def start(name_or_component) + with_component(name_or_component) do |component| + return self if booted.include?(component) - return self if booted.key?(name) + init(name_or_component) do + component.start + end - init(name) { |lifecycle| lifecycle.(:start) } - booted[name] = true + booted << component.finalize - self + self + end end # @api private - def call(name) - container, finalizer = finalizers[name] + def call(name_or_component) + with_component(name_or_component) do |component| + unless component + raise ComponentFileMismatchError.new(name, registered_booted_keys) + end - raise ComponentFileMismatchError.new(name, registered_booted_keys) unless finalizer + yield(component) if block_given? - lifecycle = Lifecycle.new(container, &finalizer) - yield(lifecycle) if block_given? - lifecycle + component + end end # @api private - def boot_dependency(component) - boot_file = component.boot_file(path) - start(boot_file.basename('.*').to_s.to_sym) if boot_file.exist? + def lifecycle_container(container) + LifecycleContainer.new(container) end - private + # @api private + def with_component(id_or_component) + component = + case id_or_component + when Symbol + require_boot_file(id_or_component) unless components.exists?(id_or_component) + components[id_or_component] + when Components::Bootable + id_or_component + end + raise InvalidComponentError, id_or_component unless component + + yield(component) + end + # @api private - def registered_booted_keys - finalizers.keys - booted.keys + def require_boot_file(identifier) + boot_file = boot_files.detect { |path| Pathname(path).basename('.rb').to_s == identifier.to_s } + require boot_file if boot_file end # @api private def boot_files - path.join('**/*.rb').to_s + Dir["#{path}/**/*.rb"] end # @api private - def check_component_identifier(name) - unless name.is_a?(Symbol) - raise InvalidComponentIdentifierTypeError, name - end - - unless path.join("#{name}.rb").exist? - raise InvalidComponentIdentifierError, name - end + def boot_dependency(component) + boot_file = component.boot_file(path) + start(boot_file.basename('.*').to_s.to_sym) if boot_file.exist? end end end end