hanami 0.8.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +23 -0
- data/FEATURES.md +13 -0
- data/README.md +28 -1
- data/hanami.gemspec +20 -17
- data/lib/hanami.rb +106 -7
- data/lib/hanami/action/routing_helpers.rb +2 -2
- data/lib/hanami/app.rb +72 -0
- data/lib/hanami/application.rb +144 -183
- data/lib/hanami/application_configuration.rb +1541 -0
- data/lib/hanami/application_name.rb +2 -2
- data/lib/hanami/application_namespace.rb +12 -0
- data/lib/hanami/assets/asset.rb +3 -1
- data/lib/hanami/assets/static.rb +3 -9
- data/lib/hanami/cli.rb +10 -7
- data/lib/hanami/cli_sub_commands/assets.rb +1 -9
- data/lib/hanami/cli_sub_commands/generate.rb +16 -0
- data/lib/hanami/commands/apps.rb +4 -0
- data/lib/hanami/commands/assets/precompile.rb +6 -19
- data/lib/hanami/commands/command.rb +64 -0
- data/lib/hanami/commands/console.rb +37 -26
- data/lib/hanami/commands/db/apply.rb +4 -2
- data/lib/hanami/commands/db/console.rb +11 -27
- data/lib/hanami/commands/db/create.rb +4 -2
- data/lib/hanami/commands/db/drop.rb +4 -2
- data/lib/hanami/commands/db/migrate.rb +11 -5
- data/lib/hanami/commands/db/prepare.rb +4 -2
- data/lib/hanami/commands/db/version.rb +4 -2
- data/lib/hanami/commands/generate/abstract.rb +5 -7
- data/lib/hanami/commands/generate/action.rb +18 -6
- data/lib/hanami/commands/generate/app.rb +15 -2
- data/lib/hanami/commands/generate/migration.rb +3 -2
- data/lib/hanami/commands/generate/model.rb +4 -3
- data/lib/hanami/commands/generate/secret_token.rb +31 -0
- data/lib/hanami/commands/new/abstract.rb +14 -5
- data/lib/hanami/commands/new/container.rb +1 -0
- data/lib/hanami/commands/routes.rb +5 -22
- data/lib/hanami/commands/server.rb +14 -142
- data/lib/hanami/components.rb +107 -0
- data/lib/hanami/components/app/assets.rb +55 -0
- data/lib/hanami/components/app/controller.rb +69 -0
- data/lib/hanami/components/app/logger.rb +30 -0
- data/lib/hanami/components/app/routes.rb +51 -0
- data/lib/hanami/components/app/view.rb +40 -0
- data/lib/hanami/components/component.rb +166 -0
- data/lib/hanami/components/components.rb +366 -0
- data/lib/hanami/components/routes_inspector.rb +70 -0
- data/lib/hanami/config/load_paths.rb +7 -6
- data/lib/hanami/config/mapper.rb +1 -1
- data/lib/hanami/config/security.rb +0 -8
- data/lib/hanami/configuration.rb +27 -1697
- data/lib/hanami/env.rb +67 -0
- data/lib/hanami/environment.rb +31 -21
- data/lib/hanami/environment_application_configurations.rb +30 -0
- data/lib/hanami/frameworks.rb +1 -0
- data/lib/hanami/generators/app/application.rb.tt +2 -2
- data/lib/hanami/generators/application/app/Gemfile.tt +3 -1
- data/lib/hanami/generators/application/app/config/application.rb.tt +2 -2
- data/lib/hanami/generators/application/app/gitignore_with_sqlite.tt +3 -0
- data/lib/hanami/generators/application/app/lib/app_name.rb.tt +4 -25
- data/lib/hanami/generators/application/app/spec_helper.rb.minitest.tt +1 -1
- data/lib/hanami/generators/application/app/spec_helper.rb.rspec.tt +1 -1
- data/lib/hanami/generators/application/container/Gemfile.tt +3 -1
- data/lib/hanami/generators/application/container/capybara.rb.rspec.tt +1 -1
- data/lib/hanami/generators/application/container/config.ru.tt +1 -1
- data/lib/hanami/generators/application/container/config/environment.rb.tt +35 -1
- data/lib/hanami/generators/application/container/features_helper.rb.minitest.tt +1 -1
- data/lib/hanami/generators/application/container/gitignore_with_sqlite.tt +3 -0
- data/lib/hanami/generators/application/container/lib/project.rb.tt +1 -57
- data/lib/hanami/generators/application/container/spec_helper.rb.minitest.tt +1 -1
- data/lib/hanami/generators/application/container/spec_helper.rb.rspec.tt +2 -3
- data/lib/hanami/generators/database_config.rb +8 -11
- data/lib/hanami/generators/model/entity.rb.tt +1 -2
- data/lib/hanami/generators/model/repository.rb.tt +1 -2
- data/lib/hanami/generators/template_engine.rb +8 -3
- data/lib/hanami/generators/test_framework.rb +4 -3
- data/lib/hanami/middleware.rb +41 -21
- data/lib/hanami/rake_helper.rb +6 -8
- data/lib/hanami/server.rb +43 -33
- data/lib/hanami/static.rb +2 -2
- data/lib/hanami/version.rb +35 -1
- data/lib/hanami/welcome.rb +4 -5
- metadata +68 -42
- data/lib/hanami/commands/db/abstract.rb +0 -19
- data/lib/hanami/config/configure.rb +0 -17
- data/lib/hanami/config/mapping.rb +0 -12
- data/lib/hanami/container.rb +0 -71
- data/lib/hanami/generators/application/container/gitignore_with_db.tt +0 -4
- data/lib/hanami/loader.rb +0 -257
- data/lib/hanami/repositories/car_repository.rb +0 -3
- data/lib/hanami/repositories/name_repository.rb +0 -3
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
require 'concurrent'
|
|
2
|
+
|
|
3
|
+
module Hanami
|
|
4
|
+
# Components API
|
|
5
|
+
#
|
|
6
|
+
# Components are an internal Hanami that provides precise loading mechanism
|
|
7
|
+
# for a project. It is responsible to load frameworks, configurations, code, etc..
|
|
8
|
+
#
|
|
9
|
+
# The implementation is thread-safe
|
|
10
|
+
#
|
|
11
|
+
# @since 0.9.0
|
|
12
|
+
# @api private
|
|
13
|
+
module Components
|
|
14
|
+
# Available components
|
|
15
|
+
#
|
|
16
|
+
# @since 0.9.0
|
|
17
|
+
# @api private
|
|
18
|
+
@_components = Concurrent::Hash.new
|
|
19
|
+
|
|
20
|
+
# Resolved components
|
|
21
|
+
#
|
|
22
|
+
# @since 0.9.0
|
|
23
|
+
# @api private
|
|
24
|
+
@_resolved = Concurrent::Map.new
|
|
25
|
+
|
|
26
|
+
# Register a component
|
|
27
|
+
#
|
|
28
|
+
# @param name [String] the unique component name
|
|
29
|
+
# @param blk [Proc] the logic of the component
|
|
30
|
+
#
|
|
31
|
+
# @since 0.9.0
|
|
32
|
+
# @api private
|
|
33
|
+
#
|
|
34
|
+
# @see Hanami::Components::Component
|
|
35
|
+
def self.register(name, &blk)
|
|
36
|
+
@_components[name] = Component.new(name, &blk)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Return a registered component
|
|
40
|
+
#
|
|
41
|
+
# @param name [String] the name of the component
|
|
42
|
+
#
|
|
43
|
+
# @raise [ArgumentError] if the component is unknown
|
|
44
|
+
#
|
|
45
|
+
# @since 0.9.0
|
|
46
|
+
# @api private
|
|
47
|
+
def self.component(name)
|
|
48
|
+
@_components.fetch(name) do
|
|
49
|
+
raise ArgumentError.new("Component not found: `#{name}'.\nAvailable components are: #{@_components.keys.join(', ')}")
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Mark a component as resolved by providing a value or a block.
|
|
54
|
+
# In the latter case, the returning value of the block is associated with
|
|
55
|
+
# the component.
|
|
56
|
+
#
|
|
57
|
+
# @param name [String] the name of the component to mark as resolved
|
|
58
|
+
# @param value [Object] the optional value of the component
|
|
59
|
+
# @param blk [Proc] the optional block which returning value is associated with the component.
|
|
60
|
+
#
|
|
61
|
+
# @since 0.9.0
|
|
62
|
+
# @api private
|
|
63
|
+
def self.resolved(name, value = nil, &blk)
|
|
64
|
+
if block_given?
|
|
65
|
+
@_resolved.fetch_or_store(name, &blk)
|
|
66
|
+
else
|
|
67
|
+
@_resolved.compute_if_absent(name) { value }
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Ask to resolve a component.
|
|
72
|
+
#
|
|
73
|
+
# This is used as dependency mechanism.
|
|
74
|
+
# For instance `model` component depends on `model.configuration`. Before to
|
|
75
|
+
# resolve `model`, `Components` uses this method to resolve that dependency first.
|
|
76
|
+
#
|
|
77
|
+
# @param names [String,Array<String>] one or more components to be resolved
|
|
78
|
+
#
|
|
79
|
+
# @since 0.9.0
|
|
80
|
+
# @api private
|
|
81
|
+
def self.resolve(*names)
|
|
82
|
+
Array(names).flatten.each do |name|
|
|
83
|
+
@_resolved.fetch_or_store(name) do
|
|
84
|
+
component = @_components.fetch(name)
|
|
85
|
+
component.call(Hanami.configuration)
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# Return the value of an already resolved component.
|
|
91
|
+
#
|
|
92
|
+
# @param name [String] the component name
|
|
93
|
+
#
|
|
94
|
+
# @raise [ArgumentError] if the component is unknown or not resolved yet.
|
|
95
|
+
#
|
|
96
|
+
# @since 0.9.0
|
|
97
|
+
# @api private
|
|
98
|
+
def self.[](name)
|
|
99
|
+
@_resolved.fetch(name) do
|
|
100
|
+
raise ArgumentError.new("Component not resolved: `#{name}'.\nResolved components are: #{@_resolved.keys.join(', ')}")
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
require 'hanami/components/component'
|
|
105
|
+
require 'hanami/components/components'
|
|
106
|
+
end
|
|
107
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
module Hanami
|
|
2
|
+
module Components
|
|
3
|
+
module App
|
|
4
|
+
# hanami-assets configuration for a sigle Hanami application in the project.
|
|
5
|
+
#
|
|
6
|
+
# @since 0.9.0
|
|
7
|
+
# @api private
|
|
8
|
+
class Assets
|
|
9
|
+
# Configure hanami-assets for a single Hanami application in the project.
|
|
10
|
+
#
|
|
11
|
+
# @param app [Hanami::Configuration::App] a Hanami application
|
|
12
|
+
#
|
|
13
|
+
# @since 0.9.0
|
|
14
|
+
# @api private
|
|
15
|
+
#
|
|
16
|
+
# rubocop:disable Metrics/AbcSize
|
|
17
|
+
# rubocop:disable Metrics/MethodLength
|
|
18
|
+
def self.resolve(app)
|
|
19
|
+
config = app.configuration
|
|
20
|
+
namespace = app.namespace
|
|
21
|
+
|
|
22
|
+
unless namespace.const_defined?('Assets', false)
|
|
23
|
+
assets = Hanami::Assets.duplicate(namespace) do
|
|
24
|
+
root config.root
|
|
25
|
+
|
|
26
|
+
scheme config.scheme
|
|
27
|
+
host config.host
|
|
28
|
+
port config.port
|
|
29
|
+
|
|
30
|
+
public_directory Hanami.public_directory
|
|
31
|
+
prefix Utils::PathPrefix.new('/assets').join(config.path_prefix)
|
|
32
|
+
|
|
33
|
+
manifest Hanami.public_directory.join('assets.json')
|
|
34
|
+
compile true
|
|
35
|
+
|
|
36
|
+
config.assets.__apply(self)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
assets.configure do
|
|
40
|
+
cdn host != config.host
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
namespace.const_set('Assets', assets)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
name = "#{app.app_name}.assets"
|
|
47
|
+
Components.resolved(name, namespace.const_get('Assets').configuration)
|
|
48
|
+
Components[name]
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
# rubocop:enable Metrics/MethodLength
|
|
52
|
+
# rubocop:enable Metrics/AbcSize
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
require 'hanami/action/session'
|
|
2
|
+
require 'hanami/action/routing_helpers'
|
|
3
|
+
|
|
4
|
+
module Hanami
|
|
5
|
+
module Components
|
|
6
|
+
module App
|
|
7
|
+
# hanami-controller configuration for a sigle Hanami application in the project.
|
|
8
|
+
#
|
|
9
|
+
# @since 0.9.0
|
|
10
|
+
# @api private
|
|
11
|
+
class Controller
|
|
12
|
+
STRICT_TRANSPORT_SECURITY_HEADER = 'Strict-Transport-Security'.freeze
|
|
13
|
+
STRICT_TRANSPORT_SECURITY_DEFAULT_VALUE = 'max-age=31536000'.freeze
|
|
14
|
+
|
|
15
|
+
# Configure hanami-controller for a single Hanami application in the project.
|
|
16
|
+
#
|
|
17
|
+
# @param app [Hanami::Configuration::App] a Hanami application
|
|
18
|
+
#
|
|
19
|
+
# @since 0.9.0
|
|
20
|
+
# @api private
|
|
21
|
+
#
|
|
22
|
+
# rubocop:disable Metrics/AbcSize
|
|
23
|
+
# rubocop:disable Metrics/MethodLength
|
|
24
|
+
def self.resolve(app)
|
|
25
|
+
config = app.configuration
|
|
26
|
+
namespace = app.namespace
|
|
27
|
+
|
|
28
|
+
unless namespace.const_defined?('Controller', false)
|
|
29
|
+
controller = Hanami::Controller.duplicate(namespace) do
|
|
30
|
+
handle_exceptions config.handle_exceptions
|
|
31
|
+
default_request_format config.default_request_format
|
|
32
|
+
default_response_format config.default_response_format
|
|
33
|
+
default_headers(
|
|
34
|
+
Hanami::Config::Security::X_FRAME_OPTIONS_HEADER => config.security.x_frame_options,
|
|
35
|
+
Hanami::Config::Security::X_CONTENT_TYPE_OPTIONS_HEADER => config.security.x_content_type_options,
|
|
36
|
+
Hanami::Config::Security::X_XSS_PROTECTION_HEADER => config.security.x_xss_protection,
|
|
37
|
+
Hanami::Config::Security::CONTENT_SECURITY_POLICY_HEADER => config.security.content_security_policy
|
|
38
|
+
)
|
|
39
|
+
default_headers[STRICT_TRANSPORT_SECURITY_HEADER] = STRICT_TRANSPORT_SECURITY_DEFAULT_VALUE if config.force_ssl
|
|
40
|
+
|
|
41
|
+
if config.cookies.enabled?
|
|
42
|
+
require 'hanami/action/cookies'
|
|
43
|
+
prepare { include Hanami::Action::Cookies }
|
|
44
|
+
cookies config.cookies.default_options
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
if config.sessions.enabled?
|
|
48
|
+
prepare do
|
|
49
|
+
include Hanami::Action::Session
|
|
50
|
+
include Hanami::Action::CSRFProtection
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
prepare { include Hanami::Action::RoutingHelpers }
|
|
55
|
+
|
|
56
|
+
config.controller.__apply(self)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
namespace.const_set('Controller', controller)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
Components.resolved "#{app.app_name}.controller", namespace.const_get('Controller').configuration
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
# rubocop:enable Metrics/MethodLength
|
|
66
|
+
# rubocop:enable Metrics/AbcSize
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require 'hanami/logger'
|
|
2
|
+
|
|
3
|
+
module Hanami
|
|
4
|
+
module Components
|
|
5
|
+
module App
|
|
6
|
+
# hanami/logger configuration for a sigle Hanami application in the project.
|
|
7
|
+
#
|
|
8
|
+
# @since 0.9.0
|
|
9
|
+
# @api private
|
|
10
|
+
class Logger
|
|
11
|
+
# Configure hanami/logger for a single Hanami application in the project.
|
|
12
|
+
#
|
|
13
|
+
# @param app [Hanami::Configuration::App] a Hanami application
|
|
14
|
+
#
|
|
15
|
+
# @since 0.9.0
|
|
16
|
+
# @api private
|
|
17
|
+
def self.resolve(app)
|
|
18
|
+
namespace = app.namespace
|
|
19
|
+
return unless namespace.logger.nil?
|
|
20
|
+
|
|
21
|
+
config = app.configuration
|
|
22
|
+
|
|
23
|
+
# TODO: review this logic
|
|
24
|
+
config.logger.app_name(namespace.to_s)
|
|
25
|
+
namespace.logger = config.logger.build
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
require 'hanami/routes'
|
|
2
|
+
require 'hanami/routing/default'
|
|
3
|
+
|
|
4
|
+
module Hanami
|
|
5
|
+
module Components
|
|
6
|
+
module App
|
|
7
|
+
# hanami-router configuration for a sigle Hanami application in the project.
|
|
8
|
+
#
|
|
9
|
+
# @since 0.9.0
|
|
10
|
+
# @api private
|
|
11
|
+
class Routes
|
|
12
|
+
# Configure hanami-router for a single Hanami application in the project.
|
|
13
|
+
#
|
|
14
|
+
# @param app [Hanami::Configuration::App] a Hanami application
|
|
15
|
+
#
|
|
16
|
+
# @since 0.9.0
|
|
17
|
+
# @api private
|
|
18
|
+
def self.resolve(app)
|
|
19
|
+
namespace = app.namespace
|
|
20
|
+
routes = application_routes(app)
|
|
21
|
+
|
|
22
|
+
if namespace.routes.nil? # rubocop:disable Style/IfUnlessModifier
|
|
23
|
+
namespace.routes = Hanami::Routes.new(routes)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
Components.resolved("#{app.app_name}.routes", routes)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def self.application_routes(app) # rubocop:disable Metrics/MethodLength
|
|
30
|
+
config = app.configuration
|
|
31
|
+
namespace = app.namespace
|
|
32
|
+
|
|
33
|
+
resolver = Hanami::Routing::EndpointResolver.new(pattern: config.controller_pattern, namespace: namespace)
|
|
34
|
+
default_app = Hanami::Routing::Default.new
|
|
35
|
+
|
|
36
|
+
Hanami::Router.new(
|
|
37
|
+
resolver: resolver,
|
|
38
|
+
default_app: default_app,
|
|
39
|
+
parsers: config.body_parsers,
|
|
40
|
+
scheme: config.scheme,
|
|
41
|
+
host: config.host,
|
|
42
|
+
port: config.port,
|
|
43
|
+
prefix: config.path_prefix,
|
|
44
|
+
force_ssl: config.force_ssl,
|
|
45
|
+
&config.routes
|
|
46
|
+
)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
module Hanami
|
|
2
|
+
module Components
|
|
3
|
+
module App
|
|
4
|
+
# hanami-view configuration for a sigle Hanami application in the project.
|
|
5
|
+
#
|
|
6
|
+
# @since 0.9.0
|
|
7
|
+
# @api private
|
|
8
|
+
class View
|
|
9
|
+
# Configure hanami-view for a single Hanami application in the project.
|
|
10
|
+
#
|
|
11
|
+
# @param app [Hanami::Configuration::App] a Hanami application
|
|
12
|
+
#
|
|
13
|
+
# @since 0.9.0
|
|
14
|
+
# @api private
|
|
15
|
+
#
|
|
16
|
+
# rubocop:disable Metrics/AbcSize
|
|
17
|
+
# rubocop:disable Metrics/MethodLength
|
|
18
|
+
def self.resolve(app)
|
|
19
|
+
config = app.configuration
|
|
20
|
+
namespace = app.namespace
|
|
21
|
+
|
|
22
|
+
unless namespace.const_defined?('View', false)
|
|
23
|
+
view = Hanami::View.duplicate(namespace) do
|
|
24
|
+
root config.templates
|
|
25
|
+
layout config.layout
|
|
26
|
+
|
|
27
|
+
config.view.__apply(self)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
namespace.const_set('View', view)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
Components.resolved "#{app.app_name}.view", namespace.const_get('View').configuration
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
# rubocop:enable Metrics/MethodLength
|
|
37
|
+
# rubocop:enable Metrics/AbcSize
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
module Hanami
|
|
2
|
+
module Components
|
|
3
|
+
# Base component
|
|
4
|
+
#
|
|
5
|
+
# @since 0.9.0
|
|
6
|
+
# @api private
|
|
7
|
+
#
|
|
8
|
+
# @see Hanami::Components
|
|
9
|
+
class Component
|
|
10
|
+
# Instantiate a new component
|
|
11
|
+
#
|
|
12
|
+
# @param name [String] the component name
|
|
13
|
+
# @param blk [Proc] the logic of the component
|
|
14
|
+
#
|
|
15
|
+
# @return [Hanami::Components::Component]
|
|
16
|
+
#
|
|
17
|
+
# @since 0.9.0
|
|
18
|
+
# @api private
|
|
19
|
+
def initialize(name, &blk)
|
|
20
|
+
@name = name
|
|
21
|
+
@requirements = []
|
|
22
|
+
@_prepare = ->(*) {}
|
|
23
|
+
@_resolve = -> {}
|
|
24
|
+
instance_eval(&blk)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Run or resolve the component
|
|
28
|
+
#
|
|
29
|
+
# @param configuration [Hanami::Configuration] the Hanami configuration for the project
|
|
30
|
+
#
|
|
31
|
+
# @since 0.9.0
|
|
32
|
+
# @api private
|
|
33
|
+
def call(configuration)
|
|
34
|
+
resolve_requirements
|
|
35
|
+
_prepare.call(configuration)
|
|
36
|
+
|
|
37
|
+
unless _run.nil?
|
|
38
|
+
_run.call(configuration)
|
|
39
|
+
return
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
resolved(name, _resolve.call(configuration))
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
private
|
|
46
|
+
|
|
47
|
+
# Component name
|
|
48
|
+
#
|
|
49
|
+
# @return [String]
|
|
50
|
+
#
|
|
51
|
+
# @since 0.9.0
|
|
52
|
+
# @api private
|
|
53
|
+
attr_reader :name
|
|
54
|
+
|
|
55
|
+
# Component requirements
|
|
56
|
+
#
|
|
57
|
+
# @return [Array<String>]
|
|
58
|
+
#
|
|
59
|
+
# @since 0.9.0
|
|
60
|
+
# @api private
|
|
61
|
+
attr_reader :requirements
|
|
62
|
+
|
|
63
|
+
# Prepare logic
|
|
64
|
+
#
|
|
65
|
+
# @since 0.9.0
|
|
66
|
+
# @api private
|
|
67
|
+
attr_accessor :_prepare
|
|
68
|
+
|
|
69
|
+
# Resolve logic
|
|
70
|
+
#
|
|
71
|
+
# @since 0.9.0
|
|
72
|
+
# @api private
|
|
73
|
+
attr_accessor :_resolve
|
|
74
|
+
|
|
75
|
+
# Run logic
|
|
76
|
+
#
|
|
77
|
+
# @since 0.9.0
|
|
78
|
+
# @api private
|
|
79
|
+
attr_accessor :_run
|
|
80
|
+
|
|
81
|
+
# Declare component requirement(s)
|
|
82
|
+
#
|
|
83
|
+
# @param components [Array<String>] the name of the other components to
|
|
84
|
+
# depend on
|
|
85
|
+
def requires(*components)
|
|
86
|
+
self.requirements = Array(components).flatten
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Declare prepare logic
|
|
90
|
+
#
|
|
91
|
+
# @param blk [Proc] prepare logic
|
|
92
|
+
#
|
|
93
|
+
# @since 0.9.0
|
|
94
|
+
# @api private
|
|
95
|
+
def prepare(&blk)
|
|
96
|
+
self._prepare = blk
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# Declare resolve logic
|
|
100
|
+
#
|
|
101
|
+
# @param blk [Proc] resolve logic
|
|
102
|
+
#
|
|
103
|
+
# @since 0.9.0
|
|
104
|
+
# @api private
|
|
105
|
+
def resolve(&blk)
|
|
106
|
+
self._resolve = blk
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# Declare run logic
|
|
110
|
+
#
|
|
111
|
+
# @param blk [Proc] run logic
|
|
112
|
+
#
|
|
113
|
+
# @since 0.9.0
|
|
114
|
+
# @api private
|
|
115
|
+
def run(&blk)
|
|
116
|
+
self._run = blk
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# Set requirements
|
|
120
|
+
#
|
|
121
|
+
# @param names [Array<String>] the requirements
|
|
122
|
+
#
|
|
123
|
+
# @since 0.9.0
|
|
124
|
+
# @api private
|
|
125
|
+
def requirements=(names)
|
|
126
|
+
@requirements = Array(names).flatten
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# Resolve the requirements before to execute the logic of this component
|
|
130
|
+
#
|
|
131
|
+
# @since 0.9.0
|
|
132
|
+
# @api private
|
|
133
|
+
#
|
|
134
|
+
# @see Hanami::Components.resolve
|
|
135
|
+
def resolve_requirements
|
|
136
|
+
Components.resolve(requirements)
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
# Get a registered component by name
|
|
140
|
+
#
|
|
141
|
+
# @param name [String] the component name
|
|
142
|
+
#
|
|
143
|
+
# @since 0.9.0
|
|
144
|
+
# @api private
|
|
145
|
+
#
|
|
146
|
+
# @see Hanami::Components.component
|
|
147
|
+
def component(name)
|
|
148
|
+
Components.component(name)
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
# Mark a component as resolved by providing a value or a block.
|
|
152
|
+
#
|
|
153
|
+
# @param name [String] the name of the component to mark as resolved
|
|
154
|
+
# @param value [Object] the optional value of the component
|
|
155
|
+
# @param blk [Proc] the optional block which returning value is associated with the component.
|
|
156
|
+
#
|
|
157
|
+
# @since 0.9.0
|
|
158
|
+
# @api private
|
|
159
|
+
#
|
|
160
|
+
# @see Hanami::Components.resolved
|
|
161
|
+
def resolved(name, value = nil, &blk)
|
|
162
|
+
Components.resolved(name, value, &blk)
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
end
|