lib/hanami/providers/settings.rb in hanami-2.0.0.beta1.1 vs lib/hanami/providers/settings.rb in hanami-2.0.0.beta2
- old
+ new
@@ -1,23 +1,98 @@
# frozen_string_literal: true
require "dry/system/provider/source"
+require_relative "../constants"
+require_relative "../errors"
module Hanami
module Providers
+ # The settings provider loads and registers the "settings" component in app and slice
+ # containers.
+ #
+ # To register this provider with a slice container, you should use
+ # {.register_with_slice}, which will register the provider only if settings are
+ # defined for the slice.
+ #
+ # @see Slice::ClassMethods.prepare_container_providers
+ #
+ # @api private
+ # @since 2.0.0
class Settings < Dry::System::Provider::Source
- def self.for_slice(slice)
- Class.new(self) do |klass|
- klass.instance_variable_set(:@slice, slice)
+ class << self
+ # Registers the provider with the slice's container, but only if settings are
+ # defined for the slice.
+ def register_with_slice(slice)
+ return unless settings_defined?(slice)
+
+ slice.register_provider(:settings, source: with_slice(slice))
end
+
+ # Creates a new subclass of the provider for the given slice.
+ #
+ # You must do this before registering the provider with a container. The provider
+ # uses the slice to locate the settings definition based on the slice's config.
+ def with_slice(slice)
+ Class.new(self) do |klass|
+ klass.instance_variable_set(:@slice, slice)
+ end
+ end
+
+ # Returns the slice for the provider
+ def slice
+ unless @slice
+ raise SliceLoadError, "a slice must be given to #{self} via `.with_slice(slice)`"
+ end
+
+ @slice
+ end
+
+ private
+
+ # Returns true if settings are defined for the slice.
+ #
+ # Settings are considered defined if a `Settings` class is already defined in the
+ # slice namespace, or a `config/settings.rb` exists under the slice root.
+ def settings_defined?(slice)
+ slice.namespace.const_defined?(SETTINGS_CLASS_NAME) ||
+ slice.root.join("#{SETTINGS_PATH}#{RB_EXT}").file?
+ end
end
- def self.slice
- @slice || Hanami.app
+ def prepare
+ require_slice_settings unless slice_settings_class?
end
def start
- register :settings, self.class.slice.settings
+ settings = slice_settings_class.new(slice.config.settings_store)
+
+ register :settings, settings
+ end
+
+ private
+
+ def slice
+ self.class.slice
+ end
+
+ def slice_settings_class?
+ slice.namespace.const_defined?(SETTINGS_CLASS_NAME)
+ end
+
+ def slice_settings_class
+ slice.namespace.const_get(SETTINGS_CLASS_NAME)
+ end
+
+ def require_slice_settings
+ require "hanami/settings"
+
+ slice_settings_require_path = File.join(slice.root, SETTINGS_PATH)
+
+ begin
+ require slice_settings_require_path
+ rescue LoadError => e
+ raise e unless e.path == slice_settings_require_path
+ end
end
end
end
end