hanami 2.1.0 → 2.2.0.beta1
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 +30 -6
- data/FEATURES.md +1 -1
- data/README.md +7 -7
- data/hanami.gemspec +6 -6
- data/lib/hanami/app.rb +6 -2
- data/lib/hanami/config/actions.rb +1 -1
- data/lib/hanami/config/assets.rb +1 -1
- data/lib/hanami/config/db.rb +33 -0
- data/lib/hanami/config/logger.rb +2 -2
- data/lib/hanami/config.rb +37 -10
- data/lib/hanami/extensions/db/repo.rb +103 -0
- data/lib/hanami/extensions/view/context.rb +1 -1
- data/lib/hanami/extensions/view/part.rb +1 -1
- data/lib/hanami/extensions/view/slice_configured_helpers.rb +1 -1
- data/lib/hanami/extensions.rb +4 -0
- data/lib/hanami/helpers/assets_helper.rb +5 -5
- data/lib/hanami/helpers/form_helper/form_builder.rb +4 -6
- data/lib/hanami/middleware/public_errors_app.rb +2 -2
- data/lib/hanami/provider_registrar.rb +26 -0
- data/lib/hanami/providers/assets.rb +2 -20
- data/lib/hanami/providers/db/adapter.rb +68 -0
- data/lib/hanami/providers/db/adapters.rb +44 -0
- data/lib/hanami/providers/db/config.rb +66 -0
- data/lib/hanami/providers/db/sql_adapter.rb +80 -0
- data/lib/hanami/providers/db.rb +203 -0
- data/lib/hanami/providers/db_logging.rb +22 -0
- data/lib/hanami/providers/rack.rb +3 -3
- data/lib/hanami/providers/relations.rb +31 -0
- data/lib/hanami/providers/routes.rb +1 -13
- data/lib/hanami/rake_tasks.rb +9 -8
- data/lib/hanami/settings.rb +3 -3
- data/lib/hanami/slice.rb +90 -10
- data/lib/hanami/version.rb +1 -1
- data/lib/hanami/web/rack_logger.rb +3 -3
- data/lib/hanami.rb +3 -0
- data/spec/integration/container/provider_environment_spec.rb +52 -0
- data/spec/integration/db/auto_registration_spec.rb +39 -0
- data/spec/integration/db/db_inflector_spec.rb +57 -0
- data/spec/integration/db/db_slices_spec.rb +327 -0
- data/spec/integration/db/db_spec.rb +220 -0
- data/spec/integration/db/logging_spec.rb +238 -0
- data/spec/integration/db/provider_config_spec.rb +88 -0
- data/spec/integration/db/provider_spec.rb +35 -0
- data/spec/integration/db/repo_spec.rb +215 -0
- data/spec/integration/db/slices_importing_from_parent.rb +130 -0
- data/spec/integration/slices/slice_configuration_spec.rb +4 -4
- data/spec/integration/view/config/template_spec.rb +1 -1
- data/spec/integration/view/context/request_spec.rb +1 -1
- data/spec/support/app_integration.rb +3 -0
- data/spec/unit/hanami/config/db_spec.rb +38 -0
- data/spec/unit/hanami/config/router_spec.rb +1 -1
- data/spec/unit/hanami/helpers/form_helper_spec.rb +33 -2
- data/spec/unit/hanami/providers/db/config/default_config_spec.rb +107 -0
- data/spec/unit/hanami/providers/db/config_spec.rb +206 -0
- data/spec/unit/hanami/slice_spec.rb +33 -1
- data/spec/unit/hanami/version_spec.rb +1 -1
- metadata +62 -20
@@ -10,18 +10,6 @@ module Hanami
|
|
10
10
|
# @api private
|
11
11
|
# @since 2.0.0
|
12
12
|
class Assets < Dry::System::Provider::Source
|
13
|
-
# @api private
|
14
|
-
def self.for_slice(slice)
|
15
|
-
Class.new(self) do |klass|
|
16
|
-
klass.instance_variable_set(:@slice, slice)
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
# @api private
|
21
|
-
def self.slice
|
22
|
-
@slice || Hanami.app
|
23
|
-
end
|
24
|
-
|
25
13
|
# @api private
|
26
14
|
def prepare
|
27
15
|
require "hanami/assets"
|
@@ -29,18 +17,12 @@ module Hanami
|
|
29
17
|
|
30
18
|
# @api private
|
31
19
|
def start
|
32
|
-
root =
|
20
|
+
root = target.app.root.join("public", "assets", Hanami::Assets.public_assets_dir(target).to_s)
|
33
21
|
|
34
|
-
assets = Hanami::Assets.new(config:
|
22
|
+
assets = Hanami::Assets.new(config: target.config.assets, root: root)
|
35
23
|
|
36
24
|
register(:assets, assets)
|
37
25
|
end
|
38
|
-
|
39
|
-
private
|
40
|
-
|
41
|
-
def slice
|
42
|
-
self.class.slice
|
43
|
-
end
|
44
26
|
end
|
45
27
|
end
|
46
28
|
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry/configurable"
|
4
|
+
|
5
|
+
module Hanami
|
6
|
+
module Providers
|
7
|
+
class DB < Dry::System::Provider::Source
|
8
|
+
# @api public
|
9
|
+
# @since 2.2.0
|
10
|
+
class Adapter
|
11
|
+
include Dry::Configurable
|
12
|
+
|
13
|
+
# @api public
|
14
|
+
# @since 2.2.0
|
15
|
+
setting :plugins, mutable: true
|
16
|
+
|
17
|
+
# @api private
|
18
|
+
def initialize(...)
|
19
|
+
@skip_defaults = Hash.new(false)
|
20
|
+
end
|
21
|
+
|
22
|
+
# @api public
|
23
|
+
# @since 2.2.0
|
24
|
+
def skip_defaults(setting_name = nil)
|
25
|
+
@skip_defaults[setting_name] = true
|
26
|
+
end
|
27
|
+
|
28
|
+
# @api private
|
29
|
+
private def skip_defaults?(setting_name = nil)
|
30
|
+
@skip_defaults[setting_name]
|
31
|
+
end
|
32
|
+
|
33
|
+
# @api private
|
34
|
+
def configure_for_database(database_url)
|
35
|
+
end
|
36
|
+
|
37
|
+
# @api public
|
38
|
+
# @since 2.2.0
|
39
|
+
def plugin(**plugin_spec, &config_block)
|
40
|
+
plugins << [plugin_spec, config_block]
|
41
|
+
end
|
42
|
+
|
43
|
+
# @api public
|
44
|
+
# @since 2.2.0
|
45
|
+
def plugins
|
46
|
+
config.plugins ||= []
|
47
|
+
end
|
48
|
+
|
49
|
+
# @api private
|
50
|
+
def gateway_cache_keys
|
51
|
+
gateway_options
|
52
|
+
end
|
53
|
+
|
54
|
+
# @api private
|
55
|
+
def gateway_options
|
56
|
+
{}
|
57
|
+
end
|
58
|
+
|
59
|
+
# @api public
|
60
|
+
# @since 2.2.0
|
61
|
+
def clear
|
62
|
+
config.plugins = nil
|
63
|
+
self
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Hanami
|
4
|
+
module Providers
|
5
|
+
class DB < Dry::System::Provider::Source
|
6
|
+
# @api public
|
7
|
+
# @since 2.2.0
|
8
|
+
class Adapters
|
9
|
+
# @api private
|
10
|
+
# @since 2.2.0
|
11
|
+
ADAPTER_CLASSES = Hash.new(Adapter).update(
|
12
|
+
sql: SQLAdapter
|
13
|
+
).freeze
|
14
|
+
private_constant :ADAPTER_CLASSES
|
15
|
+
|
16
|
+
extend Forwardable
|
17
|
+
|
18
|
+
def_delegators :adapters, :[], :[]=, :each, :to_h
|
19
|
+
|
20
|
+
# @api private
|
21
|
+
# @since 2.2.0
|
22
|
+
attr_reader :adapters
|
23
|
+
|
24
|
+
# @api private
|
25
|
+
# @since 2.2.0
|
26
|
+
def initialize
|
27
|
+
@adapters = Hash.new do |hsh, key|
|
28
|
+
hsh[key] = ADAPTER_CLASSES[key].new
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# @api private
|
33
|
+
# @since 2.2.0
|
34
|
+
def initialize_copy(source)
|
35
|
+
@adapters = source.adapters.dup
|
36
|
+
|
37
|
+
source.adapters.each do |key, val|
|
38
|
+
@adapters[key] = val.dup
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry/core"
|
4
|
+
|
5
|
+
module Hanami
|
6
|
+
module Providers
|
7
|
+
class DB < Dry::System::Provider::Source
|
8
|
+
# @api public
|
9
|
+
# @since 2.2.0
|
10
|
+
class Config < Dry::Configurable::Config
|
11
|
+
include Dry::Core::Constants
|
12
|
+
|
13
|
+
# @api public
|
14
|
+
# @since 2.2.0
|
15
|
+
def adapter_name
|
16
|
+
self[:adapter]
|
17
|
+
end
|
18
|
+
|
19
|
+
# @api public
|
20
|
+
# @since 2.2.0
|
21
|
+
def adapter(name = Undefined)
|
22
|
+
return adapter_name if name.eql?(Undefined)
|
23
|
+
|
24
|
+
adapter = (adapters[name] ||= Adapter.new)
|
25
|
+
yield adapter if block_given?
|
26
|
+
adapter
|
27
|
+
end
|
28
|
+
|
29
|
+
# @api public
|
30
|
+
# @since 2.2.0
|
31
|
+
def any_adapter
|
32
|
+
adapter = (adapters[nil] ||= Adapter.new)
|
33
|
+
yield adapter if block_given?
|
34
|
+
adapter
|
35
|
+
end
|
36
|
+
|
37
|
+
# @api private
|
38
|
+
# @since 2.2.0
|
39
|
+
def gateway_cache_keys
|
40
|
+
adapters[adapter_name].gateway_cache_keys
|
41
|
+
end
|
42
|
+
|
43
|
+
# @api private
|
44
|
+
# @since 2.2.0
|
45
|
+
def gateway_options
|
46
|
+
adapters[adapter_name].gateway_options
|
47
|
+
end
|
48
|
+
|
49
|
+
# @api public
|
50
|
+
# @since 2.2.0
|
51
|
+
def each_plugin
|
52
|
+
universal_plugins = adapters[nil].plugins
|
53
|
+
adapter_plugins = adapters[adapter_name].plugins
|
54
|
+
|
55
|
+
plugins = universal_plugins + adapter_plugins
|
56
|
+
|
57
|
+
return to_enum(__method__) unless block_given?
|
58
|
+
|
59
|
+
plugins.each do |plugin_spec, config_block|
|
60
|
+
yield plugin_spec, config_block
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Hanami
|
4
|
+
module Providers
|
5
|
+
class DB < Dry::System::Provider::Source
|
6
|
+
# @api public
|
7
|
+
# @since 2.2.0
|
8
|
+
class SQLAdapter < Adapter
|
9
|
+
# @api public
|
10
|
+
# @since 2.2.0
|
11
|
+
setting :extensions, mutable: true
|
12
|
+
|
13
|
+
# @api public
|
14
|
+
# @since 2.2.0
|
15
|
+
def extension(*extensions)
|
16
|
+
self.extensions.concat(extensions)
|
17
|
+
end
|
18
|
+
|
19
|
+
# @api public
|
20
|
+
# @since 2.2.0
|
21
|
+
def extensions
|
22
|
+
config.extensions ||= []
|
23
|
+
end
|
24
|
+
|
25
|
+
# @api private
|
26
|
+
def configure_for_database(database_url)
|
27
|
+
return if skip_defaults?
|
28
|
+
|
29
|
+
configure_plugins
|
30
|
+
configure_extensions(database_url)
|
31
|
+
end
|
32
|
+
|
33
|
+
# @api private
|
34
|
+
private def configure_plugins
|
35
|
+
return if skip_defaults?(:plugins)
|
36
|
+
|
37
|
+
plugin relations: :instrumentation do |plugin|
|
38
|
+
plugin.notifications = target["notifications"]
|
39
|
+
end
|
40
|
+
|
41
|
+
plugin relations: :auto_restrictions
|
42
|
+
end
|
43
|
+
|
44
|
+
# @api private
|
45
|
+
private def configure_extensions(database_url)
|
46
|
+
return if skip_defaults?(:extensions)
|
47
|
+
|
48
|
+
# Extensions for all SQL databases
|
49
|
+
extension(
|
50
|
+
:caller_logging,
|
51
|
+
:error_sql,
|
52
|
+
:sql_comments
|
53
|
+
)
|
54
|
+
|
55
|
+
# Extensions for specific databases
|
56
|
+
if database_url.to_s.start_with?("postgresql://")
|
57
|
+
extension(
|
58
|
+
:pg_array,
|
59
|
+
:pg_enum,
|
60
|
+
:pg_json,
|
61
|
+
:pg_range
|
62
|
+
)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# @api private
|
67
|
+
def gateway_options
|
68
|
+
{extensions: config.extensions}
|
69
|
+
end
|
70
|
+
|
71
|
+
# @api public
|
72
|
+
# @since 2.2.0
|
73
|
+
def clear
|
74
|
+
config.extensions = nil
|
75
|
+
super
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,203 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry/configurable"
|
4
|
+
require "dry/core"
|
5
|
+
|
6
|
+
module Hanami
|
7
|
+
module Providers
|
8
|
+
# @api private
|
9
|
+
# @since 2.2.0
|
10
|
+
class DB < Dry::System::Provider::Source
|
11
|
+
extend Dry::Core::Cache
|
12
|
+
|
13
|
+
include Dry::Configurable(config_class: Providers::DB::Config)
|
14
|
+
|
15
|
+
setting :database_url
|
16
|
+
setting :adapter, default: :sql
|
17
|
+
setting :adapters, mutable: true, default: Adapters.new
|
18
|
+
setting :relations_path, default: "relations"
|
19
|
+
|
20
|
+
def initialize(...)
|
21
|
+
super(...)
|
22
|
+
|
23
|
+
@configured_for_database = false
|
24
|
+
end
|
25
|
+
|
26
|
+
def finalize_config
|
27
|
+
apply_parent_config and return if apply_parent_config?
|
28
|
+
|
29
|
+
configure_for_database
|
30
|
+
end
|
31
|
+
|
32
|
+
def prepare
|
33
|
+
prepare_and_import_parent_db and return if import_from_parent?
|
34
|
+
|
35
|
+
override_rom_inflector
|
36
|
+
|
37
|
+
finalize_config
|
38
|
+
|
39
|
+
require "hanami-db"
|
40
|
+
|
41
|
+
unless database_url
|
42
|
+
raise Hanami::ComponentLoadError, "A database_url is required to start :db."
|
43
|
+
end
|
44
|
+
|
45
|
+
# Avoid making spurious connections by reusing identically configured gateways across slices
|
46
|
+
gateway = fetch_or_store(database_url, config.gateway_cache_keys) {
|
47
|
+
ROM::Gateway.setup(
|
48
|
+
config.adapter,
|
49
|
+
database_url,
|
50
|
+
**config.gateway_options
|
51
|
+
)
|
52
|
+
}
|
53
|
+
|
54
|
+
@rom_config = ROM::Configuration.new(gateway)
|
55
|
+
|
56
|
+
config.each_plugin do |plugin_spec, config_block|
|
57
|
+
if config_block
|
58
|
+
@rom_config.plugin(config.adapter, plugin_spec) do |plugin_config|
|
59
|
+
instance_exec(plugin_config, &config_block)
|
60
|
+
end
|
61
|
+
else
|
62
|
+
@rom_config.plugin(config.adapter, plugin_spec)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
register "config", @rom_config
|
67
|
+
register "gateway", gateway
|
68
|
+
end
|
69
|
+
|
70
|
+
# @api private
|
71
|
+
def start
|
72
|
+
start_and_import_parent_db and return if import_from_parent?
|
73
|
+
|
74
|
+
# Set up DB logging for the whole app. We share the app's notifications bus across all
|
75
|
+
# slices, so we only need to configure the subsciprtion for DB logging just once.
|
76
|
+
target.app.start :db_logging
|
77
|
+
|
78
|
+
# Find and register relations
|
79
|
+
relations_path = target.source_path.join(config.relations_path)
|
80
|
+
relations_path.glob("*.rb").each do |relation_file|
|
81
|
+
relation_name = relation_file
|
82
|
+
.relative_path_from(relations_path)
|
83
|
+
.basename(relation_file.extname)
|
84
|
+
.to_s
|
85
|
+
|
86
|
+
relation_class = target.namespace
|
87
|
+
.const_get(:Relations) # TODO don't hardcode
|
88
|
+
.const_get(target.inflector.camelize(relation_name))
|
89
|
+
|
90
|
+
@rom_config.register_relation(relation_class)
|
91
|
+
end
|
92
|
+
|
93
|
+
# TODO: register mappers & commands
|
94
|
+
|
95
|
+
rom = ROM.container(@rom_config)
|
96
|
+
|
97
|
+
register "rom", rom
|
98
|
+
end
|
99
|
+
|
100
|
+
def stop
|
101
|
+
target["db.rom"].disconnect
|
102
|
+
end
|
103
|
+
|
104
|
+
# @api private
|
105
|
+
def database_url
|
106
|
+
return @database_url if instance_variable_defined?(:@database_url)
|
107
|
+
|
108
|
+
# For "main" slice, expect MAIN__DATABASE_URL
|
109
|
+
slice_url_var = "#{target.slice_name.name.gsub("/", "__").upcase}__DATABASE_URL"
|
110
|
+
chosen_url = config.database_url || ENV[slice_url_var] || ENV["DATABASE_URL"]
|
111
|
+
chosen_url &&= Hanami::DB::Testing.database_url(chosen_url) if Hanami.env?(:test)
|
112
|
+
|
113
|
+
@database_url = chosen_url
|
114
|
+
end
|
115
|
+
|
116
|
+
private
|
117
|
+
|
118
|
+
def parent_db_provider
|
119
|
+
return @parent_db_provider if instance_variable_defined?(:@parent_db_provider)
|
120
|
+
|
121
|
+
@parent_db_provider = target.parent && target.parent.container.providers[:db]
|
122
|
+
end
|
123
|
+
|
124
|
+
def apply_parent_config
|
125
|
+
parent_db_provider.source.finalize_config
|
126
|
+
|
127
|
+
self.class.settings.keys.each do |key|
|
128
|
+
# Preserve settings already configured locally
|
129
|
+
next if config.configured?(key)
|
130
|
+
|
131
|
+
# Skip adapter config, we handle this below
|
132
|
+
next if key == :adapters
|
133
|
+
|
134
|
+
config[key] = parent_db_provider.source.config[key]
|
135
|
+
end
|
136
|
+
|
137
|
+
parent_db_provider.source.config.adapters.each do |adapter_name, parent_adapter|
|
138
|
+
adapter = config.adapters[adapter_name]
|
139
|
+
|
140
|
+
adapter.class.settings.keys.each do |key|
|
141
|
+
next if adapter.config.configured?(key)
|
142
|
+
|
143
|
+
adapter.config[key] = parent_adapter.config[key]
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def apply_parent_config?
|
149
|
+
target.config.db.configure_from_parent && parent_db_provider
|
150
|
+
end
|
151
|
+
|
152
|
+
def configure_for_database
|
153
|
+
return if @configured_for_database
|
154
|
+
|
155
|
+
config.adapter(config.adapter_name).configure_for_database(database_url)
|
156
|
+
@configured_for_database = true
|
157
|
+
end
|
158
|
+
|
159
|
+
def import_from_parent?
|
160
|
+
target.config.db.import_from_parent && target.parent
|
161
|
+
end
|
162
|
+
|
163
|
+
def prepare_and_import_parent_db
|
164
|
+
return unless parent_db_provider
|
165
|
+
|
166
|
+
target.parent.prepare :db
|
167
|
+
@rom_config = target.parent["db.config"]
|
168
|
+
|
169
|
+
register "config", (@rom_config = target.parent["db.config"])
|
170
|
+
register "gateway", target.parent["db.gateway"]
|
171
|
+
end
|
172
|
+
|
173
|
+
def start_and_import_parent_db
|
174
|
+
return unless parent_db_provider
|
175
|
+
|
176
|
+
target.parent.start :db
|
177
|
+
|
178
|
+
register "rom", target.parent["db.rom"]
|
179
|
+
end
|
180
|
+
|
181
|
+
# ROM 5.3 doesn't have a configurable inflector.
|
182
|
+
#
|
183
|
+
# This is a problem in Hanami because using different
|
184
|
+
# inflection rules for ROM will lead to constant loading
|
185
|
+
# errors.
|
186
|
+
def override_rom_inflector
|
187
|
+
return if ROM::Inflector == Hanami.app["inflector"]
|
188
|
+
|
189
|
+
ROM.instance_eval {
|
190
|
+
remove_const :Inflector
|
191
|
+
const_set :Inflector, Hanami.app["inflector"]
|
192
|
+
}
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
Dry::System.register_provider_source(
|
197
|
+
:db,
|
198
|
+
source: DB,
|
199
|
+
group: :hanami,
|
200
|
+
provider_options: {namespace: true}
|
201
|
+
)
|
202
|
+
end
|
203
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Hanami
|
4
|
+
module Providers
|
5
|
+
# @api private
|
6
|
+
# @since 2.2.0
|
7
|
+
class DBLogging < Dry::System::Provider::Source
|
8
|
+
# @api private
|
9
|
+
# @since 2.2.0
|
10
|
+
def prepare
|
11
|
+
require "dry/monitor/sql/logger"
|
12
|
+
target["notifications"].register_event :sql
|
13
|
+
end
|
14
|
+
|
15
|
+
# @api private
|
16
|
+
# @since 2.2.0
|
17
|
+
def start
|
18
|
+
Dry::Monitor::SQL::Logger.new(target["logger"]).subscribe(target["notifications"])
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -20,8 +20,8 @@ module Hanami
|
|
20
20
|
# Explicitly register the Rack middleware events on our notifications bus. The Dry::Monitor
|
21
21
|
# rack extension (activated above) does register these globally, but if the notifications
|
22
22
|
# bus has been used before this provider loads, then it will have created its own separate
|
23
|
-
#
|
24
|
-
# the Rack events globally
|
23
|
+
# local copy of all registered events as of that moment in time, which will not be included
|
24
|
+
# in the Rack events globally registered above.
|
25
25
|
notifications = target["notifications"]
|
26
26
|
notifications.register_event(Dry::Monitor::Rack::Middleware::REQUEST_START)
|
27
27
|
notifications.register_event(Dry::Monitor::Rack::Middleware::REQUEST_STOP)
|
@@ -37,7 +37,7 @@ module Hanami
|
|
37
37
|
clock: Dry::Monitor::Clock.new(unit: :microsecond)
|
38
38
|
)
|
39
39
|
|
40
|
-
rack_logger = Hanami::Web::RackLogger.new(target[:logger], env: target.env)
|
40
|
+
rack_logger = Hanami::Web::RackLogger.new(target[:logger], env: target.container.env)
|
41
41
|
rack_logger.attach(monitor_middleware)
|
42
42
|
|
43
43
|
register "monitor", monitor_middleware
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Hanami
|
4
|
+
module Providers
|
5
|
+
# @api private
|
6
|
+
# @since 2.2.0
|
7
|
+
class Relations < Dry::System::Provider::Source
|
8
|
+
def start
|
9
|
+
start_and_import_parent_relations and return if target.parent && target.config.db.import_from_parent
|
10
|
+
|
11
|
+
target.start :db
|
12
|
+
|
13
|
+
register_relations target["db.rom"]
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def register_relations(rom)
|
19
|
+
rom.relations.each do |name, _|
|
20
|
+
register name, rom.relations[name]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def start_and_import_parent_relations
|
25
|
+
target.parent.start :relations
|
26
|
+
|
27
|
+
register_relations target.parent["db.rom"]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -10,18 +10,6 @@ module Hanami
|
|
10
10
|
# @api private
|
11
11
|
# @since 2.0.0
|
12
12
|
class Routes < Dry::System::Provider::Source
|
13
|
-
# @api private
|
14
|
-
def self.for_slice(slice)
|
15
|
-
Class.new(self) do |klass|
|
16
|
-
klass.instance_variable_set(:@slice, slice)
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
# @api private
|
21
|
-
def self.slice
|
22
|
-
@slice || Hanami.app
|
23
|
-
end
|
24
|
-
|
25
13
|
# @api private
|
26
14
|
def prepare
|
27
15
|
require "hanami/slice/routes_helper"
|
@@ -33,7 +21,7 @@ module Hanami
|
|
33
21
|
# router during the process of booting. This ensures the router's resolver can run strict
|
34
22
|
# action key checks once when it runs on a fully booted slice.
|
35
23
|
register :routes do
|
36
|
-
Hanami::Slice::RoutesHelper.new(
|
24
|
+
Hanami::Slice::RoutesHelper.new(target.router)
|
37
25
|
end
|
38
26
|
end
|
39
27
|
end
|
data/lib/hanami/rake_tasks.rb
CHANGED
@@ -32,14 +32,15 @@ Hanami::CLI::RakeTasks.register_tasks do
|
|
32
32
|
# Please use them when you're in control of your deployment environment.
|
33
33
|
#
|
34
34
|
# If you're not in control and your deployment requires these "standard"
|
35
|
-
# Rake tasks, they are here to solve this
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
35
|
+
# Rake tasks, they are here only to solve this specific problem.
|
36
|
+
|
37
|
+
if Hanami.bundled?("hanami-db")
|
38
|
+
namespace :db do
|
39
|
+
task :migrate do
|
40
|
+
Hanami::CLI::Commands::App::DB::Migrate.new.call
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
43
44
|
|
44
45
|
if Hanami.bundled?("hanami-assets")
|
45
46
|
namespace :assets do
|
data/lib/hanami/settings.rb
CHANGED
@@ -8,7 +8,7 @@ module Hanami
|
|
8
8
|
# Provides user-defined settings for an Hanami app or slice.
|
9
9
|
#
|
10
10
|
# Define your own settings by inheriting from this class in `config/settings.rb` within an app or
|
11
|
-
# slice. Your settings will be loaded from matching ENV vars (with upper-cased names) and
|
11
|
+
# slice. Your settings will be loaded from matching ENV vars (with upper-cased names) and be
|
12
12
|
# registered as a component as part of the Hanami app {Hanami::Slice::ClassMethods#prepare
|
13
13
|
# prepare} step.
|
14
14
|
#
|
@@ -160,8 +160,8 @@ module Hanami
|
|
160
160
|
value = store.fetch(name, Undefined)
|
161
161
|
|
162
162
|
if value.eql?(Undefined)
|
163
|
-
# When a key is missing entirely from the store, _read_ its value from the config instead
|
164
|
-
#
|
163
|
+
# When a key is missing entirely from the store, _read_ its value from the config instead.
|
164
|
+
# This ensures its setting constructor runs (with a `nil` argument given) and raises any
|
165
165
|
# necessary errors.
|
166
166
|
public_send(name)
|
167
167
|
else
|