dev_suite 0.2.4 → 0.2.7

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 (152) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +4 -5
  3. data/.vscode/extensions.json +8 -0
  4. data/.vscode/launch.json +39 -0
  5. data/.vscode/settings.json +28 -0
  6. data/Gemfile +6 -1
  7. data/Gemfile.lock +28 -2
  8. data/README.md +69 -8
  9. data/bin/rspec +27 -0
  10. data/dev_suite.gemspec +0 -4
  11. data/lib/dev_suite/cli/commands/base.rb +0 -2
  12. data/lib/dev_suite/cli/commands/tree.rb +3 -3
  13. data/lib/dev_suite/cli/commands/version.rb +1 -1
  14. data/lib/dev_suite/cli/main.rb +1 -1
  15. data/lib/dev_suite/dev_suite.rb +12 -0
  16. data/lib/dev_suite/directory_tree/builder/base.rb +1 -1
  17. data/lib/dev_suite/directory_tree/builder/builder.rb +13 -0
  18. data/lib/dev_suite/directory_tree/builder.rb +1 -12
  19. data/lib/dev_suite/directory_tree/config/config.rb +11 -0
  20. data/lib/dev_suite/directory_tree/config/configuration.rb +34 -0
  21. data/lib/dev_suite/directory_tree/config.rb +2 -36
  22. data/lib/dev_suite/directory_tree/directory_tree.rb +0 -3
  23. data/lib/dev_suite/directory_tree/node/node.rb +12 -0
  24. data/lib/dev_suite/directory_tree/node.rb +1 -4
  25. data/lib/dev_suite/directory_tree/renderer/base.rb +1 -7
  26. data/lib/dev_suite/directory_tree/renderer/renderer.rb +14 -0
  27. data/lib/dev_suite/directory_tree/renderer.rb +1 -13
  28. data/lib/dev_suite/directory_tree/visualizer/base.rb +1 -1
  29. data/lib/dev_suite/directory_tree/visualizer/visualizer.rb +16 -0
  30. data/lib/dev_suite/directory_tree/visualizer.rb +1 -15
  31. data/lib/dev_suite/performance/analyzer.rb +1 -1
  32. data/lib/dev_suite/performance/config/config.rb +11 -0
  33. data/lib/dev_suite/performance/config/configuration.rb +30 -0
  34. data/lib/dev_suite/performance/config.rb +2 -30
  35. data/lib/dev_suite/performance/data/data.rb +9 -0
  36. data/lib/dev_suite/performance/data.rb +1 -1
  37. data/lib/dev_suite/performance/profiler/base.rb +1 -1
  38. data/lib/dev_suite/performance/profiler/profiler.rb +16 -0
  39. data/lib/dev_suite/performance/profiler.rb +1 -20
  40. data/lib/dev_suite/performance/profiler_manager.rb +1 -0
  41. data/lib/dev_suite/performance/{reportor → reporter}/base.rb +2 -2
  42. data/lib/dev_suite/performance/{reportor → reporter}/helpers/stat_mappings.rb +1 -1
  43. data/lib/dev_suite/performance/{reportor → reporter}/helpers/table_builder.rb +1 -1
  44. data/lib/dev_suite/performance/{reportor → reporter}/helpers.rb +1 -1
  45. data/lib/dev_suite/performance/reporter/reporter.rb +15 -0
  46. data/lib/dev_suite/performance/{reportor → reporter}/simple.rb +1 -1
  47. data/lib/dev_suite/performance/reporter.rb +9 -0
  48. data/lib/dev_suite/performance.rb +1 -1
  49. data/lib/dev_suite/request_logger/adapter/adapter.rb +31 -0
  50. data/lib/dev_suite/request_logger/adapter/base.rb +17 -0
  51. data/lib/dev_suite/request_logger/adapter/faraday.rb +37 -0
  52. data/lib/dev_suite/request_logger/adapter/middleware/faraday.rb +22 -0
  53. data/lib/dev_suite/request_logger/adapter/net_http.rb +43 -0
  54. data/lib/dev_suite/request_logger/adapter.rb +9 -0
  55. data/lib/dev_suite/request_logger/config/config.rb +11 -0
  56. data/lib/dev_suite/request_logger/config/configuration.rb +24 -0
  57. data/lib/dev_suite/request_logger/config.rb +9 -0
  58. data/lib/dev_suite/request_logger/extractor/base.rb +17 -0
  59. data/lib/dev_suite/request_logger/extractor/extractor.rb +22 -0
  60. data/lib/dev_suite/request_logger/extractor/faraday.rb +37 -0
  61. data/lib/dev_suite/request_logger/extractor/net_http.rb +36 -0
  62. data/lib/dev_suite/request_logger/extractor.rb +9 -0
  63. data/lib/dev_suite/request_logger/logger.rb +87 -0
  64. data/lib/dev_suite/request_logger/request.rb +19 -0
  65. data/lib/dev_suite/request_logger/request_logger.rb +32 -0
  66. data/lib/dev_suite/request_logger/response.rb +28 -0
  67. data/lib/dev_suite/request_logger.rb +7 -0
  68. data/lib/dev_suite/utils/color/color.rb +12 -0
  69. data/lib/dev_suite/utils/color/config/config.rb +13 -0
  70. data/lib/dev_suite/utils/color/config/configuration.rb +31 -0
  71. data/lib/dev_suite/utils/color/config.rb +2 -31
  72. data/lib/dev_suite/utils/color/palette/base.rb +1 -14
  73. data/lib/dev_suite/utils/color/palette/palette.rb +16 -0
  74. data/lib/dev_suite/utils/color/palette.rb +1 -13
  75. data/lib/dev_suite/utils/color/strategy/base.rb +1 -1
  76. data/lib/dev_suite/utils/color/strategy/strategy.rb +20 -0
  77. data/lib/dev_suite/utils/color/strategy/theme.rb +6 -7
  78. data/lib/dev_suite/utils/color/strategy.rb +1 -21
  79. data/lib/dev_suite/utils/color.rb +1 -4
  80. data/lib/dev_suite/utils/construct/component/base.rb +30 -0
  81. data/lib/dev_suite/utils/construct/component/component.rb +12 -0
  82. data/lib/dev_suite/utils/construct/component/initializer.rb +28 -0
  83. data/lib/dev_suite/utils/construct/component/manager.rb +57 -0
  84. data/lib/dev_suite/utils/construct/component.rb +11 -0
  85. data/lib/dev_suite/utils/construct/config/attribute/attr_definition.rb +76 -0
  86. data/lib/dev_suite/utils/construct/config/attribute/attr_initialization.rb +22 -0
  87. data/lib/dev_suite/utils/construct/config/attribute/attr_resolving.rb +80 -0
  88. data/lib/dev_suite/utils/construct/config/attribute/attribute.rb +24 -0
  89. data/lib/dev_suite/utils/construct/config/attribute/validator.rb +55 -0
  90. data/lib/dev_suite/utils/construct/config/attribute.rb +13 -0
  91. data/lib/dev_suite/utils/construct/config/base.rb +25 -0
  92. data/lib/dev_suite/utils/construct/config/config.rb +16 -0
  93. data/lib/dev_suite/utils/construct/config/dependency_handler.rb +56 -0
  94. data/lib/dev_suite/utils/construct/config/hook/hook.rb +22 -0
  95. data/lib/dev_suite/utils/construct/config/hook/hook_registry.rb +24 -0
  96. data/lib/dev_suite/utils/construct/config/hook/hook_runner.rb +20 -0
  97. data/lib/dev_suite/utils/construct/config/hook/manager.rb +36 -0
  98. data/lib/dev_suite/utils/construct/config/hook.rb +13 -0
  99. data/lib/dev_suite/utils/construct/config/manager.rb +41 -0
  100. data/lib/dev_suite/utils/construct/config/settings/base.rb +59 -0
  101. data/lib/dev_suite/utils/construct/config/settings/manager.rb +38 -0
  102. data/lib/dev_suite/utils/construct/config/settings/settings.rb +14 -0
  103. data/lib/dev_suite/utils/construct/config/settings.rb +13 -0
  104. data/lib/dev_suite/utils/construct/config.rb +11 -0
  105. data/lib/dev_suite/utils/construct/construct.rb +10 -0
  106. data/lib/dev_suite/utils/construct.rb +16 -0
  107. data/lib/dev_suite/utils/dependency_loader.rb +71 -0
  108. data/lib/dev_suite/utils/emoji.rb +71 -0
  109. data/lib/dev_suite/utils/error_handler.rb +24 -0
  110. data/lib/dev_suite/utils/file_loader/config/config.rb +13 -0
  111. data/lib/dev_suite/utils/file_loader/config/configuration.rb +33 -0
  112. data/lib/dev_suite/utils/file_loader/config.rb +11 -0
  113. data/lib/dev_suite/utils/file_loader/file_loader.rb +23 -0
  114. data/lib/dev_suite/utils/file_loader/loader/base.rb +21 -0
  115. data/lib/dev_suite/utils/file_loader/loader/json.rb +21 -0
  116. data/lib/dev_suite/utils/file_loader/loader/loader.rb +41 -0
  117. data/lib/dev_suite/utils/file_loader/loader/text.rb +21 -0
  118. data/lib/dev_suite/utils/file_loader/loader/yaml.rb +38 -0
  119. data/lib/dev_suite/utils/file_loader/loader.rb +13 -0
  120. data/lib/dev_suite/utils/file_loader/loader_manager.rb +34 -0
  121. data/lib/dev_suite/utils/file_loader/loader_registry.rb +36 -0
  122. data/lib/dev_suite/utils/file_loader.rb +9 -0
  123. data/lib/dev_suite/utils/logger.rb +58 -0
  124. data/lib/dev_suite/utils/path_matcher/matcher.rb +31 -0
  125. data/lib/dev_suite/utils/path_matcher/path_matcher.rb +17 -0
  126. data/lib/dev_suite/utils/path_matcher/pattern.rb +35 -0
  127. data/lib/dev_suite/utils/path_matcher.rb +9 -0
  128. data/lib/dev_suite/utils/table/config/config.rb +13 -0
  129. data/lib/dev_suite/utils/table/config/configuration.rb +32 -0
  130. data/lib/dev_suite/utils/table/config.rb +2 -23
  131. data/lib/dev_suite/utils/table/formatter/formatter.rb +12 -0
  132. data/lib/dev_suite/utils/table/formatter.rb +1 -2
  133. data/lib/dev_suite/utils/table/renderer/base.rb +1 -7
  134. data/lib/dev_suite/utils/table/renderer/renderer.rb +16 -0
  135. data/lib/dev_suite/utils/table/renderer/simple.rb +9 -5
  136. data/lib/dev_suite/utils/table/renderer.rb +1 -13
  137. data/lib/dev_suite/utils/table/table.rb +6 -0
  138. data/lib/dev_suite/utils/table.rb +0 -6
  139. data/lib/dev_suite/utils/utils.rb +15 -0
  140. data/lib/dev_suite/utils.rb +1 -3
  141. data/lib/dev_suite/version.rb +3 -1
  142. data/lib/dev_suite.rb +1 -10
  143. metadata +101 -44
  144. data/lib/dev_suite/directory_tree/settings.rb +0 -18
  145. data/lib/dev_suite/emoji.rb +0 -33
  146. data/lib/dev_suite/error_handler.rb +0 -22
  147. data/lib/dev_suite/logger.rb +0 -56
  148. data/lib/dev_suite/performance/reportor.rb +0 -22
  149. data/lib/dev_suite/utils/config_tools/configuration.rb +0 -134
  150. data/lib/dev_suite/utils/config_tools/settings.rb +0 -67
  151. data/lib/dev_suite/utils/config_tools.rb +0 -10
  152. data/lib/dev_suite/utils/table/settings.rb +0 -34
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DevSuite
4
+ module Utils
5
+ module Construct
6
+ module Config
7
+ module Attribute
8
+ require_relative "validator"
9
+
10
+ module AttrResolving
11
+ private
12
+
13
+ # Sets a configuration attribute value with validation and resolution
14
+ def set_config_attr(attr:, value:)
15
+ attr_details = fetch_attr_details(attr)
16
+
17
+ store_original_value(attr, value)
18
+ validated_value = validate_config_attr(attr, value, attr_details)
19
+ resolved_value = resolve_config_attr_value(validated_value, attr_details)
20
+
21
+ store_resolved_value(attr, resolved_value)
22
+ end
23
+
24
+ # Fetches the details of a configuration attribute
25
+ def fetch_attr_details(attr_name)
26
+ self.class.config_attrs[attr_name]
27
+ end
28
+
29
+ # Stores the original value of an attribute before processing
30
+ def store_original_value(attr_name, value)
31
+ instance_variable_set("@original_#{attr_name}", value)
32
+ end
33
+
34
+ # Stores the resolved value of an attribute after processing
35
+ def store_resolved_value(attr_name, value)
36
+ instance_variable_set("@#{attr_name}", value)
37
+ end
38
+
39
+ # Validates the value of a configuration attribute
40
+ def validate_config_attr(attr_name, value, attr_details)
41
+ if attr_details[:type]
42
+ Validator.validate_config_attr_type!(
43
+ attr: attr_name,
44
+ value: value,
45
+ type: attr_details[:type],
46
+ )
47
+ end
48
+ value
49
+ end
50
+
51
+ # Resolves the value of a configuration attribute
52
+ def resolve_config_attr_value(value, attr_details)
53
+ if attr_details[:resolver]
54
+ resolve_config_attr(
55
+ value: value,
56
+ resolver: attr_details[:resolver],
57
+ )
58
+ else
59
+ value
60
+ end
61
+ end
62
+
63
+ # Resolves the value of an attribute based on its resolver.
64
+ # If no resolver is provided, the value is returned as is.
65
+ def resolve_config_attr(value:, resolver:)
66
+ case resolver
67
+ when Proc
68
+ resolver.call(value)
69
+ when Symbol
70
+ send(resolver, value)
71
+ else
72
+ value
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DevSuite
4
+ module Utils
5
+ module Construct
6
+ module Config
7
+ module Attribute
8
+ require_relative "attr_definition"
9
+ require_relative "attr_initialization"
10
+ require_relative "attr_resolving"
11
+
12
+ class << self
13
+ def included(base)
14
+ base.extend(AttrDefinition)
15
+ end
16
+ end
17
+
18
+ include AttrInitialization
19
+ include AttrResolving
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DevSuite
4
+ module Utils
5
+ module Construct
6
+ module Config
7
+ module Attribute
8
+ module Validator
9
+ extend self
10
+
11
+ # Validates an attribute's value based on its type.
12
+ #
13
+ # @param attr [Symbol] The name of the attribute.
14
+ # @param value [Object] The value to validate.
15
+ # @param type [Symbol] The expected type of the attribute.
16
+ def validate_config_attr_type!(attr:, value:, type:)
17
+ case type
18
+ when :symbol
19
+ validate_symbol!(value)
20
+ when :hash
21
+ validate_hash!(value)
22
+ when :array
23
+ validate_array!(value)
24
+ when :class
25
+ validate_instance_of!(value, Object)
26
+ else
27
+ raise ArgumentError, "Unknown type #{type} for attribute #{attr}"
28
+ end
29
+ end
30
+
31
+ # Utility method to validate a Symbol.
32
+ def validate_symbol!(value)
33
+ raise ArgumentError, "Expected a Symbol, got #{value.class}" unless value.is_a?(Symbol)
34
+ end
35
+
36
+ # Utility method to validate a Hash.
37
+ def validate_hash!(value)
38
+ raise ArgumentError, "Expected a Hash, got #{value.class}" unless value.is_a?(Hash)
39
+ end
40
+
41
+ # Utility method to validate an Array.
42
+ def validate_array!(value)
43
+ raise ArgumentError, "Expected an Array, got #{value.class}" unless value.is_a?(Array)
44
+ end
45
+
46
+ # Utility method to validate a class instance.
47
+ def validate_instance_of!(value, klass)
48
+ raise ArgumentError, "Expected an instance of #{klass}, got #{value.class}" unless value.is_a?(klass)
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DevSuite
4
+ module Utils
5
+ module Construct
6
+ module Config
7
+ module Attribute
8
+ require_relative "attribute/attribute"
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DevSuite
4
+ module Utils
5
+ module Construct
6
+ module Config
7
+ class Base
8
+ # Foundation for all configurations
9
+ include Attribute
10
+ include Hook
11
+
12
+ # Include the settings manager and dependency handler
13
+ include Settings::Manager
14
+ include DependencyHandler
15
+
16
+ def initialize
17
+ run_hooks(:before_initialize)
18
+ initialize_config_attrs
19
+ run_hooks(:after_initialize)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DevSuite
4
+ module Utils
5
+ module Construct
6
+ module Config
7
+ require_relative "attribute"
8
+ require_relative "hook"
9
+ require_relative "settings"
10
+ require_relative "dependency_handler"
11
+ require_relative "base"
12
+ require_relative "manager"
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DevSuite
4
+ module Utils
5
+ module Construct
6
+ module Config
7
+ module DependencyHandler
8
+ class << self
9
+ def included(base)
10
+ base.class_eval do
11
+ attr_accessor(:missing_dependencies)
12
+ end
13
+ base.include(InstanceMethods)
14
+ end
15
+ end
16
+
17
+ module InstanceMethods
18
+ def initialize(*args)
19
+ super
20
+ @missing_dependencies ||= []
21
+ end
22
+
23
+ def delete_option_on_failure(attr_name, option_key, *missing_dependencies)
24
+ log_missing_dependency(attr_name, option_key, missing_dependencies)
25
+ send(attr_name).delete(option_key)
26
+ track_missing_dependency(missing_dependencies)
27
+ end
28
+
29
+ private
30
+
31
+ def track_missing_dependency(missing_dependencies)
32
+ @missing_dependencies = missing_dependencies
33
+ end
34
+
35
+ def log_missing_dependency(attr_name, option_key, missing_dependencies)
36
+ missing_dependencies.each do |dependency|
37
+ Utils::Logger.log(
38
+ "Missing dependency: #{dependency}. " \
39
+ "Please add `gem '#{dependency}'` to your Gemfile and run `bundle install`.",
40
+ level: :warn,
41
+ emoji: :warning,
42
+ )
43
+
44
+ Utils::Logger.log(
45
+ "Deleting option #{option_key} from `config.#{attr_name}`",
46
+ level: :warn,
47
+ emoji: :warning,
48
+ )
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DevSuite
4
+ module Utils
5
+ module Construct
6
+ module Config
7
+ module Hook
8
+ require_relative "hook_registry"
9
+ require_relative "hook_runner"
10
+
11
+ class << self
12
+ def included(base)
13
+ base.extend(HookRegistry)
14
+ end
15
+ end
16
+
17
+ include HookRunner
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DevSuite
4
+ module Utils
5
+ module Construct
6
+ module Config
7
+ module Hook
8
+ module HookRegistry
9
+ # Registers a hook for a specific stage
10
+ def register_hook(stage, &block)
11
+ hooks[stage] ||= []
12
+ hooks[stage] << block
13
+ end
14
+
15
+ # Retrieves the hooks registered for this class
16
+ def hooks
17
+ @hooks ||= {}
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DevSuite
4
+ module Utils
5
+ module Construct
6
+ module Config
7
+ module Hook
8
+ module HookRunner
9
+ private
10
+
11
+ # Runs all hooks registered for a given stage
12
+ def run_hooks(stage)
13
+ self.class.hooks[stage]&.each { |hook| instance_eval(&hook) }
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DevSuite
4
+ module Utils
5
+ module Construct
6
+ module Config
7
+ module Hook
8
+ module Manager
9
+ class << self
10
+ def included(base)
11
+ base.extend(ClassMethods)
12
+ end
13
+ end
14
+
15
+ module ClassMethods
16
+ def register_hook(stage, &block)
17
+ hooks[stage] ||= []
18
+ hooks[stage] << block
19
+ end
20
+
21
+ def hooks
22
+ @hooks ||= {}
23
+ end
24
+ end
25
+
26
+ private
27
+
28
+ def run_hooks(stage)
29
+ self.class.hooks[stage]&.each { |hook| instance_eval(&hook) }
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DevSuite
4
+ module Utils
5
+ module Construct
6
+ module Config
7
+ module Hook
8
+ require_relative "hook/hook"
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DevSuite
4
+ module Utils
5
+ module Construct
6
+ module Config
7
+ module Manager
8
+ class << self
9
+ def included(base)
10
+ base.extend(ClassMethods)
11
+ end
12
+ end
13
+
14
+ module ClassMethods
15
+ # Provides access to a single instance of the configuration class
16
+ # It dynamically uses the Configuration class in the including module's namespace
17
+ def configuration
18
+ @configuration ||= self::Configuration.new
19
+ end
20
+
21
+ # Allows block-based configuration
22
+ # Example usage:
23
+ # ConfigClass.configure do |config|
24
+ # config.attr_name = value
25
+ # end
26
+ def configure
27
+ yield(configuration)
28
+ rescue StandardError => e
29
+ ErrorHandler.handle_error(e)
30
+ end
31
+
32
+ # Resets the configuration by reinitializing it with default values
33
+ def reset!
34
+ @configuration = self::Configuration.new # Reinitialize the configuration instance
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DevSuite
4
+ module Utils
5
+ module Construct
6
+ module Config
7
+ module Settings
8
+ class Base
9
+ def initialize(settings = {})
10
+ @default_settings = settings
11
+ @settings = merge_settings(@default_settings, settings)
12
+ end
13
+
14
+ def set(*keys, value)
15
+ key_path = normalize_keys(keys)
16
+ last_key = key_path.pop
17
+ target = key_path.each_with_object(@settings) do |key, nested|
18
+ nested[key] ||= {}
19
+ end
20
+ target[last_key] = value
21
+ end
22
+
23
+ def get(*keys)
24
+ key_path = normalize_keys(keys)
25
+ key_path.reduce(@settings) do |nested, key|
26
+ nested.is_a?(Hash) ? nested[key] : nil
27
+ end
28
+ end
29
+
30
+ def reset!
31
+ @settings = @default_settings
32
+ end
33
+
34
+ private
35
+
36
+ def normalize_keys(keys)
37
+ key_path = keys.flatten
38
+ if key_path.size == 1 && key_path.first.is_a?(String)
39
+ key_path.first.to_s.split(".").map(&:to_sym)
40
+ else
41
+ key_path.map(&:to_sym)
42
+ end
43
+ end
44
+
45
+ def merge_settings(defaults, overrides)
46
+ defaults.merge(overrides) do |_key, oldval, newval|
47
+ if oldval.is_a?(Hash) && newval.is_a?(Hash)
48
+ merge_settings(oldval, newval)
49
+ else
50
+ newval
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DevSuite
4
+ module Utils
5
+ module Construct
6
+ module Config
7
+ module Settings
8
+ module Manager
9
+ class << self
10
+ def included(base)
11
+ base.extend(ClassMethods)
12
+ end
13
+ end
14
+
15
+ module ClassMethods
16
+ # Ensure that default configuration attributes are applied to subclasses.
17
+ def inherited(subclass)
18
+ subclass.set_default_settings
19
+ super
20
+ end
21
+
22
+ # Define default settings for the class.
23
+ def set_default_settings(settings = {})
24
+ config_attr(:settings, default_value: settings, type: :hash, resolver: :resolve_settings)
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ def resolve_settings(value)
31
+ Base.new(value)
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DevSuite
4
+ module Utils
5
+ module Construct
6
+ module Config
7
+ module Settings
8
+ require_relative "base"
9
+ require_relative "manager"
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DevSuite
4
+ module Utils
5
+ module Construct
6
+ module Config
7
+ module Settings
8
+ require_relative "settings/settings"
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DevSuite
4
+ module Utils
5
+ module Construct
6
+ module Config
7
+ require_relative "config/config"
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DevSuite
4
+ module Utils
5
+ module Construct
6
+ require_relative "config"
7
+ require_relative "component"
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DevSuite
4
+ module Utils
5
+ module Construct
6
+ # The Construct module serves as a namespace for reusable constructs that
7
+ # provide foundational utilities, such as configuration management, which
8
+ # can be included in other modules throughout the DevSuite framework.
9
+ #
10
+ # This module centralizes shared functionality to promote code reuse,
11
+ # maintainability, and consistency across different modules.
12
+
13
+ require_relative "construct/construct"
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DevSuite
4
+ module Utils
5
+ module DependencyLoader
6
+ class << self
7
+ # Public method to safely load multiple dependencies.
8
+ # Executes the given block if all dependencies are successfully loaded.
9
+ # Calls the on_failure handler with the list of missing dependencies if any are not found.
10
+ #
11
+ # @param dependencies [Array<String>] List of gem names to load.
12
+ # @param on_failure [Proc] Handler to call with missing dependencies if any are not found.
13
+ # @yield Executes the block if all dependencies are loaded.
14
+ def safe_load_dependencies(*dependencies, on_failure: method(:default_failure_handler))
15
+ missing_dependencies = find_missing_dependencies(dependencies)
16
+
17
+ if missing_dependencies.empty?
18
+ yield if block_given?
19
+ else
20
+ on_failure.call(missing_dependencies)
21
+ end
22
+ end
23
+
24
+ # Check if a gem is installed by attempting to require it.
25
+ #
26
+ # @param gem_name [String] The name of the gem to check.
27
+ # @return [Boolean] true if the gem is installed, false otherwise.
28
+ def gem_installed?(gem_name)
29
+ require gem_name
30
+ true
31
+ rescue LoadError
32
+ false
33
+ end
34
+
35
+ private
36
+
37
+ # Finds and returns a list of missing dependencies from the provided list.
38
+ #
39
+ # @param dependencies [Array<String>] List of gem names to check.
40
+ # @return [Array<String>] List of missing dependencies.
41
+ def find_missing_dependencies(dependencies)
42
+ dependencies.reject { |gem_name| gem_installed?(gem_name) }
43
+ end
44
+
45
+ # Default failure handler that logs missing dependencies.
46
+ #
47
+ # @param missing_dependencies [Array<String>] List of missing dependencies.
48
+ def default_failure_handler(missing_dependencies)
49
+ missing_dependencies.each do |gem_name|
50
+ log_missing_dependency(gem_name)
51
+ end
52
+ end
53
+
54
+ # Logs a warning about a missing dependency.
55
+ #
56
+ # @param gem_name [String] The name of the missing gem.
57
+ def log_missing_dependency(gem_name)
58
+ gem_simple_name = gem_name.split("/").last.capitalize
59
+ message = "#{gem_simple_name} gem not installed. Please add `gem '#{gem_simple_name.downcase}'` " \
60
+ "to your Gemfile and run `bundle install`."
61
+
62
+ Utils::Logger.log(
63
+ message,
64
+ level: :warn,
65
+ emoji: :warning,
66
+ )
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end