carry_out 0.2.8 → 0.2.9
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
- - ">="
|