lib/dry/system/container.rb in dry-system-0.17.0 vs lib/dry/system/container.rb in dry-system-0.18.0

- old
+ new

@@ -1,26 +1,26 @@ # frozen_string_literal: true -require 'pathname' +require "pathname" -require 'dry-auto_inject' -require 'dry-configurable' -require 'dry-container' -require 'dry/inflector' +require "dry-auto_inject" +require "dry-configurable" +require "dry-container" +require "dry/inflector" -require 'dry/core/deprecations' +require "dry/core/deprecations" -require 'dry/system' -require 'dry/system/errors' -require 'dry/system/loader' -require 'dry/system/booter' -require 'dry/system/auto_registrar' -require 'dry/system/manual_registrar' -require 'dry/system/importer' -require 'dry/system/component' -require 'dry/system/constants' -require 'dry/system/plugins' +require "dry/system" +require "dry/system/errors" +require "dry/system/loader" +require "dry/system/booter" +require "dry/system/auto_registrar" +require "dry/system/manual_registrar" +require "dry/system/importer" +require "dry/system/component" +require "dry/system/constants" +require "dry/system/plugins" module Dry module System # Abstract container class to inherit from # @@ -46,12 +46,10 @@ # # Every container needs to be configured with following settings: # # * `:name` - a unique container identifier # * `:root` - a system root directory (defaults to `pwd`) - # * `:system_dir` - directory name relative to root, where bootable components - # can be defined in `boot` dir this defaults to `system` # # @example # class MyApp < Dry::System::Container # configure do |config| # config.name = :my_app @@ -73,12 +71,13 @@ extend Dry::System::Plugins setting :name setting :default_namespace setting(:root, Pathname.pwd.freeze) { |path| Pathname(path) } - setting :system_dir, 'system' - setting :registrations_dir, 'container' + setting :system_dir, "system" + setting :bootable_dirs, ["system/boot"] + setting :registrations_dir, "container" setting :auto_register, [] setting :inflector, Dry::Inflector.new setting :loader, Dry::System::Loader setting :booter, Dry::System::Booter setting :auto_registrar, Dry::System::AutoRegistrar @@ -93,11 +92,11 @@ else @strategies ||= Dry::AutoInject::Strategies end end - extend Dry::Core::Deprecations['Dry::System::Container'] + extend Dry::Core::Deprecations["Dry::System::Container"] # Define a new configuration setting # # @see https://dry-rb.org/gems/dry-configurable # @@ -168,13 +167,14 @@ end end # Registers finalization function for a bootable component # - # By convention, boot files for components should be placed in - # `%{system_dir}/boot` and they will be loaded on demand when components - # are loaded in isolation, or during finalization process. + # By convention, boot files for components should be placed in a + # `bootable_dirs` entry and they will be loaded on demand when + # components are loaded in isolation, or during the finalization + # process. # # @example # # system/container.rb # class MyApp < Dry::System::Container # configure do |config| @@ -253,34 +253,28 @@ boot_external(name, **opts, &block) else boot_local(name, **opts, &block) end + booter.register_component component + components[name] = component end deprecate :finalize, :boot # @api private def boot_external(identifier, from:, key: nil, namespace: nil, &block) - component = System.providers[from].component( + System.providers[from].component( identifier, key: key, namespace: namespace, finalize: block, container: self ) - - booter.register_component(component) - - component end # @api private def boot_local(identifier, namespace: nil, &block) - component = Components::Bootable.new( + Components::Bootable.new( identifier, container: self, namespace: namespace, &block ) - - booter.register_component(component) - - component end # Return if a container was finalized # # @return [TrueClass, FalseClass] @@ -486,11 +480,11 @@ # MyApp['user_repo].db # instance under 'persistence.db' key # # @param options [Hash] injector options # # @api public - def injector(options = { strategies: strategies }) + def injector(options = {strategies: strategies}) Dry::AutoInject(self, options) end # Requires one or more files relative to the container's root # @@ -504,11 +498,11 @@ # @param paths [Array<String>] one or more paths, supports globs too # # @api public def require_from_root(*paths) paths.flat_map { |path| - path.to_s.include?('*') ? ::Dir[root.join(path)].sort : root.join(path) + path.to_s.include?("*") ? ::Dir[root.join(path)].sort : root.join(path) }.each { |path| Kernel.require path.to_s } end @@ -567,16 +561,24 @@ @load_paths ||= [] end # @api private def booter - @booter ||= config.booter.new(boot_path) + @booter ||= config.booter.new(boot_paths) end # @api private - def boot_path - root.join("#{config.system_dir}/boot") + def boot_paths + config.bootable_dirs.map { |dir| + dir = Pathname(dir) + + if dir.relative? + root.join(dir) + else + dir + end + } end # @api private def auto_registrar @auto_registrar ||= config.auto_registrar.new(self) @@ -633,16 +635,16 @@ # @api private def load_component(key, &block) return self if registered?(key) component(key).tap do |component| - if component.boot? + if component.bootable? booter.start(component) else root_key = component.root_key - if (bootable_dep = component(root_key)).boot? - booter.start(bootable_dep) + if (root_bootable = component(root_key)).bootable? + booter.start(root_bootable) elsif importer.key?(root_key) load_imported_component(component.namespaced(root_key)) end load_local_component(component, &block) unless registered?(key)