module Hanami::Slice::ClassMethods

rubocop:disable Metrics/ModuleLength

Constants

ROUTER_NOT_ALLOWED_HANDLER
ROUTER_NOT_FOUND_HANDLER

Attributes

autoloader[R]

Returns the slice’s autoloader.

Each slice has its own ‘Zeitwerk::Loader` autoloader instance, which is setup when the slice is {#prepare prepared}.

@return [Zeitwerk::Loader]

@see github.com/fxn/zeitwerk

@api public @since 2.0.0

container[R]

Returns the slice’s container.

This is a ‘Dry::System::Container` that is already configured for the slice.

In ordinary usage, you shouldn’t need direct access the container at all, since the slice provides its own methods for interacting with the container (such as {#[]}, {#keys}, {#key?} {#register}, {#register_provider}, {#prepare}, {#start}, {#stop}).

If you need to configure the container directly, use {#prepare_container}.

@see dry-rb.org/gems/dry-system

@api public @since 2.0.0

parent[R]

Returns the slice’s parent.

For top-level slices defined in ‘slices/` or `config/slices/`, this will be the Hanami app itself (`Hanami.app`). For nested slices, this will be the slice in which they were registered.

@return [Hanami::Slice]

@see register_slice

@api public @since 2.0.0

Public Instance Methods

[](...) click to toggle source

@overload [](key)

Resolves the component with the given key from the container.

For a prepared slice, this will attempt to load and register the matching component if it
is not loaded already. For a booted slice, this will return from already registered
components only.

@return [Object] the resolved component's object

@raise Dry::Container::KeyError if the component could not be found or loaded

@see #resolve

@api public
@since 2.0.0
# File lib/hanami/slice.rb, line 623
def [](...)
  container.[](...)
end
app() click to toggle source

Returns the Hanami app.

@return [Hanami::App]

@api public @since 2.0.0

# File lib/hanami/slice.rb, line 100
def app
  Hanami.app
end
app?() click to toggle source

Returns true if the slice is Hanami.app

@return [Boolean]

@api public @since 2.2.0

# File lib/hanami/slice.rb, line 110
def app?
  eql?(app)
end
boot() click to toggle source

Boots the slice.

This will prepare the slice (if not already prepared), start each of its providers, register all the slice’s components from its Ruby source files, and import components from any other slices. It will also boot any of the slice’s own registered nested slices. It will then freeze its container so no further components can be registered.

Call ‘boot` if you want to fully load a slice and incur all load time up front, such as when preparing an app to serve web requests. Booting slices is the approach taken when running Hanami’s standard Puma setup (see ‘config.ru`).

@return [self]

@see prepare

@api public @since 2.0.0

# File lib/hanami/slice.rb, line 325
def boot
  return self if booted?

  prepare

  container.finalize!
  slices.each(&:boot)

  @booted = true

  self
end
booted?() click to toggle source

Returns true if the slice has been booted.

@return [Boolean]

@see boot

@api public @since 2.0.0

# File lib/hanami/slice.rb, line 370
def booted?
  !!@booted
end
call(...) click to toggle source

@overload call(rack_env)

Calls the slice's [Rack][rack] app and returns a Rack-compatible response object

[rack]: https://github.com/rack/rack

@param rack_env [Hash] the Rack environment for the request

@return [Array] the three-element Rack response array

@see #rack_app

@api public
@since 2.0.0
# File lib/hanami/slice.rb, line 790
def call(...)
  rack_app.call(...)
end
config() click to toggle source

Returns the slice’s config.

A slice’s config is copied from the app config at time of first access.

@return [Hanami::Config]

@see App::ClassMethods.config

@api public @since 2.0.0

# File lib/hanami/slice.rb, line 124
def config
  @config ||= app.config.dup.tap do |slice_config|
    # Unset config from app that does not apply to ordinary slices
    slice_config.root = nil
  end
end
configure_provider(*args, **kwargs, &block) click to toggle source

@api public @since 2.1.0

# File lib/hanami/slice.rb, line 532
def configure_provider(*args, **kwargs, &block)
  container.register_provider(*args, **kwargs, from: :hanami, &block)
end
environment(env_name, &block) click to toggle source

Evaluates the block for a given app environment only.

If the given ‘env_name` matches {Hanami.env}, then the block will be evaluated in the context of `self` (the slice) via `instance_eval`. The slice is also passed as the block’s optional argument.

If the env does not match, then the block is not evaluated at all.

@example

module MySlice
  class Slice < Hanami::Slice
    environment(:test) do
      config.logger.level = :info
    end
  end
end

@overload environment(env_name)

@param env_name [Symbol] the environment name

@overload environment(env_name)

@param env_name [Symbol] the environment name
@yieldparam slice [self] the slice

@return [self]

@see Hanami.env

@api public @since 2.0.0

# File lib/hanami/slice.rb, line 161
def environment(env_name, &block)
  instance_eval(&block) if env_name == config.env
  self
end
export(keys) click to toggle source

Specifies the components to export from the slice.

Slices importing from this slice can import the specified components only.

@example

module MySlice
  class Slice < Hanami::Slice
    export ["search", "index_entity"]
  end
end

@param keys [Array<String>] the component keys to export

@return [self]

@api public @since 2.0.0

# File lib/hanami/slice.rb, line 652
def export(keys)
  container.config.exports = keys
  self
end
import(from:, **kwargs) click to toggle source

@overload import(from:, as: nil, keys: nil)

Specifies components to import from another slice.

Booting a slice will register all imported components. For a prepared slice, these
components will be be imported automatically when resolved.

@example
  module MySlice
    class Slice < Hanami:Slice
      # Component from Search::Slice will import as "search.index_entity"
      import keys: ["index_entity"], from: :search
    end
  end

@example Other import variations
  # Different key namespace: component will be "search_backend.index_entity"
  import keys: ["index_entity"], from: :search, as: "search_backend"

  # Import to root key namespace: component will be "index_entity"
  import keys: ["index_entity"], from: :search, as: nil

  # Import all components
  import from: :search

@param keys [Array<String>, nil] Array of component keys to import. To import all
  available components, omit this argument.
@param from [Symbol] name of the slice to import from
@param as [Symbol, String, nil]

@see #export

@api public
@since 2.0.0
# File lib/hanami/slice.rb, line 690
def import(from:, **kwargs)
  slice = self

  container.after(:configure) do
    if from.is_a?(Symbol) || from.is_a?(String)
      slice_name = from
      from = slice.parent.slices[from.to_sym].container
    end

    as = kwargs[:as] || slice_name

    import(from: from, as: as, **kwargs)
  end
end
inflector() click to toggle source

Returns the slice’s configured inflector.

Unless explicitly re-configured for the slice, this will be the app’s inflector.

@return [Dry::Inflector]

@see Config#inflector @see Config#inflections

@api public @since 2.0.0

# File lib/hanami/slice.rb, line 237
def inflector
  config.inflector
end
key?(...) click to toggle source

@overload key?(key)

Returns true if the component with the given key is registered in the container.

For a prepared slice, calling `key?` will also try to load the component if not loaded
already.

@param key [String, Symbol] the component key

@return [Boolean]

@api public
@since 2.0.0
# File lib/hanami/slice.rb, line 584
def key?(...)
  container.key?(...)
end
keys() click to toggle source

Returns an array of keys for all currently registered components in the container.

For a prepared slice, this will be the set of components that have been previously resolved. For a booted slice, this will be all components available for the slice.

@return [Array<String>]

@api public @since 2.0.0

# File lib/hanami/slice.rb, line 604
def keys
  container.keys
end
namespace() click to toggle source

Returns the constant for the slice’s module namespace.

@example

MySlice::Slice.namespace # => MySlice

@return [Module] the namespace module constant

@see SliceName#namespace

@api public @since 2.0.0

# File lib/hanami/slice.rb, line 188
def namespace
  slice_name.namespace
end
prepare(provider_name = nil) click to toggle source

@overload prepare

Prepares the slice.

This will define the slice's `Slice` and `Deps` constants, make all Ruby source files
inside the slice's root dir autoloadable, as well as lazily loadable as container
components.

Call `prepare` when you want to access particular components within the slice while still
minimizing load time. Preparing slices is the approach taken when loading the Hanami
console or when running tests.

@return [self]

@see #boot

@api public
@since 2.0.0

@overload prepare(provider_name)

Prepares a provider.

This triggers the provider's `prepare` lifecycle step.

@param provider_name [Symbol] the name of the provider to start

@return [self]

@api public
@since 2.0.0
# File lib/hanami/slice.rb, line 270
def prepare(provider_name = nil)
  if provider_name
    container.prepare(provider_name)
  else
    prepare_slice
  end

  self
end
prepare_container(&block) click to toggle source

Captures the given block to be called with the slice’s container during the slice’s ‘prepare` step, after the slice has already configured the container.

This is intended for advanced usage only and should not be needed for ordinary slice configuration and usage.

@example

module MySlice
  class Slice < Hanami::Slice
    prepare_container do |container|
      # ...
    end
  end
end

@yieldparam container [Dry::System::Container] the slice’s container

@return [self]

@see prepare

@api public @since 2.0.0

# File lib/hanami/slice.rb, line 303
def prepare_container(&block)
  @prepare_container_block = block
  self
end
prepared?() click to toggle source

Returns true if the slice has been prepared.

@return [Boolean]

@see prepare

@api public @since 2.0.0

# File lib/hanami/slice.rb, line 358
def prepared?
  !!@prepared
end
rack_app() click to toggle source

Returns a [Rack] app for the slice, or nil if no routes are defined.

The rack app will be memoized on first access.

[rack]: github.com/rack/rack

@return [#call, nil] the rack app, or nil if no routes are defined

@see routes @see router

@api public @since 2.0.0

# File lib/hanami/slice.rb, line 771
def rack_app
  return unless router

  @rack_app ||= router.to_rack_app
end
register(...) click to toggle source

Registers a component in the slice’s container.

@overload register(key, object)

Registers the given object as the component. This same object will be returned whenever
the component is resolved.

@param key [String] the component's key
@param object [Object] the object to register as the component

@overload register(key, memoize: false, &block)

Registers the given block as the component. When the component is resolved, the return
value of the block will be returned.

Since the block is not called until resolution-time, this is a useful way to register
components that have dependencies on other components in the container, which as yet may
be unavailable at the time of registration.

All auto-registered components are registered in block form.

When `memoize` is true, the component will be memoized upon first resolution and the same
object returned on all subsequent resolutions, meaning the block is only called once.
Otherwise, the block will be called and a new object returned on every resolution.

@param key [String] the component's key
@param memoize [Boolean]
@yieldreturn [Object] the object to register as the component

@overload register(key, call: true, &block)

Registers the given block as the component. When `call: false` is given, then the block
itself will become the component.

When such a component is resolved, the block will not be called, and instead the `Proc`
object for that block will be returned.

@param key [String] the component's key
@param call [Boolean]

@return [container]

@see [] @see resolve

@api public @since 2.0.0

# File lib/hanami/slice.rb, line 462
def register(...)
  container.register(...)
end
register_provider(...) click to toggle source

@overload register_provider(name, namespace: nil, from: nil, source: nil, if: true, &block)

Registers a provider and its lifecycle hooks.

In most cases, you should call this from a dedicated file for the provider in your app or
slice's `config/providers/` dir. This allows the provider to be loaded when individual
matching components are resolved (for prepared slices) or when slices are booted.

@example Simple provider
  # config/providers/db.rb
  Hanami.app.register_provider(:db) do
    start do
      require "db"
      register("db", DB.new)
    end
  end

@example Provider with lifecycle steps, also using dependencies from the target container
  # config/providers/db.rb
  Hanami.app.register_provider(:db) do
    prepare do
      require "db"
      db = DB.new(target_container["settings"].database_url)
      register("db", db)
    end

    start do
      container["db"].establish_connection
    end

    stop do
      container["db"].close_connection
    end
  end

@example Probvider registration under a namespace
  # config/providers/db.rb
  Hanami.app.register_provider(:persistence, namespace: true) do
    start do
      require "db"

      # Namespace option above means this will be registered as "persistence.db"
      register("db", DB.new)
    end
  end

@param name [Symbol] the unique name for the provider
@param namespace [Boolean, String, nil] register components from the provider with given
  namespace. May be an explicit string, or `true` for the namespace to be the provider's
  name
@param from [Symbol, nil] the group for an external provider source to use, with the
  provider source name inferred from `name` or passed explicitly as `source:`
@param source [Symbol, nil] the name of the external provider source to use, if different
  from the value provided as `name`
@param if [Boolean] a boolean-returning expression to determine whether to register the
  provider

@return [container]

@api public
@since 2.0.0
# File lib/hanami/slice.rb, line 526
def register_provider(...)
  container.register_provider(...)
end
register_slice(...) click to toggle source

@overload register_slice(name, &block)

Registers a nested slice with the given name.

This will define a new {Slice} subclass for the slice. If a block is given, it is passed
the class object, and will be evaluated in the context of the class like `class_eval`.

@example
  MySlice::Slice.register_slice do
    # Configure the slice or do other class-level things here
  end

@param name [Symbol] the identifier for the slice to be registered
@yieldparam slice [Hanami::Slice] the newly defined slice class

@overload register_slice(name, slice_class)

Registers a nested slice with the given name.

The given `slice_class` will be registered as the slice. It must be a subclass of {Slice}.

@param name [Symbol] the identifier for the slice to be registered
@param slice_class [Hanami::Slice]

@return [slices]

@see SliceRegistrar#register

@api public @since 2.0.0

# File lib/hanami/slice.rb, line 414
def register_slice(...)
  slices.register(...)
end
registered?(...) click to toggle source

Required for the slice to act as a provider target @api public @since 2.2.0

# File lib/hanami/slice.rb, line 591
def registered?(...)
  container.registered?(...)
end
resolve(...) click to toggle source

@see []

@api public @since 2.0.0

# File lib/hanami/slice.rb, line 631
def resolve(...)
  container.resolve(...)
end
root() click to toggle source

Returns the slice’s root, either the root as explicitly configured, or a default fallback of the slice’s name within the app’s ‘slices/` dir.

@return [Pathname]

@see Config#root

@api public @since 2.0.0

# File lib/hanami/slice.rb, line 201
def root
  # Provides a best guess for a root when it is not yet configured.
  #
  # This is particularly useful for user-defined slice classes that access `settings` inside
  # the class body (since the root needed to find the settings file). In this case,
  # `configuration.root` may be nil when `settings` is called, since the root is configured by
  # `SliceRegistrar#configure_slice` _after_ the class is loaded.
  #
  # In common cases, this best guess will be correct since most Hanami slices will be expected
  # to live in the app SLICES_DIR. For advanced cases, the correct slice root should be
  # explicitly configured at the beginning of the slice class body, before any calls to
  # `settings`.
  config.root || app.root.join(SLICES_DIR, slice_name.to_s)
end
router(inspector: nil) click to toggle source

Returns the slice’s router, if or nil if no routes are defined.

An optional ‘inspector`, implementing the `Hanami::Router::Inspector` interface, may be provided at first call (the router is then memoized for subsequent accesses). An inspector is used by the `hanami routes` CLI comment to provide a list of available routes.

The returned router is a {Slice::Router}, which provides all ‘Hanami::Router` functionality, with the addition of support for slice mounting with the {Slice::Router#slice}.

@param inspector [Hanami::Router::Inspector, nil] an optional routes inspector

@return [Hanami::Slice::Router, nil]

@api public @since 2.0.0

# File lib/hanami/slice.rb, line 750
def router(inspector: nil)
  raise SliceLoadError, "#{self} must be prepared before loading the router" unless prepared?

  @_mutex.synchronize do
    @_router ||= load_router(inspector: inspector)
  end
end
routes() click to toggle source

Returns the slice’s routes, or nil if no routes are defined.

You can define your routes in ‘config/routes.rb`.

@return [Hanami::Routes, nil]

@see Hanami::Routes

@api public @since 2.0.0

# File lib/hanami/slice.rb, line 731
def routes
  @routes ||= load_routes
end
settings() click to toggle source

Returns the slice’s settings, or nil if no settings are defined.

You can define your settings in ‘config/settings.rb`.

@return [Hanami::Settings, nil]

@see Hanami::Settings

@api public @since 2.0.0

# File lib/hanami/slice.rb, line 715
def settings
  return @settings if instance_variable_defined?(:@settings)

  @settings = Settings.load_for_slice(self)
end
shutdown() click to toggle source

Shuts down the slice’s providers, as well as the providers in any nested slices.

@return [self]

@api public @since 2.0.0

# File lib/hanami/slice.rb, line 344
def shutdown
  slices.each(&:shutdown)
  container.shutdown!
  self
end
slice_name() click to toggle source

Returns a {SliceName} for the slice, an object with methods returning the name of the slice in various formats.

@return [SliceName]

@api public @since 2.0.0

# File lib/hanami/slice.rb, line 173
def slice_name
  @slice_name ||= SliceName.new(self, inflector: method(:inflector))
end
slices() click to toggle source

Returns the slice’s collection of nested slices.

@return [SliceRegistrar]

@see register_slice

@api public @since 2.0.0

# File lib/hanami/slice.rb, line 382
def slices
  @slices ||= SliceRegistrar.new(self)
end
source_path() click to toggle source

Returns the slice’s root component directory, accounting for App as a special case.

@return [Pathname]

@api public @since 2.2.0

# File lib/hanami/slice.rb, line 222
def source_path
  app? ? root.join(APP_DIR) : root
end
start(...) click to toggle source

@overload start(provider_name)

Starts a provider.

This triggers the provider's `prepare` and `start` lifecycle steps.

@example
  MySlice::Slice.start(:persistence)

@param provider_name [Symbol] the name of the provider to start

@return [container]

@api public
@since 2.0.0
# File lib/hanami/slice.rb, line 550
def start(...)
  container.start(...)
end
stop(...) click to toggle source

@overload stop(provider_name)

Stops a provider.

This triggers the provider's `stop` lifecycle hook.

@example
  MySlice::Slice.stop(:persistence)

@param provider_name [Symbol] the name of the provider to start

@return [container]

@api public
@since 2.0.0
# File lib/hanami/slice.rb, line 568
def stop(...)
  container.stop(...)
end

Private Instance Methods

assets_dir?() click to toggle source
# File lib/hanami/slice.rb, line 1081
def assets_dir?
  source_path.join("assets").directory?
end
concrete_db_provider?() click to toggle source
# File lib/hanami/slice.rb, line 1093
def concrete_db_provider?
  root.join(CONFIG_DIR, "providers", "db.rb").exist?
end
db_config_dir?() click to toggle source
# File lib/hanami/slice.rb, line 1097
def db_config_dir?
  root.join("config", "db").directory?
end
db_source_dir?() click to toggle source
# File lib/hanami/slice.rb, line 1105
def db_source_dir?
  source_path.join("db").directory?
end
ensure_root() click to toggle source
# File lib/hanami/slice.rb, line 839
def ensure_root
  unless config.root
    raise SliceLoadError, "Slice must have a `config.root` before it can be prepared"
  end
end
ensure_slice_consts() click to toggle source
# File lib/hanami/slice.rb, line 830
def ensure_slice_consts
  if namespace.const_defined?(:Container) || namespace.const_defined?(:Deps)
    raise(
      SliceLoadError,
      "#{namespace}::Container and #{namespace}::Deps constants must not already be defined"
    )
  end
end
ensure_slice_name() click to toggle source
# File lib/hanami/slice.rb, line 824
def ensure_slice_name
  unless name
    raise SliceLoadError, "Slice must have a class name before it can be prepared"
  end
end
import_db_from_parent?() click to toggle source
# File lib/hanami/slice.rb, line 1109
def import_db_from_parent?
  parent &&
    config.db.import_from_parent &&
    parent.container.providers[:db]
end
load_router(inspector:) click to toggle source
# File lib/hanami/slice.rb, line 1002
def load_router(inspector:)
  return unless routes

  require_relative "slice/router"

  slice = self
  config = self.config
  rack_monitor = self["rack.monitor"]

  show_welcome = Hanami.env?(:development) && routes.empty?
  render_errors = render_errors?
  render_detailed_errors = render_detailed_errors?

  error_handlers = {}.tap do |hsh|
    if render_errors || render_detailed_errors
      hsh[:not_allowed] = ROUTER_NOT_ALLOWED_HANDLER
      hsh[:not_found] = ROUTER_NOT_FOUND_HANDLER
    end
  end

  Slice::Router.new(
    inspector: inspector,
    routes: routes,
    resolver: config.router.resolver.new(slice: self),
    **error_handlers,
    **config.router.options
  ) do
    use(rack_monitor)

    use(Hanami::Web::Welcome) if show_welcome

    use(
      Hanami::Middleware::RenderErrors,
      config,
      Hanami::Middleware::PublicErrorsApp.new(slice.root.join("public"))
    )

    if render_detailed_errors
      require "hanami/webconsole"
      use(Hanami::Webconsole::Middleware, config)
    end

    if Hanami.bundled?("hanami-controller")
      if config.actions.method_override
        require "rack/method_override"
        use(Rack::MethodOverride)
      end

      if config.actions.sessions.enabled?
        use(*config.actions.sessions.middleware)
      end
    end

    if Hanami.bundled?("hanami-assets") && config.assets.serve
      use(Hanami::Middleware::Assets)
    end

    middleware_stack.update(config.middleware_stack)
  end
end
load_routes() click to toggle source
# File lib/hanami/slice.rb, line 980
def load_routes
  return false unless Hanami.bundled?("hanami-router")

  if root.directory?
    routes_require_path = File.join(root, ROUTES_PATH)

    begin
      require_relative "./routes"
      require routes_require_path
    rescue LoadError => e
      raise e unless e.path == routes_require_path
    end
  end

  begin
    routes_class = namespace.const_get(ROUTES_CLASS_NAME)
    routes_class.routes
  rescue NameError => e
    raise e unless e.name == ROUTES_CLASS_NAME.to_sym
  end
end
prepare_all() click to toggle source
# File lib/hanami/slice.rb, line 845
def prepare_all
  prepare_settings
  prepare_container_consts
  prepare_container_plugins
  prepare_container_base_config
  prepare_container_component_dirs
  prepare_container_imports
  prepare_container_providers
end
prepare_autoloader() click to toggle source
# File lib/hanami/slice.rb, line 956
def prepare_autoloader
  # Component dirs are automatically pushed to the autoloader by dry-system's
  # zeitwerk plugin. This method adds other dirs that are not otherwise configured
  # as component dirs.

  # Everything in the slice root can be autoloaded except `config/` and `slices/`,
  # which are framework-managed directories

  if root.join(CONFIG_DIR)&.directory?
    autoloader.ignore(root.join(CONFIG_DIR))
  end

  if root.join(SLICES_DIR)&.directory?
    autoloader.ignore(root.join(SLICES_DIR))
  end

  autoloader.setup
end
prepare_container_base_config() click to toggle source
# File lib/hanami/slice.rb, line 875
def prepare_container_base_config
  container.config.name = slice_name.to_sym
  container.config.root = root
  container.config.provider_registrar = ProviderRegistrar.for_slice(self)
  container.config.provider_dirs = [File.join("config", "providers")]
  container.config.registrations_dir = File.join("config", "registrations")

  container.config.env = config.env
  container.config.inflector = config.inflector
end
prepare_container_component_dirs() click to toggle source
# File lib/hanami/slice.rb, line 886
def prepare_container_component_dirs
  return unless root.directory?

  # Component files in both the root and `lib/` define classes in the slice's
  # namespace

  if root.join(LIB_DIR)&.directory?
    container.config.component_dirs.add(LIB_DIR) do |dir|
      dir.namespaces.add_root(key: nil, const: slice_name.name)
    end
  end

  # When auto-registering components in the root, ignore files in `config/` (this is
  # for framework config only), `lib/` (these will be auto-registered as above), as
  # well as the configured no_auto_register_paths
  no_auto_register_paths = ([LIB_DIR, CONFIG_DIR] + config.no_auto_register_paths)
    .map { |path|
      path.end_with?(File::SEPARATOR) ? path : "#{path}#{File::SEPARATOR}"
    }

  # TODO: Change `""` (signifying the root) once dry-rb/dry-system#238 is resolved
  container.config.component_dirs.add("") do |dir|
    dir.namespaces.add_root(key: nil, const: slice_name.name)
    dir.auto_register = -> component {
      relative_path = component.file_path.relative_path_from(root).to_s
      !relative_path.start_with?(*no_auto_register_paths)
    }
  end
end
prepare_container_consts() click to toggle source
# File lib/hanami/slice.rb, line 859
def prepare_container_consts
  namespace.const_set :Container, container
  namespace.const_set :Deps, container.injector
end
prepare_container_imports() click to toggle source
# File lib/hanami/slice.rb, line 916
def prepare_container_imports
  import(
    keys: config.shared_app_component_keys,
    from: app.container,
    as: nil
  )
end
prepare_container_plugins() click to toggle source
# File lib/hanami/slice.rb, line 864
def prepare_container_plugins
  container.use(:env, inferrer: -> { Hanami.env })

  container.use(
    :zeitwerk,
    loader: autoloader,
    run_setup: false,
    eager_load: false
  )
end
prepare_container_providers() click to toggle source
# File lib/hanami/slice.rb, line 924
def prepare_container_providers
  # Check here for the `routes` definition only, not `router` itself, because the
  # `router` requires the slice to be prepared before it can be loaded, and at this
  # point we're still in the process of preparing.
  if routes
    require_relative "providers/routes"
    register_provider(:routes, source: Providers::Routes)
  end

  if assets_dir? && Hanami.bundled?("hanami-assets")
    require_relative "providers/assets"
    register_provider(:assets, source: Providers::Assets)
  end

  if Hanami.bundled?("hanami-db")
    # Explicit require here to ensure the provider source registers itself, to allow the user
    # to configure it within their own concrete provider file.
    require_relative "providers/db"

    if register_db_provider?
      # Only register providers if the user hasn't provided their own
      if !container.providers[:db]
        register_provider(:db, namespace: true, source: Providers::DB)
      end

      if !container.providers[:relations]
        register_provider(:relations, namespace: true, source: Providers::Relations)
      end
    end
  end
end
prepare_settings() click to toggle source
# File lib/hanami/slice.rb, line 855
def prepare_settings
  container.register(:settings, settings) if settings
end
prepare_slice() click to toggle source

rubocop:disable Metrics/AbcSize

# File lib/hanami/slice.rb, line 798
def prepare_slice
  return self if prepared?

  config.finalize!

  ensure_slice_name
  ensure_slice_consts
  ensure_root

  prepare_all

  instance_exec(container, &@prepare_container_block) if @prepare_container_block
  container.configured!

  prepare_autoloader

  # Load child slices last, ensuring their parent is fully prepared beforehand
  # (useful e.g. for slices that may wish to access constants defined in the
  # parent's autoloaded directories)
  prepare_slices

  @prepared = true

  self
end
prepare_slices() click to toggle source
# File lib/hanami/slice.rb, line 975
def prepare_slices
  slices.load_slices.each(&:prepare)
  slices.freeze
end
register_db_provider?() click to toggle source
# File lib/hanami/slice.rb, line 1085
def register_db_provider?
  concrete_db_provider? ||
    db_config_dir? ||
    relations_dir? ||
    db_source_dir? ||
    import_db_from_parent?
end
relations_dir?() click to toggle source
# File lib/hanami/slice.rb, line 1101
def relations_dir?
  source_path.join("relations").directory?
end
render_detailed_errors?() click to toggle source
# File lib/hanami/slice.rb, line 1067
def render_detailed_errors?
  config.render_detailed_errors && Hanami.bundled?("hanami-webconsole")
end
render_errors?() click to toggle source
# File lib/hanami/slice.rb, line 1063
def render_errors?
  config.render_errors
end