carry_out 0.2.8 → 0.2.9
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/README.md +47 -0
- data/carry_out.gemspec +6 -2
- data/lib/carry_out/plan.rb +40 -10
- data/lib/carry_out/version.rb +1 -1
- data/lib/carry_out.rb +52 -6
- metadata +7 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 15539f051ef8fbb7bde23ab9027e1a309b318eb6
|
4
|
+
data.tar.gz: 75df54ddbd00851be278a80faaa350e2483ad0c5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c9df9545f0b391a1f31471ecbc1b85a4f5257fd9399144c75d55643cb787620ac7486dc46de7ee297877779a975b7b3a1817ac14ad62b31172895f9a851c581c
|
7
|
+
data.tar.gz: 33bcc7bc1820b9c2dbd2bd8a084f6a8168d145e854d6ee50ad0fd0ae370ce8a8255ba0a361dadc97201b277353a5b6f1b1d283063d75935f7a3edac6702593dd
|
data/README.md
CHANGED
@@ -221,6 +221,53 @@ plan = CarryOut
|
|
221
221
|
# or .unless(CarryOut.get(:silenced))
|
222
222
|
```
|
223
223
|
|
224
|
+
### Magic Directives (Experimental)
|
225
|
+
|
226
|
+
*This feature is highly experimental. It has not been thoroughly tested in larger application environments like Rails and is not yet guaranteed to remain part of this gem.*
|
227
|
+
|
228
|
+
CarryOut provides some magic methods that can improve the readability of a plan. These rely on a search strategy to find classes by name. A very limited strategy is provided out-of-the-box. This strategy accepts an array of modules and will only find classes that are direct children of any of the provided modules. The first match gets priority.
|
229
|
+
|
230
|
+
```ruby
|
231
|
+
CarryOut.defaults = {
|
232
|
+
search: [ MyModule1 ]
|
233
|
+
}
|
234
|
+
```
|
235
|
+
|
236
|
+
If the default strategy is insufficient (and it most likely will be), a custom strategy can be provided as a lambda/Proc. For example, a strategy that works in Rails is to put the following in an initializer:
|
237
|
+
|
238
|
+
```ruby
|
239
|
+
CarryOut.defaults = {
|
240
|
+
search: -> (name) { name.constantize }
|
241
|
+
}
|
242
|
+
```
|
243
|
+
|
244
|
+
#### Magic will\_, then\_, and within\_
|
245
|
+
|
246
|
+
The magic versions of `will`, `then`, and `within` will use the configured search strategy to convert the remaning portion of the directive into a class reference.
|
247
|
+
|
248
|
+
Using the default strategy as configured above:
|
249
|
+
```ruby
|
250
|
+
module MyModule1
|
251
|
+
class SayHello
|
252
|
+
def execute; puts "Hello!"; end
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
plan = CarryOut.will_say_hello
|
257
|
+
```
|
258
|
+
|
259
|
+
#### Magic returning\_as\_
|
260
|
+
|
261
|
+
The magic `returning_as_` directive is an alternative to passing the `as:` option to a `will`/`then` directive. The remainder of the directive becomes the key symbol into which the unit's return value will be stored.
|
262
|
+
|
263
|
+
```ruby
|
264
|
+
plan = CarryOut
|
265
|
+
.will_receive_message
|
266
|
+
.returning_as_message
|
267
|
+
.then_log
|
268
|
+
.message(CarryOut.get(:message))
|
269
|
+
```
|
270
|
+
|
224
271
|
## Motivation
|
225
272
|
|
226
273
|
I've been trying to keep my Rails controllers clean, but I prefer to avoid shoving inter-model business logic inside database models. The recommendation I most frequently run into is to move that kind of logic into something akin to service objects. I like that idea, but I want to keep my services small and composable, and I want to separate the "what" from the "how" of my logic.
|
data/carry_out.gemspec
CHANGED
@@ -24,10 +24,14 @@ Gem::Specification.new do |spec|
|
|
24
24
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
25
25
|
spec.require_paths = ["lib"]
|
26
26
|
|
27
|
-
spec.required_ruby_version = '
|
27
|
+
spec.required_ruby_version = '>= 1.9.3'
|
28
28
|
|
29
29
|
spec.add_development_dependency "bundler", "~> 1.12"
|
30
30
|
spec.add_development_dependency "rake", "~> 10.0"
|
31
31
|
spec.add_development_dependency "minitest", "~> 5.0"
|
32
|
-
spec.add_development_dependency "coveralls"
|
32
|
+
spec.add_development_dependency "coveralls", "~> 0.8"
|
33
|
+
|
34
|
+
if RUBY_VERSION < '2.0'
|
35
|
+
spec.add_development_dependency "tins", "~> 1.6.0"
|
36
|
+
end
|
33
37
|
end
|
data/lib/carry_out/plan.rb
CHANGED
@@ -1,15 +1,17 @@
|
|
1
1
|
module CarryOut
|
2
2
|
class Plan
|
3
|
-
|
3
|
+
MATCH_CONTINUATION_METHOD = /^(?:will|then)_(.+)/
|
4
|
+
MATCH_CONTEXT_METHOD = /^within_(.+)/
|
5
|
+
MATCH_RETURNING_METHOD = /^returning_as_(.+)/
|
6
|
+
|
4
7
|
def initialize(unit = nil, options = {})
|
5
8
|
@nodes = {}
|
6
9
|
@node_meta = {}
|
7
10
|
@previously_added_node = nil
|
8
11
|
@wrapper = options[:within]
|
12
|
+
@search = options[:search] || []
|
9
13
|
|
10
|
-
unless unit.nil?
|
11
|
-
self.then(unit, options)
|
12
|
-
end
|
14
|
+
self.then(unit, options) unless unit.nil?
|
13
15
|
end
|
14
16
|
|
15
17
|
def execute(context = nil, &block)
|
@@ -41,8 +43,8 @@ module CarryOut
|
|
41
43
|
self.then(*args)
|
42
44
|
end
|
43
45
|
|
44
|
-
def then(unit, options = {})
|
45
|
-
add_node(PlanNode.new(unit), options[:as])
|
46
|
+
def then(unit = nil, options = {})
|
47
|
+
add_node(PlanNode.new(unit), options[:as]) unless unit.nil?
|
46
48
|
self
|
47
49
|
end
|
48
50
|
|
@@ -53,8 +55,21 @@ module CarryOut
|
|
53
55
|
end
|
54
56
|
|
55
57
|
def method_missing(method, *args, &block)
|
56
|
-
if
|
57
|
-
|
58
|
+
if MATCH_CONTINUATION_METHOD =~ method
|
59
|
+
obj = find_object($1)
|
60
|
+
return super if obj.nil?
|
61
|
+
self.then(obj, *args, &block)
|
62
|
+
elsif MATCH_CONTEXT_METHOD =~ method
|
63
|
+
obj = find_object($1)
|
64
|
+
return super if obj.nil?
|
65
|
+
@wrapper = obj.new
|
66
|
+
self
|
67
|
+
elsif @previously_added_node
|
68
|
+
if MATCH_RETURNING_METHOD =~ method
|
69
|
+
node_meta(@previously_added_node)[:as] = $1.to_sym
|
70
|
+
else
|
71
|
+
@previously_added_node.send(method, *args, &block)
|
72
|
+
end
|
58
73
|
self
|
59
74
|
else
|
60
75
|
super
|
@@ -106,7 +121,18 @@ module CarryOut
|
|
106
121
|
node_result = node.execute(result.artifacts)
|
107
122
|
result.add(publish_to, node_result) unless publish_to.nil?
|
108
123
|
rescue UnitError => error
|
109
|
-
result.add(publish_to ||
|
124
|
+
result.add(publish_to || key_for_node(node), CarryOut::Error.new(error.error.message, error.error))
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def find_object(name)
|
129
|
+
constant_name = name.to_s.split('_').map { |w| w.capitalize }.join('')
|
130
|
+
|
131
|
+
if @search.respond_to?(:call)
|
132
|
+
@search.call(constant_name)
|
133
|
+
else
|
134
|
+
containing_module = @search.find { |m| m.const_get(constant_name) rescue nil }
|
135
|
+
containing_module.const_get(constant_name) unless containing_module.nil?
|
110
136
|
end
|
111
137
|
end
|
112
138
|
|
@@ -121,8 +147,12 @@ module CarryOut
|
|
121
147
|
guards.nil? || guards.map { |guard| guard.call(artifacts) }.all?
|
122
148
|
end
|
123
149
|
|
150
|
+
def key_for_node(node)
|
151
|
+
@nodes.key(node)
|
152
|
+
end
|
153
|
+
|
124
154
|
def node_meta(node)
|
125
|
-
@node_meta[
|
155
|
+
@node_meta[key_for_node(node)]
|
126
156
|
end
|
127
157
|
end
|
128
158
|
end
|
data/lib/carry_out/version.rb
CHANGED
data/lib/carry_out.rb
CHANGED
@@ -9,15 +9,61 @@ require "carry_out/unit"
|
|
9
9
|
require "carry_out/unit_error"
|
10
10
|
|
11
11
|
module CarryOut
|
12
|
-
|
13
|
-
|
12
|
+
MATCH_CONTINUATION_METHOD = /^will_/
|
13
|
+
MATCH_WITHIN_METHOD = /^within_/
|
14
|
+
|
15
|
+
class ConfiguredCarryOut
|
16
|
+
def initialize(options = {})
|
17
|
+
@config = options
|
18
|
+
end
|
19
|
+
|
20
|
+
def get(*args)
|
21
|
+
Reference.new(*args)
|
22
|
+
end
|
23
|
+
|
24
|
+
def method_missing(method, *args, &block)
|
25
|
+
if MATCH_CONTINUATION_METHOD =~ method
|
26
|
+
create_plan.send(method, *args, &block)
|
27
|
+
elsif MATCH_WITHIN_METHOD =~ method
|
28
|
+
create_plan.send(method, *args, &block)
|
29
|
+
else
|
30
|
+
super
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def will(*args)
|
35
|
+
create_plan.will(*args)
|
36
|
+
end
|
37
|
+
|
38
|
+
def within(wrapper = nil, &block)
|
39
|
+
create_plan(within: wrapper || block)
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
def create_plan(options = {})
|
44
|
+
Plan.new(nil, @config.merge(options))
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.configured_with(options = {})
|
49
|
+
ConfiguredCarryOut.new(options)
|
14
50
|
end
|
15
51
|
|
16
|
-
def self.
|
17
|
-
|
52
|
+
def self.defaults=(options = {})
|
53
|
+
@default_options = options
|
54
|
+
@default_carry_out = nil
|
18
55
|
end
|
19
56
|
|
20
|
-
def self.
|
21
|
-
|
57
|
+
def self.method_missing(method, *args, &block)
|
58
|
+
default_carry_out.send(method, *args, &block)
|
22
59
|
end
|
60
|
+
|
61
|
+
private
|
62
|
+
def self.default_options
|
63
|
+
@default_options ||= Hash.new
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.default_carry_out
|
67
|
+
@default_carry_out ||= ConfiguredCarryOut.new(default_options)
|
68
|
+
end
|
23
69
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: carry_out
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Fields
|
@@ -56,16 +56,16 @@ dependencies:
|
|
56
56
|
name: coveralls
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - "
|
59
|
+
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '0'
|
61
|
+
version: '0.8'
|
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: '0'
|
68
|
+
version: '0.8'
|
69
69
|
description: |2
|
70
70
|
CarryOut connects units of logic into workflows. Each unit can extend
|
71
71
|
the DSL with parameter methods. Artifacts and errors are collected as
|
@@ -106,9 +106,9 @@ require_paths:
|
|
106
106
|
- lib
|
107
107
|
required_ruby_version: !ruby/object:Gem::Requirement
|
108
108
|
requirements:
|
109
|
-
- - "
|
109
|
+
- - ">="
|
110
110
|
- !ruby/object:Gem::Version
|
111
|
-
version:
|
111
|
+
version: 1.9.3
|
112
112
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
113
113
|
requirements:
|
114
114
|
- - ">="
|