atacama 0.1.11 → 0.2.2
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 +5 -5
- data/Gemfile.lock +20 -22
- data/README.md +61 -9
- data/atacama.gemspec +4 -4
- data/lib/atacama/types.rb +1 -1
- data/lib/atacama/version.rb +1 -1
- metadata +19 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: c8753adca74983de69877148940b2946ae8e2967e9c7ba8b9ebe618732d05a68
|
4
|
+
data.tar.gz: c02d3388d74627055810e76a053bb8bd9fe208e9cc19e391ac0a982d97fc8456
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 543ad31ef753efbb7e2a49dfa71e1930a0bbfc41d5973dfd157bdb59e8856a6fb22fa172b3b0635e9469ab01ab387bfc7d11b23504539a10ef7f38f02577aff2
|
7
|
+
data.tar.gz: 258ccb35ddaf927f2ffb3126b42a9fcc1ff6da081b7de48c2dee3b927834839813e0514622874085373d5f7247db8c323cdf5cbded685ae326ff189f3672e13a
|
data/Gemfile.lock
CHANGED
@@ -1,50 +1,48 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
atacama (0.
|
5
|
-
dry-types
|
4
|
+
atacama (0.2.2)
|
5
|
+
dry-types
|
6
6
|
|
7
7
|
GEM
|
8
8
|
remote: https://rubygems.org/
|
9
9
|
specs:
|
10
10
|
coderay (1.1.2)
|
11
|
-
concurrent-ruby (1.
|
12
|
-
dry-configurable (0.
|
11
|
+
concurrent-ruby (1.1.10)
|
12
|
+
dry-configurable (0.13.0)
|
13
13
|
concurrent-ruby (~> 1.0)
|
14
|
-
|
14
|
+
dry-core (~> 0.6)
|
15
|
+
dry-container (0.9.0)
|
15
16
|
concurrent-ruby (~> 1.0)
|
16
|
-
dry-configurable (~> 0.
|
17
|
-
dry-core (0.
|
17
|
+
dry-configurable (~> 0.13, >= 0.13.0)
|
18
|
+
dry-core (0.7.1)
|
18
19
|
concurrent-ruby (~> 1.0)
|
19
|
-
dry-
|
20
|
-
dry-
|
21
|
-
|
22
|
-
dry-
|
23
|
-
|
24
|
-
dry-equalizer (~> 0.2)
|
25
|
-
dry-types (0.13.2)
|
20
|
+
dry-inflector (0.2.1)
|
21
|
+
dry-logic (1.2.0)
|
22
|
+
concurrent-ruby (~> 1.0)
|
23
|
+
dry-core (~> 0.5, >= 0.5)
|
24
|
+
dry-types (1.5.1)
|
26
25
|
concurrent-ruby (~> 1.0)
|
27
26
|
dry-container (~> 0.3)
|
28
|
-
dry-core (~> 0.
|
29
|
-
dry-equalizer (~> 0.2)
|
27
|
+
dry-core (~> 0.5, >= 0.5)
|
30
28
|
dry-inflector (~> 0.1, >= 0.1.2)
|
31
|
-
dry-logic (~> 0
|
29
|
+
dry-logic (~> 1.0, >= 1.0.2)
|
32
30
|
method_source (0.9.2)
|
33
31
|
minitest (5.11.3)
|
34
32
|
pry (0.12.2)
|
35
33
|
coderay (~> 1.1.0)
|
36
34
|
method_source (~> 0.9.0)
|
37
|
-
rake (
|
35
|
+
rake (13.0.6)
|
38
36
|
|
39
37
|
PLATFORMS
|
40
38
|
ruby
|
41
39
|
|
42
40
|
DEPENDENCIES
|
43
41
|
atacama!
|
44
|
-
bundler
|
45
|
-
minitest
|
42
|
+
bundler
|
43
|
+
minitest
|
46
44
|
pry
|
47
|
-
rake
|
45
|
+
rake
|
48
46
|
|
49
47
|
BUNDLED WITH
|
50
|
-
1.
|
48
|
+
1.17.3
|
data/README.md
CHANGED
@@ -30,7 +30,7 @@ Or install it yourself as:
|
|
30
30
|
|
31
31
|
The basic object is `Contract`. It enforces type contracts by utilizing `dry-types`.
|
32
32
|
|
33
|
-
```
|
33
|
+
```ruby
|
34
34
|
class UserFetcher < Atacama::Contract
|
35
35
|
option :id, Types::Strict::Number.gt(0)
|
36
36
|
returns Types.Instance(User)
|
@@ -43,19 +43,30 @@ end
|
|
43
43
|
UserFetcher.call(id: 1)
|
44
44
|
```
|
45
45
|
|
46
|
-
With the use of two classes, we can compose together multiple Contracts to yield a pipeline
|
47
|
-
of changes to execute.
|
46
|
+
With the use of two classes, we can compose together multiple Contracts to yield a pipeline of changes to execute.
|
48
47
|
|
49
|
-
|
48
|
+
Steps contain two flow control objects:
|
49
|
+
* `Option(key: value)` which informs the Transformer to take this value and yield it to the subsequent steps in the chain.
|
50
|
+
* `Return(value)` halts execution and early returns from the pipeline. Useful for things like validation and error handling.
|
51
|
+
|
52
|
+
The `Transformer` always returns a value object.
|
53
|
+
|
54
|
+
```ruby
|
50
55
|
class UserFetcher < Atacama::Step
|
51
56
|
option :id, type: Types::Strict::Number.gt(0)
|
52
57
|
returns Types.Option(model: Types.Instance(User))
|
53
58
|
|
59
|
+
# Both #Option and #Return are flow control values that tell the transaction what is a
|
60
|
+
# value object and what should halt execution and return.
|
54
61
|
def call
|
55
|
-
Option(model: User.find(id))
|
62
|
+
Option(model: User.find!(id))
|
63
|
+
rescue ActiveRecord::RecordNotFound
|
64
|
+
Return(Error.new('Not found'))
|
56
65
|
end
|
57
66
|
end
|
58
67
|
|
68
|
+
# Around steps allow for yielding to child steps for things like instrumentation or
|
69
|
+
# ActiveRecord::Transactions.
|
59
70
|
class Duration < Atacama::Step
|
60
71
|
def call
|
61
72
|
start = Time.now
|
@@ -64,11 +75,19 @@ class Duration < Atacama::Step
|
|
64
75
|
end
|
65
76
|
end
|
66
77
|
|
78
|
+
# The transaction class descends the queue of steps, yielding options to each step
|
79
|
+
# defined.
|
80
|
+
#
|
81
|
+
# Steps can be defined with:
|
82
|
+
# * Procs
|
83
|
+
# * Class references
|
84
|
+
# * Instance methods
|
85
|
+
#
|
67
86
|
class UpdateUser < Atacama::Transformer
|
68
|
-
option :
|
87
|
+
option :id, type: Types::Strict::Number.gt(0)
|
69
88
|
option :attributes, type: Types::Strict::Hash
|
70
89
|
|
71
|
-
returns_option :model, Types.Instance(User)
|
90
|
+
returns_option :model, Types.Instance(User) | Types.Instance(Error)
|
72
91
|
|
73
92
|
step :duration, with: Duration do
|
74
93
|
step :find, with: UserFetcher
|
@@ -90,14 +109,47 @@ UpdateUser.call(id: 1, attributes: {
|
|
90
109
|
Any step can be mocked out without the need for a third party library. Just pass any object that
|
91
110
|
responds to `#call` in the class initializer.
|
92
111
|
|
93
|
-
```
|
112
|
+
```ruby
|
94
113
|
UpdateUser.new(steps: {
|
95
|
-
save: lambda do
|
114
|
+
save: lambda do
|
96
115
|
puts "skipping save"
|
97
116
|
end
|
98
117
|
})
|
99
118
|
```
|
100
119
|
|
120
|
+
Sometimes you need to compose these objects together and inject dependencies. Those injected values
|
121
|
+
will be passed in to the object when it's later invoked with `#call`.
|
122
|
+
|
123
|
+
```ruby
|
124
|
+
UpdateUser.inject(id: 1).call(attributes: { email: 'hello@world.com' })
|
125
|
+
```
|
126
|
+
|
127
|
+
Injected contracts can then be used inside of a Contract. Useful for Polymorphic objects.
|
128
|
+
|
129
|
+
```ruby
|
130
|
+
class HistoryCreate < Atacama::Step
|
131
|
+
option :history_class, type: Types::Strict::Class
|
132
|
+
option :model, type: Types.Instance(ActiveRecord::Base)
|
133
|
+
|
134
|
+
def call
|
135
|
+
history_class.from_model(model)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
class UpdateUser < Atacama::Transformer
|
140
|
+
option :id, type: Types::Strict::Number.gt(0)
|
141
|
+
option :attributes, type: Types::Strict::Hash
|
142
|
+
|
143
|
+
returns_option :model, Types.Instance(User) | Types.Instance(Error)
|
144
|
+
|
145
|
+
step :duration, with: Duration do
|
146
|
+
step :find, with: UserFetcher
|
147
|
+
step :save, with: Saver
|
148
|
+
step :history, with: HistoryCreate.inject(history_class: UserHistory)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
```
|
152
|
+
|
101
153
|
## Development
|
102
154
|
|
103
155
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
data/atacama.gemspec
CHANGED
@@ -23,10 +23,10 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
24
24
|
spec.require_paths = ['lib']
|
25
25
|
|
26
|
-
spec.add_dependency 'dry-types'
|
26
|
+
spec.add_dependency 'dry-types'
|
27
27
|
|
28
|
-
spec.add_development_dependency 'bundler'
|
29
|
-
spec.add_development_dependency 'minitest'
|
30
|
-
spec.add_development_dependency 'rake'
|
28
|
+
spec.add_development_dependency 'bundler'
|
29
|
+
spec.add_development_dependency 'minitest'
|
30
|
+
spec.add_development_dependency 'rake'
|
31
31
|
spec.add_development_dependency 'pry'
|
32
32
|
end
|
data/lib/atacama/types.rb
CHANGED
@@ -4,7 +4,7 @@ module Atacama
|
|
4
4
|
# The type namespace to interact with DRY::Types
|
5
5
|
# @see https://dry-rb.org/gems/dry-types/built-in-types/ dry-types Documentation
|
6
6
|
module Types
|
7
|
-
include Dry
|
7
|
+
include Dry.Types()
|
8
8
|
Boolean = Types::True | Types::False
|
9
9
|
|
10
10
|
# Defines a type which checks that the Option value contains a valid
|
data/lib/atacama/version.rb
CHANGED
metadata
CHANGED
@@ -1,71 +1,71 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: atacama
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tyler Johnston
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-09-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dry-types
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0
|
19
|
+
version: '0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 0
|
26
|
+
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: bundler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: minitest
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - "
|
45
|
+
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - "
|
52
|
+
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
54
|
+
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: rake
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - "
|
59
|
+
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
61
|
+
version: '0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- - "
|
66
|
+
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
68
|
+
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: pry
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -127,8 +127,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
127
127
|
- !ruby/object:Gem::Version
|
128
128
|
version: '0'
|
129
129
|
requirements: []
|
130
|
-
|
131
|
-
rubygems_version: 2.6.11
|
130
|
+
rubygems_version: 3.0.3.1
|
132
131
|
signing_key:
|
133
132
|
specification_version: 4
|
134
133
|
summary: DRY Service Objects
|