hanami 2.0.0.beta4 → 2.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +19 -0
  3. data/hanami.gemspec +8 -7
  4. data/lib/hanami/app.rb +47 -36
  5. data/lib/hanami/assets/app_config.rb +7 -15
  6. data/lib/hanami/assets/config.rb +5 -6
  7. data/lib/hanami/config/actions/content_security_policy.rb +1 -1
  8. data/lib/hanami/config/actions/cookies.rb +27 -0
  9. data/lib/hanami/config/actions/sessions.rb +42 -5
  10. data/lib/hanami/config/actions.rb +81 -17
  11. data/lib/hanami/config/logger.rb +112 -23
  12. data/lib/hanami/config/router.rb +0 -1
  13. data/lib/hanami/config/views.rb +6 -10
  14. data/lib/hanami/config.rb +235 -73
  15. data/lib/hanami/constants.rb +4 -0
  16. data/lib/hanami/errors.rb +17 -0
  17. data/lib/hanami/extensions/action/slice_configured_action.rb +9 -5
  18. data/lib/hanami/extensions/action.rb +59 -7
  19. data/lib/hanami/extensions/view/context.rb +3 -4
  20. data/lib/hanami/extensions/view/slice_configured_view.rb +4 -4
  21. data/lib/hanami/extensions/view.rb +7 -5
  22. data/lib/hanami/providers/inflector.rb +6 -0
  23. data/lib/hanami/providers/logger.rb +8 -0
  24. data/lib/hanami/providers/rack.rb +12 -0
  25. data/lib/hanami/providers/routes.rb +14 -4
  26. data/lib/hanami/routes.rb +36 -1
  27. data/lib/hanami/settings/env_store.rb +1 -1
  28. data/lib/hanami/settings.rb +102 -36
  29. data/lib/hanami/slice/router.rb +38 -16
  30. data/lib/hanami/slice/routing/middleware/stack.rb +66 -42
  31. data/lib/hanami/slice/routing/resolver.rb +10 -17
  32. data/lib/hanami/slice/view_name_inferrer.rb +1 -1
  33. data/lib/hanami/slice.rb +553 -14
  34. data/lib/hanami/slice_registrar.rb +20 -15
  35. data/lib/hanami/version.rb +2 -3
  36. data/lib/hanami/web/rack_logger.rb +14 -4
  37. data/lib/hanami.rb +122 -23
  38. data/spec/integration/action/csrf_protection_spec.rb +1 -1
  39. data/spec/integration/container/application_routes_helper_spec.rb +3 -1
  40. data/spec/integration/container/provider_lifecycle_spec.rb +61 -0
  41. data/spec/integration/container/standard_providers/rack_provider_spec.rb +44 -0
  42. data/spec/integration/container/{standard_bootable_components_spec.rb → standard_providers_spec.rb} +3 -3
  43. data/spec/integration/rack_app/body_parser_spec.rb +3 -0
  44. data/spec/integration/rack_app/middleware_spec.rb +427 -3
  45. data/spec/integration/rack_app/non_booted_rack_app_spec.rb +2 -1
  46. data/spec/integration/rack_app/rack_app_spec.rb +39 -11
  47. data/spec/integration/setup_spec.rb +4 -4
  48. data/spec/integration/slices/external_slice_spec.rb +2 -1
  49. data/spec/integration/slices/slice_configuration_spec.rb +3 -1
  50. data/spec/integration/slices/slice_loading_spec.rb +4 -4
  51. data/spec/integration/slices/slice_routing_spec.rb +4 -3
  52. data/spec/integration/slices_spec.rb +100 -0
  53. data/spec/isolation/hanami/boot/success_spec.rb +1 -1
  54. data/spec/support/app_integration.rb +2 -10
  55. data/spec/unit/hanami/config/actions/content_security_policy_spec.rb +7 -7
  56. data/spec/unit/hanami/config/actions/default_values_spec.rb +1 -1
  57. data/spec/unit/hanami/config/actions/sessions_spec.rb +1 -3
  58. data/spec/unit/hanami/config/actions_spec.rb +1 -12
  59. data/spec/unit/hanami/config/logger_spec.rb +38 -55
  60. data/spec/unit/hanami/config/router_spec.rb +1 -1
  61. data/spec/unit/hanami/config/views_spec.rb +3 -13
  62. data/spec/unit/hanami/settings_spec.rb +1 -1
  63. data/spec/unit/hanami/slice_configurable_spec.rb +5 -5
  64. data/spec/unit/hanami/slice_spec.rb +32 -0
  65. data/spec/unit/hanami/version_spec.rb +1 -1
  66. data/spec/unit/hanami/web/rack_logger_spec.rb +13 -2
  67. metadata +54 -45
  68. data/lib/hanami/config/sessions.rb +0 -50
  69. data/spec/unit/hanami/config_spec.rb +0 -43
@@ -1,34 +1,116 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "dry/configurable"
4
- require "hanami/logger"
4
+ require "dry/logger"
5
5
 
6
6
  module Hanami
7
7
  class Config
8
8
  # Hanami logger config
9
9
  #
10
+ # @api public
10
11
  # @since 2.0.0
11
12
  class Logger
12
13
  include Dry::Configurable
13
14
 
15
+ # @return [Hanami::SliceName]
16
+ #
17
+ # @api private
18
+ # @since 2.0.o
14
19
  attr_reader :app_name
15
20
 
16
- protected :config
17
-
21
+ # @!attribute [rw] level
22
+ # Sets or returns the logger level.
23
+ #
24
+ # Defaults to `:info` for the production environment and `:debug` for all others.
25
+ #
26
+ # @return [Symbol]
27
+ #
28
+ # @api public
29
+ # @since 2.0.0
18
30
  setting :level
19
31
 
32
+ # @!attribute [rw] stream
33
+ # Sets or returns the logger's stream.
34
+ #
35
+ # This can be a file path or an `IO`-like object for the logger to write to.
36
+ #
37
+ # Defaults to `"log/test.log"` for the test environment and `$stdout` for all others.
38
+ #
39
+ # @return [String, #write]
40
+ #
41
+ # @api public
42
+ # @since 2.0.0
20
43
  setting :stream
21
44
 
45
+ # @!attribute [rw] formatter
46
+ # Sets or returns the logger's formatter.
47
+ #
48
+ # This may be a name that matches a formatter registered with `Dry::Logger`, which includes
49
+ # `:string`, `:rack` and `:json`.
50
+ #
51
+ # This may also be an instance of Ruby's built-in `::Logger::Formatter` or any compatible
52
+ # object.
53
+ #
54
+ # Defaults to `:json` for the production environment, and `:rack` for all others.
55
+ #
56
+ # @return [Symbol, ::Logger::Formatter]
57
+ #
58
+ # @api public
59
+ # @since 2.0.0
22
60
  setting :formatter
23
61
 
24
- setting :colors
25
-
62
+ # @!attribute [rw] template
63
+ # Sets or returns log entry string template
64
+ #
65
+ # Defaults to `false`.
66
+ #
67
+ # @return [Boolean]
68
+ #
69
+ # @api public
70
+ # @since 2.0.0
71
+ setting :template, default: "[%<progname>s] [%<severity>s] [%<time>s] %<message>s"
72
+
73
+ # @!attribute [rw] filters
74
+ # Sets or returns an array of attribute names to filter from logs.
75
+ #
76
+ # Defaults to `["_csrf", "password", "password_confirmation"]`. If you want to preserve
77
+ # these defaults, append to this array rather than reassigning it.
78
+ #
79
+ # @return [Array<String>]
80
+ #
81
+ # @api public
82
+ # @since 2.0.0
26
83
  setting :filters, default: %w[_csrf password password_confirmation].freeze
27
84
 
28
- setting :options, default: [], constructor: ->(value) { Array(value).flatten }, cloneable: true
29
-
30
- setting :logger_class, default: Hanami::Logger
31
-
85
+ # @!attribute [rw] logger_constructor
86
+ # Sets or returns the constructor proc to use for the logger instantiation.
87
+ #
88
+ # Defaults to `Dry.method(:Logger)`.
89
+ #
90
+ # @api public
91
+ # @since 2.0.0
92
+ setting :logger_constructor, default: Dry.method(:Logger)
93
+
94
+ # @!attribute [rw] options
95
+ # Sets or returns a hash of options to pass to the {logger_constructor} when initializing
96
+ # the logger.
97
+ #
98
+ # Defaults to `[]`
99
+ #
100
+ # @return [Hash]
101
+ #
102
+ # @api public
103
+ # @since 2.0.0
104
+ setting :options, default: {}
105
+
106
+ # Returns a new `Logger` config.
107
+ #
108
+ # You should not need to initialize this directly, instead use {Hanami::Config#logger}.
109
+ #
110
+ # @param env [Symbol] the Hanami env
111
+ # @param app_name [Hanami::SliceName]
112
+ #
113
+ # @api private
32
114
  def initialize(env:, app_name:)
33
115
  @app_name = app_name
34
116
 
@@ -49,28 +131,34 @@ module Hanami
49
131
  config.formatter = case env
50
132
  when :production
51
133
  :json
134
+ else
135
+ :rack
52
136
  end
53
-
54
- config.colors = case env
55
- when :production, :test
56
- false
57
- end
58
137
  end
59
138
 
139
+ # Returns a new instance of the logger.
140
+ #
141
+ # @return [logger_class]
142
+ #
143
+ # @api public
144
+ # @since 2.0.0
60
145
  def instance
61
- logger_class.new(
62
- app_name.name,
63
- *options,
64
- stream: stream,
65
- level: level,
66
- formatter: formatter,
67
- filter: filters,
68
- colorizer: colors
69
- )
146
+ logger_constructor.call(app_name.name, **logger_constructor_opts)
70
147
  end
71
148
 
72
149
  private
73
150
 
151
+ # @api private
152
+ def logger_constructor_opts
153
+ {stream: stream,
154
+ level: level,
155
+ formatter: formatter,
156
+ filters: filters,
157
+ template: template,
158
+ **options}
159
+ end
160
+
161
+ # @api private
74
162
  def method_missing(name, *args, &block)
75
163
  if config.respond_to?(name)
76
164
  config.public_send(name, *args, &block)
@@ -79,6 +167,7 @@ module Hanami
79
167
  end
80
168
  end
81
169
 
170
+ # @api private
82
171
  def respond_to_missing?(name, _incude_all = false)
83
172
  config.respond_to?(name) || super
84
173
  end
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "dry/configurable"
4
- require_relative "../slice/routing/resolver"
5
4
 
6
5
  module Hanami
7
6
  class Config
@@ -7,7 +7,9 @@ module Hanami
7
7
  class Config
8
8
  # Hanami views config
9
9
  #
10
- # @since 2.0.0
10
+ # This is NOT RELEASED as of 2.0.0.
11
+ #
12
+ # @api private
11
13
  class Views
12
14
  include Dry::Configurable
13
15
 
@@ -16,6 +18,7 @@ module Hanami
16
18
  attr_reader :base_config
17
19
  protected :base_config
18
20
 
21
+ # @api private
19
22
  def initialize(*)
20
23
  super
21
24
 
@@ -24,21 +27,14 @@ module Hanami
24
27
  configure_defaults
25
28
  end
26
29
 
30
+ # @api private
27
31
  def initialize_copy(source)
28
32
  super
29
33
  @base_config = source.base_config.dup
30
34
  end
35
+ private :initialize_copy
31
36
 
32
- # Returns the list of available settings
33
- #
34
- # @return [Set]
35
- #
36
- # @since 2.0.0
37
37
  # @api private
38
- def settings
39
- self.class.settings + View.settings - NON_FORWARDABLE_METHODS
40
- end
41
-
42
38
  def finalize!
43
39
  return self if frozen?
44
40
 
data/lib/hanami/config.rb CHANGED
@@ -1,33 +1,97 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "uri"
4
- require "concurrent/hash"
5
- require "concurrent/array"
4
+ require "pathname"
6
5
  require "dry/configurable"
7
6
  require "dry/inflector"
8
- require "pathname"
9
7
 
10
8
  require_relative "constants"
11
- require_relative "config/logger"
12
- require_relative "config/sessions"
13
- require_relative "settings/env_store"
14
- require_relative "slice/routing/middleware/stack"
15
9
 
16
10
  module Hanami
17
- # Hanami app configuration
11
+ # Hanami app config
18
12
  #
19
13
  # @since 2.0.0
20
14
  class Config
21
15
  include Dry::Configurable
22
16
 
17
+ # @!attribute [rw] root
18
+ # Sets the root for the app or slice.
19
+ #
20
+ # For the app, this defaults to `Dir.pwd`. For slices detected in `slices/` `config/slices/`,
21
+ # this defaults to `slices/[slice_name]/`.
22
+ #
23
+ # Accepts a string path and will return a `Pathname`.
24
+ #
25
+ # @return [Pathname]
26
+ #
27
+ # @api public
28
+ # @since 2.0.0
23
29
  setting :root, constructor: ->(path) { Pathname(path) if path }
24
30
 
25
- setting :no_auto_register_paths, default: %w[entities]
26
-
31
+ # @!attribute [rw] inflector
32
+ # Sets the app's inflector.
33
+ #
34
+ # This expects a `Dry::Inflector` (or compatible) inflector instance.
35
+ #
36
+ # To configure custom inflection rules without having to assign a whole inflector, see
37
+ # {#inflections}.
38
+ #
39
+ # @return [Dry::Inflector]
40
+ #
41
+ # @see #inflections
42
+ #
43
+ # @api public
44
+ # @since 2.0.0
27
45
  setting :inflector, default: Dry::Inflector.new
28
46
 
47
+ # @!attribute [rw] settings_store
48
+ # Sets the store used to retrieve {Hanami::Settings} values.
49
+ #
50
+ # Defaults to an instance of {Hanami::Settings::EnvStore}.
51
+ #
52
+ # @return [#fetch]
53
+ #
54
+ # @see Hanami::Settings
55
+ # @see Hanami::Settings::EnvStore#fetch
56
+ #
57
+ # @api public
58
+ # @since 2.0.0
29
59
  setting :settings_store, default: Hanami::Settings::EnvStore.new
30
60
 
61
+ # @!attribute [rw] slices
62
+ # Sets the slices to load when the app is preared or booted.
63
+ #
64
+ # Defaults to `nil`, which will load all slices. Set this to an array of slice names to load
65
+ # only those slices.
66
+ #
67
+ # This attribute is also populated from the `HANAMI_SLICES` environment variable.
68
+ #
69
+ # @example
70
+ # config.slices = ["admin", "search"]
71
+ #
72
+ # @example
73
+ # ENV["HANAMI_SLICES"] # => "admin,search"
74
+ # config.slices # => ["admin", "search"]
75
+ #
76
+ # @return [Array<String>, nil]
77
+ #
78
+ # @api public
79
+ # @since 2.0.0
80
+ setting :slices
81
+
82
+ # @!attribute [rw] shared_app_component_keys
83
+ # Sets the keys for the components to be imported from the app into all other slices.
84
+ #
85
+ # You should append items to this array, since the default shared components are essential for
86
+ # slices to operate within the app.
87
+ #
88
+ # @example
89
+ # config.shared_app_component_keys += ["shared_component_a", "shared_component_b"]
90
+ #
91
+ # @return [Array<String>]
92
+ #
93
+ # @api public
94
+ # @since 2.0.0
31
95
  setting :shared_app_component_keys, default: %w[
32
96
  inflector
33
97
  logger
@@ -37,73 +101,125 @@ module Hanami
37
101
  settings
38
102
  ]
39
103
 
40
- setting :slices
104
+ # @!attribute [rw] no_auto_register_paths
105
+ # Sets the paths to skip from container auto-registration.
106
+ #
107
+ # Defaults to `["entities"]`.
108
+ #
109
+ # @return [Array<String>] array of relative paths
110
+ #
111
+ # @api public
112
+ # @since 2.0.0
113
+ setting :no_auto_register_paths, default: %w[entities]
41
114
 
115
+ # @!attribute [rw] base_url
116
+ # Sets the base URL for app's web server.
117
+ #
118
+ # This is passed to the {Slice::ClassMethods#router router} and used for generating links.
119
+ #
120
+ # Defaults to `"http://0.0.0.0:2300"`. String values passed are turned into `URI` instances.
121
+ #
122
+ # @return [URI]
123
+ #
124
+ # @see Slice::ClassMethods#router
125
+ #
126
+ # @api public
127
+ # @since 2.0.0
42
128
  setting :base_url, default: "http://0.0.0.0:2300", constructor: ->(url) { URI(url) }
43
129
 
44
- setting :sessions, default: :null, constructor: ->(*args) { Sessions.new(*args) }
45
-
46
- setting :logger, cloneable: true
47
-
48
- DEFAULT_ENVIRONMENTS = Concurrent::Hash.new { |h, k| h[k] = Concurrent::Array.new }
49
- private_constant :DEFAULT_ENVIRONMENTS
50
-
51
- # @return [Symbol] The name of the application
130
+ # Returns the app or slice's {Hanami::SliceName slice_name}.
52
131
  #
53
- # @api public
132
+ # This is useful for default config values that depend on this name.
133
+ #
134
+ # @return [Hanami::SliceName]
135
+ #
136
+ # @api private
137
+ # @since 2.0.0
54
138
  attr_reader :app_name
55
139
 
56
- # @return [String] The current environment
140
+ # Returns the app's environment.
57
141
  #
58
- # @api public
142
+ # @example
143
+ # config.env # => :development
144
+ #
145
+ # @return [Symbol]
146
+ #
147
+ # @see #environment
148
+ #
149
+ # @api private
150
+ # @since 2.0.0
59
151
  attr_reader :env
60
152
 
61
- # @return [Hanami::Config::Actions]
153
+ # Returns the app's actions config, or a null config if hanami-controller is not bundled.
154
+ #
155
+ # @example When hanami-controller is bundled
156
+ # config.actions.default_request_format # => :html
157
+ #
158
+ # @example When hanami-controller is not bundled
159
+ # config.actions.default_request_format # => NoMethodError
160
+ #
161
+ # @return [Hanami::Config::Actions, Hanami::Config::NullConfig]
62
162
  #
63
163
  # @api public
164
+ # @since 2.0.0
64
165
  attr_reader :actions
65
166
 
66
- # @return [Hanami::Slice::Routing::Middleware::Stack]
167
+ # Returns the app's middleware stack, or nil if hanami-router is not bundled.
168
+ #
169
+ # Use this to configure middleware that should apply to all routes.
170
+ #
171
+ # @example
172
+ # config.middleware.use :body_parser, :json
173
+ # config.middleware.use MyCustomMiddleware
174
+ #
175
+ # @return [Hanami::Slice::Routing::Middleware::Stack, nil]
67
176
  #
68
177
  # @api public
178
+ # @since 2.0.0
69
179
  attr_reader :middleware
70
180
 
71
181
  # @api private
182
+ # @since 2.0.0
72
183
  alias_method :middleware_stack, :middleware
73
184
 
74
- # @return [Hanami::Config::Router]
185
+ # Returns the app's router config, or a null config if hanami-router is not bundled.
186
+ #
187
+ # @example When hanami-router is bundled
188
+ # config.router.resolver # => Hanami::Slice::Routing::Resolver
189
+ #
190
+ # @example When hanami-router is not bundled
191
+ # config.router.resolver # => NoMethodError
192
+ #
193
+ # @return [Hanami::Config::Router, Hanami::Config::NullConfig]
75
194
  #
76
195
  # @api public
196
+ # @since 2.0.0
77
197
  attr_reader :router
78
198
 
79
- # @return [Hanami::Config::Views]
199
+ # Returns the app's views config, or a null config if hanami-view is not bundled.
80
200
  #
81
- # @api public
201
+ # This is NOT RELEASED as of 2.0.0.
202
+ #
203
+ # @api private
82
204
  attr_reader :views
83
205
 
84
- # @return [Hanami::Assets::AppConfiguration]
206
+ # Returns the app's assets config.
85
207
  #
86
- # @api public
87
- attr_reader :assets
88
-
89
- # @return [Concurrent::Hash] A hash of default environments
208
+ # This is NOT RELEASED as of 2.0.0.
90
209
  #
91
210
  # @api private
92
- attr_reader :environments
93
- private :environments
211
+ attr_reader :assets
94
212
 
95
213
  # @api private
96
214
  def initialize(app_name:, env:)
97
215
  @app_name = app_name
98
-
99
- @environments = DEFAULT_ENVIRONMENTS.clone
100
216
  @env = env
101
217
 
102
218
  # Apply default values that are only knowable at initialize-time (vs require-time)
103
219
  self.root = Dir.pwd
104
220
  load_from_env
105
221
 
106
- config.logger = Config::Logger.new(env: env, app_name: app_name)
222
+ @logger = Config::Logger.new(env: env, app_name: app_name)
107
223
 
108
224
  # TODO: Make assets config dependent
109
225
  require "hanami/assets/app_config"
@@ -128,37 +244,11 @@ module Hanami
128
244
  yield self if block_given?
129
245
  end
130
246
 
131
- # Apply config for the given environment
132
- #
133
- # @param env [String] the environment name
134
- #
135
- # @return [Hanami::Config]
136
- #
137
- # @api public
138
- def environment(env_name, &block)
139
- environments[env_name] << block
140
- apply_env_config
141
-
142
- self
143
- end
144
-
145
- # Configure application's inflections
146
- #
147
- # @see https://dry-rb.org/gems/dry-inflector
148
- #
149
- # @return [Dry::Inflector]
150
- #
151
- # @api public
152
- def inflections(&block)
153
- self.inflector = Dry::Inflector.new(&block)
154
- end
155
-
156
247
  # @api private
157
248
  def initialize_copy(source)
158
249
  super
159
250
 
160
251
  @app_name = app_name.dup
161
- @environments = environments.dup
162
252
 
163
253
  @assets = source.assets.dup
164
254
  @actions = source.actions.dup
@@ -168,11 +258,15 @@ module Hanami
168
258
  end
169
259
  @views = source.views.dup
170
260
  end
261
+ private :initialize_copy
171
262
 
263
+ # Finalizes the config.
264
+ #
265
+ # This is called when the app or slice is prepared. After this, no further changes to config can
266
+ # be made.
267
+ #
172
268
  # @api private
173
269
  def finalize!
174
- apply_env_config
175
-
176
270
  # Finalize nested configs
177
271
  assets.finalize!
178
272
  actions.finalize!
@@ -183,16 +277,90 @@ module Hanami
183
277
  super
184
278
  end
185
279
 
186
- # Set a default global logger instance
280
+ # Configures the app's custom inflections.
281
+ #
282
+ # You should call this one time only. Subsequent calls will override previously configured
283
+ # inflections.
284
+ #
285
+ # @example
286
+ # config.inflections do |inflections|
287
+ # inflections.acronym "WNBA"
288
+ # end
289
+ #
290
+ # @see https://dry-rb.org/gems/dry-inflector
291
+ #
292
+ # @return [Dry::Inflector] the configured inflector
293
+ #
294
+ # @api public
295
+ # @since 2.0.0
296
+ def inflections(&block)
297
+ self.inflector = Dry::Inflector.new(&block)
298
+ end
299
+
300
+ # Disabling this to permit distinct documentation for `#logger` vs `#logger=`
301
+ #
302
+ # rubocop:disable Style/TrivialAccessors
303
+
304
+ # Returns the logger config.
305
+ #
306
+ # Use this to configure various options for the default `Dry::Logger::Dispatcher` logger instance.
307
+ #
308
+ # @example
309
+ # config.logger.level = :debug
310
+ #
311
+ # @return [Hanami::Config::Logger]
312
+ #
313
+ # @see Hanami::Config::Logger
314
+ #
315
+ # @api public
316
+ # @since 2.0.0
317
+ def logger
318
+ @logger
319
+ end
320
+
321
+ # Sets the app's logger instance.
322
+ #
323
+ # This entirely replaces the default `Dry::Logger::Dispatcher` instance that would have been
324
+ #
325
+ # @see #logger_instance
187
326
  #
188
327
  # @api public
328
+ # @since 2.0.0
189
329
  def logger=(logger_instance)
190
330
  @logger_instance = logger_instance
191
331
  end
192
332
 
193
- # Return configured logger instance
333
+ # rubocop:enable Style/TrivialAccessors
334
+
335
+ # Returns the configured logger instance.
336
+ #
337
+ # Unless you've replaced the logger with {#logger=}, this returns a `Dry::Logger::Dispatcher` configured
338
+ # with the options configured through {#logger}.
339
+ #
340
+ # This configured logger is registered in all app and slice containers as `"logger"`. For
341
+ # typical usage, you should access the logger via this component, not directly from config.
342
+ #
343
+ # @example Accessing the logger component
344
+ # Hanami.app["logger"] # => #<Dry::Logger::Dispatcher>
345
+ #
346
+ # @example Injecting the logger as a dependency
347
+ # module MyApp
348
+ # class MyClass
349
+ # include Deps["logger"]
350
+ #
351
+ # def my_method
352
+ # logger.info("hello")
353
+ # end
354
+ # end
355
+ # end
356
+ #
357
+ # @return [Dry::Logger::Dispatcher]
358
+ #
359
+ # @see #logger
360
+ # @see Hanami::Config::Logger
194
361
  #
195
362
  # @api public
363
+ # @since 2.0.0
196
364
  def logger_instance
197
365
  @logger_instance || logger.instance
198
366
  end
@@ -203,12 +371,6 @@ module Hanami
203
371
  self.slices = ENV["HANAMI_SLICES"]&.split(",")&.map(&:strip)
204
372
  end
205
373
 
206
- def apply_env_config(env = self.env)
207
- environments[env].each do |block|
208
- instance_eval(&block)
209
- end
210
- end
211
-
212
374
  # @api private
213
375
  def load_dependent_config(gem_name)
214
376
  if Hanami.bundled?(gem_name)
@@ -13,6 +13,10 @@ module Hanami
13
13
  PATH_DELIMITER = "/"
14
14
  private_constant :PATH_DELIMITER
15
15
 
16
+ # @api private
17
+ APP_PATH = "config/app.rb"
18
+ private_constant :APP_PATH
19
+
16
20
  # @api private
17
21
  CONFIG_DIR = "config"
18
22
  private_constant :CONFIG_DIR
data/lib/hanami/errors.rb CHANGED
@@ -1,18 +1,35 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Hanami
4
+ # Base class for all Hanami errors.
5
+ #
6
+ # @api public
4
7
  # @since 2.0.0
5
8
  Error = Class.new(StandardError)
6
9
 
10
+ # Error raised when {Hanami::App} fails to load.
11
+ #
12
+ # @api public
7
13
  # @since 2.0.0
8
14
  AppLoadError = Class.new(Error)
9
15
 
16
+ # Error raised when an {Hanami::Slice} fails to load.
17
+ #
18
+ # @api public
10
19
  # @since 2.0.0
11
20
  SliceLoadError = Class.new(Error)
12
21
 
22
+ # Error raised when an individual component fails to load.
23
+ #
24
+ # @api public
13
25
  # @since 2.0.0
14
26
  ComponentLoadError = Class.new(Error)
15
27
 
28
+ # Error raised when unsupported middleware configuration is given.
29
+ #
30
+ # @see Hanami::Slice::Routing::Middleware::Stack#use
31
+ #
32
+ # @api public
16
33
  # @since 2.0.0
17
34
  UnsupportedMiddlewareSpecError = Class.new(Error)
18
35
  end