hanami 2.1.1 → 2.2.0.beta2

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.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +33 -0
  3. data/README.md +7 -7
  4. data/hanami.gemspec +6 -6
  5. data/lib/hanami/app.rb +5 -1
  6. data/lib/hanami/config/db.rb +33 -0
  7. data/lib/hanami/config.rb +36 -9
  8. data/lib/hanami/constants.rb +4 -0
  9. data/lib/hanami/extensions/db/repo.rb +103 -0
  10. data/lib/hanami/extensions.rb +4 -0
  11. data/lib/hanami/helpers/form_helper/form_builder.rb +4 -6
  12. data/lib/hanami/provider/source.rb +16 -0
  13. data/lib/hanami/provider_registrar.rb +28 -0
  14. data/lib/hanami/providers/assets.rb +2 -20
  15. data/lib/hanami/providers/db/adapter.rb +75 -0
  16. data/lib/hanami/providers/db/adapters.rb +50 -0
  17. data/lib/hanami/providers/db/config.rb +62 -0
  18. data/lib/hanami/providers/db/gateway.rb +70 -0
  19. data/lib/hanami/providers/db/sql_adapter.rb +100 -0
  20. data/lib/hanami/providers/db.rb +298 -0
  21. data/lib/hanami/providers/db_logging.rb +22 -0
  22. data/lib/hanami/providers/inflector.rb +1 -1
  23. data/lib/hanami/providers/logger.rb +1 -1
  24. data/lib/hanami/providers/rack.rb +3 -3
  25. data/lib/hanami/providers/relations.rb +31 -0
  26. data/lib/hanami/providers/routes.rb +2 -14
  27. data/lib/hanami/rake_tasks.rb +8 -7
  28. data/lib/hanami/slice.rb +84 -4
  29. data/lib/hanami/version.rb +1 -1
  30. data/lib/hanami.rb +3 -0
  31. data/spec/integration/container/provider_environment_spec.rb +52 -0
  32. data/spec/integration/db/auto_registration_spec.rb +39 -0
  33. data/spec/integration/db/commands_spec.rb +80 -0
  34. data/spec/integration/db/db_inflector_spec.rb +57 -0
  35. data/spec/integration/db/db_slices_spec.rb +332 -0
  36. data/spec/integration/db/db_spec.rb +245 -0
  37. data/spec/integration/db/gateways_spec.rb +320 -0
  38. data/spec/integration/db/logging_spec.rb +238 -0
  39. data/spec/integration/db/mappers_spec.rb +84 -0
  40. data/spec/integration/db/provider_config_spec.rb +88 -0
  41. data/spec/integration/db/provider_spec.rb +35 -0
  42. data/spec/integration/db/relations_spec.rb +60 -0
  43. data/spec/integration/db/repo_spec.rb +215 -0
  44. data/spec/integration/db/slices_importing_from_parent.rb +130 -0
  45. data/spec/integration/slices/slice_configuration_spec.rb +4 -4
  46. data/spec/support/app_integration.rb +3 -0
  47. data/spec/unit/hanami/config/db_spec.rb +38 -0
  48. data/spec/unit/hanami/config/router_spec.rb +1 -1
  49. data/spec/unit/hanami/helpers/form_helper_spec.rb +35 -4
  50. data/spec/unit/hanami/providers/db/config/default_config_spec.rb +100 -0
  51. data/spec/unit/hanami/providers/db/config_spec.rb +156 -0
  52. data/spec/unit/hanami/slice_spec.rb +32 -0
  53. data/spec/unit/hanami/version_spec.rb +1 -1
  54. metadata +72 -20
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 190712bdfa529ad5769aa5effd9335e436b067cd91b6a109a3aa9a4718a73507
4
- data.tar.gz: 353ccb232425a07133e981d5d8ae6c6906f49cb48d38d7f2b55dc4e28a9c797b
3
+ metadata.gz: 6d6bd309aaaf86dce283f25dbdf786db6da76567ae8b00aed92c34de637f8909
4
+ data.tar.gz: 3b6430d47afb052bdc4df9ce200ceb3b2888b733b040bdb4de056052a8e99db2
5
5
  SHA512:
6
- metadata.gz: 4a4e7e1885c9b3eb494863b63f4d376739d6736764b435b83ce75e9a1bb68340681a26bea3883ed20c679e4d88bf99b3d487ae40e2e80f0fb15adb99acfa561d
7
- data.tar.gz: 8fe1a9d8f9f7372d67ee3f7b9c6e55b0e1aa59acbaee7264028d876dd5cd7b586f147ae08cd268d67c923d5028344bf37868d190cd2d56229932db56828dcce1
6
+ metadata.gz: a73cfea60952ba798fe2d04b2cf430996f8b81960959054251e4277b9f0a53aadfdad23850d389fcedcdb3f77a0855acd2e128e5d8aa3cc8a82df485ae11d592
7
+ data.tar.gz: 05a033e21dd6b9499b125583de931a39f128828ef5f8d730c7ef1522db765ffef35eb1938013b8f58d1199d68aa8564d5183a726bb733e4d1c5b1aaae9f79f7f
data/CHANGELOG.md CHANGED
@@ -2,6 +2,39 @@
2
2
 
3
3
  The web, with simplicity.
4
4
 
5
+ ## v2.2.0.beta2 - 2024-09-26
6
+
7
+ ### Added
8
+
9
+ - [Tim Riley] Support multiple gateways within each slice's `:db` provider (#1452)
10
+ - [Tim Riley] Register ROM commands and mappers in `db/commands/` and `db/mappers/`. Support registration of components from deeply nested files within these directories. (#1448)
11
+ - [Adam Lassek, Tim Riley] Make `slice` available inside providers (as an alias for `target`) (#1446)
12
+
13
+ ### Changed
14
+
15
+ - [Tim Riley] Register deeply nested relation files with ROM (#1448)
16
+ - [Kyle Plump] Raise helpful error when preparing `:db` provider if the relevant driver gem for the configured database type is not installed (#1453)
17
+ - [Sean Collins] Remove "disabled" attribute on the `<option>` generated via the `select` helper's `prompt:`, so it shows properly on the select box in the browser (#1444)
18
+
19
+ ## v2.2.0.beta1 - 2024-07-16
20
+
21
+ ### Added
22
+
23
+ - [Tim Riley, Adam Lassek] Introduce database layer
24
+ - [Adam Lassek] Add `Hanami::Slice.app?`, returning false for slices and true for the app (#1399)
25
+ - [Tim Riley] Add `Slice#registered?`, an additional method delegating to the internal container. Returns true only if a component is already registered for the given, without triggering lazy loading (#1382)
26
+
27
+ ### Changed
28
+
29
+ - [Tim Riley] `target` inside providers is now the slice itself, instead of the slice's internal container (#1382)
30
+ - Drop support for Ruby 3.0
31
+
32
+ ### Fixed
33
+
34
+ - [Damian C. Rossney] Allow form `label` helper to receive a symbol (#1423)
35
+ - [Damian C. Rossney] Fix invalid input names generated when using form `fields_for_collection` helper (#1421)
36
+ - [Tim Riley] Fix dry-logger compatibility check for versions of dry-logger >= 1.0.4 (#1384)
37
+
5
38
  ## v2.1.1 - 2024-05-12
6
39
 
7
40
  ### Fixed
data/README.md CHANGED
@@ -4,7 +4,7 @@ The web, with simplicity.
4
4
 
5
5
  ## Version
6
6
 
7
- **This branch contains the code for `hanami` 2.0.x.**
7
+ **This branch contains the code for `hanami`: 2.2**
8
8
 
9
9
  ## Frameworks
10
10
 
@@ -14,9 +14,8 @@ This repository is for the full-stack framework, which provides the glue that ti
14
14
 
15
15
  * [**Hanami::Router**](https://github.com/hanami/router) - Rack compatible HTTP router for Ruby
16
16
  * [**Hanami::Controller**](https://github.com/hanami/controller) - Full featured, fast and testable actions for Rack
17
+ * [**Hanami::Validations**](https://github.com/hanami/validations) - Parameter validations & coercion for actions
17
18
  * [**Hanami::View**](https://github.com/hanami/view) - Presentation with a separation between views and templates
18
- * [**Hanami::Helpers**](https://github.com/hanami/helpers) - View helpers for Ruby applications
19
- * [**Hanami::Mailer**](https://github.com/hanami/mailer) - Mail for Ruby applications
20
19
  * [**Hanami::Assets**](https://github.com/hanami/assets) - Assets management for Ruby
21
20
 
22
21
  These components are designed to be used independently or together in a Hanami application.
@@ -24,12 +23,13 @@ These components are designed to be used independently or together in a Hanami a
24
23
  ## Status
25
24
 
26
25
  [![Gem Version](https://badge.fury.io/rb/hanami.svg)](https://badge.fury.io/rb/hanami)
27
- [![CI](https://github.com/hanami/hanami/workflows/ci/badge.svg?branch=main)](https://github.com/hanami/hanami/actions?query=workflow%3Aci+branch%3Amain)
26
+ [![CI](https://github.com/hanami/hanami/actions/workflows/ci.yml/badge.svg)](https://github.com/hanami/hanami/actions?query=workflow%3Aci+branch%3Amain)
27
+ [![Test Coverage](https://codecov.io/gh/hanami/hanami/branch/main/graph/badge.svg)](https://codecov.io/gh/hanami/hanami)
28
28
  [![Depfu](https://badges.depfu.com/badges/ba000e0f69e6ef1c44cd3038caaa1841/overview.svg)](https://depfu.com/github/hanami/hanami?project=Bundler)
29
29
 
30
30
  ## Installation
31
31
 
32
- __Hanami__ supports Ruby (MRI) 3.0+
32
+ __Hanami__ supports Ruby (MRI) 3.1+.
33
33
 
34
34
  ```shell
35
35
  gem install hanami
@@ -110,7 +110,7 @@ $ bundle exec rspec path/to/spec.rb
110
110
 
111
111
  ### Development Requirements
112
112
 
113
- * Ruby >= 3.0
113
+ * Ruby >= 3.1
114
114
  * Bundler
115
115
  * Node.js (MacOS)
116
116
 
@@ -120,4 +120,4 @@ __Hanami__ uses [Semantic Versioning 2.0.0](http://semver.org)
120
120
 
121
121
  ## Copyright
122
122
 
123
- Copyright © 2014 Hanami Team – Released under MIT License.
123
+ Copyright © 2014–2024 Hanami Team – Released under MIT License.
data/hanami.gemspec CHANGED
@@ -27,19 +27,19 @@ Gem::Specification.new do |spec|
27
27
  spec.test_files = Dir["spec/**/*"]
28
28
  spec.require_paths = ["lib"]
29
29
  spec.metadata["rubygems_mfa_required"] = "true"
30
- spec.required_ruby_version = ">= 3.0"
30
+ spec.required_ruby_version = ">= 3.1"
31
31
 
32
32
  spec.metadata["allowed_push_host"] = "https://rubygems.org"
33
33
 
34
34
  spec.add_dependency "bundler", ">= 1.16", "< 3"
35
- spec.add_dependency "dry-configurable", "~> 1.0", "< 2"
35
+ spec.add_dependency "dry-configurable", "~> 1.0", ">= 1.2.0", "< 2"
36
36
  spec.add_dependency "dry-core", "~> 1.0", "< 2"
37
- spec.add_dependency "dry-inflector", "~> 1.0", "< 2"
37
+ spec.add_dependency "dry-inflector", "~> 1.0", ">= 1.1.0", "< 2"
38
38
  spec.add_dependency "dry-monitor", "~> 1.0", ">= 1.0.1", "< 2"
39
- spec.add_dependency "dry-system", "~> 1.0", "< 2"
39
+ spec.add_dependency "dry-system", "= 1.1.0.beta2"
40
40
  spec.add_dependency "dry-logger", "~> 1.0", "< 2"
41
- spec.add_dependency "hanami-cli", "~> 2.1"
42
- spec.add_dependency "hanami-utils", "~> 2.1"
41
+ spec.add_dependency "hanami-cli", "= 2.2.0.beta2"
42
+ spec.add_dependency "hanami-utils", "~> 2.2.beta"
43
43
  spec.add_dependency "zeitwerk", "~> 2.6"
44
44
 
45
45
  spec.add_development_dependency "rspec", "~> 3.8"
data/lib/hanami/app.rb CHANGED
@@ -152,7 +152,7 @@ module Hanami
152
152
  register_provider(:inflector, source: Hanami::Providers::Inflector)
153
153
 
154
154
  # Allow logger to be replaced by users with a manual provider, for advanced cases
155
- unless container.providers.find_and_load_provider(:logger)
155
+ unless container.providers[:logger]
156
156
  require_relative "providers/logger"
157
157
  register_provider(:logger, source: Hanami::Providers::Logger)
158
158
  end
@@ -161,6 +161,10 @@ module Hanami
161
161
  require_relative "providers/rack"
162
162
  register_provider(:rack, source: Hanami::Providers::Rack, namespace: true)
163
163
  end
164
+
165
+ if Hanami.bundled?("hanami-db")
166
+ register_provider(:db_logging, source: Hanami::Providers::DBLogging)
167
+ end
164
168
  end
165
169
 
166
170
  def prepare_autoloader
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/configurable"
4
+
5
+ module Hanami
6
+ class Config
7
+ # Hanami DB config
8
+ #
9
+ # @since 2.2.0
10
+ # @api public
11
+ class DB
12
+ include Dry::Configurable
13
+
14
+ setting :configure_from_parent, default: true
15
+
16
+ setting :import_from_parent, default: false
17
+
18
+ private
19
+
20
+ def method_missing(name, *args, &block)
21
+ if config.respond_to?(name)
22
+ config.public_send(name, *args, &block)
23
+ else
24
+ super
25
+ end
26
+ end
27
+
28
+ def respond_to_missing?(name, _include_all = false)
29
+ config.respond_to?(name) || super
30
+ end
31
+ end
32
+ end
33
+ end
data/lib/hanami/config.rb CHANGED
@@ -110,7 +110,12 @@ module Hanami
110
110
  #
111
111
  # @api public
112
112
  # @since 2.0.0
113
- setting :no_auto_register_paths, default: %w[entities]
113
+ setting :no_auto_register_paths, default: [
114
+ "db",
115
+ "entities",
116
+ "relations",
117
+ "structs"
118
+ ]
114
119
 
115
120
  # @!attribute [rw] base_url
116
121
  # Sets the base URL for app's web server.
@@ -216,6 +221,20 @@ module Hanami
216
221
  # @since 2.0.0
217
222
  attr_reader :actions
218
223
 
224
+ # Returns the app's db config, or a null config if hanami-db is not bundled.
225
+ #
226
+ # @example When hanami-db is bundled
227
+ # config.db.import_from_parent # => false
228
+ #
229
+ # @example When hanami-db is not bundle
230
+ # config.db.import_from_parent # => NoMethodError
231
+ #
232
+ # @return [Hanami::Config::DB, Hanami::Config::NullConfig]
233
+ #
234
+ # @api public
235
+ # @since 2.2.0
236
+ attr_reader :db
237
+
219
238
  # Returns the app's middleware stack, or nil if hanami-router is not bundled.
220
239
  #
221
240
  # Use this to configure middleware that should apply to all routes.
@@ -288,16 +307,27 @@ module Hanami
288
307
  self.render_detailed_errors = (env == :development)
289
308
  load_from_env
290
309
 
291
- @logger = Config::Logger.new(env: env, app_name: app_name)
292
310
 
293
311
  @actions = load_dependent_config("hanami-controller") {
294
312
  require_relative "config/actions"
295
313
  Actions.new
296
314
  }
297
315
 
316
+ @assets = load_dependent_config("hanami-assets") {
317
+ require_relative "config/assets"
318
+ Hanami::Config::Assets.new
319
+ }
320
+
321
+ @db = load_dependent_config("hanami-db") { DB.new }
322
+
323
+ @logger = Config::Logger.new(env: env, app_name: app_name)
324
+
325
+ @middleware = load_dependent_config("hanami-router") {
326
+ Slice::Routing::Middleware::Stack.new
327
+ }
328
+
298
329
  @router = load_dependent_config("hanami-router") {
299
330
  require_relative "config/router"
300
- @middleware = Slice::Routing::Middleware::Stack.new
301
331
  Router.new(self)
302
332
  }
303
333
 
@@ -306,11 +336,6 @@ module Hanami
306
336
  Views.new
307
337
  }
308
338
 
309
- @assets = load_dependent_config("hanami-assets") {
310
- require_relative "config/assets"
311
- Hanami::Config::Assets.new
312
- }
313
-
314
339
  yield self if block_given?
315
340
  end
316
341
  # rubocop:enable Metrics/AbcSize
@@ -321,8 +346,10 @@ module Hanami
321
346
 
322
347
  @app_name = app_name.dup
323
348
 
324
- @assets = source.assets.dup
325
349
  @actions = source.actions.dup
350
+ @assets = source.assets.dup
351
+ @db = source.db.dup
352
+ @logger = source.logger.dup
326
353
  @middleware = source.middleware.dup
327
354
  @router = source.router.dup.tap do |router|
328
355
  router.instance_variable_set(:@base_config, self)
@@ -52,4 +52,8 @@ module Hanami
52
52
  # @api private
53
53
  RB_EXT = ".rb"
54
54
  private_constant :RB_EXT
55
+
56
+ # @api private
57
+ RB_EXT_REGEXP = %r{.rb$}
58
+ private_constant :RB_EXT_REGEXP
55
59
  end
@@ -0,0 +1,103 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "hanami/db"
4
+
5
+ module Hanami
6
+ module Extensions
7
+ # @api private
8
+ # @since 2.2.0
9
+ module DB
10
+ # @api private
11
+ # @since 2.2.0
12
+ module Repo
13
+ def self.included(repo_class)
14
+ super
15
+
16
+ repo_class.extend(Hanami::SliceConfigurable)
17
+ repo_class.extend(ClassMethods)
18
+ end
19
+
20
+ # @api private
21
+ # @since 2.2.0
22
+ module ClassMethods
23
+ def configure_for_slice(slice)
24
+ extend SliceConfiguredRepo.new(slice)
25
+ end
26
+ end
27
+ end
28
+
29
+ # @api private
30
+ # @since 2.2.0
31
+ class SliceConfiguredRepo < Module
32
+ attr_reader :slice
33
+
34
+ def initialize(slice)
35
+ super()
36
+ @slice = slice
37
+ end
38
+
39
+ def extended(repo_class)
40
+ define_inherited
41
+ configure_repo(repo_class)
42
+ define_new
43
+ end
44
+
45
+ def inspect
46
+ "#<#{self.class.name}[#{slice.name}]>"
47
+ end
48
+
49
+ private
50
+
51
+ def define_inherited
52
+ root_for_repo_class = method(:root_for_repo_class)
53
+
54
+ define_method(:inherited) do |subclass|
55
+ super(subclass)
56
+
57
+ unless subclass.root
58
+ root = root_for_repo_class.(subclass)
59
+ subclass.root root if root
60
+ end
61
+ end
62
+ end
63
+
64
+ def configure_repo(repo_class)
65
+ repo_class.struct_namespace struct_namespace
66
+ end
67
+
68
+ def define_new
69
+ resolve_rom = method(:resolve_rom)
70
+
71
+ define_method(:new) do |**kwargs|
72
+ super(container: kwargs.fetch(:container) { resolve_rom.() })
73
+ end
74
+ end
75
+
76
+ def resolve_rom
77
+ slice["db.rom"]
78
+ end
79
+
80
+ def root_for_repo_class(repo_class)
81
+ return unless repo_class.to_s.end_with?("Repo")
82
+
83
+ slice.inflector.demodulize(repo_class)
84
+ .then { slice.inflector.underscore(_1) }
85
+ .then { _1.gsub(/_repo$/, "") }
86
+ .then { slice.inflector.pluralize(_1) }
87
+ .then { _1.to_sym }
88
+ end
89
+
90
+ def struct_namespace
91
+ @struct_namespace ||=
92
+ if slice.namespace.const_defined?(:Structs)
93
+ slice.namespace.const_get(:Structs)
94
+ else
95
+ slice.namespace.const_set(:Structs, Module.new)
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
102
+
103
+ Hanami::DB::Repo.include(Hanami::Extensions::DB::Repo)
@@ -1,5 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ if Hanami.bundled?("hanami-db")
4
+ require_relative "extensions/db/repo"
5
+ end
6
+
3
7
  if Hanami.bundled?("hanami-controller")
4
8
  require_relative "extensions/action"
5
9
  end
@@ -226,10 +226,8 @@ module Hanami
226
226
  # @api public
227
227
  # @since 2.1.0
228
228
  def fields_for_collection(name, &block)
229
- collection_base_name = [base_name, name.to_s].compact.join(INPUT_NAME_SEPARATOR)
230
-
231
229
  _value(name).each_with_index do |value, index|
232
- fields_for("#{collection_base_name}.#{index}", index, value, &block)
230
+ fields_for("#{name}.#{index}", index, value, &block)
233
231
  end
234
232
  end
235
233
 
@@ -295,7 +293,7 @@ module Hanami
295
293
  attributes[:for] = _input_id(attributes[:for] || content)
296
294
 
297
295
  if content && !for_attribute_given
298
- content = inflector.humanize(content.split(INPUT_NAME_SEPARATOR).last)
296
+ content = inflector.humanize(content.to_s.split(INPUT_NAME_SEPARATOR).last)
299
297
  end
300
298
 
301
299
  tag.label(content, **attributes, &block)
@@ -940,7 +938,7 @@ module Hanami
940
938
  #
941
939
  # =>
942
940
  # <select name="book[store]" id="book-store" class="form-control">
943
- # <option disabled="disabled">Select a store</option>
941
+ # <option>Select a store</option>
944
942
  # <option value="it">Italy</option>
945
943
  # <option value="au">Australia</option>
946
944
  # </select>
@@ -997,7 +995,7 @@ module Hanami
997
995
  input_value = _value(name)
998
996
 
999
997
  option_tags = []
1000
- option_tags << tag.option(prompt, disabled: true) if prompt
998
+ option_tags << tag.option(prompt) if prompt
1001
999
 
1002
1000
  already_selected = nil
1003
1001
  values.each do |content, value|
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hanami
4
+ module Provider
5
+ class Source < Dry::System::Provider::Source
6
+ attr_reader :slice
7
+
8
+ def initialize(slice:, **options, &block)
9
+ @slice = slice
10
+ super(**options, &block)
11
+ end
12
+
13
+ def target_container = slice
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @api private
4
+ # @since 2.2.0
5
+ module Hanami
6
+ class ProviderRegistrar < Dry::System::ProviderRegistrar
7
+ def self.for_slice(slice)
8
+ Class.new(self) do
9
+ define_singleton_method(:new) do |container|
10
+ super(container, slice)
11
+ end
12
+ end
13
+ end
14
+
15
+ attr_reader :slice
16
+
17
+ def initialize(container, slice)
18
+ super(container)
19
+ @slice = slice
20
+ end
21
+
22
+ def provider_source_class = Hanami::Provider::Source
23
+
24
+ def provider_source_options
25
+ {slice: slice}
26
+ end
27
+ end
28
+ end
@@ -9,19 +9,7 @@ module Hanami
9
9
  #
10
10
  # @api private
11
11
  # @since 2.0.0
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
-
12
+ class Assets < Hanami::Provider::Source
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 = slice.app.root.join("public", "assets", Hanami::Assets.public_assets_dir(slice).to_s)
20
+ root = slice.app.root.join("public", "assets", Hanami::Assets.public_assets_dir(target).to_s)
33
21
 
34
22
  assets = Hanami::Assets.new(config: slice.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,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/configurable"
4
+
5
+ module Hanami
6
+ module Providers
7
+ class DB < Hanami::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_from_adapter(other_adapter)
35
+ return if skip_defaults?
36
+
37
+ plugins.concat(other_adapter.plugins).uniq! unless skip_defaults?(:plugins)
38
+ end
39
+
40
+ # @api private
41
+ def configure_for_database(database_url)
42
+ end
43
+
44
+ # @api public
45
+ # @since 2.2.0
46
+ def plugin(**plugin_spec, &config_block)
47
+ plugins << [plugin_spec, config_block]
48
+ end
49
+
50
+ # @api public
51
+ # @since 2.2.0
52
+ def plugins
53
+ config.plugins ||= []
54
+ end
55
+
56
+ # @api private
57
+ def gateway_cache_keys
58
+ gateway_options
59
+ end
60
+
61
+ # @api private
62
+ def gateway_options
63
+ {}
64
+ end
65
+
66
+ # @api public
67
+ # @since 2.2.0
68
+ def clear
69
+ config.plugins = nil
70
+ self
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hanami
4
+ module Providers
5
+ class DB < Hanami::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
+ def self.new_adapter(name)
23
+ ADAPTER_CLASSES[name].new
24
+ end
25
+
26
+ # @api private
27
+ # @since 2.2.0
28
+ attr_reader :adapters
29
+
30
+ # @api private
31
+ # @since 2.2.0
32
+ def initialize
33
+ @adapters = Hash.new do |hsh, key|
34
+ hsh[key] = self.class.new_adapter(key)
35
+ end
36
+ end
37
+
38
+ # @api private
39
+ # @since 2.2.0
40
+ def initialize_copy(source)
41
+ @adapters = source.adapters.dup
42
+
43
+ source.adapters.each do |key, val|
44
+ @adapters[key] = val.dup
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end