trailblazer-future 2.1.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +12 -0
- data/.travis.yml +6 -0
- data/CHANGES.md +4 -0
- data/LICENSE.txt +9 -0
- data/README.md +48 -0
- data/Rakefile +10 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/gems.rb +3 -0
- data/lib/trailblazer/future.rb +9 -0
- data/lib/trailblazer/future/version.rb +5 -0
- data/lib/trailblazer/v2_1/activity.rb +123 -0
- data/lib/trailblazer/v2_1/activity/config.rb +37 -0
- data/lib/trailblazer/v2_1/activity/dsl/add_task.rb +22 -0
- data/lib/trailblazer/v2_1/activity/dsl/helper.rb +68 -0
- data/lib/trailblazer/v2_1/activity/dsl/magnetic.rb +36 -0
- data/lib/trailblazer/v2_1/activity/dsl/magnetic/builder.rb +101 -0
- data/lib/trailblazer/v2_1/activity/dsl/magnetic/builder/default_normalizer.rb +26 -0
- data/lib/trailblazer/v2_1/activity/dsl/magnetic/builder/fast_track.rb +118 -0
- data/lib/trailblazer/v2_1/activity/dsl/magnetic/builder/normalizer.rb +113 -0
- data/lib/trailblazer/v2_1/activity/dsl/magnetic/builder/path.rb +105 -0
- data/lib/trailblazer/v2_1/activity/dsl/magnetic/builder/railway.rb +97 -0
- data/lib/trailblazer/v2_1/activity/dsl/magnetic/builder/state.rb +58 -0
- data/lib/trailblazer/v2_1/activity/dsl/magnetic/finalizer.rb +51 -0
- data/lib/trailblazer/v2_1/activity/dsl/magnetic/generate.rb +62 -0
- data/lib/trailblazer/v2_1/activity/dsl/magnetic/merge.rb +16 -0
- data/lib/trailblazer/v2_1/activity/dsl/magnetic/process_options.rb +76 -0
- data/lib/trailblazer/v2_1/activity/dsl/magnetic/structure/alterations.rb +44 -0
- data/lib/trailblazer/v2_1/activity/dsl/magnetic/structure/plus_poles.rb +85 -0
- data/lib/trailblazer/v2_1/activity/dsl/magnetic/structure/polarization.rb +23 -0
- data/lib/trailblazer/v2_1/activity/dsl/record.rb +11 -0
- data/lib/trailblazer/v2_1/activity/dsl/schema/dependencies.rb +46 -0
- data/lib/trailblazer/v2_1/activity/dsl/schema/sequence.rb +46 -0
- data/lib/trailblazer/v2_1/activity/dsl/strategy/build_state.rb +32 -0
- data/lib/trailblazer/v2_1/activity/dsl/strategy/fast_track.rb +24 -0
- data/lib/trailblazer/v2_1/activity/dsl/strategy/path.rb +26 -0
- data/lib/trailblazer/v2_1/activity/dsl/strategy/plan.rb +36 -0
- data/lib/trailblazer/v2_1/activity/dsl/strategy/railway.rb +23 -0
- data/lib/trailblazer/v2_1/activity/interface.rb +16 -0
- data/lib/trailblazer/v2_1/activity/introspect.rb +167 -0
- data/lib/trailblazer/v2_1/activity/present.rb +95 -0
- data/lib/trailblazer/v2_1/activity/structures.rb +57 -0
- data/lib/trailblazer/v2_1/activity/task_builder.rb +41 -0
- data/lib/trailblazer/v2_1/activity/task_wrap.rb +40 -0
- data/lib/trailblazer/v2_1/activity/task_wrap/call_task.rb +19 -0
- data/lib/trailblazer/v2_1/activity/task_wrap/merge.rb +23 -0
- data/lib/trailblazer/v2_1/activity/task_wrap/runner.rb +62 -0
- data/lib/trailblazer/v2_1/activity/task_wrap/trace.rb +44 -0
- data/lib/trailblazer/v2_1/activity/task_wrap/variable_mapping.rb +162 -0
- data/lib/trailblazer/v2_1/activity/testing.rb +32 -0
- data/lib/trailblazer/v2_1/activity/trace.rb +97 -0
- data/lib/trailblazer/v2_1/circuit.rb +71 -0
- data/lib/trailblazer/v2_1/container_chain.rb +45 -0
- data/lib/trailblazer/v2_1/context.rb +79 -0
- data/lib/trailblazer/v2_1/deprecation/call.rb +46 -0
- data/lib/trailblazer/v2_1/deprecation/context.rb +43 -0
- data/lib/trailblazer/v2_1/dsl.rb +47 -0
- data/lib/trailblazer/v2_1/macro.rb +11 -0
- data/lib/trailblazer/v2_1/macro/contract.rb +5 -0
- data/lib/trailblazer/v2_1/operation.rb +91 -0
- data/lib/trailblazer/v2_1/operation/auto_inject.rb +47 -0
- data/lib/trailblazer/v2_1/operation/callable.rb +42 -0
- data/lib/trailblazer/v2_1/operation/class_dependencies.rb +25 -0
- data/lib/trailblazer/v2_1/operation/contract.rb +61 -0
- data/lib/trailblazer/v2_1/operation/deprecated_macro.rb +19 -0
- data/lib/trailblazer/v2_1/operation/deprecations.rb +21 -0
- data/lib/trailblazer/v2_1/operation/guard.rb +18 -0
- data/lib/trailblazer/v2_1/operation/heritage.rb +30 -0
- data/lib/trailblazer/v2_1/operation/inject.rb +36 -0
- data/lib/trailblazer/v2_1/operation/inspect.rb +79 -0
- data/lib/trailblazer/v2_1/operation/model.rb +50 -0
- data/lib/trailblazer/v2_1/operation/module.rb +29 -0
- data/lib/trailblazer/v2_1/operation/nested.rb +98 -0
- data/lib/trailblazer/v2_1/operation/persist.rb +14 -0
- data/lib/trailblazer/v2_1/operation/policy.rb +44 -0
- data/lib/trailblazer/v2_1/operation/public_call.rb +55 -0
- data/lib/trailblazer/v2_1/operation/pundit.rb +38 -0
- data/lib/trailblazer/v2_1/operation/railway.rb +32 -0
- data/lib/trailblazer/v2_1/operation/railway/fast_track.rb +13 -0
- data/lib/trailblazer/v2_1/operation/railway/macaroni.rb +23 -0
- data/lib/trailblazer/v2_1/operation/railway/normalizer.rb +58 -0
- data/lib/trailblazer/v2_1/operation/railway/task_builder.rb +37 -0
- data/lib/trailblazer/v2_1/operation/rescue.rb +42 -0
- data/lib/trailblazer/v2_1/operation/responder.rb +18 -0
- data/lib/trailblazer/v2_1/operation/result.rb +30 -0
- data/lib/trailblazer/v2_1/operation/test.rb +17 -0
- data/lib/trailblazer/v2_1/operation/trace.rb +46 -0
- data/lib/trailblazer/v2_1/operation/validate.rb +76 -0
- data/lib/trailblazer/v2_1/operation/wrap.rb +83 -0
- data/lib/trailblazer/v2_1/option.rb +78 -0
- data/lib/trailblazer/v2_1/rails.rb +12 -0
- data/lib/trailblazer/v2_1/rails/cell.rb +22 -0
- data/lib/trailblazer/v2_1/rails/controller.rb +66 -0
- data/lib/trailblazer/v2_1/rails/form.rb +21 -0
- data/lib/trailblazer/v2_1/rails/railtie.rb +31 -0
- data/lib/trailblazer/v2_1/rails/railtie/extend_application_controller.rb +28 -0
- data/lib/trailblazer/v2_1/rails/railtie/loader.rb +58 -0
- data/lib/trailblazer/v2_1/rails/test/integration.rb +6 -0
- data/lib/trailblazer/v2_1/versions.txt +7 -0
- data/test/rails5.0/.gitignore +17 -0
- data/test/rails5.0/Gemfile +21 -0
- data/test/rails5.0/Rakefile +3 -0
- data/test/rails5.0/app/concepts/artist/cell/dashboard.rb +7 -0
- data/test/rails5.0/app/concepts/artist/cell/show.rb +4 -0
- data/test/rails5.0/app/concepts/artist/view/dashboard.erb +4 -0
- data/test/rails5.0/app/concepts/artist/view/show.erb +1 -0
- data/test/rails5.0/app/concepts/params/operation/with_args.rb +5 -0
- data/test/rails5.0/app/concepts/song/contract/form.rb +6 -0
- data/test/rails5.0/app/concepts/song/operation/create.rb +15 -0
- data/test/rails5.0/app/concepts/song/operation/show.rb +3 -0
- data/test/rails5.0/app/concepts/song/operation/update.rb +15 -0
- data/test/rails5.0/app/controllers/application_controller.rb +46 -0
- data/test/rails5.0/app/controllers/args_controller.rb +5 -0
- data/test/rails5.0/app/controllers/artists_controller.rb +24 -0
- data/test/rails5.0/app/controllers/params_controller.rb +11 -0
- data/test/rails5.0/app/controllers/songs_controller.rb +35 -0
- data/test/rails5.0/app/models/artist.rb +2 -0
- data/test/rails5.0/app/models/song.rb +2 -0
- data/test/rails5.0/app/views/args/with_args.html.erb +1 -0
- data/test/rails5.0/app/views/layouts/application.html.erb +2 -0
- data/test/rails5.0/app/views/songs/edit.html.erb +4 -0
- data/test/rails5.0/app/views/songs/new.html.erb +5 -0
- data/test/rails5.0/app/views/songs/new_with_result.html.erb +3 -0
- data/test/rails5.0/app/views/songs/show.html.erb +3 -0
- data/test/rails5.0/bin/bundle +3 -0
- data/test/rails5.0/bin/rails +4 -0
- data/test/rails5.0/bin/rake +4 -0
- data/test/rails5.0/bin/setup +29 -0
- data/test/rails5.0/config.ru +4 -0
- data/test/rails5.0/config/application.rb +25 -0
- data/test/rails5.0/config/boot.rb +3 -0
- data/test/rails5.0/config/database.yml +21 -0
- data/test/rails5.0/config/environment.rb +5 -0
- data/test/rails5.0/config/environments/development.rb +41 -0
- data/test/rails5.0/config/environments/test.rb +42 -0
- data/test/rails5.0/config/initializers/assets.rb +11 -0
- data/test/rails5.0/config/initializers/backtrace_silencers.rb +7 -0
- data/test/rails5.0/config/initializers/cookies_serializer.rb +3 -0
- data/test/rails5.0/config/initializers/filter_parameter_logging.rb +4 -0
- data/test/rails5.0/config/initializers/inflections.rb +16 -0
- data/test/rails5.0/config/initializers/mime_types.rb +4 -0
- data/test/rails5.0/config/initializers/session_store.rb +3 -0
- data/test/rails5.0/config/initializers/wrap_parameters.rb +14 -0
- data/test/rails5.0/config/locales/en.yml +23 -0
- data/test/rails5.0/config/routes.rb +15 -0
- data/test/rails5.0/config/secrets.yml +17 -0
- data/test/rails5.0/db/migrate/20161122145124_create_songs.rb +8 -0
- data/test/rails5.0/db/schema.rb +19 -0
- data/test/rails5.0/log/.keep +0 -0
- data/test/rails5.0/test/concepts/song/operation/create_test.rb +11 -0
- data/test/rails5.0/test/concepts/song/operation/update_test.rb +34 -0
- data/test/rails5.0/test/integration/.keep +0 -0
- data/test/rails5.0/test/integration/args_controller_test.rb +8 -0
- data/test/rails5.0/test/integration/artists_controller_test.rb +28 -0
- data/test/rails5.0/test/integration/params_controller_test.rb +8 -0
- data/test/rails5.0/test/integration/songs_controller_test.rb +40 -0
- data/test/rails5.0/test/test_helper.rb +7 -0
- data/test/test_helper.rb +5 -0
- data/trailblazer-future.gemspec +25 -0
- metadata +246 -0
@@ -0,0 +1,101 @@
|
|
1
|
+
module Trailblazer::V2_1
|
2
|
+
module Activity::Magnetic
|
3
|
+
|
4
|
+
# TODO: move?
|
5
|
+
module Options
|
6
|
+
# Produce two hashes, one "local" options with DSL-specific options such as `:fast_track`,
|
7
|
+
# one with generic DSL options, for example tuples like `Right=>Output(:failure)`.
|
8
|
+
def self.normalize(options, local_keys)
|
9
|
+
local, foreign = {}, {}
|
10
|
+
options.each { |k,v| local_keys.include?(k) ? local[k] = v : foreign[k] = v }
|
11
|
+
|
12
|
+
return foreign, local
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# Called from Path/Railway/FastTrack, creates the specific {Builder} instance.
|
17
|
+
def self.Builder(implementation, normalizer, builder_options={})
|
18
|
+
builder = implementation.new(normalizer, builder_options.freeze).freeze # e.g. Path.new(...)
|
19
|
+
|
20
|
+
return builder, implementation.InitialAdds(builder_options)
|
21
|
+
end
|
22
|
+
|
23
|
+
class Builder
|
24
|
+
def initialize(normalizer, builder_options)
|
25
|
+
@normalizer, @builder_options = normalizer, builder_options
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.merge(activity_adds, merged_adds)
|
29
|
+
merged_adds = merged_adds[2..-1] || []
|
30
|
+
|
31
|
+
activity_adds + merged_adds
|
32
|
+
end
|
33
|
+
|
34
|
+
# DSL method to create a Path within an activity which is embedded.
|
35
|
+
#
|
36
|
+
# Output(:success) => Path() {}
|
37
|
+
def Path(*args)
|
38
|
+
Activity::DSL.Path(@normalizer, *args)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Public top-level entry point.
|
42
|
+
def insert(strategy, polarizer, task, options, &block)
|
43
|
+
normalizer = options[:normalizer] || @normalizer # DISCUSS: do this at a deeper point?
|
44
|
+
|
45
|
+
task, local_options, connection_options, sequence_options, extension_options = normalizer.(task, options)
|
46
|
+
|
47
|
+
polarizations = strategy.send(polarizer, @builder_options) # Railway.StepPolarizations( @builder_options )
|
48
|
+
|
49
|
+
insert_element( polarizations, task, local_options, connection_options, sequence_options, extension_options, &block )
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
# Internal top-level entry point to add task(s) and connections.
|
55
|
+
# High level interface for DSL calls like ::task or ::step.
|
56
|
+
def insert_element(polarizations, task, local_options, connection_options, sequence_options, extension_options, &block)
|
57
|
+
adds, *returned_options = Builder.adds_for(polarizations, task, local_options, connection_options, sequence_options, extension_options, &block)
|
58
|
+
end
|
59
|
+
|
60
|
+
# @return Adds
|
61
|
+
def self.adds_for(polarizations, task, local_options, connection_options, sequence_options, extension_options, &block)
|
62
|
+
# go through all wiring options such as Output()=>:color.
|
63
|
+
polarizations_from_user_options, additional_adds = process_dsl_options(connection_options, local_options, &block)
|
64
|
+
|
65
|
+
polarizations = polarizations + polarizations_from_user_options
|
66
|
+
|
67
|
+
result = adds(task, polarizations, local_options, sequence_options, local_options)
|
68
|
+
|
69
|
+
return result + (local_options[:adds] || []) + additional_adds, task, local_options, connection_options, sequence_options, extension_options
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.process_dsl_options(options, id:nil, plus_poles:, **, &block)
|
73
|
+
DSL::ProcessOptions.(id, options, plus_poles, &block)
|
74
|
+
end
|
75
|
+
|
76
|
+
# Low-level interface for DSL calls (e.g. Start, where "you know what you're doing")
|
77
|
+
# @private
|
78
|
+
def self.adds(task, polarizations, options, sequence_options, magnetic_to:nil, id:nil, plus_poles:, **) # DISCUSS: no :id ?
|
79
|
+
magnetic_to, plus_poles = PlusPoles.apply_polarizations(
|
80
|
+
polarizations,
|
81
|
+
magnetic_to,
|
82
|
+
plus_poles,
|
83
|
+
options
|
84
|
+
)
|
85
|
+
|
86
|
+
Add( id, task, magnetic_to, plus_poles,
|
87
|
+
options, #{ fast_track: true },
|
88
|
+
sequence_options #{ group: :main }
|
89
|
+
)
|
90
|
+
end
|
91
|
+
|
92
|
+
def self.Add(id, task, magnetic_to, plus_poles, options, sequence_options)
|
93
|
+
[
|
94
|
+
[ :add, [id, [ magnetic_to, task, plus_poles ], sequence_options] ],
|
95
|
+
]
|
96
|
+
end
|
97
|
+
end # Builder
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Trailblazer::V2_1
|
2
|
+
module Activity::Magnetic
|
3
|
+
# This normalizer only processes basic input and is meant for bootstrapping.
|
4
|
+
#
|
5
|
+
# task Callable, id: "success", before: "another"
|
6
|
+
class DefaultNormalizer
|
7
|
+
# Declarative::Variables
|
8
|
+
def self.build(plus_poles:, **options)
|
9
|
+
return new(plus_poles: plus_poles), options
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(**default_options)
|
13
|
+
@default_options = default_options
|
14
|
+
end
|
15
|
+
|
16
|
+
# Processes the user arguments from the DSL
|
17
|
+
def call(task, options)
|
18
|
+
local_options = @default_options.merge(options) # here, we merge default :plus_poles.
|
19
|
+
|
20
|
+
local_options, sequence_options = Options.normalize( local_options, Activity::Schema::Dependencies.sequence_keywords )
|
21
|
+
|
22
|
+
return task, local_options, {}, sequence_options, {}
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
# TODO: move me to Operation.
|
2
|
+
module Trailblazer::V2_1
|
3
|
+
module Activity::Magnetic
|
4
|
+
class Builder
|
5
|
+
|
6
|
+
class FastTrack < Builder
|
7
|
+
def self.for(normalizer, builder_options={}) # Build the Builder.
|
8
|
+
Activity::Magnetic::Builder(
|
9
|
+
FastTrack,
|
10
|
+
normalizer,
|
11
|
+
{ track_color: :success, end_semantic: :success, failure_color: :failure }.merge( builder_options )
|
12
|
+
)
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.StepPolarizations(**options)
|
16
|
+
[
|
17
|
+
*Railway.StepPolarizations(options),
|
18
|
+
StepPolarization.new(options)
|
19
|
+
]
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.FailPolarizations(**options)
|
23
|
+
[
|
24
|
+
*Railway.FailPolarizations(options),
|
25
|
+
FailPolarization.new(options)
|
26
|
+
]
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.PassPolarizations(**options)
|
30
|
+
[
|
31
|
+
*Railway.PassPolarizations(options),
|
32
|
+
PassPolarization.new(options)
|
33
|
+
]
|
34
|
+
end
|
35
|
+
|
36
|
+
# pass_fast: true simply means: color my :success Output with :pass_fast color
|
37
|
+
class StepPolarization < Railway::StepPolarization
|
38
|
+
def call(magnetic_to, plus_poles, options)
|
39
|
+
plus_poles = plus_poles.reconnect( :success => :pass_fast ) if options[:pass_fast]
|
40
|
+
plus_poles = plus_poles.reconnect( :failure => :fail_fast ) if options[:fail_fast]
|
41
|
+
|
42
|
+
# add fast track outputs if :fast_track
|
43
|
+
plus_poles = plus_poles.reverse_merge(
|
44
|
+
Activity.Output(Activity::FastTrack::FailFast, :fail_fast) => :fail_fast,
|
45
|
+
Activity.Output(Activity::FastTrack::PassFast, :pass_fast) => :pass_fast
|
46
|
+
) if options[:fast_track]
|
47
|
+
|
48
|
+
[
|
49
|
+
magnetic_to,
|
50
|
+
plus_poles
|
51
|
+
]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
class FailPolarization < Railway::StepPolarization
|
56
|
+
def call(magnetic_to, plus_poles, options)
|
57
|
+
plus_poles = plus_poles.reconnect( :failure => :fail_fast, :success => :fail_fast ) if options[:fail_fast]
|
58
|
+
plus_poles = plus_poles.reverse_merge( Activity.Output(Activity::FastTrack::FailFast, :fail_fast) => :fail_fast, Activity.Output(Activity::FastTrack::PassFast, :pass_fast) => :pass_fast ) if options[:fast_track]
|
59
|
+
|
60
|
+
[
|
61
|
+
magnetic_to,
|
62
|
+
plus_poles
|
63
|
+
]
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
class PassPolarization < Railway::StepPolarization
|
68
|
+
def call(magnetic_to, plus_poles, options)
|
69
|
+
plus_poles = plus_poles.reconnect( :success => :pass_fast, :failure => :pass_fast ) if options[:pass_fast]
|
70
|
+
plus_poles = plus_poles.reverse_merge( Activity.Output(Activity::FastTrack::FailFast, :fail_fast) => :fail_fast, Activity.Output(Activity::FastTrack::PassFast, :pass_fast) => :pass_fast ) if options[:fast_track]
|
71
|
+
|
72
|
+
[
|
73
|
+
magnetic_to,
|
74
|
+
plus_poles
|
75
|
+
]
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def self.default_plus_poles(*args)
|
80
|
+
Railway.default_plus_poles(*args)
|
81
|
+
end
|
82
|
+
|
83
|
+
# Adds the End.fail_fast and End.pass_fast end to the Railway sequence.
|
84
|
+
def self.InitialAdds(pass_fast_end: Activity.End(:pass_fast), fail_fast_end: Activity.End(:fail_fast), **builder_options)
|
85
|
+
path_adds = Railway.InitialAdds(**builder_options)
|
86
|
+
|
87
|
+
ends =
|
88
|
+
adds(
|
89
|
+
pass_fast_end,
|
90
|
+
|
91
|
+
Path::EndEventPolarizations(builder_options),
|
92
|
+
|
93
|
+
{},
|
94
|
+
{ group: :end },
|
95
|
+
|
96
|
+
id: "End.pass_fast",
|
97
|
+
magnetic_to: [:pass_fast],
|
98
|
+
plus_poles: {},
|
99
|
+
)+
|
100
|
+
adds(
|
101
|
+
fail_fast_end,
|
102
|
+
|
103
|
+
Path::EndEventPolarizations(builder_options),
|
104
|
+
|
105
|
+
{},
|
106
|
+
{ group: :end },
|
107
|
+
|
108
|
+
magnetic_to: [:fail_fast],
|
109
|
+
id: "End.fail_fast",
|
110
|
+
plus_poles: {},
|
111
|
+
)
|
112
|
+
|
113
|
+
path_adds + ends
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
module Trailblazer::V2_1
|
2
|
+
module Activity::Magnetic
|
3
|
+
# One {Normalizer} instance is called for every DSL call (step/pass/fail etc.) and normalizes/defaults
|
4
|
+
# the user options, such as setting `:id`, connecting the task's outputs or wrapping the user's
|
5
|
+
# task via {TaskBuilder::Binary} in order to translate true/false to `Right` or `Left`.
|
6
|
+
#
|
7
|
+
# The Normalizer sits in the `@builder`, which receives all DSL calls from the Operation subclass.
|
8
|
+
class Normalizer
|
9
|
+
def self.build(task_builder: Activity::TaskBuilder.method(:Binary), default_outputs: Builder::Path.default_outputs, pipeline: Pipeline, extension:[], **options)
|
10
|
+
return new(
|
11
|
+
default_outputs: default_outputs,
|
12
|
+
extension: extension,
|
13
|
+
task_builder: task_builder,
|
14
|
+
pipeline: pipeline,
|
15
|
+
), options
|
16
|
+
end
|
17
|
+
|
18
|
+
def initialize(task_builder:, default_outputs:, pipeline:, **options)
|
19
|
+
@task_builder = task_builder
|
20
|
+
@default_outputs = default_outputs
|
21
|
+
@pipeline = pipeline # TODO: test me.
|
22
|
+
freeze
|
23
|
+
end
|
24
|
+
|
25
|
+
def call(task, options)
|
26
|
+
ctx = {
|
27
|
+
task: task,
|
28
|
+
options: options,
|
29
|
+
task_builder: @task_builder,
|
30
|
+
default_outputs: @default_outputs,
|
31
|
+
}
|
32
|
+
|
33
|
+
signal, (ctx, ) = @pipeline.( [ctx], {} )
|
34
|
+
|
35
|
+
return ctx[:options][:task], ctx[:local_options], ctx[:connection_options], ctx[:sequence_options], ctx[:extension_options]
|
36
|
+
end
|
37
|
+
|
38
|
+
# needs the basic Normalizer
|
39
|
+
|
40
|
+
# :default_plus_poles is an injectable option.
|
41
|
+
module Pipeline
|
42
|
+
extend Trailblazer::V2_1::Activity::Path( normalizer_class: DefaultNormalizer, plus_poles: PlusPoles.new.merge( Builder::Path.default_outputs.values ) ) # FIXME: the DefaultNormalizer actually doesn't need Left.
|
43
|
+
|
44
|
+
def self.split_options( ctx, task:, options:, ** )
|
45
|
+
keywords = extract_dsl_keywords(options)
|
46
|
+
extensions = extract_extensions(options)
|
47
|
+
|
48
|
+
# sort through the "original" user DSL options.
|
49
|
+
options, extension_options = Options.normalize( options, extensions ) # DISCUSS:
|
50
|
+
options, local_options = Options.normalize( options, keywords ) # DISCUSS:
|
51
|
+
local_options, sequence_options = Options.normalize( local_options, Activity::Schema::Dependencies.sequence_keywords )
|
52
|
+
|
53
|
+
ctx[:local_options],
|
54
|
+
ctx[:connection_options],
|
55
|
+
ctx[:sequence_options],
|
56
|
+
ctx[:extension_options] = local_options, options, sequence_options, extension_options
|
57
|
+
end
|
58
|
+
|
59
|
+
# Filter out connections, e.g. `Output(:fail_fast) => :success` and return only the keywords like `:id` or `:replace`.
|
60
|
+
def self.extract_dsl_keywords(options, connection_classes = [Activity::Output, Activity::DSL::OutputSemantic])
|
61
|
+
options.keys - options.keys.find_all { |k| connection_classes.include?( k.class ) }
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.extract_extensions(options, extensions_classes = [Activity::DSL::Extension])
|
65
|
+
options.keys.find_all { |k| extensions_classes.include?( k.class ) }
|
66
|
+
end
|
67
|
+
|
68
|
+
# FIXME; why don't we use the extensions passed into the initializer?
|
69
|
+
def self.initialize_extension_option( ctx, options:, ** )
|
70
|
+
ctx[:options] = options.merge( Activity::DSL::Extension.new( Activity::DSL.method(:record) ) => true )
|
71
|
+
end
|
72
|
+
|
73
|
+
# Normalizes ctx[:options] (the user-options via the DSL) into the internal Hash format.
|
74
|
+
def self.normalize_for_macro( ctx, task:, options:, task_builder:, ** )
|
75
|
+
ctx[:options] =
|
76
|
+
if task.is_a?(::Hash) # macro.
|
77
|
+
task.merge(options) # Note that the user options are merged over the macro options.
|
78
|
+
else # user step
|
79
|
+
{ id: task }
|
80
|
+
.merge(options) # default :id
|
81
|
+
.merge( task: task_builder.(task) )
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# :outputs passed: I know what I want to have connected.
|
86
|
+
# no :outputs: use default_outputs
|
87
|
+
# ALWAYS connect all outputs to their semantic-color.
|
88
|
+
|
89
|
+
# Create the `plus_poles: <PlusPoles>` tuple where the PlusPoles instance will act as the interface
|
90
|
+
# to rewire or add connections for the DSL.
|
91
|
+
def self.initialize_plus_poles( ctx, local_options:, default_outputs:, ** )
|
92
|
+
outputs = local_options[:outputs] || default_outputs
|
93
|
+
|
94
|
+
ctx[:local_options] =
|
95
|
+
{
|
96
|
+
plus_poles: PlusPoles.initial(outputs),
|
97
|
+
}
|
98
|
+
.merge(local_options)
|
99
|
+
end
|
100
|
+
|
101
|
+
task Activity::TaskBuilder::Binary( method(:initialize_extension_option) ), id: "initialize_extension_option"
|
102
|
+
task Activity::TaskBuilder::Binary( method(:normalize_for_macro) ), id: "normalize_for_macro"
|
103
|
+
|
104
|
+
task Activity::TaskBuilder::Binary( Activity::TaskWrap::VariableMapping.method(:normalizer_step_for_input_output) )
|
105
|
+
|
106
|
+
task Activity::TaskBuilder::Binary( method(:split_options) ), id: "split_options"
|
107
|
+
task Activity::TaskBuilder::Binary( method(:initialize_plus_poles) ), id: "initialize_plus_poles"
|
108
|
+
# task ->((ctx, _), **) { pp ctx; [Activity::Right, [ctx, _]] }
|
109
|
+
end
|
110
|
+
end # Normalizer
|
111
|
+
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
module Trailblazer::V2_1
|
2
|
+
module Activity::Magnetic
|
3
|
+
class Builder
|
4
|
+
|
5
|
+
class Path < Builder
|
6
|
+
# strategy_options:
|
7
|
+
# :track_color
|
8
|
+
# :end_semantic
|
9
|
+
def self.for(normalizer, builder_options={}) # Build the Builder.
|
10
|
+
Activity::Magnetic::Builder(
|
11
|
+
Path,
|
12
|
+
normalizer,
|
13
|
+
{ track_color: :success, end_semantic: :success }.merge( builder_options )
|
14
|
+
)
|
15
|
+
end
|
16
|
+
|
17
|
+
# In most cases, a task has a binary signal, which is why we decided to make that
|
18
|
+
# the default output set.
|
19
|
+
def self.default_outputs
|
20
|
+
{
|
21
|
+
:success => Activity.Output(Activity::Right, :success),
|
22
|
+
:failure => Activity.Output(Activity::Left, :failure)
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
# @return [Adds] list of Adds instances that can be chained or added to an existing sequence.
|
27
|
+
def self.InitialAdds(**options)
|
28
|
+
StartAdds(**options) + EndAdds(**options)
|
29
|
+
end
|
30
|
+
|
31
|
+
# TODO: make this nicer.
|
32
|
+
def self.StartAdds(track_color:, end_semantic:, start_outputs: {success: self.default_outputs[:success]}, **)
|
33
|
+
builder_options={ track_color: track_color, end_semantic: end_semantic }
|
34
|
+
|
35
|
+
adds(
|
36
|
+
Activity::Start.new(semantic: :default),
|
37
|
+
|
38
|
+
TaskPolarizations(builder_options),
|
39
|
+
|
40
|
+
{}, { group: :start },
|
41
|
+
|
42
|
+
id: "Start.default",
|
43
|
+
magnetic_to: [],
|
44
|
+
plus_poles: PlusPoles.initial(start_outputs), # FIXME: this is actually redundant with Normalizer
|
45
|
+
)
|
46
|
+
end
|
47
|
+
|
48
|
+
# TODO: make this nicer.
|
49
|
+
def self.EndAdds(track_color:, end_semantic:, track_end: Activity.End(end_semantic), end_id: nil, **)
|
50
|
+
# an end can either be a reference to another task,
|
51
|
+
# or a "real" end event.
|
52
|
+
if end_id
|
53
|
+
[[:magnetic_to,
|
54
|
+
[ end_id, [track_color] ] ]
|
55
|
+
]
|
56
|
+
else
|
57
|
+
builder_options={ track_color: track_color, end_semantic: end_semantic }
|
58
|
+
|
59
|
+
adds(
|
60
|
+
track_end,
|
61
|
+
|
62
|
+
EndEventPolarizations(builder_options), # only sets :magnetic_to.
|
63
|
+
|
64
|
+
{}, { group: :end },
|
65
|
+
|
66
|
+
id: "End.#{track_color}",
|
67
|
+
plus_poles: {},
|
68
|
+
magnetic_to: nil,
|
69
|
+
)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def self.TaskPolarizations(track_color:, **)
|
74
|
+
[TaskPolarization.new( track_color: track_color )]
|
75
|
+
end
|
76
|
+
|
77
|
+
def self.EndEventPolarizations(track_color:, **)
|
78
|
+
[EndEventPolarization.new( track_color: track_color )]
|
79
|
+
end
|
80
|
+
|
81
|
+
class TaskPolarization
|
82
|
+
def initialize(track_color:)
|
83
|
+
@track_color = track_color
|
84
|
+
end
|
85
|
+
|
86
|
+
def call(magnetic_to, plus_poles, options)
|
87
|
+
[
|
88
|
+
magnetic_to || [@track_color],
|
89
|
+
plus_poles.reconnect( :success => @track_color )
|
90
|
+
]
|
91
|
+
end
|
92
|
+
end # TaskPolarization
|
93
|
+
|
94
|
+
class EndEventPolarization < TaskPolarization
|
95
|
+
def call(magnetic_to, plus_poles, options)
|
96
|
+
[
|
97
|
+
magnetic_to || [@track_color],
|
98
|
+
{}
|
99
|
+
]
|
100
|
+
end
|
101
|
+
end # EndEventPolarization
|
102
|
+
end # Path
|
103
|
+
end # Builder
|
104
|
+
end
|
105
|
+
end
|