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
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DevSuite
|
4
|
+
module Utils
|
5
|
+
module Store
|
6
|
+
module Driver
|
7
|
+
class File < Base
|
8
|
+
def initialize(**options)
|
9
|
+
super()
|
10
|
+
@path = options[:path] || fetch_setting(:path, default: "tmp/store.json")
|
11
|
+
@data = {}
|
12
|
+
load_data
|
13
|
+
end
|
14
|
+
|
15
|
+
def set(key, value)
|
16
|
+
Data.set_value_by_path(@data, key, value)
|
17
|
+
save_data
|
18
|
+
end
|
19
|
+
|
20
|
+
def fetch(key)
|
21
|
+
Data.get_value_by_path(@data, key)
|
22
|
+
end
|
23
|
+
|
24
|
+
def delete(key)
|
25
|
+
Data.delete_key_by_path(@data, key)
|
26
|
+
save_data
|
27
|
+
end
|
28
|
+
|
29
|
+
def clear
|
30
|
+
@data = {}
|
31
|
+
save_data
|
32
|
+
end
|
33
|
+
|
34
|
+
def import(source)
|
35
|
+
raise ArgumentError, "The file does not exist" unless ::File.exist?(source)
|
36
|
+
|
37
|
+
@data = FileLoader.load(source)
|
38
|
+
end
|
39
|
+
|
40
|
+
def export(destination)
|
41
|
+
FileWriter.write(destination, @data)
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def load_data
|
47
|
+
@data = FileLoader.load(@path) if ::File.exist?(@path)
|
48
|
+
end
|
49
|
+
|
50
|
+
def save_data
|
51
|
+
FileWriter.write(@path, @data)
|
52
|
+
end
|
53
|
+
|
54
|
+
def fetch_setting(key, default: nil)
|
55
|
+
Config.configuration.settings.get(key, default: default)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DevSuite
|
4
|
+
module Utils
|
5
|
+
module Store
|
6
|
+
module Driver
|
7
|
+
class Memory < Base
|
8
|
+
def initialize
|
9
|
+
super
|
10
|
+
@data = {}
|
11
|
+
end
|
12
|
+
|
13
|
+
def set(key, value)
|
14
|
+
Data.set_value_by_path(@data, key, value)
|
15
|
+
end
|
16
|
+
|
17
|
+
def fetch(key)
|
18
|
+
Data.get_value_by_path(@data, key)
|
19
|
+
end
|
20
|
+
|
21
|
+
def delete(key)
|
22
|
+
Data.delete_key_by_path(@data, key)
|
23
|
+
end
|
24
|
+
|
25
|
+
def clear
|
26
|
+
@data.clear
|
27
|
+
end
|
28
|
+
|
29
|
+
def import(source)
|
30
|
+
raise ArgumentError, "The file does not exist" unless ::File.exist?(source)
|
31
|
+
|
32
|
+
@data = FileLoader.load(source)
|
33
|
+
end
|
34
|
+
|
35
|
+
def export(destination)
|
36
|
+
FileWriter.write(destination, @data)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DevSuite
|
4
|
+
module Utils
|
5
|
+
module Store
|
6
|
+
require_relative "config"
|
7
|
+
require_relative "driver"
|
8
|
+
|
9
|
+
class Store
|
10
|
+
def initialize(**options)
|
11
|
+
@driver = initialize_driver(**options)
|
12
|
+
end
|
13
|
+
|
14
|
+
def set(key, value)
|
15
|
+
@driver.set(key, value)
|
16
|
+
end
|
17
|
+
|
18
|
+
def fetch(key)
|
19
|
+
@driver.fetch(key)
|
20
|
+
end
|
21
|
+
|
22
|
+
def delete(key)
|
23
|
+
@driver.delete(key)
|
24
|
+
end
|
25
|
+
|
26
|
+
def import(source)
|
27
|
+
@driver.import(source)
|
28
|
+
end
|
29
|
+
|
30
|
+
def export(destination)
|
31
|
+
@driver.export(destination)
|
32
|
+
end
|
33
|
+
|
34
|
+
def clear
|
35
|
+
@driver.clear
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def initialize_driver(**options)
|
41
|
+
return Config.configuration.driver unless options.key?(:driver)
|
42
|
+
|
43
|
+
build_driver(options)
|
44
|
+
end
|
45
|
+
|
46
|
+
def build_driver(options)
|
47
|
+
Driver.build_component(options.fetch(:driver), **options.except(:driver))
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
class << self
|
52
|
+
# Retrieve the singleton store instance
|
53
|
+
def instance
|
54
|
+
@store ||= Store.new
|
55
|
+
end
|
56
|
+
|
57
|
+
# Reset the singleton store instance
|
58
|
+
def reset!
|
59
|
+
@store = nil
|
60
|
+
end
|
61
|
+
|
62
|
+
# Create a new store instance (isolated from the singleton)
|
63
|
+
def create(**options)
|
64
|
+
Store.new(**options)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -2,14 +2,26 @@
|
|
2
2
|
|
3
3
|
module DevSuite
|
4
4
|
module Utils
|
5
|
+
PATH = "dev_suite/utils"
|
6
|
+
|
7
|
+
# Load essential modules immediately because they are critical for
|
8
|
+
# application startup and early functionality.
|
5
9
|
require_relative "emoji"
|
6
10
|
require_relative "logger"
|
11
|
+
require_relative "data"
|
7
12
|
require_relative "error_handler"
|
13
|
+
require_relative "warning_handler"
|
8
14
|
require_relative "dependency_loader"
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
15
|
+
|
16
|
+
# Core utilities
|
17
|
+
autoload :Construct, "#{PATH}/construct"
|
18
|
+
|
19
|
+
# Functional utilities
|
20
|
+
autoload :Store, "#{PATH}/store"
|
21
|
+
autoload :Color, "#{PATH}/color"
|
22
|
+
autoload :Table, "#{PATH}/table"
|
23
|
+
autoload :FileLoader, "#{PATH}/file_loader"
|
24
|
+
autoload :FileWriter, "#{PATH}/file_writer"
|
25
|
+
autoload :PathMatcher, "#{PATH}/path_matcher"
|
14
26
|
end
|
15
27
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DevSuite
|
4
|
+
module Utils
|
5
|
+
module WarningHandler
|
6
|
+
extend self
|
7
|
+
|
8
|
+
def warn_if_missing(attribute_name, value)
|
9
|
+
if value.nil? || (value.respond_to?(:empty?) && value.empty?)
|
10
|
+
log_warning("#{attribute_name} is missing or empty!")
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def log_warning(message)
|
17
|
+
Utils::Logger.log(
|
18
|
+
message,
|
19
|
+
level: :warn,
|
20
|
+
emoji: :warning,
|
21
|
+
)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/dev_suite/version.rb
CHANGED
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DevSuite
|
4
|
+
module Workflow
|
5
|
+
class Engine
|
6
|
+
attr_reader :steps, :context
|
7
|
+
|
8
|
+
def initialize(context = {}, **options)
|
9
|
+
@steps = []
|
10
|
+
@context = StepContext.new(context, **options)
|
11
|
+
end
|
12
|
+
|
13
|
+
# Add steps to the engine
|
14
|
+
def add_step(step)
|
15
|
+
@steps << step
|
16
|
+
self # Return the current engine instance to support chaining
|
17
|
+
end
|
18
|
+
|
19
|
+
# Execute the workflow
|
20
|
+
def execute
|
21
|
+
@steps.each do |step|
|
22
|
+
step.execute(@context)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DevSuite
|
4
|
+
module Workflow
|
5
|
+
module Step
|
6
|
+
class Base
|
7
|
+
attr_accessor :name, :next_step
|
8
|
+
|
9
|
+
def initialize(name, &action)
|
10
|
+
@name = name
|
11
|
+
@action = action
|
12
|
+
@next_step = nil
|
13
|
+
end
|
14
|
+
|
15
|
+
# Executes the step and moves to the next step
|
16
|
+
def execute(context)
|
17
|
+
result = perform_action(context)
|
18
|
+
Utils::Logger.log("Step: #{@name} - Result: #{result}", level: :info)
|
19
|
+
update_context(context, result)
|
20
|
+
execute_next_step(context)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Chain the next step
|
24
|
+
def next(step)
|
25
|
+
@next_step = step
|
26
|
+
step
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
# Perform the action associated with this step
|
32
|
+
def perform_action(context)
|
33
|
+
@action.call(context)
|
34
|
+
end
|
35
|
+
|
36
|
+
# Update the context with the result of the action
|
37
|
+
def update_context(context, result)
|
38
|
+
context.update(result)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Execute the next step if it exists
|
42
|
+
def execute_next_step(context)
|
43
|
+
@next_step&.execute(context)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DevSuite
|
4
|
+
module Workflow
|
5
|
+
module Step
|
6
|
+
class Composite < Base
|
7
|
+
def initialize(name)
|
8
|
+
super
|
9
|
+
@steps = []
|
10
|
+
end
|
11
|
+
|
12
|
+
# Add steps to the composite
|
13
|
+
def add_step(step)
|
14
|
+
@steps << step
|
15
|
+
self
|
16
|
+
end
|
17
|
+
|
18
|
+
# Override execute to run all steps in sequence
|
19
|
+
def execute(context)
|
20
|
+
@steps.each do |step|
|
21
|
+
step.execute(context)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DevSuite
|
4
|
+
module Workflow
|
5
|
+
module Step
|
6
|
+
class Conditional < Base
|
7
|
+
def initialize(name, condition, &action)
|
8
|
+
super(name, &action)
|
9
|
+
@condition = condition
|
10
|
+
end
|
11
|
+
|
12
|
+
# Only execute if the condition is met
|
13
|
+
def execute(context)
|
14
|
+
if @condition.call(context)
|
15
|
+
super
|
16
|
+
else
|
17
|
+
Utils::Logger.log("Step: #{@name} - Skipped due to condition", level: :info)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DevSuite
|
4
|
+
module Workflow
|
5
|
+
module Step
|
6
|
+
class Loop < Base
|
7
|
+
def initialize(name, iterations, &action)
|
8
|
+
super(name, &action)
|
9
|
+
@iterations = iterations
|
10
|
+
end
|
11
|
+
|
12
|
+
def execute(context)
|
13
|
+
@iterations.times do |i|
|
14
|
+
Utils::Logger.log("Step: #{@name} - Iteration: #{i + 1}", level: :info)
|
15
|
+
super(context)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DevSuite
|
4
|
+
module Workflow
|
5
|
+
module Step
|
6
|
+
class Parallel < Base
|
7
|
+
# Executes multiple tasks in parallel using threads
|
8
|
+
def execute(context)
|
9
|
+
tasks = @action.call(context)
|
10
|
+
threads = tasks.map do |task|
|
11
|
+
Thread.new { task.call(context) }
|
12
|
+
end
|
13
|
+
threads.each(&:join)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DevSuite
|
4
|
+
module Workflow
|
5
|
+
class StepContext
|
6
|
+
attr_accessor :data, :store
|
7
|
+
|
8
|
+
def initialize(data = {}, **options)
|
9
|
+
@data = data
|
10
|
+
@store = create_store(options)
|
11
|
+
end
|
12
|
+
|
13
|
+
# Update the context with new data
|
14
|
+
def update(new_data)
|
15
|
+
Utils::Data.deep_merge!(@data, new_data)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Retrieve data by key
|
19
|
+
def get(key)
|
20
|
+
Utils::Data.get_value_by_path(@data, key)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def create_store(options)
|
26
|
+
driver = options[:driver] || :file
|
27
|
+
path = options[:path]
|
28
|
+
Utils::Store.create(driver: driver, path: path)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DevSuite
|
4
|
+
module Workflow
|
5
|
+
require_relative "step_context"
|
6
|
+
require_relative "step"
|
7
|
+
require_relative "engine"
|
8
|
+
|
9
|
+
class << self
|
10
|
+
def create_engine(context = {}, **options)
|
11
|
+
Engine.new(context, **options)
|
12
|
+
end
|
13
|
+
|
14
|
+
def create_step(name, &block)
|
15
|
+
Step::Base.new(name, &block)
|
16
|
+
end
|
17
|
+
|
18
|
+
def create_parallel_step(name, &block)
|
19
|
+
Step::Parallel.new(name, &block)
|
20
|
+
end
|
21
|
+
|
22
|
+
def create_conditional_step(name, condition, &block)
|
23
|
+
Step::Conditional.new(name, condition, &block)
|
24
|
+
end
|
25
|
+
|
26
|
+
def create_loop_step(name, iterations, &block)
|
27
|
+
Step::Loop.new(name, iterations, &block)
|
28
|
+
end
|
29
|
+
|
30
|
+
def create_composite_step(name)
|
31
|
+
Step::Composite.new(name)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|