dev_suite 0.2.7 → 0.2.9

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.
Files changed (104) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +1 -1
  3. data/Gemfile.lock +9 -11
  4. data/README.md +142 -0
  5. data/dev_suite.gemspec +1 -0
  6. data/examples/workflow/basic_workflow.rb +15 -0
  7. data/examples/workflow/composite_workflow.rb +21 -0
  8. data/examples/workflow/conditional_workflow.rb +17 -0
  9. data/examples/workflow/full_workflow.rb +79 -0
  10. data/examples/workflow/loop_workflow.rb +17 -0
  11. data/examples/workflow/parallel_workflow.rb +17 -0
  12. data/lib/dev_suite/dev_suite.rb +2 -0
  13. data/lib/dev_suite/request_builder/builder/base.rb +27 -0
  14. data/lib/dev_suite/request_builder/builder/builder.rb +10 -0
  15. data/lib/dev_suite/request_builder/builder/http.rb +32 -0
  16. data/lib/dev_suite/request_builder/builder.rb +9 -0
  17. data/lib/dev_suite/request_builder/config/config.rb +11 -0
  18. data/lib/dev_suite/request_builder/config/configuration.rb +24 -0
  19. data/lib/dev_suite/request_builder/config.rb +9 -0
  20. data/lib/dev_suite/request_builder/formatter/base.rb +13 -0
  21. data/lib/dev_suite/request_builder/formatter/formatter.rb +10 -0
  22. data/lib/dev_suite/request_builder/formatter/graphql.rb +19 -0
  23. data/lib/dev_suite/request_builder/formatter.rb +9 -0
  24. data/lib/dev_suite/request_builder/request_builder.rb +21 -0
  25. data/lib/dev_suite/request_builder/tool/base.rb +19 -0
  26. data/lib/dev_suite/request_builder/tool/curl.rb +91 -0
  27. data/lib/dev_suite/request_builder/tool/tool.rb +11 -0
  28. data/lib/dev_suite/request_builder/tool/validator/curl.rb +38 -0
  29. data/lib/dev_suite/request_builder/tool/validator/validator.rb +11 -0
  30. data/lib/dev_suite/request_builder/tool/validator.rb +11 -0
  31. data/lib/dev_suite/request_builder/tool.rb +9 -0
  32. data/lib/dev_suite/request_builder.rb +7 -0
  33. data/lib/dev_suite/request_logger/adapter/adapter.rb +11 -9
  34. data/lib/dev_suite/request_logger/adapter/faraday.rb +12 -1
  35. data/lib/dev_suite/request_logger/adapter/middleware/faraday.rb +3 -3
  36. data/lib/dev_suite/request_logger/adapter/net_http.rb +15 -6
  37. data/lib/dev_suite/request_logger/config/configuration.rb +1 -0
  38. data/lib/dev_suite/request_logger/extractor/base.rb +8 -2
  39. data/lib/dev_suite/request_logger/extractor/extractor.rb +5 -6
  40. data/lib/dev_suite/request_logger/extractor/faraday.rb +32 -14
  41. data/lib/dev_suite/request_logger/extractor/net_http.rb +53 -12
  42. data/lib/dev_suite/request_logger/logger.rb +9 -3
  43. data/lib/dev_suite/request_logger/request.rb +12 -0
  44. data/lib/dev_suite/request_logger/response.rb +34 -9
  45. data/lib/dev_suite/utils/construct/component/base.rb +13 -0
  46. data/lib/dev_suite/utils/construct/component/component.rb +1 -0
  47. data/lib/dev_suite/utils/construct/component/manager.rb +27 -10
  48. data/lib/dev_suite/utils/construct/component/validator/base.rb +25 -0
  49. data/lib/dev_suite/utils/construct/component/validator/validation_error.rb +21 -0
  50. data/lib/dev_suite/utils/construct/component/validator/validation_rule.rb +68 -0
  51. data/lib/dev_suite/utils/construct/component/validator/validator.rb +15 -0
  52. data/lib/dev_suite/utils/construct/component/validator.rb +13 -0
  53. data/lib/dev_suite/utils/construct/config/dependency_handler.rb +25 -34
  54. data/lib/dev_suite/utils/construct/config/settings/base.rb +35 -26
  55. data/lib/dev_suite/utils/data/base_operations.rb +61 -0
  56. data/lib/dev_suite/utils/data/data.rb +19 -0
  57. data/lib/dev_suite/utils/data/path_access.rb +172 -0
  58. data/lib/dev_suite/utils/data/search_filter.rb +60 -0
  59. data/lib/dev_suite/utils/data/serialization.rb +29 -0
  60. data/lib/dev_suite/utils/data/transformations.rb +45 -0
  61. data/lib/dev_suite/utils/data.rb +9 -0
  62. data/lib/dev_suite/utils/dependency_loader.rb +2 -2
  63. data/lib/dev_suite/utils/emoji.rb +1 -0
  64. data/lib/dev_suite/utils/file_loader/file_loader.rb +1 -5
  65. data/lib/dev_suite/utils/file_loader/loader/json.rb +4 -1
  66. data/lib/dev_suite/utils/file_loader/loader/loader.rb +23 -19
  67. data/lib/dev_suite/utils/file_loader/loader.rb +0 -2
  68. data/lib/dev_suite/utils/file_writer/atomic_writer.rb +53 -0
  69. data/lib/dev_suite/utils/file_writer/backup_manager.rb +21 -0
  70. data/lib/dev_suite/utils/file_writer/file_writer.rb +24 -0
  71. data/lib/dev_suite/utils/file_writer/writer/base.rb +43 -0
  72. data/lib/dev_suite/utils/file_writer/writer/json.rb +24 -0
  73. data/lib/dev_suite/utils/file_writer/writer/text.rb +27 -0
  74. data/lib/dev_suite/utils/file_writer/writer/writer.rb +14 -0
  75. data/lib/dev_suite/utils/file_writer/writer/yaml.rb +44 -0
  76. data/lib/dev_suite/utils/file_writer/writer.rb +11 -0
  77. data/lib/dev_suite/utils/file_writer/writer_manager.rb +32 -0
  78. data/lib/dev_suite/utils/file_writer.rb +9 -0
  79. data/lib/dev_suite/utils/store/config/config.rb +13 -0
  80. data/lib/dev_suite/utils/store/config/configuration.rb +30 -0
  81. data/lib/dev_suite/utils/store/config.rb +11 -0
  82. data/lib/dev_suite/utils/store/driver/base.rb +35 -0
  83. data/lib/dev_suite/utils/store/driver/driver.rb +18 -0
  84. data/lib/dev_suite/utils/store/driver/file.rb +61 -0
  85. data/lib/dev_suite/utils/store/driver/memory.rb +42 -0
  86. data/lib/dev_suite/utils/store/driver.rb +11 -0
  87. data/lib/dev_suite/utils/store/store.rb +69 -0
  88. data/lib/dev_suite/utils/store.rb +9 -0
  89. data/lib/dev_suite/utils/utils.rb +17 -5
  90. data/lib/dev_suite/utils/warning_handler.rb +25 -0
  91. data/lib/dev_suite/version.rb +1 -1
  92. data/lib/dev_suite/workflow/engine.rb +27 -0
  93. data/lib/dev_suite/workflow/step/base.rb +48 -0
  94. data/lib/dev_suite/workflow/step/composite.rb +27 -0
  95. data/lib/dev_suite/workflow/step/conditional.rb +23 -0
  96. data/lib/dev_suite/workflow/step/loop.rb +21 -0
  97. data/lib/dev_suite/workflow/step/parallel.rb +18 -0
  98. data/lib/dev_suite/workflow/step/step.rb +13 -0
  99. data/lib/dev_suite/workflow/step.rb +9 -0
  100. data/lib/dev_suite/workflow/step_context.rb +32 -0
  101. data/lib/dev_suite/workflow/workflow.rb +35 -0
  102. data/lib/dev_suite/workflow.rb +7 -0
  103. metadata +87 -3
  104. data/lib/dev_suite/utils/construct/component/initializer.rb +0 -28
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1a7188e92386a13da83abc637b7446d68c485eff8e6e2198a53f88360ac13f02
4
- data.tar.gz: f76c576284ba7b90bc671a389cd6e43065079f04ae19567b0e633a147e2b2276
3
+ metadata.gz: 46a0bbcc4003a1f927cd0e4b8b1ffbc0a5045b48a7f5a5f7afc1d64b779ee636
4
+ data.tar.gz: 9500cbcf2e4b9e3ca4f15e523364b8b2a4508e3c336a3675d1bff78b80d8cb27
5
5
  SHA512:
6
- metadata.gz: b565a159f2aee25115301ae629dcd2e44e844005586c2505e92cd18f75f9845a856c16f8db1c5a309eb249f645ba1e90b6c36ca4e0958f6106f39d0d86f7434a
7
- data.tar.gz: 7a34933bf806f8e3fb09351b200698da8d6f5568fefc3054f7ba0591c939dc264b9962c77cd56b6f01e5304b2bb60e5301885f33f34b05bebd54858046cb1e73
6
+ metadata.gz: 586986165449f7145547b0ac188cef0e2b9b75ed69c74e320898a3c33eccce00c0c4b383c23f9b32a6a0bc50470bccdc018339f9a7240fcbcb176595a9a00b35
7
+ data.tar.gz: ff3e828d65d93aa9f8bbfb320c25cd3b1216bf66a03169ba269748eb3d2ec38851527beeb369b2e0edf5f058cbe3ca91b6680061eb590b9f149cbdce604143ab
@@ -15,7 +15,7 @@ jobs:
15
15
  - name: Set up Ruby
16
16
  uses: ruby/setup-ruby@v1
17
17
  with:
18
- ruby-version: 3.0 # Specify your project's Ruby version
18
+ ruby-version: 3.0
19
19
 
20
20
  - name: Install dependencies
21
21
  run: bundle install
data/Gemfile.lock CHANGED
@@ -1,8 +1,9 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- dev_suite (0.2.7)
4
+ dev_suite (0.2.9)
5
5
  benchmark (~> 0.1)
6
+ csv (~> 3.0)
6
7
  get_process_mem (~> 1.0)
7
8
  thor (~> 1.1)
8
9
 
@@ -13,6 +14,7 @@ GEM
13
14
  benchmark (0.3.0)
14
15
  bigdecimal (3.1.8)
15
16
  coderay (1.1.3)
17
+ csv (3.3.0)
16
18
  diff-lcs (1.5.1)
17
19
  docile (1.4.1)
18
20
  faraday (1.10.3)
@@ -56,8 +58,8 @@ GEM
56
58
  language_server-protocol (3.17.0.3)
57
59
  method_source (1.1.0)
58
60
  multipart-post (2.4.1)
59
- parallel (1.25.1)
60
- parser (3.3.4.1)
61
+ parallel (1.26.3)
62
+ parser (3.3.5.0)
61
63
  ast (~> 2.4.1)
62
64
  racc
63
65
  pry (0.14.2)
@@ -67,8 +69,6 @@ GEM
67
69
  rainbow (3.1.1)
68
70
  rake (13.2.1)
69
71
  regexp_parser (2.9.2)
70
- rexml (3.3.6)
71
- strscan
72
72
  rspec (3.13.0)
73
73
  rspec-core (~> 3.13.0)
74
74
  rspec-expectations (~> 3.13.0)
@@ -82,18 +82,17 @@ GEM
82
82
  diff-lcs (>= 1.2.0, < 2.0)
83
83
  rspec-support (~> 3.13.0)
84
84
  rspec-support (3.13.1)
85
- rubocop (1.65.1)
85
+ rubocop (1.66.1)
86
86
  json (~> 2.3)
87
87
  language_server-protocol (>= 3.17.0)
88
88
  parallel (~> 1.10)
89
89
  parser (>= 3.3.0.2)
90
90
  rainbow (>= 2.2.2, < 4.0)
91
91
  regexp_parser (>= 2.4, < 3.0)
92
- rexml (>= 3.2.5, < 4.0)
93
- rubocop-ast (>= 1.31.1, < 2.0)
92
+ rubocop-ast (>= 1.32.2, < 2.0)
94
93
  ruby-progressbar (~> 1.7)
95
94
  unicode-display_width (>= 2.4.0, < 3.0)
96
- rubocop-ast (1.32.0)
95
+ rubocop-ast (1.32.3)
97
96
  parser (>= 3.3.1.0)
98
97
  rubocop-shopify (2.15.1)
99
98
  rubocop (~> 1.51)
@@ -105,8 +104,7 @@ GEM
105
104
  simplecov_json_formatter (~> 0.1)
106
105
  simplecov-html (0.12.3)
107
106
  simplecov_json_formatter (0.1.4)
108
- strscan (3.1.0)
109
- thor (1.3.1)
107
+ thor (1.3.2)
110
108
  unicode-display_width (2.5.0)
111
109
 
112
110
  PLATFORMS
data/README.md CHANGED
@@ -214,6 +214,148 @@ Log detailed HTTP requests and responses across different adapters like Net::HTT
214
214
  ```
215
215
  </details>
216
216
 
217
+ ### Workflow Engine
218
+ Manage complex workflows consisting of multiple sequential steps, including handling data between steps and supporting dynamic operations like conditionals, loops, and parallel execution.
219
+
220
+ <details>
221
+ <summary>Show more</summary>
222
+
223
+ **How to Use**:
224
+ ```ruby
225
+ workflow = DevSuite::Workflow.create_engine(initial_context)
226
+
227
+ # Define steps
228
+ step1 = DevSuite::Workflow.create_step("Step 1") do |ctx|
229
+ ctx.update({ result: "Step 1 Complete" })
230
+ end
231
+
232
+ step2 = DevSuite::Workflow.create_step("Step 2") do |ctx|
233
+ puts "Previous Result: #{ctx.get(:result)}"
234
+ ctx.update({ result: "Step 2 Complete" })
235
+ end
236
+
237
+ # Chain steps together
238
+ workflow.add_step(step1).add_step(step2)
239
+
240
+ # Execute workflow
241
+ workflow.execute
242
+ ```
243
+
244
+ **Chaining Steps**:
245
+ You can chain multiple steps together to create a workflow:
246
+ ```ruby
247
+ workflow = DevSuite::Workflow.create_engine(initial_context)
248
+
249
+ step1 = DevSuite::Workflow.create_step("Step 1") { |ctx| ctx.update({ data: 'Data from Step 1' }) }
250
+ step2 = DevSuite::Workflow.create_step("Step 2") { |ctx| puts "Received: #{ctx.get(:data)}" }
251
+
252
+ workflow.add_step(step1)
253
+ .add_step(step2)
254
+ .execute
255
+ ```
256
+
257
+ **Data Handling**:
258
+ Each step in the workflow has access to a shared context, where you can store and retrieve data:
259
+ ```ruby
260
+ workflow = DevSuite::Workflow.create_engine({ some_key: 'initial_value' })
261
+
262
+ step1 = DevSuite::Workflow.create_step("Step 1") do |ctx|
263
+ # Retrieve data
264
+ puts ctx.get(:some_key) # Output: initial_value
265
+ # Set data
266
+ ctx.update({ new_key: 'new_value' })
267
+ end
268
+
269
+ step2 = DevSuite::Workflow.create_step("Step 2") do |ctx|
270
+ # Use updated data
271
+ puts ctx.get(:new_key) # Output: new_value
272
+ end
273
+
274
+ workflow.add_step(step1).add_step(step2).execute
275
+ ```
276
+
277
+ **Conditional Execution**:
278
+ Conditionally execute steps based on logic defined in the workflow context:
279
+ ```ruby
280
+ conditional_step = DevSuite::Workflow.create_conditional_step("Conditional Step", ->(ctx) { ctx.get(:result) == "Step 1 Complete" }) do |ctx|
281
+ puts "Condition met! Executing conditional step."
282
+ ctx.update({ result: "Conditional Step Executed" })
283
+ end
284
+
285
+ workflow.add_step(conditional_step).execute
286
+ ```
287
+
288
+ **Parallel Execution**:
289
+ You can execute multiple steps in parallel:
290
+ ```ruby
291
+ parallel_step = DevSuite::Workflow.create_parallel_step("Parallel Step") do |ctx|
292
+ [
293
+ ->(ctx) { ctx.update({ task1: "Task 1 done" }) },
294
+ ->(ctx) { ctx.update({ task2: "Task 2 done" }) }
295
+ ]
296
+ end
297
+
298
+ workflow.add_step(parallel_step).execute
299
+ ```
300
+
301
+ **Save and Load Context**:
302
+ Save the workflow's context to a file and reload it for later use:
303
+ ```ruby
304
+ # Saving context to a YAML file
305
+ workflow = DevSuite::Workflow.create_engine({ user: 'John' })
306
+ workflow.add_step(DevSuite::Workflow.create_step("Example") { |ctx| ctx.update({ status: 'completed' }) })
307
+ workflow.execute
308
+
309
+ File.open('context.yml', 'w') { |file| file.write(YAML.dump(workflow.context.data)) }
310
+
311
+ # Loading context from a YAML file
312
+ loaded_data = YAML.load_file('context.yml')
313
+ workflow = DevSuite::Workflow.create_engine(loaded_data)
314
+ ```
315
+
316
+ **Looping**:
317
+ You can loop steps in the workflow, for instance, if you need to repeat a step multiple times:
318
+ ```ruby
319
+ loop_step = DevSuite::Workflow.create_loop_step("Repeat 5 Times", 5) do |ctx|
320
+ count = ctx.get(:count) || 0
321
+ ctx.update({ count: count + 1 })
322
+ puts "Iteration: #{ctx.get(:count)}"
323
+ end
324
+
325
+ workflow.add_step(loop_step).execute
326
+ ```
327
+
328
+ **Using the Store**:
329
+ By default, the workflow context provides access to an integrated store via ctx.store. You can save and retrieve data across steps:
330
+ ```ruby
331
+ # Using the store in the workflow
332
+ workflow = DevSuite::Workflow.create_engine
333
+ step = DevSuite::Workflow.create_step("Store Example") do |ctx|
334
+ ctx.store.set(:step_result, "Step 1 Completed")
335
+ end
336
+
337
+ workflow.add_step(step).execute
338
+
339
+ # Fetch data from the store
340
+ puts ctx.store.fetch(:step_result) # Output: Step 1 Completed
341
+ ```
342
+
343
+ **Sample Output**:
344
+ ```bash
345
+ Step 1 executed: result => Step 1 Complete
346
+ Step 2 executed: Previous Result: Step 1 Complete
347
+ Task 1 done
348
+ Task 2 done
349
+ Iteration: 1
350
+ Iteration: 2
351
+ ...
352
+ Condition met! Executing conditional step.
353
+ Store contains: { name: "John Doe", age: 30 }
354
+ Step 1 Completed
355
+ ```
356
+
357
+ </details>
358
+
217
359
  ## Development
218
360
 
219
361
  After checking out the repo, run `bin/setup`for an interactive prompt that will allow you to experiment.
data/dev_suite.gemspec CHANGED
@@ -31,6 +31,7 @@ Gem::Specification.new do |spec|
31
31
 
32
32
  # Runtime dependencies
33
33
  spec.add_dependency("benchmark", "~> 0.1")
34
+ spec.add_dependency("csv", "~> 3.0")
34
35
  spec.add_dependency("get_process_mem", "~> 1.0")
35
36
  spec.add_dependency("thor", "~> 1.1")
36
37
  end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH.unshift(File.expand_path("../../lib", __dir__))
4
+ require "dev_suite"
5
+
6
+ # Create a basic workflow
7
+ engine = DevSuite::Workflow::Engine.new(user: "Alice")
8
+
9
+ # Add a basic step
10
+ basic_step = DevSuite::Workflow.create_step("Greet User") do |context|
11
+ puts "Hello, #{context.get(:user)}!"
12
+ end
13
+
14
+ engine.add_step(basic_step)
15
+ engine.execute
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH.unshift(File.expand_path("../../lib", __dir__))
4
+ require "dev_suite"
5
+
6
+ # Create a workflow with multiple sub-steps
7
+ engine = DevSuite::Workflow::Engine.new
8
+
9
+ composite_step = DevSuite::Workflow.create_composite_step("Composite Task")
10
+
11
+ # Add sub-steps
12
+ sub_step1 = DevSuite::Workflow.create_step("Sub-Step 1") do |context|
13
+ puts "Executing Sub-Step 1"
14
+ end
15
+ sub_step2 = DevSuite::Workflow.create_step("Sub-Step 2") do |context|
16
+ puts "Executing Sub-Step 2"
17
+ end
18
+
19
+ composite_step.add_step(sub_step1).add_step(sub_step2)
20
+ engine.add_step(composite_step)
21
+ engine.execute
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH.unshift(File.expand_path("../../lib", __dir__))
4
+ require "dev_suite"
5
+
6
+ # Create a conditional workflow
7
+ engine = DevSuite::Workflow::Engine.new(user: "Bob", role: "admin")
8
+
9
+ # Add a conditional step
10
+ conditional_step = DevSuite::Workflow.create_conditional_step("Admin Greeting", ->(ctx) {
11
+ ctx.get(:role) == "admin"
12
+ }) do |context|
13
+ puts "Welcome Admin, #{context.get(:user)}!"
14
+ end
15
+
16
+ engine.add_step(conditional_step)
17
+ engine.execute
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH.unshift(File.expand_path("../../lib", __dir__))
4
+ require "dev_suite"
5
+
6
+ # Create the workflow engine with an initial context
7
+ engine = DevSuite::Workflow.create_engine(
8
+ {
9
+ user: "Alice",
10
+ role: "admin",
11
+ iteration_count: 0,
12
+ },
13
+ driver: :file,
14
+ path: "tmp/workflow_store.json",
15
+ )
16
+
17
+ # Step 1: Create a basic step to greet the user
18
+ greet_step = DevSuite::Workflow.create_step("Greet User") do |context|
19
+ puts "Hello, #{context.get(:user)}!"
20
+ end
21
+
22
+ # Step 2: Create a conditional step to greet only admins
23
+ admin_step = DevSuite::Workflow.create_conditional_step("Admin Greeting", ->(ctx) {
24
+ ctx.get(:role) == "admin"
25
+ }) do |context|
26
+ puts "Welcome, Admin #{context.get(:user)}!"
27
+ end
28
+
29
+ # Step 3: Create a loop step that repeats 3 times
30
+ loop_step = DevSuite::Workflow.create_loop_step("Loop Step", 3) do |ctx|
31
+ iteration = ctx.get(:iteration_count) + 1
32
+ ctx.update({ iteration_count: iteration })
33
+ puts "Iteration #{iteration} completed."
34
+ end
35
+
36
+ # Step 4: Create a parallel step to run two tasks simultaneously
37
+ parallel_step = DevSuite::Workflow.create_parallel_step("Parallel Task") do |context|
38
+ [
39
+ ->(ctx) { puts "Task 1 executed" },
40
+ ->(ctx) { puts "Task 2 executed" },
41
+ ]
42
+ end
43
+
44
+ # Step 5: Create a composite step that combines two sub-steps
45
+ composite_step = DevSuite::Workflow.create_composite_step("Composite Task")
46
+
47
+ # Sub-Step 1
48
+ sub_step1 = DevSuite::Workflow.create_step("Sub-Step 1") do |context|
49
+ puts "Executing Sub-Step 1"
50
+ end
51
+
52
+ # Sub-Step 2
53
+ sub_step2 = DevSuite::Workflow.create_step("Sub-Step 2") do |context|
54
+ puts "Executing Sub-Step 2"
55
+ end
56
+
57
+ # Add sub-steps to the composite step
58
+ composite_step.add_step(sub_step1).add_step(sub_step2)
59
+
60
+ # Step 6: A step to store the final workflow result
61
+ store_step = DevSuite::Workflow.create_step("Store Result") do |context|
62
+ context.store.set(:workflow_result, "Workflow Completed")
63
+ puts "Result stored in context."
64
+ end
65
+
66
+ # Add all steps to the workflow engine
67
+ engine.add_step(greet_step)
68
+ .add_step(admin_step)
69
+ .add_step(loop_step)
70
+ .add_step(parallel_step)
71
+ .add_step(composite_step)
72
+ .add_step(store_step)
73
+
74
+ # Execute the workflow
75
+ puts "Executing workflow..."
76
+ engine.execute
77
+
78
+ # Retrieve the result from the context store after execution
79
+ puts "Final result from context store: #{engine.context.store.fetch(:workflow_result)}"
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH.unshift(File.expand_path("../../lib", __dir__))
4
+ require "dev_suite"
5
+
6
+ # Create a workflow with a looping step
7
+ engine = DevSuite::Workflow::Engine.new(iteration_count: 0)
8
+
9
+ # Add a loop step
10
+ loop_step = DevSuite::Workflow.create_loop_step("Repeat Task", 3) do |context|
11
+ iteration = context.get(:iteration_count) + 1
12
+ context.update({ iteration_count: iteration })
13
+ puts "Iteration #{iteration}"
14
+ end
15
+
16
+ engine.add_step(loop_step)
17
+ engine.execute
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH.unshift(File.expand_path("../../lib", __dir__))
4
+ require "dev_suite"
5
+
6
+ # Create a workflow with parallel tasks
7
+ engine = DevSuite::Workflow::Engine.new
8
+
9
+ parallel_step = DevSuite::Workflow.create_parallel_step("Parallel Task") do |context|
10
+ [
11
+ ->(ctx) { puts "Task 1 executed" },
12
+ ->(ctx) { puts "Task 2 executed" },
13
+ ]
14
+ end
15
+
16
+ engine.add_step(parallel_step)
17
+ engine.execute
@@ -7,6 +7,8 @@ module DevSuite
7
7
  require_relative "performance"
8
8
  require_relative "directory_tree"
9
9
  require_relative "request_logger"
10
+ require_relative "request_builder"
11
+ require_relative "workflow"
10
12
 
11
13
  class Error < StandardError; end
12
14
  end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DevSuite
4
+ module RequestBuilder
5
+ module Builder
6
+ class Base
7
+ attr_reader :url, :headers, :tool
8
+
9
+ def initialize(url:, headers: {}, tool:)
10
+ @url = url
11
+ @headers = headers
12
+ @tool = tool
13
+ end
14
+
15
+ def build_command
16
+ raise NotImplementedError, "Subclasses must implement the `build_command` method"
17
+ end
18
+
19
+ protected
20
+
21
+ def format_headers
22
+ headers.map { |key, value| "#{key}: #{value}" }.join("\n")
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DevSuite
4
+ module RequestBuilder
5
+ module Builder
6
+ require_relative "base"
7
+ require_relative "http"
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DevSuite
4
+ module RequestBuilder
5
+ module Builder
6
+ class Http < Base
7
+ attr_reader :http_method, :body
8
+
9
+ def initialize(url:, http_method: "GET", headers: {}, body: nil, tool:)
10
+ super(url: url, headers: headers, tool: tool)
11
+ @http_method = http_method.upcase
12
+ @body = body
13
+ end
14
+
15
+ def build_command
16
+ case tool
17
+ when :curl
18
+ Tool::Curl.new.build_command(http_method: http_method, url: url, headers: headers, body: format_body(body))
19
+ else
20
+ raise ArgumentError, "Unknown tool: #{tool}"
21
+ end
22
+ end
23
+
24
+ private
25
+
26
+ def format_body(body)
27
+ Formatter::Graphql.new.format_body(body)
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DevSuite
4
+ module RequestBuilder
5
+ module Builder
6
+ require_relative "builder/builder"
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DevSuite
4
+ module RequestBuilder
5
+ module Config
6
+ include Utils::Construct::Config::Manager
7
+
8
+ require_relative "configuration"
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DevSuite
4
+ module RequestBuilder
5
+ module Config
6
+ class Configuration < Utils::Construct::Config::Base
7
+ set_default_settings(
8
+ tool: {
9
+ curl: {
10
+ use_insecure: false,
11
+ raw_data: false,
12
+ verbose: false,
13
+ follow_redirects: true,
14
+ cookie: nil,
15
+ user_agent: "Mozilla/5.0 (compatible; RequestBuilder/1.0)",
16
+ max_time: nil,
17
+ connect_timeout: nil,
18
+ },
19
+ },
20
+ )
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DevSuite
4
+ module RequestBuilder
5
+ module Config
6
+ require_relative "config/config"
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DevSuite
4
+ module RequestBuilder
5
+ module Formatter
6
+ class Base
7
+ def format_body(body)
8
+ raise NotImplementedError, "Subclasses must implement the `format_body` method"
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DevSuite
4
+ module RequestBuilder
5
+ module Formatter
6
+ require_relative "base"
7
+ require_relative "graphql"
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DevSuite
4
+ module RequestBuilder
5
+ module Formatter
6
+ class Graphql < Base
7
+ def format_body(body)
8
+ if body.is_a?(Hash) && body[:query] && body[:variables]
9
+ { query: body[:query], variables: body[:variables] }.to_json
10
+ elsif body.is_a?(String)
11
+ { query: body, variables: {} }.to_json
12
+ else
13
+ raise ArgumentError, "Invalid GraphQL body format"
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DevSuite
4
+ module RequestBuilder
5
+ module Formatter
6
+ require_relative "formatter/formatter"
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DevSuite
4
+ module RequestBuilder
5
+ require_relative "config"
6
+ require_relative "formatter"
7
+ require_relative "tool"
8
+ require_relative "builder"
9
+
10
+ class << self
11
+ def build(protocol:, tool:, **options)
12
+ case protocol
13
+ when :http
14
+ Builder::Http.new(tool: tool, **options)
15
+ else
16
+ raise ArgumentError, "Unknown protocol: #{protocol}"
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DevSuite
4
+ module RequestBuilder
5
+ module Tool
6
+ class Base < Utils::Construct::Component::Base
7
+ def build_command(http_method:, url:, headers:, body: nil)
8
+ raise NotImplementedError
9
+ end
10
+
11
+ private
12
+
13
+ def fetch_setting(key, default: nil)
14
+ Config.configuration.settings.get(key, default: default)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end