dev_suite 0.2.11 → 0.2.12
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/.codeclimate.yml +49 -7
- data/Gemfile +4 -0
- data/Gemfile.lock +14 -1
- data/README.md +4 -0
- data/lib/dev_suite/method_tracer/logger.rb +52 -21
- data/lib/dev_suite/utils/color/colorizer.rb +1 -1
- data/lib/dev_suite/utils/color/palette/default.rb +33 -0
- data/lib/dev_suite/utils/data/path_access/data_traverser.rb +86 -0
- data/lib/dev_suite/utils/data/path_access/errors.rb +12 -0
- data/lib/dev_suite/utils/data/path_access/key_handler.rb +27 -0
- data/lib/dev_suite/utils/data/path_access/path_accessor.rb +36 -0
- data/lib/dev_suite/utils/data/path_access/path_parser.rb +35 -0
- data/lib/dev_suite/utils/data/path_access.rb +5 -151
- data/lib/dev_suite/utils/file_writer/file_writer.rb +14 -4
- data/lib/dev_suite/utils/file_writer/writer/base.rb +40 -15
- data/lib/dev_suite/utils/file_writer/writer/json.rb +1 -1
- data/lib/dev_suite/utils/file_writer/writer/text.rb +11 -9
- data/lib/dev_suite/utils/file_writer/writer/yaml.rb +1 -1
- data/lib/dev_suite/utils/file_writer/writer_manager.rb +40 -17
- data/lib/dev_suite/utils/logger/base.rb +54 -0
- data/lib/dev_suite/utils/logger/emoji.rb +17 -0
- data/lib/dev_suite/utils/logger/errors.rb +9 -0
- data/lib/dev_suite/utils/logger/formatter.rb +41 -0
- data/lib/dev_suite/utils/logger/logger.rb +29 -0
- data/lib/dev_suite/utils/logger.rb +1 -52
- data/lib/dev_suite/utils/table/renderer/simple.rb +5 -5
- data/lib/dev_suite/version.rb +1 -1
- metadata +12 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 89babbbfc8efcac3d35e1f60db7c5c880183eb7b77f5d43cd0a9380081815795
|
4
|
+
data.tar.gz: 34000a8d5129edf959325eaf30244333484128f399a72cc07e91329597a719fe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9aef9871a87ca4f4c076ad72191a179dc894acf9667b5ef1f1ca52389ce0c08dda75477d5f59fc611bbe2b0c6c26ef19df8a9ec0f4bfe1b025d83809390d6c1c
|
7
|
+
data.tar.gz: 0f99342d6399fde0bd6c7f3104bbcd490b64ae67f450d706f4518057c2534110660e420a24f2d38b5481a17757a97092e79f9d6bca450ea0b88273eeae959dda
|
data/.codeclimate.yml
CHANGED
@@ -1,12 +1,54 @@
|
|
1
1
|
version: "2"
|
2
2
|
checks:
|
3
|
-
|
3
|
+
argument-count:
|
4
4
|
enabled: true
|
5
|
-
|
5
|
+
complexity:
|
6
6
|
enabled: true
|
7
|
-
|
8
|
-
|
9
|
-
|
7
|
+
duplication:
|
8
|
+
enabled: true
|
9
|
+
file-lines:
|
10
|
+
enabled: true
|
11
|
+
method-lines:
|
12
|
+
enabled: true
|
13
|
+
return-statements:
|
14
|
+
enabled: true
|
15
|
+
similar-code:
|
16
|
+
enabled: true
|
17
|
+
npath-complexity:
|
18
|
+
enabled: true
|
19
|
+
identical-code:
|
20
|
+
enabled: true
|
21
|
+
|
22
|
+
engines:
|
23
|
+
rubocop:
|
24
|
+
enabled: true
|
25
|
+
channel: rubocop-1-48-1
|
26
|
+
config:
|
27
|
+
file: .rubocop.yml
|
28
|
+
bundler-audit:
|
29
|
+
enabled: true
|
30
|
+
channel: bundler-audit-0-9-1
|
31
|
+
duplication:
|
32
|
+
enabled: true
|
33
|
+
config:
|
34
|
+
languages:
|
35
|
+
ruby:
|
36
|
+
mass_threshold: 50
|
37
|
+
paths:
|
38
|
+
- "lib/**/*.rb"
|
39
|
+
fixme:
|
40
|
+
enabled: false
|
41
|
+
config:
|
42
|
+
strings:
|
43
|
+
- "TODO"
|
44
|
+
- "FIXME"
|
45
|
+
|
10
46
|
exclude_patterns:
|
11
|
-
- "
|
12
|
-
- "
|
47
|
+
- "spec/"
|
48
|
+
- "test/"
|
49
|
+
- "vendor/"
|
50
|
+
- "bin/"
|
51
|
+
- "log/"
|
52
|
+
- "tmp/"
|
53
|
+
- "coverage/"
|
54
|
+
- "examples/"
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
dev_suite (0.2.
|
4
|
+
dev_suite (0.2.12)
|
5
5
|
benchmark (~> 0.1)
|
6
6
|
csv (~> 3.0)
|
7
7
|
get_process_mem (~> 1.0)
|
@@ -10,11 +10,16 @@ PATH
|
|
10
10
|
GEM
|
11
11
|
remote: https://rubygems.org/
|
12
12
|
specs:
|
13
|
+
addressable (2.8.7)
|
14
|
+
public_suffix (>= 2.0.2, < 7.0)
|
13
15
|
ast (2.4.2)
|
14
16
|
benchmark (0.3.0)
|
15
17
|
bigdecimal (3.1.8)
|
16
18
|
coderay (1.1.3)
|
17
19
|
concurrent-ruby (1.3.4)
|
20
|
+
crack (1.0.0)
|
21
|
+
bigdecimal
|
22
|
+
rexml
|
18
23
|
csv (3.3.0)
|
19
24
|
diff-lcs (1.5.1)
|
20
25
|
docile (1.4.1)
|
@@ -47,6 +52,7 @@ GEM
|
|
47
52
|
get_process_mem (1.0.0)
|
48
53
|
bigdecimal (>= 2.0)
|
49
54
|
ffi (~> 1.0)
|
55
|
+
hashdiff (1.1.1)
|
50
56
|
i18n (1.14.5)
|
51
57
|
concurrent-ruby (~> 1.0)
|
52
58
|
json (2.7.2)
|
@@ -60,10 +66,12 @@ GEM
|
|
60
66
|
pry (0.14.2)
|
61
67
|
coderay (~> 1.1)
|
62
68
|
method_source (~> 1.0)
|
69
|
+
public_suffix (6.0.1)
|
63
70
|
racc (1.8.1)
|
64
71
|
rainbow (3.1.1)
|
65
72
|
rake (13.2.1)
|
66
73
|
regexp_parser (2.9.2)
|
74
|
+
rexml (3.3.8)
|
67
75
|
rspec (3.13.0)
|
68
76
|
rspec-core (~> 3.13.0)
|
69
77
|
rspec-expectations (~> 3.13.0)
|
@@ -101,6 +109,10 @@ GEM
|
|
101
109
|
simplecov_json_formatter (0.1.4)
|
102
110
|
thor (1.3.2)
|
103
111
|
unicode-display_width (2.5.0)
|
112
|
+
webmock (3.24.0)
|
113
|
+
addressable (>= 2.8.0)
|
114
|
+
crack (>= 0.3.2)
|
115
|
+
hashdiff (>= 0.4.0, < 2.0.0)
|
104
116
|
|
105
117
|
PLATFORMS
|
106
118
|
arm64-darwin-23
|
@@ -115,6 +127,7 @@ DEPENDENCIES
|
|
115
127
|
rubocop (~> 1.65)
|
116
128
|
rubocop-shopify (~> 2.15)
|
117
129
|
simplecov (~> 0.21)
|
130
|
+
webmock (~> 3.13)
|
118
131
|
|
119
132
|
BUNDLED WITH
|
120
133
|
2.5.17
|
data/README.md
CHANGED
@@ -428,6 +428,10 @@ Trace all method calls within a specific block of code, including optional loggi
|
|
428
428
|
🏁 #depth:1 < MathOperations#greet #=> "Hello, Ruby!" at (irb):12 in 0.02ms
|
429
429
|
Hello, Ruby!
|
430
430
|
```
|
431
|
+
|
432
|
+
**Tips**:
|
433
|
+
|
434
|
+
Use `max_depth` to Limit Tracing: If you have deeply nested method calls, use the `max_depth` option to limit the depth of tracing. This can help reduce the amount of log output and focus on the most relevant parts of your code. A recommended value for `max_depth` is between `2` and `5`, depending on the complexity of your code.
|
431
435
|
</details>
|
432
436
|
|
433
437
|
## Development
|
@@ -7,39 +7,70 @@ module DevSuite
|
|
7
7
|
def log_method_call(tp, tracer)
|
8
8
|
tracer.depth += 1
|
9
9
|
|
10
|
-
method_name = Helpers.format_method_name(tp)
|
11
|
-
params_str = Helpers.format_params(tp) if tracer.show_params
|
12
|
-
indent = Helpers.calculate_indent(tracer.depth)
|
13
|
-
|
14
10
|
# Store the start time for execution time calculation
|
15
11
|
tracer.start_times[tp.method_id] = Time.now
|
16
12
|
|
17
|
-
message =
|
18
|
-
Utils::Logger.log(
|
19
|
-
message,
|
20
|
-
emoji: :start,
|
21
|
-
color: :blue,
|
22
|
-
)
|
13
|
+
message = build_call_message(tp, tracer)
|
14
|
+
Utils::Logger.log(message, emoji: :start, color: :blue)
|
23
15
|
end
|
24
16
|
|
25
17
|
def log_method_return(tp, tracer)
|
26
18
|
duration = Helpers.calculate_duration(tp, tracer.start_times)
|
27
19
|
|
28
|
-
|
29
|
-
|
30
|
-
exec_time_str = Helpers.format_execution_time(duration) if tracer.show_execution_time
|
31
|
-
indent = Helpers.calculate_indent(tracer.depth)
|
32
|
-
|
33
|
-
message = "#{indent}#depth:#{tracer.depth} < #{method_name}#{result_str} at #{tp.path}:#{tp.lineno}#{exec_time_str}"
|
34
|
-
Utils::Logger.log(
|
35
|
-
message,
|
36
|
-
emoji: :finish,
|
37
|
-
color: :cyan,
|
38
|
-
)
|
20
|
+
message = build_return_message(tp, tracer, duration)
|
21
|
+
Utils::Logger.log(message, emoji: :finish, color: :cyan)
|
39
22
|
|
40
23
|
# Decrement depth safely
|
41
24
|
tracer.depth = [tracer.depth - 1, 0].max
|
42
25
|
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
# Builds the log message for method calls
|
30
|
+
#
|
31
|
+
# @param tp [TracePoint] The TracePoint object
|
32
|
+
# @param tracer [Tracer] The tracer instance
|
33
|
+
# @return [String] The formatted log message
|
34
|
+
def build_call_message(tp, tracer)
|
35
|
+
method_name = colorize_text(Helpers.format_method_name(tp), :blue)
|
36
|
+
params_str = tracer.show_params ? colorize_text(Helpers.format_params(tp), :yellow) : ""
|
37
|
+
indent = Helpers.calculate_indent(tracer.depth)
|
38
|
+
depth_str = colorize_text("#depth:#{tracer.depth}", :magenta)
|
39
|
+
|
40
|
+
"#{indent}#{depth_str} > #{method_name} at #{tp.path}:#{tp.lineno} #{params_str}"
|
41
|
+
end
|
42
|
+
|
43
|
+
# Builds the log message for method returns
|
44
|
+
#
|
45
|
+
# @param tp [TracePoint] The TracePoint object
|
46
|
+
# @param tracer [Tracer] The tracer instance
|
47
|
+
# @param duration [Float] The execution time
|
48
|
+
# @return [String] The formatted log message
|
49
|
+
def build_return_message(tp, tracer, duration)
|
50
|
+
method_name = colorize_text(Helpers.format_method_name(tp), :cyan)
|
51
|
+
result_str = tracer.show_results ? colorize_text(Helpers.format_result(tp), :green) : ""
|
52
|
+
exec_time_str = if tracer.show_execution_time
|
53
|
+
colorize_text(
|
54
|
+
Helpers.format_execution_time(duration),
|
55
|
+
:light_white,
|
56
|
+
)
|
57
|
+
else
|
58
|
+
""
|
59
|
+
end
|
60
|
+
indent = Helpers.calculate_indent(tracer.depth)
|
61
|
+
depth_str = colorize_text("#depth:#{tracer.depth}", :magenta)
|
62
|
+
|
63
|
+
"#{indent}#{depth_str} < #{method_name}#{result_str} at #{tp.path}:#{tp.lineno}#{exec_time_str}"
|
64
|
+
end
|
65
|
+
|
66
|
+
# Helper method to colorize text
|
67
|
+
#
|
68
|
+
# @param text [String] The text to colorize
|
69
|
+
# @param color [Symbol] The color to use
|
70
|
+
# @return [String] The colorized text
|
71
|
+
def colorize_text(text, color)
|
72
|
+
Utils::Color.colorize(text, color: color)
|
73
|
+
end
|
43
74
|
end
|
44
75
|
end
|
45
76
|
end
|
@@ -6,6 +6,8 @@ module DevSuite
|
|
6
6
|
module Palette
|
7
7
|
class Default < Base
|
8
8
|
COLORS = {
|
9
|
+
# Standard Colors
|
10
|
+
black: 30,
|
9
11
|
red: 31,
|
10
12
|
green: 32,
|
11
13
|
yellow: 33,
|
@@ -14,6 +16,37 @@ module DevSuite
|
|
14
16
|
cyan: 36,
|
15
17
|
white: 37,
|
16
18
|
default: 39,
|
19
|
+
|
20
|
+
# Light Colors
|
21
|
+
light_black: 90,
|
22
|
+
light_red: 91,
|
23
|
+
light_green: 92,
|
24
|
+
light_yellow: 93,
|
25
|
+
light_blue: 94,
|
26
|
+
light_magenta: 95,
|
27
|
+
light_cyan: 96,
|
28
|
+
light_white: 97,
|
29
|
+
|
30
|
+
# Background Colors
|
31
|
+
bg_black: 40,
|
32
|
+
bg_red: 41,
|
33
|
+
bg_green: 42,
|
34
|
+
bg_yellow: 43,
|
35
|
+
bg_blue: 44,
|
36
|
+
bg_magenta: 45,
|
37
|
+
bg_cyan: 46,
|
38
|
+
bg_white: 47,
|
39
|
+
bg_default: 49,
|
40
|
+
|
41
|
+
# Light Background Colors
|
42
|
+
bg_light_black: 100,
|
43
|
+
bg_light_red: 101,
|
44
|
+
bg_light_green: 102,
|
45
|
+
bg_light_yellow: 103,
|
46
|
+
bg_light_blue: 104,
|
47
|
+
bg_light_magenta: 105,
|
48
|
+
bg_light_cyan: 106,
|
49
|
+
bg_light_white: 107,
|
17
50
|
}.freeze
|
18
51
|
end
|
19
52
|
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "key_handler"
|
4
|
+
|
5
|
+
module DevSuite
|
6
|
+
module Utils
|
7
|
+
module Data
|
8
|
+
module PathAccess
|
9
|
+
module DataTraverser
|
10
|
+
extend self
|
11
|
+
|
12
|
+
# Traverse nested data for retrieving a value
|
13
|
+
def fetch(data, keys)
|
14
|
+
keys.reduce(data) { |current, key| traverse_data(current, key) }
|
15
|
+
end
|
16
|
+
|
17
|
+
# Traverse nested data for setting a value
|
18
|
+
def assign(data, keys, value)
|
19
|
+
last_key = keys.pop
|
20
|
+
target = keys.reduce(data) { |current, key| traverse_or_create(current, key) }
|
21
|
+
set_final_value(target, last_key, value)
|
22
|
+
end
|
23
|
+
|
24
|
+
# Traverse nested data for deleting a value
|
25
|
+
def remove(data, keys)
|
26
|
+
last_key = keys.pop
|
27
|
+
target = keys.reduce(data) { |current, key| traverse_data(current, key) }
|
28
|
+
delete_final_value(target, last_key)
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
# Traverse through hash or array data types
|
34
|
+
def traverse_data(current, key)
|
35
|
+
KeyHandler.validate_path(current, key)
|
36
|
+
case current
|
37
|
+
when Hash
|
38
|
+
current[KeyHandler.find_key(current, key)]
|
39
|
+
when Array
|
40
|
+
current[key.to_i]
|
41
|
+
else
|
42
|
+
raise DataStructureError, "Unexpected data type at '#{key}'"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Traverse or create new hash elements when setting a value
|
47
|
+
def traverse_or_create(current, key)
|
48
|
+
KeyHandler.validate_path(current, key)
|
49
|
+
case current
|
50
|
+
when Hash
|
51
|
+
current[KeyHandler.find_key(current, key)] ||= {}
|
52
|
+
when Array
|
53
|
+
current[key.to_i] ||= {}
|
54
|
+
else
|
55
|
+
raise DataStructureError, "Unexpected data type at '#{key}'"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# Set the final value in hash or array
|
60
|
+
def set_final_value(target, key, value)
|
61
|
+
case target
|
62
|
+
when Hash
|
63
|
+
target[KeyHandler.find_key(target, key)] = value
|
64
|
+
when Array
|
65
|
+
target[key] = value if key.is_a?(Integer)
|
66
|
+
else
|
67
|
+
raise DataStructureError, "Cannot set value on unsupported data type"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# Delete the final value from hash or array
|
72
|
+
def delete_final_value(target, key)
|
73
|
+
case target
|
74
|
+
when Hash
|
75
|
+
target.delete(KeyHandler.find_key(target, key))
|
76
|
+
when Array
|
77
|
+
target.delete_at(key) if key.is_a?(Integer)
|
78
|
+
else
|
79
|
+
raise DataStructureError, "Cannot delete key from unsupported data type"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DevSuite
|
4
|
+
module Utils
|
5
|
+
module Data
|
6
|
+
module PathAccess
|
7
|
+
module KeyHandler
|
8
|
+
extend self
|
9
|
+
|
10
|
+
# Find an existing key in a hash, handling both symbol and string keys
|
11
|
+
def find_key(hash, key)
|
12
|
+
return key if hash.key?(key)
|
13
|
+
return key.to_s if hash.key?(key.to_s)
|
14
|
+
return key.to_sym if hash.key?(key.to_sym)
|
15
|
+
|
16
|
+
key
|
17
|
+
end
|
18
|
+
|
19
|
+
# Validate the path by checking if it's pointing to a valid data structure
|
20
|
+
def validate_path(data, key)
|
21
|
+
raise InvalidPathError, "Invalid path at '#{key}'" if data.nil?
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "path_parser"
|
4
|
+
require_relative "data_traverser"
|
5
|
+
require_relative "key_handler"
|
6
|
+
require_relative "errors"
|
7
|
+
|
8
|
+
module DevSuite
|
9
|
+
module Utils
|
10
|
+
module Data
|
11
|
+
module PathAccess
|
12
|
+
module PathAccessor
|
13
|
+
extend self
|
14
|
+
|
15
|
+
# Get value from nested data
|
16
|
+
def get(data, path)
|
17
|
+
keys = PathParser.parse(path)
|
18
|
+
DataTraverser.fetch(data, keys)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Set value in nested data
|
22
|
+
def set(data, path, value)
|
23
|
+
keys = PathParser.parse(path)
|
24
|
+
DataTraverser.assign(data, keys, value)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Delete key in nested data
|
28
|
+
def delete(data, path)
|
29
|
+
keys = PathParser.parse(path)
|
30
|
+
DataTraverser.remove(data, keys)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DevSuite
|
4
|
+
module Utils
|
5
|
+
module Data
|
6
|
+
module PathAccess
|
7
|
+
module PathParser
|
8
|
+
extend self
|
9
|
+
|
10
|
+
def parse(path)
|
11
|
+
return path if path.is_a?(Array)
|
12
|
+
return parse_symbol_path(path) if path.is_a?(Symbol)
|
13
|
+
return parse_string_path(path) if path.is_a?(String)
|
14
|
+
|
15
|
+
[path]
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def parse_symbol_path(symbol_path)
|
21
|
+
symbol_path.to_s.split(/\.|\[|\]/).reject(&:empty?).map { |part| parse_part(part) }
|
22
|
+
end
|
23
|
+
|
24
|
+
def parse_string_path(string_path)
|
25
|
+
string_path.split(/\.|\[|\]/).reject(&:empty?).map { |part| parse_part(part) }
|
26
|
+
end
|
27
|
+
|
28
|
+
def parse_part(part)
|
29
|
+
part.match?(/^\d+$/) ? part.to_i : part.to_sym
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -4,167 +4,21 @@ module DevSuite
|
|
4
4
|
module Utils
|
5
5
|
module Data
|
6
6
|
module PathAccess
|
7
|
+
require_relative "path_access/path_accessor"
|
8
|
+
|
7
9
|
# Fetch value from a nested structure using a path
|
8
10
|
def get_value_by_path(data, path)
|
9
|
-
|
10
|
-
traverse_path_for_get(data, keys)
|
11
|
+
PathAccessor.get(data, path)
|
11
12
|
end
|
12
13
|
|
13
14
|
# Set value in a nested structure using a path
|
14
15
|
def set_value_by_path(data, path, value)
|
15
|
-
|
16
|
-
last_key = keys.pop
|
17
|
-
target = traverse_path_for_set(data, keys)
|
18
|
-
|
19
|
-
set_final_value(target, last_key, value)
|
16
|
+
PathAccessor.set(data, path, value)
|
20
17
|
end
|
21
18
|
|
22
19
|
# Delete a key from a nested structure using a path
|
23
20
|
def delete_key_by_path(data, path)
|
24
|
-
|
25
|
-
last_key = keys.pop
|
26
|
-
target = traverse_path_for_delete(data, keys)
|
27
|
-
|
28
|
-
delete_final_key(target, last_key)
|
29
|
-
end
|
30
|
-
|
31
|
-
private
|
32
|
-
|
33
|
-
# Parse the path into an array of keys/symbols/integers
|
34
|
-
def parse_path(path)
|
35
|
-
return path if path.is_a?(Array)
|
36
|
-
return [path] if single_symbol_path?(path)
|
37
|
-
|
38
|
-
parse_symbol_or_string_path(path)
|
39
|
-
end
|
40
|
-
|
41
|
-
# Check if the path is a symbol without dots
|
42
|
-
def single_symbol_path?(path)
|
43
|
-
path.is_a?(Symbol) && !path.to_s.include?(".")
|
44
|
-
end
|
45
|
-
|
46
|
-
# Parse a symbol or string path into an array of keys
|
47
|
-
def parse_symbol_or_string_path(path)
|
48
|
-
if path.is_a?(Symbol)
|
49
|
-
parse_symbol_path(path)
|
50
|
-
else
|
51
|
-
parse_string_path(path)
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
# Parse a symbol path that contains dots (e.g., :"test.1")
|
56
|
-
def parse_symbol_path(path)
|
57
|
-
path.to_s.split(".").map { |part| parse_part(part) }
|
58
|
-
end
|
59
|
-
|
60
|
-
# Parse a string path into keys (e.g., 'users.1.name')
|
61
|
-
def parse_string_path(path)
|
62
|
-
path.to_s.split(/\.|\[|\]/).reject(&:empty?).map { |part| parse_part(part) }
|
63
|
-
end
|
64
|
-
|
65
|
-
# Parse each part into either a symbol or integer
|
66
|
-
def parse_part(part)
|
67
|
-
part.match?(/^\d+$/) ? part.to_i : part.to_sym
|
68
|
-
end
|
69
|
-
|
70
|
-
# Helper to traverse the path for getting values
|
71
|
-
def traverse_path_for_get(data, keys)
|
72
|
-
keys.reduce(data) do |current_data, key|
|
73
|
-
check_invalid_path(current_data, key)
|
74
|
-
|
75
|
-
case current_data
|
76
|
-
when Hash
|
77
|
-
fetch_from_hash(current_data, key)
|
78
|
-
when Array
|
79
|
-
fetch_from_array(current_data, key)
|
80
|
-
else
|
81
|
-
raise KeyError, "Invalid data type at '#{key}'"
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
# Helper to traverse the path for setting values
|
87
|
-
def traverse_path_for_set(data, keys)
|
88
|
-
keys.reduce(data) do |current_data, key|
|
89
|
-
check_invalid_path(current_data, key)
|
90
|
-
|
91
|
-
case current_data
|
92
|
-
when Hash
|
93
|
-
current_data[find_existing_key(current_data, key)] ||= {}
|
94
|
-
when Array
|
95
|
-
current_data[key.to_i] ||= {}
|
96
|
-
else
|
97
|
-
break nil
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
# Helper to check for invalid paths
|
103
|
-
def check_invalid_path(data, key)
|
104
|
-
raise KeyError, "Invalid path at '#{key}'" if data.nil?
|
105
|
-
end
|
106
|
-
|
107
|
-
# Fetch value from a hash, trying both symbol and string keys
|
108
|
-
def fetch_from_hash(hash, key)
|
109
|
-
hash[key.to_sym] || hash[key.to_s]
|
110
|
-
end
|
111
|
-
|
112
|
-
# Fetch value from an array if the key is an integer
|
113
|
-
def fetch_from_array(array, key)
|
114
|
-
key.is_a?(Integer) ? array[key] : nil
|
115
|
-
end
|
116
|
-
|
117
|
-
# Set the final value in a hash or array
|
118
|
-
def set_final_value(target, last_key, value)
|
119
|
-
case target
|
120
|
-
when Hash
|
121
|
-
target[find_existing_key(target, last_key)] = value
|
122
|
-
when Array
|
123
|
-
if last_key.is_a?(Integer)
|
124
|
-
target[last_key] = value
|
125
|
-
else
|
126
|
-
raise KeyError, "Invalid path or type at '#{last_key}'"
|
127
|
-
end
|
128
|
-
else
|
129
|
-
raise KeyError, "Invalid target type for path at '#{last_key}'"
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
# Check if the key already exists and return the key in its original type (symbol or string)
|
134
|
-
def find_existing_key(hash, key)
|
135
|
-
return key if hash.key?(key) # Key already exists in original form
|
136
|
-
return key.to_s if hash.key?(key.to_s) # Exists as a string
|
137
|
-
return key.to_sym if hash.key?(key.to_sym) # Exists as a symbol
|
138
|
-
|
139
|
-
key # Otherwise, return the key as-is (use the incoming type)
|
140
|
-
end
|
141
|
-
|
142
|
-
# Helper to traverse the path for deletion
|
143
|
-
def traverse_path_for_delete(data, keys)
|
144
|
-
keys.reduce(data) do |current_data, key|
|
145
|
-
check_invalid_path(current_data, key)
|
146
|
-
|
147
|
-
case current_data
|
148
|
-
when Hash
|
149
|
-
current_data[find_existing_key(current_data, key)]
|
150
|
-
when Array
|
151
|
-
current_data[key.to_i]
|
152
|
-
else
|
153
|
-
raise KeyError, "Invalid data type at '#{key}'"
|
154
|
-
end
|
155
|
-
end
|
156
|
-
end
|
157
|
-
|
158
|
-
# Helper to delete the final key in a hash or array
|
159
|
-
def delete_final_key(target, last_key)
|
160
|
-
case target
|
161
|
-
when Hash
|
162
|
-
target.delete(find_existing_key(target, last_key))
|
163
|
-
when Array
|
164
|
-
target.delete_at(last_key.to_i) if last_key.is_a?(Integer)
|
165
|
-
else
|
166
|
-
raise KeyError, "Cannot delete key from unsupported data type"
|
167
|
-
end
|
21
|
+
PathAccessor.delete(data, path)
|
168
22
|
end
|
169
23
|
end
|
170
24
|
end
|
@@ -10,13 +10,23 @@ module DevSuite
|
|
10
10
|
|
11
11
|
class << self
|
12
12
|
def write(path, content)
|
13
|
-
|
14
|
-
|
13
|
+
WriterManager.write(path, content)
|
14
|
+
end
|
15
|
+
|
16
|
+
def append(path, content)
|
17
|
+
WriterManager.append(path, content)
|
18
|
+
end
|
19
|
+
|
20
|
+
def delete_lines(path, start_line, end_line = start_line)
|
21
|
+
WriterManager.delete_lines(path, start_line, end_line)
|
15
22
|
end
|
16
23
|
|
17
24
|
def update_key(path, key, value)
|
18
|
-
|
19
|
-
|
25
|
+
WriterManager.update_key(path, key, value)
|
26
|
+
end
|
27
|
+
|
28
|
+
def delete_key(path, key)
|
29
|
+
WriterManager.delete_key(path, key)
|
20
30
|
end
|
21
31
|
end
|
22
32
|
end
|
@@ -5,21 +5,51 @@ module DevSuite
|
|
5
5
|
module FileWriter
|
6
6
|
module Writer
|
7
7
|
class Base < Utils::Construct::Component::Base
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
attr_reader :path
|
9
|
+
|
10
|
+
def initialize(path)
|
11
|
+
super()
|
12
|
+
@path = path
|
13
|
+
end
|
14
|
+
|
15
|
+
def read
|
16
|
+
FileLoader.load(path)
|
11
17
|
end
|
12
18
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
19
|
+
def write(content, backup: false)
|
20
|
+
create_backup if backup
|
21
|
+
AtomicWriter.new(path, content).write
|
22
|
+
end
|
17
23
|
|
18
|
-
|
24
|
+
def append(content)
|
25
|
+
current_content = read
|
26
|
+
updated_content = current_content.merge(content)
|
27
|
+
write(updated_content)
|
28
|
+
end
|
29
|
+
|
30
|
+
def delete_lines(start_line, end_line = start_line)
|
31
|
+
lines = ::File.readlines(path)
|
32
|
+
lines.slice!(start_line - 1, end_line - start_line + 1)
|
33
|
+
write(lines.join)
|
34
|
+
end
|
35
|
+
|
36
|
+
def update_key(key, value, **options)
|
37
|
+
content = read
|
19
38
|
Utils::Data.set_value_by_path(content, key, value)
|
39
|
+
write(content, **options)
|
40
|
+
end
|
41
|
+
|
42
|
+
def delete_key(key, **options)
|
43
|
+
content = read
|
44
|
+
Utils::Data.delete_key_by_path(content, key)
|
45
|
+
write(content, **options)
|
46
|
+
end
|
20
47
|
|
21
|
-
|
22
|
-
|
48
|
+
def append_array(array_key, new_elements)
|
49
|
+
data = read
|
50
|
+
data[array_key] ||= []
|
51
|
+
data[array_key].concat(new_elements)
|
52
|
+
write(data)
|
23
53
|
end
|
24
54
|
|
25
55
|
private
|
@@ -28,11 +58,6 @@ module DevSuite
|
|
28
58
|
::File.exist?(path)
|
29
59
|
end
|
30
60
|
|
31
|
-
# Load the file content using a file loader
|
32
|
-
def load_file_content(file_path)
|
33
|
-
FileLoader.load(file_path)
|
34
|
-
end
|
35
|
-
|
36
61
|
def create_backup(path)
|
37
62
|
BackupManager.new(path).create_backup if file_exists?(path)
|
38
63
|
end
|
@@ -5,20 +5,22 @@ module DevSuite
|
|
5
5
|
module FileWriter
|
6
6
|
module Writer
|
7
7
|
class Text < Base
|
8
|
-
def write(path, content, backup: false)
|
9
|
-
create_backup(path) if backup
|
10
|
-
|
11
|
-
AtomicWriter.new(path, content).write
|
12
|
-
end
|
13
|
-
|
14
8
|
# Updates a key-like pattern in a plain text file (find and replace)
|
15
|
-
def update_key(
|
16
|
-
content =
|
9
|
+
def update_key(key, value, backup: false)
|
10
|
+
content = read
|
17
11
|
|
18
12
|
# Simple pattern matching and replacement (e.g., `key: value`)
|
19
13
|
updated_content = content.gsub(/^#{Regexp.escape(key)}:.*/, "#{key}: #{value}")
|
20
14
|
|
21
|
-
write(
|
15
|
+
write(updated_content, backup: backup)
|
16
|
+
end
|
17
|
+
|
18
|
+
def append(content)
|
19
|
+
::File.open(path, "a") do |file|
|
20
|
+
file.write("\n") if ::File.size(path).nonzero?
|
21
|
+
|
22
|
+
file.write(content.strip)
|
23
|
+
end
|
22
24
|
end
|
23
25
|
end
|
24
26
|
end
|
@@ -5,7 +5,7 @@ module DevSuite
|
|
5
5
|
module FileWriter
|
6
6
|
module Writer
|
7
7
|
class Yaml < Base
|
8
|
-
def write(
|
8
|
+
def write(content, normalize: false, backup: false, yaml_options: {})
|
9
9
|
validate_content(content)
|
10
10
|
create_backup(path) if backup
|
11
11
|
|
@@ -3,27 +3,50 @@
|
|
3
3
|
module DevSuite
|
4
4
|
module Utils
|
5
5
|
module FileWriter
|
6
|
+
class UnsupportedFileTypeError < StandardError; end
|
7
|
+
|
6
8
|
class WriterManager
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
9
|
+
WRITERS = {
|
10
|
+
".json" => Writer::Json,
|
11
|
+
".yml" => Writer::Yaml,
|
12
|
+
".yaml" => Writer::Yaml,
|
13
|
+
".txt" => Writer::Text,
|
14
|
+
}.freeze
|
11
15
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
+
class << self
|
17
|
+
def write(path, content)
|
18
|
+
writer_instance(path).write(content)
|
19
|
+
end
|
20
|
+
|
21
|
+
def append(path, content)
|
22
|
+
writer_instance(path).append(content)
|
23
|
+
end
|
24
|
+
|
25
|
+
def delete_lines(path, start_line, end_line = start_line)
|
26
|
+
writer_instance(path).delete_lines(start_line, end_line)
|
27
|
+
end
|
16
28
|
|
17
|
-
|
29
|
+
def update_key(path, key, value)
|
30
|
+
writer_instance(path).update_key(key, value)
|
31
|
+
end
|
32
|
+
|
33
|
+
def delete_key(path, key)
|
34
|
+
writer_instance(path).delete_key(key)
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
# Returns the appropriate writer instance based on the file extension
|
40
|
+
def writer_instance(path)
|
41
|
+
writer_class = WRITERS[file_extension(path)]
|
42
|
+
raise UnsupportedFileTypeError, "Unsupported file type: #{file_extension(path)}" unless writer_class
|
43
|
+
|
44
|
+
writer_class.new(path)
|
45
|
+
end
|
18
46
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
Writer::Json.new
|
23
|
-
when ".yml", ".yaml"
|
24
|
-
Writer::Yaml.new
|
25
|
-
else
|
26
|
-
Writer::Text.new
|
47
|
+
# Returns the file extension from the path
|
48
|
+
def file_extension(path)
|
49
|
+
::File.extname(path).downcase
|
27
50
|
end
|
28
51
|
end
|
29
52
|
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DevSuite
|
4
|
+
module Utils
|
5
|
+
module Logger
|
6
|
+
require_relative "formatter"
|
7
|
+
require_relative "emoji"
|
8
|
+
require_relative "errors"
|
9
|
+
|
10
|
+
class Base
|
11
|
+
LOG_LEVELS = [:none, :info, :warn, :error, :debug].freeze
|
12
|
+
|
13
|
+
attr_accessor :log_level
|
14
|
+
|
15
|
+
def initialize(log_level: :none)
|
16
|
+
validate_log_level(log_level)
|
17
|
+
@log_level = log_level
|
18
|
+
end
|
19
|
+
|
20
|
+
# Logs a message with optional emoji, prefix, and color.
|
21
|
+
def log(message, level: :none, emoji: nil, prefix: nil, color: nil)
|
22
|
+
validate_log_level(level)
|
23
|
+
return if skip_logging?(level)
|
24
|
+
|
25
|
+
options = {
|
26
|
+
level: level,
|
27
|
+
emoji: emoji,
|
28
|
+
prefix: prefix,
|
29
|
+
color: color,
|
30
|
+
}
|
31
|
+
|
32
|
+
formatted_message = Formatter.format(message, options)
|
33
|
+
output_log(formatted_message)
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def validate_log_level(level)
|
39
|
+
return if LOG_LEVELS.include?(level)
|
40
|
+
|
41
|
+
raise InvalidLogLevelError, "Invalid log level: #{level}. Valid levels are: #{LOG_LEVELS.join(", ")}."
|
42
|
+
end
|
43
|
+
|
44
|
+
def skip_logging?(level)
|
45
|
+
LOG_LEVELS.index(level) < LOG_LEVELS.index(@log_level)
|
46
|
+
end
|
47
|
+
|
48
|
+
def output_log(formatted_message)
|
49
|
+
puts formatted_message if formatted_message
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DevSuite
|
4
|
+
module Utils
|
5
|
+
module Logger
|
6
|
+
module Emoji
|
7
|
+
class << self
|
8
|
+
def resolve(emoji)
|
9
|
+
return "" unless emoji
|
10
|
+
|
11
|
+
emoji.is_a?(Symbol) ? Utils::Emoji.get(emoji) : emoji
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DevSuite
|
4
|
+
module Utils
|
5
|
+
module Logger
|
6
|
+
module Formatter
|
7
|
+
LOG_DETAILS = {
|
8
|
+
none: { prefix: "", color: :white },
|
9
|
+
info: { prefix: "[INFO]", color: :green },
|
10
|
+
warn: { prefix: "[WARNING]", color: :yellow },
|
11
|
+
error: { prefix: "[ERROR]", color: :red },
|
12
|
+
debug: { prefix: "[DEBUG]", color: :blue },
|
13
|
+
}.freeze
|
14
|
+
|
15
|
+
class << self
|
16
|
+
def format(message, options = {})
|
17
|
+
return "" if message.nil? || message.strip.empty?
|
18
|
+
|
19
|
+
details = fetch_log_details(options[:level])
|
20
|
+
prefix = options[:prefix] || details[:prefix]
|
21
|
+
color = options[:color] || details[:color]
|
22
|
+
emoji_icon = Emoji.resolve(options[:emoji])
|
23
|
+
|
24
|
+
formatted_message = build_message(prefix, emoji_icon, message)
|
25
|
+
Utils::Color.colorize(formatted_message, color: color)
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def fetch_log_details(level)
|
31
|
+
LOG_DETAILS[level || :none]
|
32
|
+
end
|
33
|
+
|
34
|
+
def build_message(prefix, emoji_icon, message)
|
35
|
+
"#{prefix} #{emoji_icon} #{message}".strip
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DevSuite
|
4
|
+
module Utils
|
5
|
+
module Logger
|
6
|
+
require_relative "base"
|
7
|
+
|
8
|
+
class << self
|
9
|
+
# Provides access to the global logger instance
|
10
|
+
#
|
11
|
+
# @return [Base] the global logger instance
|
12
|
+
def logger
|
13
|
+
@logger ||= Base.new
|
14
|
+
end
|
15
|
+
|
16
|
+
# Logs a message using the global logger instance
|
17
|
+
#
|
18
|
+
# @param message [String] The message to log.
|
19
|
+
# @param level [Symbol] The log level (:none, :info, :warn, :error, :debug).
|
20
|
+
# @param emoji [String, Symbol, nil] Optional emoji to prepend to the message.
|
21
|
+
# @param prefix [String, nil] Custom prefix for the message.
|
22
|
+
# @param color [Symbol, nil] Custom color for the message.
|
23
|
+
def log(message, level: :none, emoji: nil, prefix: nil, color: nil)
|
24
|
+
logger.log(message, level: level, emoji: emoji, prefix: prefix, color: color)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -3,58 +3,7 @@
|
|
3
3
|
module DevSuite
|
4
4
|
module Utils
|
5
5
|
module Logger
|
6
|
-
|
7
|
-
none: { prefix: "", color: :white },
|
8
|
-
info: { prefix: "[INFO]", color: :green },
|
9
|
-
warn: { prefix: "[WARNING]", color: :yellow },
|
10
|
-
error: { prefix: "[ERROR]", color: :red },
|
11
|
-
debug: { prefix: "[DEBUG]", color: :blue },
|
12
|
-
}.freeze
|
13
|
-
|
14
|
-
class << self
|
15
|
-
# Logs a message with an optional emoji and specified log level.
|
16
|
-
#
|
17
|
-
# @param message [String] The message to log.
|
18
|
-
# @param level [Symbol] The log level (:info, :warn, :error, :debug).
|
19
|
-
# @param emoji [String, Symbol] Optional emoji to prepend to the message.
|
20
|
-
def log(message, level: :none, emoji: nil, prefix: nil, color: nil)
|
21
|
-
emoji_icon = resolve_emoji(emoji)
|
22
|
-
formatted_message = format_message("#{emoji_icon} #{message}", level, prefix, color)
|
23
|
-
output_log(formatted_message)
|
24
|
-
end
|
25
|
-
|
26
|
-
private
|
27
|
-
|
28
|
-
# Resolves the emoji, either from a symbol or directly as a string.
|
29
|
-
#
|
30
|
-
# @param emoji [String, Symbol, nil] The emoji or its symbol key.
|
31
|
-
# @return [String] The resolved emoji or an empty string if none is provided.
|
32
|
-
def resolve_emoji(emoji)
|
33
|
-
return "" unless emoji
|
34
|
-
|
35
|
-
emoji.is_a?(Symbol) ? Emoji.get(emoji) : emoji
|
36
|
-
end
|
37
|
-
|
38
|
-
# Formats the log message with the appropriate prefix and color.
|
39
|
-
#
|
40
|
-
# @param message [String] The message to format.
|
41
|
-
# @param level [Symbol] The log level (:info, :warn, :error, :debug).
|
42
|
-
# @return [String] The formatted log message.
|
43
|
-
def format_message(message, level, custom_prefix, custom_color)
|
44
|
-
details = LOG_DETAILS[level]
|
45
|
-
prefix = custom_prefix || details[:prefix]
|
46
|
-
color = custom_color || details[:color]
|
47
|
-
|
48
|
-
Utils::Color.colorize("#{prefix} #{message}", color: color)
|
49
|
-
end
|
50
|
-
|
51
|
-
# Outputs the formatted log message to the console.
|
52
|
-
#
|
53
|
-
# @param formatted_message [String] The message to output.
|
54
|
-
def output_log(formatted_message)
|
55
|
-
puts formatted_message if formatted_message
|
56
|
-
end
|
57
|
-
end
|
6
|
+
require_relative "logger/logger"
|
58
7
|
end
|
59
8
|
end
|
60
9
|
end
|
@@ -49,7 +49,7 @@ module DevSuite
|
|
49
49
|
|
50
50
|
total_width = column_widths.sum + column_widths.size * 3 - 1
|
51
51
|
title_str = "| #{table.title.center(total_width - 2)} |"
|
52
|
-
colorize(title_str, settings.get("colors.title"))
|
52
|
+
puts colorize(title_str, settings.get("colors.title"))
|
53
53
|
end
|
54
54
|
|
55
55
|
def render_header(table, column_widths)
|
@@ -59,13 +59,13 @@ module DevSuite
|
|
59
59
|
text_align(column.name, column_widths[index])
|
60
60
|
end
|
61
61
|
header_str = "| #{header.join(" | ")} |"
|
62
|
-
colorize(header_str, settings.get("colors.column"))
|
62
|
+
puts colorize(header_str, settings.get("colors.column"))
|
63
63
|
end
|
64
64
|
|
65
65
|
def render_separator(column_widths)
|
66
66
|
separator = column_widths.map { |width| "-" * width }.join("-+-")
|
67
67
|
separator_str = "+-#{separator}-+"
|
68
|
-
colorize(separator_str, settings.get("colors.border"))
|
68
|
+
puts colorize(separator_str, settings.get("colors.border"))
|
69
69
|
end
|
70
70
|
|
71
71
|
def render_rows(table, column_widths)
|
@@ -73,7 +73,7 @@ module DevSuite
|
|
73
73
|
render_row(row, column_widths)
|
74
74
|
end
|
75
75
|
cells_str = cells.join("\n")
|
76
|
-
colorize(cells_str, settings.get("colors.row"))
|
76
|
+
puts colorize(cells_str, settings.get("colors.row"))
|
77
77
|
end
|
78
78
|
|
79
79
|
def render_row(row, column_widths)
|
@@ -81,7 +81,7 @@ module DevSuite
|
|
81
81
|
text_align(cell.to_s, column_widths[index])
|
82
82
|
end
|
83
83
|
cell_str = "| #{cell.join(" | ")} |"
|
84
|
-
colorize(cell_str, settings.get("colors.row"))
|
84
|
+
puts colorize(cell_str, settings.get("colors.row"))
|
85
85
|
end
|
86
86
|
end
|
87
87
|
end
|
data/lib/dev_suite/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dev_suite
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.12
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Huy Nguyen
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-10-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: benchmark
|
@@ -258,6 +258,11 @@ files:
|
|
258
258
|
- lib/dev_suite/utils/data/base_operations.rb
|
259
259
|
- lib/dev_suite/utils/data/data.rb
|
260
260
|
- lib/dev_suite/utils/data/path_access.rb
|
261
|
+
- lib/dev_suite/utils/data/path_access/data_traverser.rb
|
262
|
+
- lib/dev_suite/utils/data/path_access/errors.rb
|
263
|
+
- lib/dev_suite/utils/data/path_access/key_handler.rb
|
264
|
+
- lib/dev_suite/utils/data/path_access/path_accessor.rb
|
265
|
+
- lib/dev_suite/utils/data/path_access/path_parser.rb
|
261
266
|
- lib/dev_suite/utils/data/search_filter.rb
|
262
267
|
- lib/dev_suite/utils/data/serialization.rb
|
263
268
|
- lib/dev_suite/utils/data/transformations.rb
|
@@ -289,6 +294,11 @@ files:
|
|
289
294
|
- lib/dev_suite/utils/file_writer/writer/yaml.rb
|
290
295
|
- lib/dev_suite/utils/file_writer/writer_manager.rb
|
291
296
|
- lib/dev_suite/utils/logger.rb
|
297
|
+
- lib/dev_suite/utils/logger/base.rb
|
298
|
+
- lib/dev_suite/utils/logger/emoji.rb
|
299
|
+
- lib/dev_suite/utils/logger/errors.rb
|
300
|
+
- lib/dev_suite/utils/logger/formatter.rb
|
301
|
+
- lib/dev_suite/utils/logger/logger.rb
|
292
302
|
- lib/dev_suite/utils/path_matcher.rb
|
293
303
|
- lib/dev_suite/utils/path_matcher/matcher.rb
|
294
304
|
- lib/dev_suite/utils/path_matcher/path_matcher.rb
|