flows 0.1.0 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (147) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yml +38 -0
  3. data/.gitignore +9 -1
  4. data/.mdlrc +1 -0
  5. data/.reek.yml +54 -0
  6. data/.rubocop.yml +44 -2
  7. data/.ruby-version +1 -1
  8. data/.yardopts +1 -0
  9. data/CHANGELOG.md +65 -0
  10. data/README.md +186 -256
  11. data/Rakefile +35 -1
  12. data/bin/.rubocop.yml +5 -0
  13. data/bin/all_the_errors +55 -0
  14. data/bin/benchmark +69 -78
  15. data/bin/benchmark_cli/compare.rb +118 -0
  16. data/bin/benchmark_cli/compare/a_plus_b.rb +22 -0
  17. data/bin/benchmark_cli/compare/base.rb +45 -0
  18. data/bin/benchmark_cli/compare/command.rb +47 -0
  19. data/bin/benchmark_cli/compare/ten_steps.rb +22 -0
  20. data/bin/benchmark_cli/examples.rb +23 -0
  21. data/bin/benchmark_cli/examples/.rubocop.yml +19 -0
  22. data/bin/benchmark_cli/examples/a_plus_b/dry_do.rb +23 -0
  23. data/bin/benchmark_cli/examples/a_plus_b/dry_transaction.rb +17 -0
  24. data/bin/benchmark_cli/examples/a_plus_b/flows_do.rb +22 -0
  25. data/bin/benchmark_cli/examples/a_plus_b/flows_railway.rb +13 -0
  26. data/bin/benchmark_cli/examples/a_plus_b/flows_scp.rb +13 -0
  27. data/bin/benchmark_cli/examples/a_plus_b/flows_scp_mut.rb +13 -0
  28. data/bin/benchmark_cli/examples/a_plus_b/flows_scp_oc.rb +21 -0
  29. data/bin/benchmark_cli/examples/a_plus_b/trailblazer.rb +15 -0
  30. data/bin/benchmark_cli/examples/ten_steps/dry_do.rb +70 -0
  31. data/bin/benchmark_cli/examples/ten_steps/dry_transaction.rb +64 -0
  32. data/bin/benchmark_cli/examples/ten_steps/flows_do.rb +69 -0
  33. data/bin/benchmark_cli/examples/ten_steps/flows_railway.rb +58 -0
  34. data/bin/benchmark_cli/examples/ten_steps/flows_scp.rb +58 -0
  35. data/bin/benchmark_cli/examples/ten_steps/flows_scp_mut.rb +58 -0
  36. data/bin/benchmark_cli/examples/ten_steps/flows_scp_oc.rb +66 -0
  37. data/bin/benchmark_cli/examples/ten_steps/trailblazer.rb +60 -0
  38. data/bin/benchmark_cli/helpers.rb +12 -0
  39. data/bin/benchmark_cli/ruby.rb +15 -0
  40. data/bin/benchmark_cli/ruby/command.rb +38 -0
  41. data/bin/benchmark_cli/ruby/method_exec.rb +71 -0
  42. data/bin/benchmark_cli/ruby/self_class.rb +69 -0
  43. data/bin/benchmark_cli/ruby/structs.rb +90 -0
  44. data/bin/console +1 -0
  45. data/bin/docserver +7 -0
  46. data/bin/errors +130 -0
  47. data/bin/errors_cli/contract_error_demo.rb +49 -0
  48. data/bin/errors_cli/di_error_demo.rb +38 -0
  49. data/bin/errors_cli/flow_error_demo.rb +22 -0
  50. data/bin/errors_cli/flows_router_error_demo.rb +15 -0
  51. data/bin/errors_cli/oc_error_demo.rb +40 -0
  52. data/bin/errors_cli/railway_error_demo.rb +10 -0
  53. data/bin/errors_cli/result_error_demo.rb +13 -0
  54. data/bin/errors_cli/scp_error_demo.rb +17 -0
  55. data/docs/.nojekyll +0 -0
  56. data/docs/README.md +13 -0
  57. data/docs/_sidebar.md +2 -0
  58. data/docs/index.html +30 -0
  59. data/flows.gemspec +27 -2
  60. data/forspell.dict +17 -0
  61. data/lefthook.yml +21 -0
  62. data/lib/flows.rb +13 -5
  63. data/lib/flows/contract.rb +402 -0
  64. data/lib/flows/contract/array.rb +55 -0
  65. data/lib/flows/contract/case_eq.rb +43 -0
  66. data/lib/flows/contract/compose.rb +77 -0
  67. data/lib/flows/contract/either.rb +53 -0
  68. data/lib/flows/contract/error.rb +25 -0
  69. data/lib/flows/contract/hash.rb +75 -0
  70. data/lib/flows/contract/hash_of.rb +70 -0
  71. data/lib/flows/contract/helpers.rb +22 -0
  72. data/lib/flows/contract/predicate.rb +34 -0
  73. data/lib/flows/contract/transformer.rb +50 -0
  74. data/lib/flows/contract/tuple.rb +70 -0
  75. data/lib/flows/flow.rb +96 -7
  76. data/lib/flows/flow/errors.rb +29 -0
  77. data/lib/flows/flow/node.rb +132 -0
  78. data/lib/flows/flow/router.rb +29 -0
  79. data/lib/flows/flow/router/custom.rb +59 -0
  80. data/lib/flows/flow/router/errors.rb +11 -0
  81. data/lib/flows/flow/router/simple.rb +25 -0
  82. data/lib/flows/plugin.rb +14 -0
  83. data/lib/flows/plugin/dependency_injector.rb +159 -0
  84. data/lib/flows/plugin/dependency_injector/dependency.rb +24 -0
  85. data/lib/flows/plugin/dependency_injector/dependency_definition.rb +16 -0
  86. data/lib/flows/plugin/dependency_injector/dependency_list.rb +57 -0
  87. data/lib/flows/plugin/dependency_injector/errors.rb +58 -0
  88. data/lib/flows/plugin/implicit_init.rb +45 -0
  89. data/lib/flows/plugin/output_contract.rb +85 -0
  90. data/lib/flows/plugin/output_contract/dsl.rb +48 -0
  91. data/lib/flows/plugin/output_contract/errors.rb +74 -0
  92. data/lib/flows/plugin/output_contract/wrapper.rb +55 -0
  93. data/lib/flows/plugin/profiler.rb +114 -0
  94. data/lib/flows/plugin/profiler/injector.rb +35 -0
  95. data/lib/flows/plugin/profiler/report.rb +48 -0
  96. data/lib/flows/plugin/profiler/report/events.rb +43 -0
  97. data/lib/flows/plugin/profiler/report/flat.rb +41 -0
  98. data/lib/flows/plugin/profiler/report/flat/method_report.rb +81 -0
  99. data/lib/flows/plugin/profiler/report/raw.rb +15 -0
  100. data/lib/flows/plugin/profiler/report/tree.rb +98 -0
  101. data/lib/flows/plugin/profiler/report/tree/calculated_node.rb +116 -0
  102. data/lib/flows/plugin/profiler/report/tree/node.rb +35 -0
  103. data/lib/flows/plugin/profiler/wrapper.rb +53 -0
  104. data/lib/flows/railway.rb +154 -0
  105. data/lib/flows/railway/dsl.rb +18 -0
  106. data/lib/flows/railway/errors.rb +17 -0
  107. data/lib/flows/railway/step.rb +24 -0
  108. data/lib/flows/railway/step_list.rb +38 -0
  109. data/lib/flows/result.rb +189 -2
  110. data/lib/flows/result/do.rb +172 -0
  111. data/lib/flows/result/err.rb +12 -6
  112. data/lib/flows/result/errors.rb +29 -17
  113. data/lib/flows/result/helpers.rb +25 -3
  114. data/lib/flows/result/ok.rb +12 -6
  115. data/lib/flows/shared_context_pipeline.rb +299 -0
  116. data/lib/flows/shared_context_pipeline/dsl.rb +12 -0
  117. data/lib/flows/shared_context_pipeline/dsl/callbacks.rb +38 -0
  118. data/lib/flows/shared_context_pipeline/dsl/tracks.rb +52 -0
  119. data/lib/flows/shared_context_pipeline/errors.rb +17 -0
  120. data/lib/flows/shared_context_pipeline/mutation_step.rb +29 -0
  121. data/lib/flows/shared_context_pipeline/router_definition.rb +21 -0
  122. data/lib/flows/shared_context_pipeline/step.rb +44 -0
  123. data/lib/flows/shared_context_pipeline/track.rb +54 -0
  124. data/lib/flows/shared_context_pipeline/track_list.rb +51 -0
  125. data/lib/flows/shared_context_pipeline/wrap.rb +74 -0
  126. data/lib/flows/util.rb +17 -0
  127. data/lib/flows/util/inheritable_singleton_vars.rb +86 -0
  128. data/lib/flows/util/inheritable_singleton_vars/dup_strategy.rb +98 -0
  129. data/lib/flows/util/inheritable_singleton_vars/isolation_strategy.rb +91 -0
  130. data/lib/flows/util/prepend_to_class.rb +179 -0
  131. data/lib/flows/version.rb +1 -1
  132. metadata +288 -20
  133. data/.travis.yml +0 -8
  134. data/Gemfile.lock +0 -119
  135. data/bin/demo +0 -66
  136. data/bin/examples.rb +0 -159
  137. data/bin/profile_10steps +0 -64
  138. data/bin/ruby_benchmarks +0 -26
  139. data/lib/flows/node.rb +0 -27
  140. data/lib/flows/operation.rb +0 -54
  141. data/lib/flows/operation/builder.rb +0 -130
  142. data/lib/flows/operation/builder/build_router.rb +0 -37
  143. data/lib/flows/operation/dsl.rb +0 -72
  144. data/lib/flows/operation/errors.rb +0 -75
  145. data/lib/flows/operation/executor.rb +0 -78
  146. data/lib/flows/result_router.rb +0 -14
  147. data/lib/flows/router.rb +0 -22
@@ -1,8 +0,0 @@
1
- ---
2
- sudo: false
3
- language: ruby
4
- cache: bundler
5
- rvm:
6
- - 2.6.3
7
- - 2.5.5
8
- before_install: gem install bundler -v 2.0.1
@@ -1,119 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- flows (0.1.0)
5
-
6
- GEM
7
- remote: https://rubygems.org/
8
- specs:
9
- ast (2.4.0)
10
- benchmark-ips (2.7.2)
11
- codecov (0.1.14)
12
- json
13
- simplecov
14
- url
15
- coderay (1.1.2)
16
- concurrent-ruby (1.1.5)
17
- diff-lcs (1.3)
18
- docile (1.3.1)
19
- dry-configurable (0.8.3)
20
- concurrent-ruby (~> 1.0)
21
- dry-core (~> 0.4, >= 0.4.7)
22
- dry-container (0.7.2)
23
- concurrent-ruby (~> 1.0)
24
- dry-configurable (~> 0.1, >= 0.1.3)
25
- dry-core (0.4.9)
26
- concurrent-ruby (~> 1.0)
27
- dry-equalizer (0.2.2)
28
- dry-events (0.2.0)
29
- concurrent-ruby (~> 1.0)
30
- dry-core (~> 0.4)
31
- dry-equalizer (~> 0.2)
32
- dry-matcher (0.8.1)
33
- dry-core (>= 0.4.7)
34
- dry-monads (1.3.0)
35
- concurrent-ruby (~> 1.0)
36
- dry-core (~> 0.4, >= 0.4.4)
37
- dry-equalizer
38
- dry-transaction (0.13.0)
39
- dry-container (>= 0.2.8)
40
- dry-events (>= 0.1.0)
41
- dry-matcher (>= 0.7.0)
42
- dry-monads (>= 0.4.0)
43
- jaro_winkler (1.5.2)
44
- json (2.2.0)
45
- method_source (0.9.2)
46
- parallel (1.17.0)
47
- parser (2.6.2.0)
48
- ast (~> 2.4.0)
49
- pry (0.12.2)
50
- coderay (~> 1.1.0)
51
- method_source (~> 0.9.0)
52
- psych (3.1.0)
53
- rainbow (3.0.0)
54
- rake (10.5.0)
55
- rspec (3.8.0)
56
- rspec-core (~> 3.8.0)
57
- rspec-expectations (~> 3.8.0)
58
- rspec-mocks (~> 3.8.0)
59
- rspec-core (3.8.0)
60
- rspec-support (~> 3.8.0)
61
- rspec-expectations (3.8.2)
62
- diff-lcs (>= 1.2.0, < 2.0)
63
- rspec-support (~> 3.8.0)
64
- rspec-mocks (3.8.0)
65
- diff-lcs (>= 1.2.0, < 2.0)
66
- rspec-support (~> 3.8.0)
67
- rspec-support (3.8.0)
68
- rubocop (0.67.1)
69
- jaro_winkler (~> 1.5.1)
70
- parallel (~> 1.10)
71
- parser (>= 2.5, != 2.5.1.1)
72
- psych (>= 3.1.0)
73
- rainbow (>= 2.2.2, < 4.0)
74
- ruby-progressbar (~> 1.7)
75
- unicode-display_width (>= 1.4.0, < 1.6)
76
- rubocop-performance (1.0.0)
77
- rubocop (>= 0.58.0)
78
- rubocop-rspec (1.32.0)
79
- rubocop (>= 0.60.0)
80
- ruby-prof (1.0.0)
81
- ruby-progressbar (1.10.0)
82
- simplecov (0.16.1)
83
- docile (~> 1.1)
84
- json (>= 1.8, < 3)
85
- simplecov-html (~> 0.10.0)
86
- simplecov-html (0.10.2)
87
- stackprof (0.2.12)
88
- trailblazer-activity (0.8.4)
89
- trailblazer-context (>= 0.1.4)
90
- trailblazer-activity-dsl-linear (0.1.8)
91
- trailblazer-activity (>= 0.8.3, < 1.0.0)
92
- trailblazer-context (0.1.4)
93
- trailblazer-operation (0.5.2)
94
- trailblazer-activity-dsl-linear (>= 0.1.6, < 1.0.0)
95
- unicode-display_width (1.5.0)
96
- url (0.3.2)
97
-
98
- PLATFORMS
99
- ruby
100
-
101
- DEPENDENCIES
102
- benchmark-ips
103
- bundler (~> 2.0)
104
- codecov
105
- dry-transaction
106
- flows!
107
- pry
108
- rake (~> 10.0)
109
- rspec (~> 3.0)
110
- rubocop
111
- rubocop-performance
112
- rubocop-rspec
113
- ruby-prof
114
- simplecov
115
- stackprof
116
- trailblazer-operation
117
-
118
- BUNDLED WITH
119
- 2.0.1
data/bin/demo DELETED
@@ -1,66 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'bundler/setup'
4
- require 'flows'
5
-
6
- # Helper for demonstrations
7
- module Demo
8
- def self.run(name)
9
- puts '-' * 60
10
- puts name
11
- puts '-' * 60
12
- puts
13
-
14
- begin
15
- yield
16
- rescue StandardError => e
17
- puts "Exception raised:\n\n#{e.full_message}"
18
- end
19
- puts "\n" + '-' * 60 + "\n" * 2
20
- end
21
- end
22
-
23
- # Simple division
24
- class DivisionOperation
25
- include Flows::Operation
26
-
27
- step :check_for_zero
28
- step :divide
29
-
30
- ok_shape :result
31
- err_shape :error
32
-
33
- def check_for_zero(denominator:, **)
34
- if denominator.zero?
35
- err(error: 'Denominator cannot be zero')
36
- else
37
- ok
38
- end
39
- end
40
-
41
- def divide(numerator:, denominator:, **)
42
- ok(result: numerator / denominator)
43
- end
44
- end
45
-
46
- # Division in nested operation - we do division
47
- class NestedDivisionOperation
48
- include Flows::Operation
49
-
50
- step :do_division
51
-
52
- ok_shape :result
53
- err_shape :error
54
-
55
- def do_division(**params)
56
- DivisionOperation.new.call(**params)
57
- end
58
- end
59
-
60
- Demo.run 'Unwrap Error verbosity' do
61
- DivisionOperation.new.call(numerator: 1, denominator: 0).unwrap[:result]
62
- end
63
-
64
- Demo.run 'Unwrap Error verbosity when error happened in nested operation' do
65
- NestedDivisionOperation.new.call(numerator: 1, denominator: 0).unwrap[:result]
66
- end
@@ -1,159 +0,0 @@
1
- # rubocop:disable all
2
- require 'flows'
3
- require 'dry/transaction'
4
- require 'trailblazer/operation'
5
-
6
- #
7
- # Task: a + b = ?
8
- #
9
-
10
- class FlowsSummator
11
- include Flows::Operation
12
-
13
- step :sum
14
-
15
- ok_shape :sum
16
-
17
- def sum(a:, b:, **)
18
- ok(sum: a + b)
19
- end
20
- end
21
-
22
- class POROSummator
23
- def self.call(a:, b:)
24
- a + b
25
- end
26
- end
27
-
28
- class DrySummator
29
- include Dry::Transaction
30
-
31
- step :sum
32
-
33
- private
34
-
35
- def sum(a:, b:)
36
- Success(a + b)
37
- end
38
- end
39
-
40
- class TBSummator < Trailblazer::Operation
41
- step :sum
42
-
43
- def sum(opts, a:, b:, **)
44
- opts[:sum] = a + b
45
- end
46
- end
47
-
48
- #
49
- # Task: 10 steps which returs simple value
50
- #
51
-
52
- class FlowsTenSteps
53
- include Flows::Operation
54
-
55
- step :s1
56
- step :s2
57
- step :s3
58
- step :s4
59
- step :s5
60
- step :s6
61
- step :s7
62
- step :s8
63
- step :s9
64
- step :s10
65
-
66
- ok_shape :data
67
-
68
- def s1(**); ok(s1: true); end
69
- def s2(**); ok(s2: true); end
70
- def s3(**); ok(s3: true); end
71
- def s4(**); ok(s4: true); end
72
- def s5(**); ok(s5: true); end
73
- def s5(**); ok(s5: true); end
74
- def s6(**); ok(s6: true); end
75
- def s7(**); ok(s7: true); end
76
- def s8(**); ok(s8: true); end
77
- def s9(**); ok(s9: true); end
78
- def s10(**); ok(data: :ok); end
79
- end
80
-
81
- class POROTenSteps
82
- class << self
83
- def call()
84
- s1
85
- s2
86
- s3
87
- s4
88
- s5
89
- s6
90
- s7
91
- s8
92
- s9
93
- s10
94
- end
95
-
96
- def s1; true; end
97
- def s2; true; end
98
- def s3; true; end
99
- def s4; true; end
100
- def s5; true; end
101
- def s6; true; end
102
- def s7; true; end
103
- def s8; true; end
104
- def s9; true; end
105
- def s10; true; end
106
- end
107
- end
108
-
109
- class DryTenSteps
110
- include Dry::Transaction
111
-
112
- step :s1
113
- step :s2
114
- step :s3
115
- step :s4
116
- step :s5
117
- step :s6
118
- step :s7
119
- step :s8
120
- step :s9
121
- step :s10
122
-
123
- private
124
-
125
- def s1; Success(true); end
126
- def s2; Success(true); end
127
- def s3; Success(true); end
128
- def s4; Success(true); end
129
- def s5; Success(true); end
130
- def s6; Success(true); end
131
- def s7; Success(true); end
132
- def s8; Success(true); end
133
- def s9; Success(true); end
134
- def s10; Success(true); end
135
- end
136
-
137
- class TBTenSteps < Trailblazer::Operation
138
- step :s1
139
- step :s2
140
- step :s3
141
- step :s4
142
- step :s5
143
- step :s6
144
- step :s7
145
- step :s8
146
- step :s9
147
- step :s10
148
-
149
- def s1(opts, **); opts[:s1] = true; end
150
- def s2(opts, **); opts[:s2] = true; end
151
- def s3(opts, **); opts[:s3] = true; end
152
- def s4(opts, **); opts[:s4] = true; end
153
- def s5(opts, **); opts[:s5] = true; end
154
- def s6(opts, **); opts[:s6] = true; end
155
- def s7(opts, **); opts[:s7] = true; end
156
- def s8(opts, **); opts[:s8] = true; end
157
- def s9(opts, **); opts[:s9] = true; end
158
- def s10(opts, **); opts[:s10] = true; end
159
- end
@@ -1,64 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # rubocop:disable all
3
-
4
- require 'bundler/setup'
5
- require 'json'
6
- require 'ruby-prof'
7
- require 'stackprof'
8
-
9
- require_relative './examples'
10
-
11
- flows_ten_steps = FlowsTenSteps.new
12
-
13
- build_output_name = '10steps_build_10k_times'
14
- exec_output_name = '10steps_execution_10k_times'
15
-
16
- #
17
- # RubyProf
18
- #
19
- RubyProf.measure_mode = RubyProf::WALL_TIME
20
-
21
- puts 'Build with RubyProf...'
22
- result = RubyProf.profile do
23
- 10_000.times do
24
- FlowsTenSteps.new
25
- end
26
- end
27
- printer = RubyProf::MultiPrinter.new(result)
28
- printer.print(path: 'profile', profile: build_output_name)
29
-
30
- puts 'Execution with RubyProf...'
31
- result = RubyProf.profile do
32
- 10_000.times {
33
- flows_ten_steps.call
34
- }
35
- end
36
- printer = RubyProf::MultiPrinter.new(result)
37
- printer.print(path: 'profile', profile: exec_output_name)
38
-
39
- #
40
- # StackProf
41
- #
42
-
43
- puts 'Build with StackProf...'
44
- result = StackProf.run(mode: :wall, raw: true) do
45
- 10_000.times do
46
- FlowsTenSteps.new
47
- end
48
- end
49
- File.write("profile/#{build_output_name}.json", JSON.generate(result))
50
-
51
- puts 'Execution with StackProf...'
52
- result = StackProf.run(mode: :wall, raw: true) do
53
- 10_000.times do
54
- flows_ten_steps.call
55
- end
56
- end
57
- File.write("profile/#{exec_output_name}.json", JSON.generate(result))
58
-
59
- puts
60
- puts 'Install speedscope:'
61
- puts ' npm i -g speedscope'
62
- puts
63
- puts "speedscope profile/#{build_output_name}.json"
64
- puts "speedscope profile/#{exec_output_name}.json"
@@ -1,26 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # rubocop:disable all
3
-
4
- require 'bundler/setup'
5
- require 'benchmark/ips'
6
-
7
- puts '-' * 50
8
- puts '- method execution'
9
- puts '-' * 50
10
-
11
- class OneMethod
12
- def meth
13
- :ok
14
- end
15
- end
16
-
17
- one_method = OneMethod.new
18
- method_obj = one_method.method(:meth)
19
-
20
- Benchmark.ips do |b|
21
- b.report('native call') { one_method.meth }
22
- b.report('send(...)') { one_method.send(:meth) }
23
- b.report('Method#call') { method_obj.call }
24
-
25
- b.compare!
26
- end