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.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +1 -1
- data/Gemfile.lock +9 -11
- data/README.md +142 -0
- data/dev_suite.gemspec +1 -0
- data/examples/workflow/basic_workflow.rb +15 -0
- data/examples/workflow/composite_workflow.rb +21 -0
- data/examples/workflow/conditional_workflow.rb +17 -0
- data/examples/workflow/full_workflow.rb +79 -0
- data/examples/workflow/loop_workflow.rb +17 -0
- data/examples/workflow/parallel_workflow.rb +17 -0
- data/lib/dev_suite/dev_suite.rb +2 -0
- data/lib/dev_suite/request_builder/builder/base.rb +27 -0
- data/lib/dev_suite/request_builder/builder/builder.rb +10 -0
- data/lib/dev_suite/request_builder/builder/http.rb +32 -0
- data/lib/dev_suite/request_builder/builder.rb +9 -0
- data/lib/dev_suite/request_builder/config/config.rb +11 -0
- data/lib/dev_suite/request_builder/config/configuration.rb +24 -0
- data/lib/dev_suite/request_builder/config.rb +9 -0
- data/lib/dev_suite/request_builder/formatter/base.rb +13 -0
- data/lib/dev_suite/request_builder/formatter/formatter.rb +10 -0
- data/lib/dev_suite/request_builder/formatter/graphql.rb +19 -0
- data/lib/dev_suite/request_builder/formatter.rb +9 -0
- data/lib/dev_suite/request_builder/request_builder.rb +21 -0
- data/lib/dev_suite/request_builder/tool/base.rb +19 -0
- data/lib/dev_suite/request_builder/tool/curl.rb +91 -0
- data/lib/dev_suite/request_builder/tool/tool.rb +11 -0
- data/lib/dev_suite/request_builder/tool/validator/curl.rb +38 -0
- data/lib/dev_suite/request_builder/tool/validator/validator.rb +11 -0
- data/lib/dev_suite/request_builder/tool/validator.rb +11 -0
- data/lib/dev_suite/request_builder/tool.rb +9 -0
- data/lib/dev_suite/request_builder.rb +7 -0
- data/lib/dev_suite/request_logger/adapter/adapter.rb +11 -9
- data/lib/dev_suite/request_logger/adapter/faraday.rb +12 -1
- data/lib/dev_suite/request_logger/adapter/middleware/faraday.rb +3 -3
- data/lib/dev_suite/request_logger/adapter/net_http.rb +15 -6
- data/lib/dev_suite/request_logger/config/configuration.rb +1 -0
- data/lib/dev_suite/request_logger/extractor/base.rb +8 -2
- data/lib/dev_suite/request_logger/extractor/extractor.rb +5 -6
- data/lib/dev_suite/request_logger/extractor/faraday.rb +32 -14
- data/lib/dev_suite/request_logger/extractor/net_http.rb +53 -12
- data/lib/dev_suite/request_logger/logger.rb +9 -3
- data/lib/dev_suite/request_logger/request.rb +12 -0
- data/lib/dev_suite/request_logger/response.rb +34 -9
- data/lib/dev_suite/utils/construct/component/base.rb +13 -0
- data/lib/dev_suite/utils/construct/component/component.rb +1 -0
- data/lib/dev_suite/utils/construct/component/manager.rb +27 -10
- data/lib/dev_suite/utils/construct/component/validator/base.rb +25 -0
- data/lib/dev_suite/utils/construct/component/validator/validation_error.rb +21 -0
- data/lib/dev_suite/utils/construct/component/validator/validation_rule.rb +68 -0
- data/lib/dev_suite/utils/construct/component/validator/validator.rb +15 -0
- data/lib/dev_suite/utils/construct/component/validator.rb +13 -0
- data/lib/dev_suite/utils/construct/config/dependency_handler.rb +25 -34
- data/lib/dev_suite/utils/construct/config/settings/base.rb +35 -26
- data/lib/dev_suite/utils/data/base_operations.rb +61 -0
- data/lib/dev_suite/utils/data/data.rb +19 -0
- data/lib/dev_suite/utils/data/path_access.rb +172 -0
- data/lib/dev_suite/utils/data/search_filter.rb +60 -0
- data/lib/dev_suite/utils/data/serialization.rb +29 -0
- data/lib/dev_suite/utils/data/transformations.rb +45 -0
- data/lib/dev_suite/utils/data.rb +9 -0
- data/lib/dev_suite/utils/dependency_loader.rb +2 -2
- data/lib/dev_suite/utils/emoji.rb +1 -0
- data/lib/dev_suite/utils/file_loader/file_loader.rb +1 -5
- data/lib/dev_suite/utils/file_loader/loader/json.rb +4 -1
- data/lib/dev_suite/utils/file_loader/loader/loader.rb +23 -19
- data/lib/dev_suite/utils/file_loader/loader.rb +0 -2
- data/lib/dev_suite/utils/file_writer/atomic_writer.rb +53 -0
- data/lib/dev_suite/utils/file_writer/backup_manager.rb +21 -0
- data/lib/dev_suite/utils/file_writer/file_writer.rb +24 -0
- data/lib/dev_suite/utils/file_writer/writer/base.rb +43 -0
- data/lib/dev_suite/utils/file_writer/writer/json.rb +24 -0
- data/lib/dev_suite/utils/file_writer/writer/text.rb +27 -0
- data/lib/dev_suite/utils/file_writer/writer/writer.rb +14 -0
- data/lib/dev_suite/utils/file_writer/writer/yaml.rb +44 -0
- data/lib/dev_suite/utils/file_writer/writer.rb +11 -0
- data/lib/dev_suite/utils/file_writer/writer_manager.rb +32 -0
- data/lib/dev_suite/utils/file_writer.rb +9 -0
- data/lib/dev_suite/utils/store/config/config.rb +13 -0
- data/lib/dev_suite/utils/store/config/configuration.rb +30 -0
- data/lib/dev_suite/utils/store/config.rb +11 -0
- data/lib/dev_suite/utils/store/driver/base.rb +35 -0
- data/lib/dev_suite/utils/store/driver/driver.rb +18 -0
- data/lib/dev_suite/utils/store/driver/file.rb +61 -0
- data/lib/dev_suite/utils/store/driver/memory.rb +42 -0
- data/lib/dev_suite/utils/store/driver.rb +11 -0
- data/lib/dev_suite/utils/store/store.rb +69 -0
- data/lib/dev_suite/utils/store.rb +9 -0
- data/lib/dev_suite/utils/utils.rb +17 -5
- data/lib/dev_suite/utils/warning_handler.rb +25 -0
- data/lib/dev_suite/version.rb +1 -1
- data/lib/dev_suite/workflow/engine.rb +27 -0
- data/lib/dev_suite/workflow/step/base.rb +48 -0
- data/lib/dev_suite/workflow/step/composite.rb +27 -0
- data/lib/dev_suite/workflow/step/conditional.rb +23 -0
- data/lib/dev_suite/workflow/step/loop.rb +21 -0
- data/lib/dev_suite/workflow/step/parallel.rb +18 -0
- data/lib/dev_suite/workflow/step/step.rb +13 -0
- data/lib/dev_suite/workflow/step.rb +9 -0
- data/lib/dev_suite/workflow/step_context.rb +32 -0
- data/lib/dev_suite/workflow/workflow.rb +35 -0
- data/lib/dev_suite/workflow.rb +7 -0
- metadata +87 -3
- 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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 46a0bbcc4003a1f927cd0e4b8b1ffbc0a5045b48a7f5a5f7afc1d64b779ee636
|
4
|
+
data.tar.gz: 9500cbcf2e4b9e3ca4f15e523364b8b2a4508e3c336a3675d1bff78b80d8cb27
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 586986165449f7145547b0ac188cef0e2b9b75ed69c74e320898a3c33eccce00c0c4b383c23f9b32a6a0bc50470bccdc018339f9a7240fcbcb176595a9a00b35
|
7
|
+
data.tar.gz: ff3e828d65d93aa9f8bbfb320c25cd3b1216bf66a03169ba269748eb3d2ec38851527beeb369b2e0edf5f058cbe3ca91b6680061eb590b9f149cbdce604143ab
|
data/.github/workflows/ci.yml
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
dev_suite (0.2.
|
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.
|
60
|
-
parser (3.3.
|
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.
|
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
|
-
|
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.
|
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
|
-
|
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
@@ -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
|
data/lib/dev_suite/dev_suite.rb
CHANGED
@@ -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,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,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,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,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
|