flows 0.4.0 → 0.5.0
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/.mdlrc +1 -1
- data/.reek.yml +12 -0
- data/CHANGELOG.md +16 -0
- data/Gemfile.lock +1 -1
- data/README.md +12 -2
- data/Rakefile +1 -1
- data/bin/all_the_errors +8 -0
- data/bin/errors +12 -0
- data/bin/errors_cli/flow_error_demo.rb +22 -0
- data/docs/README.md +1 -1
- data/lib/flows/contract/case_eq.rb +3 -1
- data/lib/flows/flow/errors.rb +29 -0
- data/lib/flows/flow/node.rb +1 -0
- data/lib/flows/flow/router/custom.rb +5 -0
- data/lib/flows/flow/router/simple.rb +5 -0
- data/lib/flows/flow/router.rb +4 -0
- data/lib/flows/flow.rb +21 -0
- data/lib/flows/plugin/dependency_injector.rb +5 -5
- data/lib/flows/plugin/output_contract/dsl.rb +15 -3
- data/lib/flows/plugin/output_contract/wrapper.rb +14 -12
- data/lib/flows/plugin/output_contract.rb +1 -0
- data/lib/flows/plugin/profiler/injector.rb +35 -0
- data/lib/flows/plugin/profiler/report/events.rb +43 -0
- data/lib/flows/plugin/profiler/report/flat/method_report.rb +81 -0
- data/lib/flows/plugin/profiler/report/flat.rb +41 -0
- data/lib/flows/plugin/profiler/report/raw.rb +15 -0
- data/lib/flows/plugin/profiler/report/tree/calculated_node.rb +116 -0
- data/lib/flows/plugin/profiler/report/tree/node.rb +35 -0
- data/lib/flows/plugin/profiler/report/tree.rb +98 -0
- data/lib/flows/plugin/profiler/report.rb +48 -0
- data/lib/flows/plugin/profiler/wrapper.rb +53 -0
- data/lib/flows/plugin/profiler.rb +114 -0
- data/lib/flows/plugin.rb +1 -0
- data/lib/flows/railway/dsl.rb +3 -2
- data/lib/flows/result/do.rb +6 -8
- data/lib/flows/shared_context_pipeline/dsl/callbacks.rb +38 -0
- data/lib/flows/shared_context_pipeline/dsl/tracks.rb +52 -0
- data/lib/flows/shared_context_pipeline/dsl.rb +5 -56
- data/lib/flows/shared_context_pipeline/mutation_step.rb +6 -8
- data/lib/flows/shared_context_pipeline/step.rb +6 -8
- data/lib/flows/shared_context_pipeline/track.rb +2 -15
- data/lib/flows/shared_context_pipeline/track_list.rb +11 -6
- data/lib/flows/shared_context_pipeline/wrap.rb +64 -0
- data/lib/flows/shared_context_pipeline.rb +109 -26
- data/lib/flows/util/inheritable_singleton_vars/dup_strategy.rb +40 -51
- data/lib/flows/util/inheritable_singleton_vars/isolation_strategy.rb +39 -52
- data/lib/flows/util/inheritable_singleton_vars.rb +22 -15
- data/lib/flows/util/prepend_to_class.rb +43 -9
- data/lib/flows/version.rb +1 -1
- metadata +18 -2
@@ -16,25 +16,38 @@ module Flows
|
|
16
16
|
VAR_MAP_VAR_NAME = :@inheritable_vars_with_isolation
|
17
17
|
|
18
18
|
# @api private
|
19
|
-
module
|
20
|
-
def
|
21
|
-
|
19
|
+
module Migrator
|
20
|
+
def self.call(from, to)
|
21
|
+
parent_var_map = from.instance_variable_get(VAR_MAP_VAR_NAME)
|
22
|
+
child_var_map = to.instance_variable_get(VAR_MAP_VAR_NAME) || {}
|
22
23
|
|
23
|
-
|
24
|
-
end
|
24
|
+
to.instance_variable_set(VAR_MAP_VAR_NAME, child_var_map.merge(parent_var_map))
|
25
25
|
|
26
|
-
|
27
|
-
|
26
|
+
parent_var_map.each do |name, value_proc|
|
27
|
+
to.instance_variable_set(name, value_proc.call)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
28
31
|
|
29
|
-
|
32
|
+
# @api private
|
33
|
+
module Injector
|
34
|
+
def included(mod)
|
35
|
+
Migrator.call(self, mod)
|
36
|
+
mod.singleton_class.prepend Injector
|
30
37
|
|
31
38
|
super
|
32
39
|
end
|
33
40
|
|
34
|
-
def extended(
|
35
|
-
|
41
|
+
def extended(mod)
|
42
|
+
Migrator.call(self, mod)
|
43
|
+
mod.singleton_class.prepend Injector
|
44
|
+
|
45
|
+
super
|
46
|
+
end
|
36
47
|
|
37
|
-
|
48
|
+
def inherited(mod)
|
49
|
+
Migrator.call(self, mod)
|
50
|
+
mod.singleton_class.prepend Injector
|
38
51
|
|
39
52
|
super
|
40
53
|
end
|
@@ -43,60 +56,34 @@ module Flows
|
|
43
56
|
class << self
|
44
57
|
# Applies behaviour and defaults for singleton variables.
|
45
58
|
#
|
46
|
-
# @note Variable names should look like `:@var` or `'@var'`.
|
47
|
-
#
|
48
|
-
# @param klass [Class] target class.
|
49
|
-
# @param attrs_with_default [Hash<Symbol, String => Proc>] keys are variable names,
|
50
|
-
# values are procs or lambdas which return default values.
|
51
|
-
#
|
52
59
|
# @example
|
53
60
|
# class MyClass
|
54
|
-
# Flows::Util::InheritableSingletonVars::IsolationStrategy.
|
55
|
-
# self,
|
61
|
+
# SingletonVarsSetup = Flows::Util::InheritableSingletonVars::IsolationStrategy.make_module(
|
56
62
|
# :@my_list => -> { [] }
|
57
63
|
# )
|
64
|
+
#
|
65
|
+
# include SingletonVarsSetup
|
58
66
|
# end
|
59
|
-
def call(klass, attrs_with_default = {})
|
60
|
-
init_variables_with_default_values(klass, attrs_with_default)
|
61
|
-
|
62
|
-
var_defaults = attrs_with_default
|
63
|
-
add_variables_to_store(klass, var_defaults)
|
64
|
-
|
65
|
-
inject_inheritance_hook(klass)
|
66
|
-
end
|
67
|
-
|
68
|
-
# Moves variables between modules
|
69
67
|
#
|
70
|
-
# @
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
68
|
+
# @note Variable names should look like `:@var` or `'@var'`.
|
69
|
+
#
|
70
|
+
# @param vars_with_default [Hash<Symbol, String => Proc>] keys are variable names,
|
71
|
+
# values are procs or lambdas which return default values.
|
72
|
+
def make_module(vars_with_default = {})
|
73
|
+
Module.new.tap do |mod|
|
74
|
+
mod.instance_variable_set(VAR_MAP_VAR_NAME, vars_with_default.dup)
|
75
|
+
init_vars(mod, vars_with_default)
|
76
|
+
mod.extend Injector
|
78
77
|
end
|
79
78
|
end
|
80
79
|
|
81
80
|
private
|
82
81
|
|
83
|
-
def
|
84
|
-
|
85
|
-
|
82
|
+
def init_vars(mod, vars_with_default)
|
83
|
+
vars_with_default.each do |name, value_proc|
|
84
|
+
mod.instance_variable_set(name, value_proc.call)
|
86
85
|
end
|
87
86
|
end
|
88
|
-
|
89
|
-
def add_variables_to_store(klass, var_defaults)
|
90
|
-
store = klass.instance_variable_get(VAR_MAP_VAR_NAME) || {}
|
91
|
-
next_store = store.merge(var_defaults)
|
92
|
-
|
93
|
-
klass.instance_variable_set(VAR_MAP_VAR_NAME, next_store)
|
94
|
-
end
|
95
|
-
|
96
|
-
def inject_inheritance_hook(klass)
|
97
|
-
singleton = klass.singleton_class
|
98
|
-
singleton.prepend(InheritanceCallback) unless singleton.is_a?(InheritanceCallback)
|
99
|
-
end
|
100
87
|
end
|
101
88
|
end
|
102
89
|
end
|
@@ -41,30 +41,37 @@ module Flows
|
|
41
41
|
# Each strategy here is using following way of injecting into yours abstract classes:
|
42
42
|
#
|
43
43
|
# class BaseSomething
|
44
|
-
# Flows::Util::InheritableSingletonVars::SomeStrategy.
|
45
|
-
#
|
46
|
-
# **rest_of_the_options_here
|
44
|
+
# SingletonVarsSetup = Flows::Util::InheritableSingletonVars::SomeStrategy.make_module(
|
45
|
+
# **options_here
|
47
46
|
# )
|
47
|
+
#
|
48
|
+
# include SingeltonVarsSetup # extend also will work
|
48
49
|
# end
|
49
50
|
#
|
50
51
|
# In case of extensions and mixins:
|
51
52
|
#
|
52
53
|
# module MyExtension
|
53
|
-
#
|
54
|
-
#
|
55
|
-
#
|
56
|
-
#
|
57
|
-
#
|
58
|
-
#
|
54
|
+
# SingletonVarsSetup = Flows::Util::InheritableSingletonVars::SomeStrategy.make_module(
|
55
|
+
# **options_here
|
56
|
+
# )
|
57
|
+
#
|
58
|
+
# include SingeltonVarsSetup # extend also will work
|
59
|
+
# end
|
60
|
+
#
|
61
|
+
# class SomethingA
|
62
|
+
# extend MyExtension
|
59
63
|
# end
|
60
64
|
#
|
61
65
|
# module MyMixin
|
62
|
-
#
|
63
|
-
#
|
64
|
-
#
|
65
|
-
#
|
66
|
-
#
|
67
|
-
#
|
66
|
+
# SingletonVarsSetup = Flows::Util::InheritableSingletonVars::SomeStrategy.make_module(
|
67
|
+
# **options_here
|
68
|
+
# )
|
69
|
+
#
|
70
|
+
# include SingeltonVarsSetup # extend also will work
|
71
|
+
# end
|
72
|
+
#
|
73
|
+
# class SomethingB
|
74
|
+
# include MyMixin
|
68
75
|
# end
|
69
76
|
#
|
70
77
|
# Moreover, you can use multiple strategies in the same class.
|
@@ -78,7 +78,7 @@ module Flows
|
|
78
78
|
# module HasData
|
79
79
|
# attr_reader :data
|
80
80
|
#
|
81
|
-
#
|
81
|
+
# InitializePatch = Flows::Util::PrependToClass.make_module do
|
82
82
|
# def initialize(*args, **kwargs, &block)
|
83
83
|
# @data = kwargs[:data]
|
84
84
|
#
|
@@ -92,7 +92,7 @@ module Flows
|
|
92
92
|
# end
|
93
93
|
# end
|
94
94
|
#
|
95
|
-
#
|
95
|
+
# include InitializePatch
|
96
96
|
# end
|
97
97
|
#
|
98
98
|
# module Stuff
|
@@ -113,20 +113,54 @@ module Flows
|
|
113
113
|
#
|
114
114
|
# x.data
|
115
115
|
# # => 'data'
|
116
|
+
#
|
117
|
+
# x.greeting
|
118
|
+
# # => 'hello'
|
119
|
+
#
|
120
|
+
# @note this solution is designed to patch `include` behaviour and
|
121
|
+
# has no effect on `extend`.
|
116
122
|
module PrependToClass
|
117
123
|
class << self
|
118
|
-
#
|
119
|
-
#
|
124
|
+
# Allows to prepend some module to class when
|
125
|
+
# host module included into class.
|
126
|
+
#
|
127
|
+
# Under the hood two modules are created:
|
128
|
+
#
|
129
|
+
# * "to prepend" module made from provided block
|
130
|
+
# * "container" module which will be returned by this method
|
131
|
+
#
|
132
|
+
# When you include "container" module into your module `Mod`
|
133
|
+
# you're enabling the following behaviour:
|
134
|
+
#
|
135
|
+
# * when `Mod` included into class - "to prepend" module will be prepended to class
|
136
|
+
# * when `Mod` is included into some module `Mod2` - `Mod2` also will
|
137
|
+
# prepend "to prepend" module when included into class.
|
138
|
+
# * you can include `Mod` into `Mod2`, then include `Mod2` into `Mod3` -
|
139
|
+
# desribed behavior works for include chain of any length.
|
120
140
|
#
|
121
|
-
#
|
122
|
-
#
|
123
|
-
|
124
|
-
|
141
|
+
# Moreover, this behaviour also works with `extend`, not only `include`.
|
142
|
+
#
|
143
|
+
# @yield body for module which will be prepended
|
144
|
+
# @return [Module] module to be included or extended into your module
|
145
|
+
def make_module(&module_body)
|
146
|
+
Module.new.tap do |mod|
|
147
|
+
to_prepend_mod = Module.new(&module_body)
|
148
|
+
mod.const_set(:ToPrepend, to_prepend_mod)
|
149
|
+
|
150
|
+
set_injector_mod(mod, to_prepend_mod)
|
151
|
+
end
|
125
152
|
end
|
126
153
|
|
127
154
|
private
|
128
155
|
|
129
|
-
def
|
156
|
+
def set_injector_mod(mod, module_to_prepend)
|
157
|
+
injector = make_injector_mod(module_to_prepend)
|
158
|
+
|
159
|
+
mod.const_set(:Injector, injector)
|
160
|
+
mod.singleton_class.prepend(injector)
|
161
|
+
end
|
162
|
+
|
163
|
+
def make_injector_mod(module_to_prepend)
|
130
164
|
Module.new.tap do |injector|
|
131
165
|
injector.define_method(:included) do |target_mod|
|
132
166
|
if target_mod.class == Class
|
data/lib/flows/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: flows
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Roman Kolesnev
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-05-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -433,6 +433,7 @@ files:
|
|
433
433
|
- bin/errors
|
434
434
|
- bin/errors_cli/contract_error_demo.rb
|
435
435
|
- bin/errors_cli/di_error_demo.rb
|
436
|
+
- bin/errors_cli/flow_error_demo.rb
|
436
437
|
- bin/errors_cli/flows_router_error_demo.rb
|
437
438
|
- bin/errors_cli/oc_error_demo.rb
|
438
439
|
- bin/errors_cli/railway_error_demo.rb
|
@@ -460,6 +461,7 @@ files:
|
|
460
461
|
- lib/flows/contract/transformer.rb
|
461
462
|
- lib/flows/contract/tuple.rb
|
462
463
|
- lib/flows/flow.rb
|
464
|
+
- lib/flows/flow/errors.rb
|
463
465
|
- lib/flows/flow/node.rb
|
464
466
|
- lib/flows/flow/router.rb
|
465
467
|
- lib/flows/flow/router/custom.rb
|
@@ -476,6 +478,17 @@ files:
|
|
476
478
|
- lib/flows/plugin/output_contract/dsl.rb
|
477
479
|
- lib/flows/plugin/output_contract/errors.rb
|
478
480
|
- lib/flows/plugin/output_contract/wrapper.rb
|
481
|
+
- lib/flows/plugin/profiler.rb
|
482
|
+
- lib/flows/plugin/profiler/injector.rb
|
483
|
+
- lib/flows/plugin/profiler/report.rb
|
484
|
+
- lib/flows/plugin/profiler/report/events.rb
|
485
|
+
- lib/flows/plugin/profiler/report/flat.rb
|
486
|
+
- lib/flows/plugin/profiler/report/flat/method_report.rb
|
487
|
+
- lib/flows/plugin/profiler/report/raw.rb
|
488
|
+
- lib/flows/plugin/profiler/report/tree.rb
|
489
|
+
- lib/flows/plugin/profiler/report/tree/calculated_node.rb
|
490
|
+
- lib/flows/plugin/profiler/report/tree/node.rb
|
491
|
+
- lib/flows/plugin/profiler/wrapper.rb
|
479
492
|
- lib/flows/railway.rb
|
480
493
|
- lib/flows/railway/dsl.rb
|
481
494
|
- lib/flows/railway/errors.rb
|
@@ -489,12 +502,15 @@ files:
|
|
489
502
|
- lib/flows/result/ok.rb
|
490
503
|
- lib/flows/shared_context_pipeline.rb
|
491
504
|
- lib/flows/shared_context_pipeline/dsl.rb
|
505
|
+
- lib/flows/shared_context_pipeline/dsl/callbacks.rb
|
506
|
+
- lib/flows/shared_context_pipeline/dsl/tracks.rb
|
492
507
|
- lib/flows/shared_context_pipeline/errors.rb
|
493
508
|
- lib/flows/shared_context_pipeline/mutation_step.rb
|
494
509
|
- lib/flows/shared_context_pipeline/router_definition.rb
|
495
510
|
- lib/flows/shared_context_pipeline/step.rb
|
496
511
|
- lib/flows/shared_context_pipeline/track.rb
|
497
512
|
- lib/flows/shared_context_pipeline/track_list.rb
|
513
|
+
- lib/flows/shared_context_pipeline/wrap.rb
|
498
514
|
- lib/flows/util.rb
|
499
515
|
- lib/flows/util/inheritable_singleton_vars.rb
|
500
516
|
- lib/flows/util/inheritable_singleton_vars/dup_strategy.rb
|