etcher 0.0.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f77fefa60ba596414bd1453ca278ef82a4839286e4c822260bbf7ed391b2fa5a
4
- data.tar.gz: 34076cfa28541ac3f6778bde4167a758473bb03874aa3233029df6248af24c78
3
+ metadata.gz: 765e913767d6c9d357ce121dc81ed86269abebeac8575e664c4becbc0043b21e
4
+ data.tar.gz: b16b6a76d818bbc560d615edcafba252ba42471cfa5ba1d1fc83375f37e75086
5
5
  SHA512:
6
- metadata.gz: f6c2d11ab82fb53535fb7606e5a160381febab7632eb39f8fe91b677b629416536016db42f1838a2a59cf0c51595f6647762758b70356685a7194bda023ac00e
7
- data.tar.gz: 260f3e2e1e55d3a82d862aa3140a453f7a357dbc8a5e0702f472e113d180b62b0bd011f641c612846230726b5514231c7b7412fa07cfe3251ad3dc126d204493
6
+ metadata.gz: 70aa7039b3fabaf0b2164cc9a8c7d06a6721377ac3ba3f6b4d82e586f5fd6fd24f32d48f44ebe05b5565a624e0b1d0c00411319045638c2dabc79999d937c7e5
7
+ data.tar.gz: bd628b9a423ce9df42ba5f388214989e6692c09b5273975f3231b3081df47de4d1d024e9e345d939777c4f903c2b39cd1f8ddf35cfab2e8cb85d43ef814de3d3
checksums.yaml.gz.sig CHANGED
Binary file
data/README.adoc CHANGED
@@ -7,6 +7,7 @@
7
7
  :dry_container_link: link:https://dry-rb.org/gems/dry-container[Dry Container]
8
8
  :dry_monads_link: link:https://dry-rb.org/gems/dry-monads[Dry Monads]
9
9
  :dry_schema_link: link:https://dry-rb.org/gems/dry-schema[Dry Schema]
10
+ :dry_types_link: link:https://dry-rb.org/gems/dry-types[Dry Types]
10
11
  :dry_validation_link: link:https://dry-rb.org/gems/dry-validation[Dry Validation]
11
12
  :environment_link: link:https://rubyapi.org/3.2/o/env[Environment]
12
13
  :gitt_link: link:https://alchemists.io/projects/gitt[Gitt]
@@ -32,11 +33,11 @@ toc::[]
32
33
 
33
34
  == Features
34
35
 
35
- * Supports contracts which respond to `#call` to validate a {hash_link} before building the final record. This works extremely well with the {dry_schema_link} and {dry_validation_link} gems.
36
- * Supports models which respond to `.[]` for consuming a splatted {hash_link} to instantiate new records. This works extremely well with primitives such as: {hash_link}, {data_link}, and {struct_link}.
36
+ * Supports contracts which respond to `#call` to validate a {hash_link} before building the final record. This pairs well with the {dry_schema_link} and {dry_validation_link} gems.
37
+ * Supports models which respond to `.[]` for consuming a splatted {hash_link} to instantiate new records. This pairs well with primitives such as: {hash_link}, {data_link}, and {struct_link}.
37
38
  * Supports loading of default configurations from the {environment_link}, a {json_link} configuration, a {yaml_link} configuration, or anything that can answer a hash.
38
39
  * Supports multiple transformations which can process loaded configuration hashes and answer a transformed hash.
39
- * Supports {hash_link} overrides as a final customization which is handy for Command Line Interfaces (CLI) or anything that might require user input at runtime.
40
+ * Supports {hash_link} overrides as a final customization which is handy for Command Line Interfaces (CLIs) or anything that might require user input at runtime.
40
41
 
41
42
  == Requirements
42
43
 
@@ -119,6 +120,8 @@ The above can be broken down into a series of steps:
119
120
 
120
121
  While this is a more advanced use case, you'll usually only need to register a contract and model. The loaders and transformers provide additional firepower in situations where you need to do more with your data. We'll look at each of these components in greater detail next.
121
122
 
123
+ ℹ️ All keys are converted to symbols before being processed. This is done to ensure consistency and improve debugablity when dealing with raw input that might be a mix of strings and/or symbols.
124
+
122
125
  === Registry
123
126
 
124
127
  The registry is provided as a way to register any/all complexity for before creating a new Etcher instance. Here's what you get by default:
@@ -154,7 +157,7 @@ registry = Etcher::Registry.new
154
157
 
155
158
  === Contracts
156
159
 
157
- Contracts are critical piece of this workflow as they provide a way to validate incoming data, strip out unwanted data, and create a sanitized record for use in your application. Any contract that has the following behavior will work:
160
+ Contracts are critical piece of this workflow as they provide a way to validate incoming data, remove unwanted data, and create a sanitized record for use in your application. Any contract that has the following behavior will work:
158
161
 
159
162
  * `#call`: Must be able to consume a {hash_link} and answer an object which can respond to `#to_monad`.
160
163
 
@@ -190,6 +193,29 @@ etcher.call from: "Mork", to: "Mindy"
190
193
 
191
194
  Here you can see the power of using a contract to validate your data both as a failure and a success. Unfortunately, with the success, we only get a {hash_link} as a record and it would be nice to structured model which which we'll look at next.
192
195
 
196
+ === Types
197
+
198
+ To support contracts further, especially when working with file paths, there is a custom type for pathnames:
199
+
200
+ [source,ruby]
201
+ ----
202
+ Etcher::Types::Pathname
203
+ ----
204
+
205
+ This means you can use this custom type in your contracts to validate and cast pathnames:
206
+
207
+ [source,ruby]
208
+ ----
209
+ contract = Dry::Schema.Params do
210
+ required(:path).filled Etcher::Types::Pathname
211
+ end
212
+
213
+ contract.call(path: "a/path").to_monad
214
+ # Success(#<Dry::Schema::Result{:path=>#<Pathname:a/path>} errors={} path=[]>)
215
+ ----
216
+
217
+ All of this is made possible via {dry_types_link} so make sure to check out documentation for details.
218
+
193
219
  === Models
194
220
 
195
221
  A model is any object which responds to `.[]` and can accept a splatted hash. Example: `Model[**attributes]`. These primitives are excellent choices: {hash_link}, {data_link}, and {struct_link}.
@@ -216,7 +242,18 @@ Notice we get an failure if all attributes are not provided but if we supply the
216
242
 
217
243
  === Loaders
218
244
 
219
- Loaders are a great way to load _default_ configuration information for your application which can be in multiple formats. There are a few guidelines to using them:
245
+ Loaders are a great way to load _default_ configuration information for your application which can be in multiple formats. Loaders can either be defined when creating a new registry instance or added after the fact. Here are a few examples:
246
+
247
+ [source,ruby]
248
+ ----
249
+ # Initializer
250
+ registry = Etcher::Registry[loaders: [MyLoader.new]]
251
+
252
+ # Method
253
+ registry = Etcher::Registry.new.add_loader MyLoader.new
254
+ ----
255
+
256
+ There are a few guidelines to using them:
220
257
 
221
258
  * They must respond to `#call` with no arguments.
222
259
  * All keys are symbolized which helps streamline merging and overriding values from the same keys across multiple configurations.
@@ -329,10 +366,22 @@ While the above isn't super useful since it only answers whatever you provide as
329
366
 
330
367
  === Transformers
331
368
 
332
- Transformers are great for modifying specific keys and values. They give you finer grained control over your configuration and are the last step before validating and creating an associated record of your configuration. There are a few guidelines to using them:
369
+ Transformers are great for modifying specific keys and values. They give you finer grained control over your configuration and are the last step before validating and creating an associated record of your configuration. Transformers can either be defined when creating a new registry instance or added after the fact. Here are a few examples:
370
+
371
+ [source,ruby]
372
+ ----
373
+ # Initializer
374
+ registry = Etcher::Registry[transformers: [MyTransformer]]
375
+
376
+ # Method
377
+ registry = Etcher::Registry.new.add_transformer MyTransformer
378
+ ----
379
+
380
+ Here are a few guidelines to using them:
333
381
 
334
382
  * They can be initialized with whatever requirements you might need.
335
383
  * They must respond to `#call` which takes a single argument (i.e. `content`) and answers a modified representation of this content as a `Success` with a `Hash` for content.
384
+ * The `content` passed to your transformer will have symbolized keys.
336
385
 
337
386
  Here are a few examples of where you could go with this:
338
387
 
data/etcher.gemspec CHANGED
@@ -2,11 +2,11 @@
2
2
 
3
3
  Gem::Specification.new do |spec|
4
4
  spec.name = "etcher"
5
- spec.version = "0.0.0"
5
+ spec.version = "0.2.0"
6
6
  spec.authors = ["Brooke Kuhlmann"]
7
7
  spec.email = ["brooke@alchemists.io"]
8
8
  spec.homepage = "https://alchemists.io/projects/etcher"
9
- spec.summary = "A configuration loader, transformer, and validator."
9
+ spec.summary = "A monadic configuration loader, transformer, and validator."
10
10
  spec.license = "Hippocratic-2.1"
11
11
 
12
12
  spec.metadata = {
@@ -23,10 +23,11 @@ Gem::Specification.new do |spec|
23
23
  spec.cert_chain = [Gem.default_cert_path]
24
24
 
25
25
  spec.required_ruby_version = "~> 3.2"
26
- spec.add_dependency "cogger", "~> 0.9"
26
+ spec.add_dependency "cogger", "~> 0.10"
27
27
  spec.add_dependency "core", "~> 0.1"
28
28
  spec.add_dependency "dry-monads", "~> 1.6"
29
- spec.add_dependency "refinements", "~> 10.0"
29
+ spec.add_dependency "dry-types", "~> 1.7"
30
+ spec.add_dependency "refinements", "~> 11.0"
30
31
  spec.add_dependency "zeitwerk", "~> 2.6"
31
32
 
32
33
  spec.extra_rdoc_files = Dir["README*", "LICENSE*"]
@@ -16,9 +16,9 @@ module Etcher
16
16
  end
17
17
 
18
18
  def call(**overrides)
19
- load(overrides).then { |content| transform content }
20
- .bind { |content| validate content }
21
- .bind { |content| record content }
19
+ load(overrides.symbolize_keys!).then { |content| transform content }
20
+ .bind { |content| validate content }
21
+ .bind { |content| record content }
22
22
  end
23
23
 
24
24
  private
@@ -47,7 +47,7 @@ module Etcher
47
47
  registry.contract
48
48
  .call(content)
49
49
  .to_monad
50
- .or { |result| Failure(step: __method__, payload: result.errors.to_h) }
50
+ .or { |result| Failure step: __method__, payload: result.errors.to_h }
51
51
  end
52
52
 
53
53
  def record content
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/types"
4
+ require "pathname"
5
+
6
+ module Etcher
7
+ # Defines custom types.
8
+ module Types
9
+ include Dry.Types(default: :strict)
10
+
11
+ Pathname = Constructor ::Pathname
12
+ end
13
+ end
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: etcher
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brooke Kuhlmann
@@ -35,7 +35,7 @@ cert_chain:
35
35
  3n5C8/6Zh9DYTkpcwPSuIfAga6wf4nXc9m6JAw8AuMLaiWN/r/2s4zJsUHYERJEu
36
36
  gZGm4JqtuSg8pYjPeIJxS960owq+SfuC+jxqmRA54BisFCv/0VOJi7tiJVY=
37
37
  -----END CERTIFICATE-----
38
- date: 2023-04-23 00:00:00.000000000 Z
38
+ date: 2023-06-13 00:00:00.000000000 Z
39
39
  dependencies:
40
40
  - !ruby/object:Gem::Dependency
41
41
  name: cogger
@@ -43,14 +43,14 @@ dependencies:
43
43
  requirements:
44
44
  - - "~>"
45
45
  - !ruby/object:Gem::Version
46
- version: '0.9'
46
+ version: '0.10'
47
47
  type: :runtime
48
48
  prerelease: false
49
49
  version_requirements: !ruby/object:Gem::Requirement
50
50
  requirements:
51
51
  - - "~>"
52
52
  - !ruby/object:Gem::Version
53
- version: '0.9'
53
+ version: '0.10'
54
54
  - !ruby/object:Gem::Dependency
55
55
  name: core
56
56
  requirement: !ruby/object:Gem::Requirement
@@ -79,20 +79,34 @@ dependencies:
79
79
  - - "~>"
80
80
  - !ruby/object:Gem::Version
81
81
  version: '1.6'
82
+ - !ruby/object:Gem::Dependency
83
+ name: dry-types
84
+ requirement: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '1.7'
89
+ type: :runtime
90
+ prerelease: false
91
+ version_requirements: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '1.7'
82
96
  - !ruby/object:Gem::Dependency
83
97
  name: refinements
84
98
  requirement: !ruby/object:Gem::Requirement
85
99
  requirements:
86
100
  - - "~>"
87
101
  - !ruby/object:Gem::Version
88
- version: '10.0'
102
+ version: '11.0'
89
103
  type: :runtime
90
104
  prerelease: false
91
105
  version_requirements: !ruby/object:Gem::Requirement
92
106
  requirements:
93
107
  - - "~>"
94
108
  - !ruby/object:Gem::Version
95
- version: '10.0'
109
+ version: '11.0'
96
110
  - !ruby/object:Gem::Dependency
97
111
  name: zeitwerk
98
112
  requirement: !ruby/object:Gem::Requirement
@@ -127,6 +141,7 @@ files:
127
141
  - lib/etcher/loaders/yaml.rb
128
142
  - lib/etcher/registry.rb
129
143
  - lib/etcher/resolver.rb
144
+ - lib/etcher/types.rb
130
145
  homepage: https://alchemists.io/projects/etcher
131
146
  licenses:
132
147
  - Hippocratic-2.1
@@ -153,8 +168,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
153
168
  - !ruby/object:Gem::Version
154
169
  version: '0'
155
170
  requirements: []
156
- rubygems_version: 3.4.12
171
+ rubygems_version: 3.4.14
157
172
  signing_key:
158
173
  specification_version: 4
159
- summary: A configuration loader, transformer, and validator.
174
+ summary: A monadic configuration loader, transformer, and validator.
160
175
  test_files: []
metadata.gz.sig CHANGED
Binary file