trailblazer-operation 0.0.13 → 0.1.1
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/.travis.yml +5 -3
- data/CHANGES.md +44 -0
- data/Gemfile +13 -2
- data/Rakefile +8 -6
- data/lib/trailblazer/operation.rb +86 -12
- data/lib/trailblazer/operation/deprecated_macro.rb +19 -0
- data/lib/trailblazer/operation/inject.rb +34 -0
- data/lib/trailblazer/operation/inspect.rb +80 -0
- data/lib/trailblazer/operation/public_call.rb +62 -0
- data/lib/trailblazer/operation/railway.rb +32 -0
- data/lib/trailblazer/operation/railway/fast_track.rb +13 -0
- data/lib/trailblazer/operation/railway/normalizer.rb +73 -0
- data/lib/trailblazer/operation/railway/task_builder.rb +44 -0
- data/lib/trailblazer/operation/result.rb +6 -4
- data/lib/trailblazer/operation/skill.rb +8 -24
- data/lib/trailblazer/operation/task_wrap.rb +68 -0
- data/lib/trailblazer/operation/trace.rb +49 -0
- data/lib/trailblazer/operation/variable_mapping.rb +91 -0
- data/lib/trailblazer/operation/version.rb +1 -1
- data/test/call_test.rb +27 -8
- data/test/class_dependencies_test.rb +16 -0
- data/test/docs/doormat_test.rb +189 -0
- data/test/docs/wiring_test.rb +421 -0
- data/test/dry_container_test.rb +4 -0
- data/test/fast_track_test.rb +197 -0
- data/test/gemfiles/Gemfile.ruby-2.0 +1 -2
- data/test/gemfiles/Gemfile.ruby-2.0.lock +40 -0
- data/test/inheritance_test.rb +1 -1
- data/test/inspect_test.rb +43 -0
- data/test/introspect_test.rb +50 -0
- data/test/macro_test.rb +61 -0
- data/test/operation_test.rb +94 -0
- data/test/result_test.rb +14 -8
- data/test/ruby-2.0.0/operation_test.rb +73 -0
- data/test/ruby-2.0.0/step_test.rb +136 -0
- data/test/skill_test.rb +66 -48
- data/test/step_test.rb +228 -0
- data/test/task_wrap_test.rb +91 -0
- data/test/test_helper.rb +37 -0
- data/test/trace_test.rb +62 -0
- data/test/variable_mapping_test.rb +66 -0
- data/test/wire_test.rb +113 -0
- data/test/wiring/defaults_test.rb +197 -0
- data/test/wiring/subprocess_test.rb +70 -0
- data/trailblazer-operation.gemspec +3 -5
- metadata +62 -36
- data/lib/trailblazer/operation/1.9.3/option.rb +0 -36
- data/lib/trailblazer/operation/generic.rb +0 -12
- data/lib/trailblazer/operation/option.rb +0 -54
- data/lib/trailblazer/operation/pipetree.rb +0 -142
- data/lib/trailblazer/skill.rb +0 -70
- data/test/2.0.0-pipetree_test.rb +0 -100
- data/test/2.1.0-pipetree_test.rb +0 -100
- data/test/operation_skill_test.rb +0 -89
- data/test/pipetree_test.rb +0 -185
@@ -0,0 +1,70 @@
|
|
1
|
+
# require "test_helper"
|
2
|
+
|
3
|
+
# class WiringWithNestedTest < Minitest::Spec
|
4
|
+
# MyEnd = Class.new(Trailblazer::Circuit::End)
|
5
|
+
|
6
|
+
# class Create < Trailblazer::Operation
|
7
|
+
# class Edit < Trailblazer::Operation
|
8
|
+
# step :a
|
9
|
+
|
10
|
+
# def a(options, a_return:, **)
|
11
|
+
# options["a"] = 1
|
12
|
+
# a_return
|
13
|
+
# end
|
14
|
+
|
15
|
+
# # operations should expose their outputs with proper naming.
|
16
|
+
# #
|
17
|
+
# # {#<Trailblazer::Operation::Railway::End::Success:0x00000001b22310
|
18
|
+
# # @name=:success,
|
19
|
+
# # @options={}>=>{:role=>:success},
|
20
|
+
# # #<Trailblazer::Operation::Railway::End::Failure:0x00000001b222c0
|
21
|
+
# # @name=:failure,
|
22
|
+
# # @options={}>=>{:role=>:unauthorized}}
|
23
|
+
# def self.outputs
|
24
|
+
# # Outputs::Only(super, :success, :failure)
|
25
|
+
# # Outputs::Update( outputs, failure: { role: :unauthorized} )
|
26
|
+
|
27
|
+
# outs = super.to_a
|
28
|
+
|
29
|
+
# outs = Hash[*(outs[0]+outs[1])]
|
30
|
+
|
31
|
+
# outs.merge( outs.keys[1] => { role: :unauthorized } )
|
32
|
+
# end
|
33
|
+
# end
|
34
|
+
|
35
|
+
# attach MyEnd.new(:myend), id: "End.unauthorized"
|
36
|
+
|
37
|
+
# step ( { task: Trailblazer::Activity::Subprocess( Edit, call: :__call__ ),
|
38
|
+
# node_data: { id: "Nested/" },
|
39
|
+
# outputs: Edit.outputs, # THIS SHOULD OVERRIDE.
|
40
|
+
# connect_to: Merge({ unauthorized: "End.unauthorized" }) # connects :success automatically.
|
41
|
+
# }), fast_track: true
|
42
|
+
|
43
|
+
# step :b
|
44
|
+
# fail :f
|
45
|
+
|
46
|
+
# def b(options, a:, **)
|
47
|
+
# options["b"] = a+1
|
48
|
+
# end
|
49
|
+
|
50
|
+
# def f(options, a:, **)
|
51
|
+
# options["f"] = a+2
|
52
|
+
# end
|
53
|
+
# end
|
54
|
+
|
55
|
+
# # Edit ==> true, will run :b
|
56
|
+
# it do
|
57
|
+
# result = Create.({}, a_return: true )
|
58
|
+
# result.inspect("a", "b", "f").must_equal %{<Result:true [1, 2, nil] >}
|
59
|
+
# result.event.must_be_instance_of Trailblazer::Operation::Railway::End::Success
|
60
|
+
# end
|
61
|
+
|
62
|
+
# # Edit ==> false, will end on End.unauthorized.
|
63
|
+
# it do
|
64
|
+
# result = Create.({}, a_return: false )
|
65
|
+
# result.inspect("a", "b", "f").must_equal %{<Result:false [1, nil, nil] >}
|
66
|
+
# result.event.must_be_instance_of MyEnd
|
67
|
+
|
68
|
+
# # Create.trace({}, a_return: false ).wtf
|
69
|
+
# end
|
70
|
+
# end
|
@@ -17,14 +17,12 @@ Gem::Specification.new do |spec|
|
|
17
17
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
18
|
spec.require_paths = ["lib"]
|
19
19
|
|
20
|
-
|
21
|
-
spec.add_dependency "
|
22
|
-
spec.add_dependency "declarative"
|
23
|
-
spec.add_dependency "pipetree", ">= 0.1.1", "< 0.2.0"
|
20
|
+
spec.add_dependency "trailblazer-activity", ">= 0.3.0", "< 0.4.0"
|
21
|
+
spec.add_dependency "trailblazer-context", ">= 0.1.1", "< 0.3.0"
|
24
22
|
|
25
23
|
spec.add_development_dependency "bundler"
|
26
24
|
spec.add_development_dependency "rake"
|
27
25
|
spec.add_development_dependency "minitest"
|
28
26
|
|
29
|
-
spec.required_ruby_version = '>=
|
27
|
+
spec.required_ruby_version = '>= 2.0.0'
|
30
28
|
end
|
metadata
CHANGED
@@ -1,45 +1,37 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: trailblazer-operation
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nick Sutterer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-12-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: trailblazer-activity
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
20
|
-
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - ">="
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '0'
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: declarative
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - ">="
|
19
|
+
version: 0.3.0
|
20
|
+
- - "<"
|
32
21
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
22
|
+
version: 0.4.0
|
34
23
|
type: :runtime
|
35
24
|
prerelease: false
|
36
25
|
version_requirements: !ruby/object:Gem::Requirement
|
37
26
|
requirements:
|
38
27
|
- - ">="
|
39
28
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
29
|
+
version: 0.3.0
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 0.4.0
|
41
33
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
34
|
+
name: trailblazer-context
|
43
35
|
requirement: !ruby/object:Gem::Requirement
|
44
36
|
requirements:
|
45
37
|
- - ">="
|
@@ -47,7 +39,7 @@ dependencies:
|
|
47
39
|
version: 0.1.1
|
48
40
|
- - "<"
|
49
41
|
- !ruby/object:Gem::Version
|
50
|
-
version: 0.
|
42
|
+
version: 0.3.0
|
51
43
|
type: :runtime
|
52
44
|
prerelease: false
|
53
45
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -57,7 +49,7 @@ dependencies:
|
|
57
49
|
version: 0.1.1
|
58
50
|
- - "<"
|
59
51
|
- !ruby/object:Gem::Version
|
60
|
-
version: 0.
|
52
|
+
version: 0.3.0
|
61
53
|
- !ruby/object:Gem::Dependency
|
62
54
|
name: bundler
|
63
55
|
requirement: !ruby/object:Gem::Requirement
|
@@ -114,28 +106,48 @@ files:
|
|
114
106
|
- README.md
|
115
107
|
- Rakefile
|
116
108
|
- lib/trailblazer/operation.rb
|
117
|
-
- lib/trailblazer/operation/
|
118
|
-
- lib/trailblazer/operation/
|
119
|
-
- lib/trailblazer/operation/
|
120
|
-
- lib/trailblazer/operation/
|
109
|
+
- lib/trailblazer/operation/deprecated_macro.rb
|
110
|
+
- lib/trailblazer/operation/inject.rb
|
111
|
+
- lib/trailblazer/operation/inspect.rb
|
112
|
+
- lib/trailblazer/operation/public_call.rb
|
113
|
+
- lib/trailblazer/operation/railway.rb
|
114
|
+
- lib/trailblazer/operation/railway/fast_track.rb
|
115
|
+
- lib/trailblazer/operation/railway/normalizer.rb
|
116
|
+
- lib/trailblazer/operation/railway/task_builder.rb
|
121
117
|
- lib/trailblazer/operation/result.rb
|
122
118
|
- lib/trailblazer/operation/skill.rb
|
119
|
+
- lib/trailblazer/operation/task_wrap.rb
|
120
|
+
- lib/trailblazer/operation/trace.rb
|
121
|
+
- lib/trailblazer/operation/variable_mapping.rb
|
123
122
|
- lib/trailblazer/operation/version.rb
|
124
|
-
- lib/trailblazer/skill.rb
|
125
|
-
- test/2.0.0-pipetree_test.rb
|
126
|
-
- test/2.1.0-pipetree_test.rb
|
127
123
|
- test/benchmark/skill_resolver_benchmark.rb
|
128
124
|
- test/call_test.rb
|
125
|
+
- test/class_dependencies_test.rb
|
126
|
+
- test/docs/doormat_test.rb
|
127
|
+
- test/docs/wiring_test.rb
|
129
128
|
- test/dry_container_test.rb
|
129
|
+
- test/fast_track_test.rb
|
130
130
|
- test/gemfiles/Gemfile.ruby-1.9
|
131
131
|
- test/gemfiles/Gemfile.ruby-2.0
|
132
|
+
- test/gemfiles/Gemfile.ruby-2.0.lock
|
132
133
|
- test/gemfiles/Gemfile.ruby-2.3
|
133
134
|
- test/inheritance_test.rb
|
134
|
-
- test/
|
135
|
-
- test/
|
135
|
+
- test/inspect_test.rb
|
136
|
+
- test/introspect_test.rb
|
137
|
+
- test/macro_test.rb
|
138
|
+
- test/operation_test.rb
|
136
139
|
- test/result_test.rb
|
140
|
+
- test/ruby-2.0.0/operation_test.rb
|
141
|
+
- test/ruby-2.0.0/step_test.rb
|
137
142
|
- test/skill_test.rb
|
143
|
+
- test/step_test.rb
|
144
|
+
- test/task_wrap_test.rb
|
138
145
|
- test/test_helper.rb
|
146
|
+
- test/trace_test.rb
|
147
|
+
- test/variable_mapping_test.rb
|
148
|
+
- test/wire_test.rb
|
149
|
+
- test/wiring/defaults_test.rb
|
150
|
+
- test/wiring/subprocess_test.rb
|
139
151
|
- trailblazer-operation.gemspec
|
140
152
|
homepage: http://trailblazer.to
|
141
153
|
licenses:
|
@@ -149,7 +161,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
149
161
|
requirements:
|
150
162
|
- - ">="
|
151
163
|
- !ruby/object:Gem::Version
|
152
|
-
version:
|
164
|
+
version: 2.0.0
|
153
165
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
154
166
|
requirements:
|
155
167
|
- - ">="
|
@@ -157,22 +169,36 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
157
169
|
version: '0'
|
158
170
|
requirements: []
|
159
171
|
rubyforge_project:
|
160
|
-
rubygems_version: 2.6.
|
172
|
+
rubygems_version: 2.6.12
|
161
173
|
signing_key:
|
162
174
|
specification_version: 4
|
163
175
|
summary: Trailblazer's operation object with railway flow and integrated error handling.
|
164
176
|
test_files:
|
165
|
-
- test/2.0.0-pipetree_test.rb
|
166
|
-
- test/2.1.0-pipetree_test.rb
|
167
177
|
- test/benchmark/skill_resolver_benchmark.rb
|
168
178
|
- test/call_test.rb
|
179
|
+
- test/class_dependencies_test.rb
|
180
|
+
- test/docs/doormat_test.rb
|
181
|
+
- test/docs/wiring_test.rb
|
169
182
|
- test/dry_container_test.rb
|
183
|
+
- test/fast_track_test.rb
|
170
184
|
- test/gemfiles/Gemfile.ruby-1.9
|
171
185
|
- test/gemfiles/Gemfile.ruby-2.0
|
186
|
+
- test/gemfiles/Gemfile.ruby-2.0.lock
|
172
187
|
- test/gemfiles/Gemfile.ruby-2.3
|
173
188
|
- test/inheritance_test.rb
|
174
|
-
- test/
|
175
|
-
- test/
|
189
|
+
- test/inspect_test.rb
|
190
|
+
- test/introspect_test.rb
|
191
|
+
- test/macro_test.rb
|
192
|
+
- test/operation_test.rb
|
176
193
|
- test/result_test.rb
|
194
|
+
- test/ruby-2.0.0/operation_test.rb
|
195
|
+
- test/ruby-2.0.0/step_test.rb
|
177
196
|
- test/skill_test.rb
|
197
|
+
- test/step_test.rb
|
198
|
+
- test/task_wrap_test.rb
|
178
199
|
- test/test_helper.rb
|
200
|
+
- test/trace_test.rb
|
201
|
+
- test/variable_mapping_test.rb
|
202
|
+
- test/wire_test.rb
|
203
|
+
- test/wiring/defaults_test.rb
|
204
|
+
- test/wiring/subprocess_test.rb
|
@@ -1,36 +0,0 @@
|
|
1
|
-
class Trailblazer::Operation
|
2
|
-
# :private:
|
3
|
-
module Option
|
4
|
-
def self.call(proc, &block)
|
5
|
-
type = :proc
|
6
|
-
|
7
|
-
option =
|
8
|
-
if proc.is_a? Symbol
|
9
|
-
type = :symbol
|
10
|
-
->(input, _options) { call_method(proc, input, _options) }
|
11
|
-
elsif proc.is_a? Proc
|
12
|
-
->(input, _options) { call_proc(proc, input, _options) }
|
13
|
-
elsif proc.is_a? Uber::Callable
|
14
|
-
type = :callable
|
15
|
-
->(input, _options) { call_callable(proc, input, _options) }
|
16
|
-
end
|
17
|
-
|
18
|
-
yield type if block_given?
|
19
|
-
option
|
20
|
-
end
|
21
|
-
|
22
|
-
def self.call_proc(proc, input, options)
|
23
|
-
proc.(options)
|
24
|
-
end
|
25
|
-
|
26
|
-
def self.call_method(proc, input, options)
|
27
|
-
input.send(proc, options)
|
28
|
-
end
|
29
|
-
|
30
|
-
def self.call_callable(callable, input, options)
|
31
|
-
callable.(options)
|
32
|
-
end
|
33
|
-
|
34
|
-
KW = Option
|
35
|
-
end # Option
|
36
|
-
end
|
@@ -1,54 +0,0 @@
|
|
1
|
-
class Trailblazer::Operation
|
2
|
-
# :private:
|
3
|
-
# This code is not beautiful, but could also be worse.
|
4
|
-
# I'm expecting some of this to go to Uber, as we use this pattern everywhere.
|
5
|
-
class Option
|
6
|
-
def self.call(proc, &block)
|
7
|
-
type = :proc
|
8
|
-
|
9
|
-
option =
|
10
|
-
if proc.is_a? Symbol
|
11
|
-
type = :symbol
|
12
|
-
->(input, *_options) { call_method(proc, input, *_options) }
|
13
|
-
elsif proc.is_a? Proc
|
14
|
-
->(input, *_options) { call_proc(proc, input, *_options) }
|
15
|
-
elsif proc.is_a? Uber::Callable
|
16
|
-
type = :callable
|
17
|
-
->(input, *_options) { call_callable(proc, input, *_options) }
|
18
|
-
end
|
19
|
-
|
20
|
-
yield type if block_given?
|
21
|
-
option
|
22
|
-
end
|
23
|
-
|
24
|
-
def self.call_proc(proc, input, *options)
|
25
|
-
proc.(*options)
|
26
|
-
end
|
27
|
-
|
28
|
-
def self.call_method(proc, input, *options)
|
29
|
-
input.send(proc, *options)
|
30
|
-
end
|
31
|
-
|
32
|
-
def self.call_callable(callable, input, *options)
|
33
|
-
callable.(*options)
|
34
|
-
end
|
35
|
-
|
36
|
-
# Call the option with keyword arguments. Ruby <= 2.0.
|
37
|
-
class KW < Option
|
38
|
-
def self.call_proc(proc, input, options, tmp_options={})
|
39
|
-
return proc.(options) if proc.arity == 1
|
40
|
-
proc.(options, **options.to_hash(tmp_options))
|
41
|
-
end
|
42
|
-
|
43
|
-
def self.call_method(proc, input, options, tmp_options={})
|
44
|
-
return input.send(proc, options) if input.method(proc).arity == 1 # TODO: remove this
|
45
|
-
input.send(proc, options, **options.to_hash(tmp_options))
|
46
|
-
end
|
47
|
-
|
48
|
-
def self.call_callable(callable, input, options, tmp_options={})
|
49
|
-
return callable.(options) if callable.method(:call).arity == 1
|
50
|
-
callable.(options, **options.to_hash(tmp_options))
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
@@ -1,142 +0,0 @@
|
|
1
|
-
require "pipetree"
|
2
|
-
require "pipetree/railway"
|
3
|
-
require "trailblazer/operation/result"
|
4
|
-
|
5
|
-
if RUBY_VERSION == "1.9.3"
|
6
|
-
require "trailblazer/operation/1.9.3/option" # TODO: rename to something better.
|
7
|
-
else
|
8
|
-
require "trailblazer/operation/option" # TODO: rename to something better.
|
9
|
-
end
|
10
|
-
|
11
|
-
class Trailblazer::Operation
|
12
|
-
Instantiate = ->(klass, options) { klass.new(options) } # returns operation instance.
|
13
|
-
|
14
|
-
# Implements the API to populate the operation's pipetree and
|
15
|
-
# `Operation::call` to invoke the latter.
|
16
|
-
# Learn more about the Pipetree gem here: https://github.com/apotonick/pipetree
|
17
|
-
module Pipetree
|
18
|
-
def self.included(includer)
|
19
|
-
includer.extend ClassMethods # ::call, ::inititalize_pipetree!
|
20
|
-
includer.extend DSL # ::|, ::> and friends.
|
21
|
-
|
22
|
-
includer.initialize_pipetree!
|
23
|
-
end
|
24
|
-
|
25
|
-
module ClassMethods
|
26
|
-
# Top-level, this method is called when you do Create.() and where
|
27
|
-
# all the fun starts, ends, and hopefully starts again.
|
28
|
-
def call(options)
|
29
|
-
pipe = self["pipetree"] # TODO: injectable? WTF? how cool is that?
|
30
|
-
|
31
|
-
last, operation = pipe.(self, options)
|
32
|
-
|
33
|
-
# Any subclass of Right will be interpreted as successful.
|
34
|
-
Result.new(!!(last <= Railway::Right), options)
|
35
|
-
end
|
36
|
-
|
37
|
-
# This method would be redundant if Ruby had a Class::finalize! method the way
|
38
|
-
# Dry.RB provides it. It has to be executed with every subclassing.
|
39
|
-
def initialize_pipetree!
|
40
|
-
heritage.record :initialize_pipetree!
|
41
|
-
|
42
|
-
self["pipetree"] = Railway.new
|
43
|
-
|
44
|
-
strut = ->(last, input, options) { [last, Instantiate.(input, options)] } # first step in pipe.
|
45
|
-
self["pipetree"].add(Railway::Right, strut, name: "operation.new") # DISCUSS: using pipe API directly here. clever?
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
class Railway < ::Pipetree::Railway
|
50
|
-
FailFast = Class.new(Left)
|
51
|
-
PassFast = Class.new(Right)
|
52
|
-
|
53
|
-
def self.fail! ; Left end
|
54
|
-
def self.fail_fast!; FailFast end
|
55
|
-
def self.pass! ; Right end
|
56
|
-
def self.pass_fast!; PassFast end
|
57
|
-
end
|
58
|
-
|
59
|
-
# The Strut wrapping each step. Makes sure that Track signals are returned immediately.
|
60
|
-
class Switch < ::Pipetree::Railway::Strut
|
61
|
-
Decider = ->(result, config, *args) do
|
62
|
-
return result if result.is_a?(Class) && result <= Railway::Track # this might be pretty slow?
|
63
|
-
|
64
|
-
config[:decider_class].(result, config, *args) # e.g. And::Decider.(result, ..)
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
# Strut that doesn't evaluate the step's result but stays on `last` or configured :signal.
|
69
|
-
class Stay < ::Pipetree::Railway::Strut
|
70
|
-
Decider = ->(result, config, last, *) { config[:signal] || last }
|
71
|
-
end
|
72
|
-
|
73
|
-
module DSL
|
74
|
-
def success(*args); add(Railway::Right, Stay::Decider, *args) end
|
75
|
-
def failure(*args); add(Railway::Left, Stay::Decider, *args) end
|
76
|
-
def step(*args) ; add(Railway::Right, Railway::And::Decider, *args) end
|
77
|
-
|
78
|
-
private
|
79
|
-
# Operation-level entry point.
|
80
|
-
def add(track, decider_class, proc, options={})
|
81
|
-
heritage.record(:add, track, decider_class, proc, options)
|
82
|
-
|
83
|
-
DSL.insert(self["pipetree"], track, decider_class, proc, options)
|
84
|
-
end
|
85
|
-
|
86
|
-
def self.insert(pipe, track, decider_class, proc, options={}) # TODO: make :name required arg.
|
87
|
-
_proc, options = proc.is_a?(Array) ? macro!(proc, options) : step!(proc, options)
|
88
|
-
|
89
|
-
options = options.merge(replace: options[:name]) if options[:override] # :override
|
90
|
-
strut_class, strut_options = AddOptions.(decider_class, options) # :fail_fast and friends.
|
91
|
-
|
92
|
-
pipe.add(track, strut_class.new(_proc, strut_options), options)
|
93
|
-
end
|
94
|
-
|
95
|
-
def self.macro!(proc, options)
|
96
|
-
_proc, macro_options = proc
|
97
|
-
|
98
|
-
[ _proc, macro_options.merge(options) ]
|
99
|
-
end
|
100
|
-
|
101
|
-
def self.step!(proc, options)
|
102
|
-
name = ""
|
103
|
-
_proc = Option::KW.(proc) do |type|
|
104
|
-
name = proc if type == :symbol
|
105
|
-
name = "#{proc.source_location[0].split("/").last}:#{proc.source_location.last}" if proc.is_a? Proc if type == :proc
|
106
|
-
name = proc.class if type == :callable
|
107
|
-
end
|
108
|
-
|
109
|
-
[ _proc, { name: name }.merge(options) ]
|
110
|
-
end
|
111
|
-
|
112
|
-
AddOptions = ->(decider_class, options) do
|
113
|
-
# for #failure and #success:
|
114
|
-
if decider_class == Stay::Decider
|
115
|
-
return [Stay, signal: Railway::FailFast] if options[:fail_fast]
|
116
|
-
return [Stay, signal: Railway::PassFast] if options[:pass_fast]
|
117
|
-
return [Stay, {}]
|
118
|
-
else # for #step:
|
119
|
-
return [Switch, decider_class: decider_class, on_false: Railway::FailFast] if options[:fail_fast]
|
120
|
-
return [Switch, decider_class: decider_class, on_true: Railway::PassFast] if options[:pass_fast]
|
121
|
-
return [Switch, decider_class: decider_class]
|
122
|
-
end
|
123
|
-
end
|
124
|
-
end # DSL
|
125
|
-
end
|
126
|
-
|
127
|
-
require "uber/callable"
|
128
|
-
# Allows defining dependencies and inject/override them via runtime options, if desired.
|
129
|
-
class Pipetree::Step
|
130
|
-
include Uber::Callable
|
131
|
-
|
132
|
-
def initialize(step, dependencies={})
|
133
|
-
@step, @dependencies = step, dependencies
|
134
|
-
end
|
135
|
-
|
136
|
-
def call(input, options)
|
137
|
-
@dependencies.each { |k, v| options[k] ||= v } # not sure i like this, but the step's API is cool.
|
138
|
-
|
139
|
-
@step.(input, options)
|
140
|
-
end
|
141
|
-
end
|
142
|
-
end
|