mp-utils 0.3.1 → 0.4.1
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/lib/mp_utils.rb +2 -0
- data/lib/utils/ansi.rb +36 -24
- data/lib/utils/ansi_style_manager.rb +87 -87
- data/lib/utils/array.rb +9 -8
- data/lib/utils/constants.rb +1 -0
- data/lib/utils/directory_structure.rb +217 -0
- data/lib/utils/key.rb +20 -20
- data/lib/utils/message.rb +16 -17
- data/lib/utils/question.rb +4 -4
- data/lib/utils/string.rb +40 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0a57051627a8e74a98a9209b1c213c6148846cf4fe0f4a7a1da5e0b8dbc64cd7
|
4
|
+
data.tar.gz: bd146f3f15a46dbab724a0b18878842a9d96c1508feec23dcf7c9da9b7c99de8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8a3c24a403c587a815a14e9ffd7e9321a1642eee43ea96c1282199f7d25c38a403206e277be6855c488a366f96f9eff7f8c823956458ca2e85d09bb4d97abe4b
|
7
|
+
data.tar.gz: c41ceaf522f2d4d9b56de23e432910eeae65697fdf98080755c4d46523486caf8b9226f7eeac2a9220642125b708d1b4ee1d98d9b2b6c22fd2488010ce080e5b
|
data/lib/mp_utils.rb
CHANGED
@@ -3,8 +3,10 @@
|
|
3
3
|
require_relative 'utils/key'
|
4
4
|
require_relative 'utils/ansi'
|
5
5
|
require_relative 'utils/array'
|
6
|
+
require_relative 'utils/string'
|
6
7
|
require_relative 'utils/message'
|
7
8
|
require_relative 'utils/question'
|
8
9
|
require_relative 'utils/version_manager'
|
9
10
|
require_relative 'utils/ansi_style_manager'
|
11
|
+
require_relative 'utils/directory_structure'
|
10
12
|
require_relative 'resources/path_helper'
|
data/lib/utils/ansi.rb
CHANGED
@@ -2,18 +2,18 @@
|
|
2
2
|
|
3
3
|
require_relative 'constants'
|
4
4
|
|
5
|
-
# The ANSI class is responsible for generating ANSI codes for text styling in terminals.
|
6
|
-
# It allows the combination of multiple style and color codes.
|
5
|
+
# The ANSI class is responsible for generating ANSI codes for text styling in terminals.
|
6
|
+
# It allows the combination of multiple style and color codes.
|
7
7
|
#
|
8
|
-
# @example
|
9
|
-
# ansi = ANSI.new(:bold)
|
10
|
-
# puts ansi.to_s # => "\e[1m"
|
8
|
+
# @example
|
9
|
+
# ansi = ANSI.new(:bold)
|
10
|
+
# puts ansi.to_s # => "\e[1m"
|
11
11
|
#
|
12
|
-
# @example
|
13
|
-
# ansi = ANSI.new([:bold, :red])
|
14
|
-
# puts ansi.to_s # => "\e[1;31m"
|
12
|
+
# @example
|
13
|
+
# ansi = ANSI.new([:bold, :red])
|
14
|
+
# puts ansi.to_s # => "\e[1;31m"
|
15
15
|
class ANSI
|
16
|
-
# Hash that maps style and color names to their respective ANSI codes.
|
16
|
+
# Hash that maps style and color names to their respective ANSI codes.
|
17
17
|
CODES_HASH = {
|
18
18
|
reset_all: 0,
|
19
19
|
|
@@ -66,12 +66,24 @@ class ANSI
|
|
66
66
|
reset_background: 49
|
67
67
|
}.freeze
|
68
68
|
|
69
|
-
# @return [Array<Integer>] the ANSI codes stored in the instance.
|
69
|
+
# @return [Array<Integer>] the ANSI codes stored in the instance.
|
70
70
|
attr_reader :codes
|
71
71
|
|
72
|
-
#
|
72
|
+
# Removes ANSI escape codes from a given string.
|
73
73
|
#
|
74
|
-
#
|
74
|
+
# This class method is designed to take a string input and remove any ANSI
|
75
|
+
# escape codes, which are often used for text formatting in terminal outputs.
|
76
|
+
#
|
77
|
+
# @param value [String] the string from which ANSI codes should be removed.
|
78
|
+
# If the input is not a string, it will be converted to a string using `to_s`.
|
79
|
+
# @return [String] a new string with ANSI escape codes removed.
|
80
|
+
def self.remove_from_string(value)
|
81
|
+
value.to_s.gsub(CONSTANTS::ANSI::TOKEN_REGEX, '')
|
82
|
+
end
|
83
|
+
|
84
|
+
# Initializes a new instance of the ANSI class.
|
85
|
+
#
|
86
|
+
# @param code [Array<Symbol>, Symbol, String] One or more ANSI codes represented as symbols, integers, or strings.
|
75
87
|
def initialize(code)
|
76
88
|
@codes = if code.is_a?(Array)
|
77
89
|
ANSI.normalize_array_codes(code)
|
@@ -82,36 +94,36 @@ class ANSI
|
|
82
94
|
end
|
83
95
|
end
|
84
96
|
|
85
|
-
# Adds ANSI codes from another instance of the ANSI class.
|
97
|
+
# Adds ANSI codes from another instance of the ANSI class.
|
86
98
|
#
|
87
|
-
# @param ansi [ANSI] The instance of the ANSI class whose codes will be added.
|
88
|
-
# @return [ANSI] A new instance of the ANSI class with the combined codes.
|
89
|
-
# @raise [RuntimeError] If the argument is not an instance of the ANSI class.
|
99
|
+
# @param ansi [ANSI] The instance of the ANSI class whose codes will be added.
|
100
|
+
# @return [ANSI] A new instance of the ANSI class with the combined codes.
|
101
|
+
# @raise [RuntimeError] If the argument is not an instance of the ANSI class.
|
90
102
|
def append(ansi)
|
91
103
|
raise 'Needs be an instance of ANSI' unless ansi.is_a?(ANSI)
|
92
104
|
|
93
105
|
ANSI.new(@codes.union(ansi.codes))
|
94
106
|
end
|
95
107
|
|
96
|
-
# Adds ANSI codes from another instance of the ANSI class and updates the current instance.
|
108
|
+
# Adds ANSI codes from another instance of the ANSI class and updates the current instance.
|
97
109
|
#
|
98
|
-
# @param ansi [ANSI] The instance of the ANSI class whose codes will be added.
|
99
|
-
# @return [void]
|
110
|
+
# @param ansi [ANSI] The instance of the ANSI class whose codes will be added.
|
111
|
+
# @return [void]
|
100
112
|
def append!(ansi)
|
101
113
|
@codes = append(ansi).codes
|
102
114
|
end
|
103
115
|
|
104
|
-
# Converts the ANSI codes stored in the instance to a formatted string.
|
116
|
+
# Converts the ANSI codes stored in the instance to a formatted string.
|
105
117
|
#
|
106
|
-
# @return [String] The formatted string with the ANSI codes.
|
118
|
+
# @return [String] The formatted string with the ANSI codes.
|
107
119
|
def to_s
|
108
120
|
"\e[#{@codes.flatten.join(';')}m"
|
109
121
|
end
|
110
122
|
|
111
|
-
# Normalizes an array of codes, converting symbols and strings to their respective ANSI codes.
|
123
|
+
# Normalizes an array of codes, converting symbols and strings to their respective ANSI codes.
|
112
124
|
#
|
113
|
-
# @param array [Array<Symbol, String, Integer>] An array of codes to be normalized.
|
114
|
-
# @return [Array<Integer>] The normalized array of ANSI codes.
|
125
|
+
# @param array [Array<Symbol, String, Integer>] An array of codes to be normalized.
|
126
|
+
# @return [Array<Integer>] The normalized array of ANSI codes.
|
115
127
|
def self.normalize_array_codes(array)
|
116
128
|
array.map do |value|
|
117
129
|
next normalize_array_codes(value) if value.is_a?(Array)
|
@@ -3,25 +3,25 @@
|
|
3
3
|
require_relative 'constants'
|
4
4
|
require_relative 'ansi'
|
5
5
|
|
6
|
-
# The ANSIStyleManager class is responsible for managing and applying ANSI styles to a given string.
|
6
|
+
# The ANSIStyleManager class is responsible for managing and applying ANSI styles to a given string.
|
7
7
|
#
|
8
|
-
# It can replace tokens in the string with corresponding ANSI codes for colors, backgrounds and effects.
|
8
|
+
# It can replace tokens in the string with corresponding ANSI codes for colors, backgrounds and effects.
|
9
9
|
#
|
10
|
-
# ## Effects
|
10
|
+
# ## Effects
|
11
11
|
# Effects can be used by adding `<effect:effect_name>` at the beginning and `</effect>` at the end of
|
12
|
-
# the sequence of characters to which you want the effect to be applied.
|
13
|
-
#
|
14
|
-
# Example:
|
15
|
-
# ```ruby
|
16
|
-
# manager = ANSIStyleManager.new('The text <effect:bold>Potato</effect> will be bold.')
|
17
|
-
# puts manager
|
18
|
-
# ```
|
19
|
-
# Output:
|
20
|
-
#
|
21
|
-
# 
|
22
|
+
#
|
23
|
+
# Below is the table with all available effects:
|
24
|
+
#
|
25
25
|
# | Effect Name | Description |
|
26
26
|
# |---------------|----------------------------|
|
27
27
|
# | bold | set bold mode. |
|
@@ -33,45 +33,45 @@ require_relative 'ansi'
|
|
33
33
|
# | hidden | set hidden/invisible mode. |
|
34
34
|
# | strike | set strikethrough mode. |
|
35
35
|
# | plain | set double underline mode. |
|
36
|
-
#
|
37
|
-
# > **Note:** Some terminals may not support some of the effects listed above.
|
38
|
-
#
|
39
|
-
# ## Colors
|
40
|
-
# The ANSIStyleManager supports 3 types of coloring: Named Colors, RGB Colors, or 256 Colors.
|
41
|
-
#
|
36
|
+
#
|
37
|
+
# > **Note:** Some terminals may not support some of the effects listed above.
|
38
|
+
#
|
39
|
+
# ## Colors
|
40
|
+
# The ANSIStyleManager supports 3 types of coloring: Named Colors, RGB Colors, or 256 Colors.
|
41
|
+
#
|
42
42
|
# The foreground color can be changed by adding `<color:color_type>` at the beginning and `</color>`
|
43
|
-
# at the end of the character sequence you want to color.
|
44
|
-
#
|
45
|
-
# Example:
|
46
|
-
# ```ruby
|
47
|
-
# text = 'A <color:green>colorful <color:red>world <color:yellow>is <color:blue>much '
|
48
|
-
# text += '</color>more </color>beautiful</color>!</color> ;)'
|
49
|
-
# manager = ANSIStyleManager.new(text)
|
50
|
-
# puts manager
|
51
|
-
# ```
|
52
|
-
# Output:
|
53
|
-
#
|
54
|
-
# '
|
49
|
+
# manager = ANSIStyleManager.new(text)
|
50
|
+
# puts manager
|
51
|
+
# ```
|
52
|
+
# Output:
|
53
|
+
#
|
54
|
+
# 
|
55
|
+
#
|
56
|
+
# It is also possible to set the background color of a text.
|
57
|
+
#
|
58
58
|
# The background color can be changed by adding `<color:color_type:color_type>` at the
|
59
|
-
# beginning and `</color>` at the end of the character sequence you want to color.
|
60
|
-
#
|
61
|
-
# Example:
|
62
|
-
# ```ruby
|
63
|
-
# text = 'A <color:green:white>colorful <color:196>world <color:yellow:111>is <color:blue:255;255;255>much '
|
64
|
-
# text += '</color>more </color>beautiful</color>!</color> ;)'
|
65
|
-
# manager = ANSIStyleManager.new(text)
|
66
|
-
# puts manager
|
67
|
-
# ```
|
68
|
-
#
|
69
|
-
# Output:
|
70
|
-
#
|
71
|
-
# '
|
65
|
+
# manager = ANSIStyleManager.new(text)
|
66
|
+
# puts manager
|
67
|
+
# ```
|
68
|
+
#
|
69
|
+
# Output:
|
70
|
+
#
|
71
|
+
# 
|
72
|
+
#
|
73
|
+
# Below is the table with all available color type patterns:
|
74
|
+
#
|
75
75
|
# |Color Type |Pattern |Description |
|
76
76
|
# |-------------|--------|---------------------------------------------------------------------------------------------|
|
77
77
|
# |Reset colors |reset |Resets to the terminal's default color. |
|
@@ -80,30 +80,30 @@ require_relative 'ansi'
|
|
80
80
|
# |Named Colors |name |Accepts the following color names: black, red, green, yellow, blue, magenta, cyan and white. |
|
81
81
|
#
|
82
82
|
class ANSIStyleManager
|
83
|
-
# @return [String] the string to which ANSI styles will be applied.
|
83
|
+
# @return [String] the string to which ANSI styles will be applied.
|
84
84
|
attr_reader :string
|
85
85
|
|
86
|
-
# Initializes a new instance of the ANSIStyleManager class.
|
86
|
+
# Initializes a new instance of the ANSIStyleManager class.
|
87
87
|
#
|
88
|
-
# @param string [String] The string to which ANSI styles will be applied.
|
89
|
-
# @raise [RuntimeError] If the argument is not a string.
|
88
|
+
# @param string [String] The string to which ANSI styles will be applied.
|
89
|
+
# @raise [RuntimeError] If the argument is not a string.
|
90
90
|
def initialize(string)
|
91
91
|
raise 'Need initialize with a string' unless string.is_a?(String)
|
92
92
|
|
93
93
|
@string = String.new(string)
|
94
94
|
end
|
95
95
|
|
96
|
-
# Replaces all color and effect tokens in the string with corresponding ANSI codes.
|
97
|
-
#
|
98
|
-
# @return [void]
|
96
|
+
# Replaces all color and effect tokens in the string with corresponding ANSI codes.
|
97
|
+
#
|
98
|
+
# @return [void]
|
99
99
|
def replace_all_tokens!
|
100
100
|
replace_color_tokens!
|
101
101
|
replace_effect_tokens!
|
102
102
|
end
|
103
103
|
|
104
|
-
# Replaces all color tokens in the string with corresponding ANSI codes.
|
105
|
-
#
|
106
|
-
# @return [void]
|
104
|
+
# Replaces all color tokens in the string with corresponding ANSI codes.
|
105
|
+
#
|
106
|
+
# @return [void]
|
107
107
|
def replace_color_tokens!
|
108
108
|
scan_while_find(CONSTANTS::ANSI::COLORS) do |value|
|
109
109
|
colors = value.first.split(':')
|
@@ -118,9 +118,9 @@ class ANSIStyleManager
|
|
118
118
|
end
|
119
119
|
end
|
120
120
|
|
121
|
-
# Replaces all effect tokens in the string with corresponding ANSI codes.
|
122
|
-
#
|
123
|
-
# @return [void]
|
121
|
+
# Replaces all effect tokens in the string with corresponding ANSI codes.
|
122
|
+
#
|
123
|
+
# @return [void]
|
124
124
|
def replace_effect_tokens!
|
125
125
|
scan_while_find(CONSTANTS::ANSI::EFFECTS) do |value|
|
126
126
|
replace_tokens_with!(
|
@@ -133,9 +133,9 @@ class ANSIStyleManager
|
|
133
133
|
end
|
134
134
|
end
|
135
135
|
|
136
|
-
# Converts the string with all tokens replaced by corresponding ANSI codes.
|
136
|
+
# Converts the string with all tokens replaced by corresponding ANSI codes.
|
137
137
|
#
|
138
|
-
# @return [String] The string with ANSI codes applied.
|
138
|
+
# @return [String] The string with ANSI codes applied.
|
139
139
|
def to_s
|
140
140
|
replace_all_tokens!
|
141
141
|
@string
|
@@ -143,11 +143,11 @@ class ANSIStyleManager
|
|
143
143
|
|
144
144
|
private
|
145
145
|
|
146
|
-
# Generates the ANSI prefix for a given color and background.
|
146
|
+
# Generates the ANSI prefix for a given color and background.
|
147
147
|
#
|
148
|
-
# @param color [String] The color name or code.
|
149
|
-
# @param background [String, nil] The background color name or code.
|
150
|
-
# @return [ANSI] The ANSI instance representing the color and background.
|
148
|
+
# @param color [String] The color name or code.
|
149
|
+
# @param background [String, nil] The background color name or code.
|
150
|
+
# @return [ANSI] The ANSI instance representing the color and background.
|
151
151
|
def color_prefix(color:, background:)
|
152
152
|
color_ansi = generate_color_ansi(color, is_background: false)
|
153
153
|
return color_ansi.to_s if background.nil?
|
@@ -155,11 +155,11 @@ class ANSIStyleManager
|
|
155
155
|
generate_color_ansi(background, is_background: true).append(color_ansi)
|
156
156
|
end
|
157
157
|
|
158
|
-
# Generates the ANSI instance for a given color.
|
158
|
+
# Generates the ANSI instance for a given color.
|
159
159
|
#
|
160
|
-
# @param color [String] The color name or code.
|
161
|
-
# @param is_background [Boolean] Whether the color is for the background.
|
162
|
-
# @return [ANSI] The ANSI instance representing the color.
|
160
|
+
# @param color [String] The color name or code.
|
161
|
+
# @param is_background [Boolean] Whether the color is for the background.
|
162
|
+
# @return [ANSI] The ANSI instance representing the color.
|
163
163
|
def generate_color_ansi(color, is_background:)
|
164
164
|
digit_values = color.scan(CONSTANTS::ANSI::COLOR_DIGITS_REGEX).flatten.compact
|
165
165
|
|
@@ -175,25 +175,25 @@ class ANSIStyleManager
|
|
175
175
|
ANSI.new(is_background ? "background_#{color}" : color)
|
176
176
|
end
|
177
177
|
|
178
|
-
# Replaces tokens in the string with corresponding ANSI codes.
|
178
|
+
# Replaces tokens in the string with corresponding ANSI codes.
|
179
179
|
#
|
180
|
-
# @param text [String] The text to be styled.
|
181
|
-
# @param to_replace [String] The token to be replaced.
|
182
|
-
# @param ansi_token [ANSI] The ANSI instance representing the style.
|
183
|
-
# @param ansi_reset_token [ANSI] The ANSI instance representing the reset style.
|
184
|
-
# @param preserve_reset_token [Boolean] Whether to preserve the reset token in the text.
|
185
|
-
# @return [void]
|
180
|
+
# @param text [String] The text to be styled.
|
181
|
+
# @param to_replace [String] The token to be replaced.
|
182
|
+
# @param ansi_token [ANSI] The ANSI instance representing the style.
|
183
|
+
# @param ansi_reset_token [ANSI] The ANSI instance representing the reset style.
|
184
|
+
# @param preserve_reset_token [Boolean] Whether to preserve the reset token in the text.
|
185
|
+
# @return [void]
|
186
186
|
def replace_tokens_with!(text:, to_replace:, ansi_token:, ansi_reset_token:, preserve_reset_token:)
|
187
187
|
colored_text = text.gsub(ansi_reset_token.to_s, "#{ansi_reset_token}#{ansi_token}") if preserve_reset_token
|
188
188
|
colored_text = text.gsub(ansi_reset_token.to_s, ansi_token.to_s) unless preserve_reset_token
|
189
189
|
@string.gsub!(to_replace, "#{ansi_token}#{colored_text}#{ansi_reset_token}")
|
190
190
|
end
|
191
191
|
|
192
|
-
# Scans the string for tokens matching the given regex and processes them with the provided block.
|
192
|
+
# Scans the string for tokens matching the given regex and processes them with the provided block.
|
193
193
|
#
|
194
|
-
# @param scan_regex [Regexp] The regex to scan for tokens.
|
195
|
-
# @yieldparam value [Array<String>] The matched tokens.
|
196
|
-
# @return [void]
|
194
|
+
# @param scan_regex [Regexp] The regex to scan for tokens.
|
195
|
+
# @yieldparam value [Array<String>] The matched tokens.
|
196
|
+
# @return [void]
|
197
197
|
def scan_while_find(scan_regex, &block)
|
198
198
|
result = @string.scan(scan_regex)
|
199
199
|
while result.count.positive?
|
data/lib/utils/array.rb
CHANGED
@@ -1,16 +1,17 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# Extension to Ruby's Array class to enhance functionality.
|
3
|
+
# Extension to Ruby's Array class to enhance functionality.
|
4
4
|
class Array
|
5
|
-
# Lists all elements in the array with their index.
|
5
|
+
# Lists all elements in the array with their index.
|
6
6
|
#
|
7
|
-
# This method outputs each element of the array to the console, prefixed by its index (1-based).
|
8
|
-
# The index is right-justified based on the length of the array, ensuring a tidy, column-aligned output.
|
7
|
+
# This method outputs each element of the array to the console, prefixed by its index (1-based).
|
8
|
+
# The index is right-justified based on the length of the array, ensuring a tidy, column-aligned output.
|
9
9
|
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
# |
|
13
|
-
# |
|
10
|
+
# @example
|
11
|
+
# # output for a 3-element array:
|
12
|
+
# |1| Element 1
|
13
|
+
# |2| Element 2
|
14
|
+
# |3| Element 3
|
14
15
|
#
|
15
16
|
# @return [void]
|
16
17
|
def list_all_elements
|
data/lib/utils/constants.rb
CHANGED
@@ -6,6 +6,7 @@ module CONSTANTS
|
|
6
6
|
|
7
7
|
# @!visibility private
|
8
8
|
module ANSI
|
9
|
+
TOKEN_REGEX = /\e\[(\d|;)+m/.freeze
|
9
10
|
COLOR_DIGITS_REGEX = /^(\d+);(\d+);(\d+)|(\d+)$/.freeze
|
10
11
|
COLOR_TOKEN_VALUE = '(?:[\w|\d]+|\d+\;\d+\;\d+)(?::[\w|\d]+|:\d+;\d+;\d+)?'
|
11
12
|
COLORS = %r{<color:(#{COLOR_TOKEN_VALUE})>((?:(?!<color:#{COLOR_TOKEN_VALUE}>|</color>).)*)</color>}m.freeze
|
@@ -0,0 +1,217 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
# Class to represent and process a directory structure.
|
6
|
+
# It can be initialized with a hash or a YAML file.
|
7
|
+
#
|
8
|
+
# ## Using HASH
|
9
|
+
#
|
10
|
+
# The following example shows how to use DirectoryStructure with a hash.
|
11
|
+
# ```ruby
|
12
|
+
# hash = {
|
13
|
+
# 'lib' => {
|
14
|
+
# 'version.rb' => nil,
|
15
|
+
# 'source' => [
|
16
|
+
# 'file_1.rb',
|
17
|
+
# 'file_2.rb',
|
18
|
+
# 'file_3.rb'
|
19
|
+
# ],
|
20
|
+
# 'resource' => {
|
21
|
+
# 'images' => [
|
22
|
+
# 'potato.png',
|
23
|
+
# 'fries.jpeg',
|
24
|
+
# 'franch_fries.png'
|
25
|
+
# ],
|
26
|
+
# 'scripts' => {
|
27
|
+
# validation: 'teste.rb',
|
28
|
+
# sorting: [
|
29
|
+
# 'shellsort.rb',
|
30
|
+
# 'quicksort.rb'
|
31
|
+
# ],
|
32
|
+
# 'build.rb' => nil
|
33
|
+
# }
|
34
|
+
# },
|
35
|
+
# generated: 'file.generated.rb'
|
36
|
+
# }
|
37
|
+
# }
|
38
|
+
# directory_structure = DirectoryStructure.new(hash)
|
39
|
+
# puts "That is my directory structure:\n#{directory_structure}"
|
40
|
+
#
|
41
|
+
# # Output:
|
42
|
+
# # That is my directory structure:
|
43
|
+
# # lib
|
44
|
+
# # ╠═ version.rb
|
45
|
+
# # ╠═ source
|
46
|
+
# # ║ ╠═ file_1.rb
|
47
|
+
# # ║ ╠═ file_2.rb
|
48
|
+
# # ║ ╚═ file_3.rb
|
49
|
+
# # ╠═ resource
|
50
|
+
# # ║ ╠═ images
|
51
|
+
# # ║ ║ ╠═ potato.png
|
52
|
+
# # ║ ║ ╠═ fries.jpeg
|
53
|
+
# # ║ ║ ╚═ franch_fries.png
|
54
|
+
# # ║ ╚═ scripts
|
55
|
+
# # ║ ╠═ validation
|
56
|
+
# # ║ ║ ╚═ teste.rb
|
57
|
+
# # ║ ╠═ sorting
|
58
|
+
# # ║ ║ ╠═ shellsort.rb
|
59
|
+
# # ║ ║ ╚═ quicksort.rb
|
60
|
+
# # ║ ╚═ build.rb
|
61
|
+
# # ╚═ generated
|
62
|
+
# # ╚═ file.generated.rb
|
63
|
+
# ```
|
64
|
+
#
|
65
|
+
# ## Using a YAML/YML File
|
66
|
+
#
|
67
|
+
# First, you need to create a yml file.
|
68
|
+
#
|
69
|
+
# Example:
|
70
|
+
# ```yml
|
71
|
+
# lib:
|
72
|
+
# version.rb:
|
73
|
+
# source:
|
74
|
+
# - file_1.rb
|
75
|
+
# - file_2.rb
|
76
|
+
# - file_3.rb
|
77
|
+
# resource:
|
78
|
+
# images:
|
79
|
+
# - potato.png
|
80
|
+
# - fries.jpeg
|
81
|
+
# - franch_fries.png
|
82
|
+
# scripts:
|
83
|
+
# validation: teste.rb
|
84
|
+
# sorting:
|
85
|
+
# - shellsort.rb
|
86
|
+
# - quicksort.rb
|
87
|
+
# build.rb:
|
88
|
+
# generated: file.generated.rb
|
89
|
+
# ```
|
90
|
+
#
|
91
|
+
# Considering that the file path is passed as a reference.
|
92
|
+
#
|
93
|
+
# You can initialize the class as in the example below:
|
94
|
+
#
|
95
|
+
# ```ruby
|
96
|
+
# path = 'Replace/By/Your/YAML/FILE/PATH'
|
97
|
+
# directory_structure = DirectoryStructure.new(path)
|
98
|
+
# puts "That is my directory structure:\n#{directory_structure}"
|
99
|
+
#
|
100
|
+
# # Output:
|
101
|
+
# # That is my directory structure:
|
102
|
+
# # lib
|
103
|
+
# # ╠═ version.rb
|
104
|
+
# # ╠═ source
|
105
|
+
# # ║ ╠═ file_1.rb
|
106
|
+
# # ║ ╠═ file_2.rb
|
107
|
+
# # ║ ╚═ file_3.rb
|
108
|
+
# # ╠═ resource
|
109
|
+
# # ║ ╠═ images
|
110
|
+
# # ║ ║ ╠═ potato.png
|
111
|
+
# # ║ ║ ╠═ fries.jpeg
|
112
|
+
# # ║ ║ ╚═ franch_fries.png
|
113
|
+
# # ║ ╚═ scripts
|
114
|
+
# # ║ ╠═ validation
|
115
|
+
# # ║ ║ ╚═ teste.rb
|
116
|
+
# # ║ ╠═ sorting
|
117
|
+
# # ║ ║ ╠═ shellsort.rb
|
118
|
+
# # ║ ║ ╚═ quicksort.rb
|
119
|
+
# # ║ ╚═ build.rb
|
120
|
+
# # ╚═ generated
|
121
|
+
# # ╚═ file.generated.rb
|
122
|
+
# ```
|
123
|
+
class DirectoryStructure
|
124
|
+
# Initializes the DirectoryStructure object.
|
125
|
+
#
|
126
|
+
# @param content [Hash, String] A hash representing the directory structure or a path to a YAML file.
|
127
|
+
# @raise [RuntimeError] If the content is not a Hash or a valid YAML file path.
|
128
|
+
def initialize(content)
|
129
|
+
if content.is_a?(Hash)
|
130
|
+
@dir_hash = content
|
131
|
+
elsif File.exist?(content)
|
132
|
+
@dir_hash = YAML.load_file(content)
|
133
|
+
else
|
134
|
+
raise 'Need be initialized with a Hash or yaml file path'
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
# Converts the directory structure to a string representation.
|
139
|
+
#
|
140
|
+
# @return [String] The string representation of the directory structure.
|
141
|
+
def to_s
|
142
|
+
@output = String.new('')
|
143
|
+
process_node(@dir_hash)
|
144
|
+
@output
|
145
|
+
end
|
146
|
+
|
147
|
+
private
|
148
|
+
|
149
|
+
# Generates the indentation string based on the key.
|
150
|
+
#
|
151
|
+
# @param key [Symbol] The key indicating the type of indentation.
|
152
|
+
# @return [String] The indentation string.
|
153
|
+
def generate_indent(key)
|
154
|
+
{ middle: '║ ', last: ' ' }[key] || ''
|
155
|
+
end
|
156
|
+
|
157
|
+
# Concatenates the node to the output string with the given prefix and indentation.
|
158
|
+
#
|
159
|
+
# @param node [String] The node to be concatenated.
|
160
|
+
# @param prefix [Symbol] The prefix indicating the type of node.
|
161
|
+
# @param indent [Array<Symbol>] The array of indentation keys.
|
162
|
+
# @return [void]
|
163
|
+
def concant(node, prefix:, indent:)
|
164
|
+
prefix_string = { middle: '╠═ ', last: '╚═ ' }[prefix] || ''
|
165
|
+
indent_string = indent.map { |i| generate_indent(i) }.join
|
166
|
+
@output << "#{indent_string}#{prefix_string}#{node}\n"
|
167
|
+
end
|
168
|
+
|
169
|
+
# Processes an array of nodes and concatenates them to the output string.
|
170
|
+
#
|
171
|
+
# @param array [Array] The array of nodes to be processed.
|
172
|
+
# @param indent [Array<Symbol>] The array of indentation keys.
|
173
|
+
# @return [void]
|
174
|
+
def process_array(array, indent:)
|
175
|
+
array.each_with_index do |item, index|
|
176
|
+
prefix = index == array.size - 1 ? :last : :middle
|
177
|
+
concant(item, prefix: prefix, indent: indent)
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
# Processes a hash of nodes and concatenates them to the output string.
|
182
|
+
#
|
183
|
+
# @param hash [Hash] The hash of nodes to be processed.
|
184
|
+
# @param level [Integer] The current level of indentation.
|
185
|
+
# @param indent [Array<Symbol>] The array of indentation keys.
|
186
|
+
# @return [void]
|
187
|
+
def process_hash(hash, level:, indent:)
|
188
|
+
hash.each_with_index do |(key, value), index|
|
189
|
+
new_indent = indent.dup
|
190
|
+
prefix = :empty
|
191
|
+
|
192
|
+
if level > new_indent.size
|
193
|
+
prefix = index == hash.size - 1 ? :last : :middle
|
194
|
+
new_indent = indent + [prefix]
|
195
|
+
end
|
196
|
+
|
197
|
+
concant(key, prefix: prefix, indent: indent)
|
198
|
+
process_node(value, indent: new_indent, level: level)
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
# Processes a node (hash, array, or other) and concatenates it to the output string.
|
203
|
+
#
|
204
|
+
# @param node [Object] The node to be processed.
|
205
|
+
# @param level [Integer] The current level of indentation.
|
206
|
+
# @param indent [Array<Symbol>] The array of indentation keys.
|
207
|
+
# @return [void]
|
208
|
+
def process_node(node, level: 0, indent: [''])
|
209
|
+
if node.is_a?(Hash)
|
210
|
+
process_hash(node, indent: indent, level: level + 1)
|
211
|
+
elsif node.is_a?(Array)
|
212
|
+
process_array(node, indent: indent)
|
213
|
+
elsif !node.nil?
|
214
|
+
concant(node, prefix: :last, indent: indent)
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
data/lib/utils/key.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# The Key class is designed to encapsulate strings within a specific prefix and suffix,
|
4
|
-
# allowing for easy identification and manipulation of placeholders within messages.
|
4
|
+
# allowing for easy identification and manipulation of placeholders within messages.
|
5
5
|
# This can be particularly useful in templating systems where placeholders need
|
6
|
-
# to be dynamically replaced with actual content.
|
6
|
+
# to be dynamically replaced with actual content.
|
7
7
|
#
|
8
8
|
# @example Creating a new Key and converting it to a string
|
9
9
|
# key = Key.new("username")
|
@@ -24,32 +24,32 @@ class Key
|
|
24
24
|
@value = value.to_s
|
25
25
|
end
|
26
26
|
|
27
|
-
# Checks equality of two Key objects based on their value.
|
27
|
+
# Checks equality of two Key objects based on their value.
|
28
28
|
#
|
29
|
-
# @param other [Key] the other Key object to compare with.
|
30
|
-
# @return [Boolean] true if both Keys have the same value, false otherwise.
|
29
|
+
# @param other [Key] the other Key object to compare with.
|
30
|
+
# @return [Boolean] true if both Keys have the same value, false otherwise.
|
31
31
|
def ==(other)
|
32
32
|
self.class == other.class && @value == other.value
|
33
33
|
end
|
34
34
|
|
35
|
-
# Returns the string representation of the Key, including its prefix and suffix.
|
36
|
-
#
|
37
|
-
# @return [String] the string representation of the Key.
|
35
|
+
# Returns the string representation of the Key, including its prefix and suffix.
|
36
|
+
#
|
37
|
+
# @return [String] the string representation of the Key.
|
38
38
|
def to_s
|
39
39
|
"#{Key.prefix}#{@value}#{Key.suffix}"
|
40
40
|
end
|
41
41
|
|
42
|
-
# Returns the escaped Regexp representation of the Key.to_s return.
|
43
|
-
#
|
44
|
-
# @return [Regexp] the escaped regexp representation of the Key.to_s return.
|
42
|
+
# Returns the escaped Regexp representation of the Key.to_s return.
|
43
|
+
#
|
44
|
+
# @return [Regexp] the escaped regexp representation of the Key.to_s return.
|
45
45
|
def to_regexp
|
46
46
|
/#{Regexp.escape(to_s)}/
|
47
47
|
end
|
48
48
|
|
49
|
-
# Finds and returns all Key instances within the given string.
|
49
|
+
# Finds and returns all Key instances within the given string.
|
50
50
|
#
|
51
|
-
# @param value [#to_s] the string to search for keys.
|
52
|
-
# @return [Array<Key>] an array of Key instances found within the given string.
|
51
|
+
# @param value [#to_s] the string to search for keys.
|
52
|
+
# @return [Array<Key>] an array of Key instances found within the given string.
|
53
53
|
def self.find_keys_in(value)
|
54
54
|
ep = Regexp.escape(prefix)
|
55
55
|
es = Regexp.escape(suffix)
|
@@ -58,16 +58,16 @@ class Key
|
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
61
|
-
# Returns the prefix used to identify the start of a Key in a string.
|
62
|
-
#
|
63
|
-
# @return [String] the prefix.
|
61
|
+
# Returns the prefix used to identify the start of a Key in a string.
|
62
|
+
#
|
63
|
+
# @return [String] the prefix.
|
64
64
|
def self.prefix
|
65
65
|
'<||'
|
66
66
|
end
|
67
67
|
|
68
|
-
# Returns the suffix used to identify the end of a Key in a string.
|
69
|
-
#
|
70
|
-
# @return [String] the suffix.
|
68
|
+
# Returns the suffix used to identify the end of a Key in a string.
|
69
|
+
#
|
70
|
+
# @return [String] the suffix.
|
71
71
|
def self.suffix
|
72
72
|
'||>'
|
73
73
|
end
|
data/lib/utils/message.rb
CHANGED
@@ -3,16 +3,14 @@
|
|
3
3
|
require_relative File.join('..', 'resources', 'path_helper')
|
4
4
|
require_relative 'key'
|
5
5
|
|
6
|
-
# The Message class represents a mechanism for dynamically handling and formatting messages.
|
7
|
-
#
|
8
|
-
# It supports the substitution of placeholders within a message template with actual data.
|
9
|
-
#
|
6
|
+
# The Message class represents a mechanism for dynamically handling and formatting messages.
|
7
|
+
# It supports the substitution of placeholders within a message template with actual data.
|
10
8
|
# The class leverages file-based message templates, allowing for easy localization or
|
11
|
-
# customization of messages.
|
9
|
+
# customization of messages.
|
12
10
|
#
|
13
11
|
# It integrates seamlessly with the Resources module to access these templates from
|
14
12
|
# a customizable path set via the "SCRIPT_CUSTOM_RESOURCES" environment variable or
|
15
|
-
# from a default library path.
|
13
|
+
# from a default library path.
|
16
14
|
#
|
17
15
|
# @example Creating a new Message instance and formatting it
|
18
16
|
# # Assuming "hellow_world" is a file that says "Hello, world!"
|
@@ -40,10 +38,11 @@ class Message
|
|
40
38
|
self.class == other.class && @message == other.message
|
41
39
|
end
|
42
40
|
|
43
|
-
# Converts the message template into a string, replacing any placeholders with actual data.
|
41
|
+
# Converts the message template into a string, replacing any placeholders with actual data.
|
44
42
|
# This method searches for keys within the message and replaces them with corresponding
|
45
43
|
# content from message files located in either the custom path or the library path and appling
|
46
|
-
# the given replaces.
|
44
|
+
# the given replaces.
|
45
|
+
# If the file name have the suffix ".aas.txt", the ANSIStyleManager will be applied to the file.
|
47
46
|
#
|
48
47
|
# @return [String] The formatted message with placeholders substituted with actual content.
|
49
48
|
def to_s
|
@@ -53,7 +52,7 @@ class Message
|
|
53
52
|
|
54
53
|
private
|
55
54
|
|
56
|
-
# Determines the custom path for message files, if set through the "SCRIPT_CUSTOM_RESOURCES" environment variable.
|
55
|
+
# Determines the custom path for message files, if set through the "SCRIPT_CUSTOM_RESOURCES" environment variable.
|
57
56
|
#
|
58
57
|
# @return [String, nil] The custom path for message files, or nil if not set.
|
59
58
|
def custom_path
|
@@ -63,15 +62,15 @@ class Message
|
|
63
62
|
File.join(path, 'messages')
|
64
63
|
end
|
65
64
|
|
66
|
-
# Provides the default library path for message files.
|
67
|
-
# when a message file is not found in the custom path.
|
65
|
+
# Provides the default library path for message files.
|
66
|
+
# This path is used as a fallback when a message file is not found in the custom path.
|
68
67
|
#
|
69
68
|
# @return [String] The path to the default library of message files.
|
70
69
|
def library_path
|
71
70
|
File.join(Resources.library_path, 'messages')
|
72
71
|
end
|
73
72
|
|
74
|
-
# Replaces keys found in the original message with their corresponding values.
|
73
|
+
# Replaces keys found in the original message with their corresponding values.
|
75
74
|
#
|
76
75
|
# @param message [String] The original message with keys to be replaced.
|
77
76
|
# @return [String] The message with keys replaced by their corresponding values.
|
@@ -87,7 +86,7 @@ class Message
|
|
87
86
|
message
|
88
87
|
end
|
89
88
|
|
90
|
-
# Replaces all placeholders in the message with their corresponding values from the @to_replace hash.
|
89
|
+
# Replaces all placeholders in the message with their corresponding values from the @to_replace hash.
|
91
90
|
#
|
92
91
|
# @param message [String] The message with placeholders to replace.
|
93
92
|
# @return [String] The message with all placeholders replaced with actual content.
|
@@ -105,8 +104,8 @@ class Message
|
|
105
104
|
message
|
106
105
|
end
|
107
106
|
|
108
|
-
# Attempts to recover and return the content of a message file identified by the file_name parameter.
|
109
|
-
# It first looks in the custom path (if defined) and then in the library path.
|
107
|
+
# Attempts to recover and return the content of a message file identified by the file_name parameter.
|
108
|
+
# It first looks in the custom path (if defined) and then in the library path.
|
110
109
|
#
|
111
110
|
# @param file_name [String] The name of the file containing the message content to be recovered.
|
112
111
|
# @return [String] The content of the message file, or the file_name itself if the file cannot be found.
|
@@ -123,8 +122,8 @@ class Message
|
|
123
122
|
file_name
|
124
123
|
end
|
125
124
|
|
126
|
-
# Reads and returns the content of a message file located at a specific path.
|
127
|
-
# If the file name have the suffix ".aas.txt", the ANSIStyleManager will be applied to the file.
|
125
|
+
# Reads and returns the content of a message file located at a specific path.
|
126
|
+
# If the file name have the suffix ".aas.txt", the ANSIStyleManager will be applied to the file.
|
128
127
|
#
|
129
128
|
# @param path [String] The path where the message file is located.
|
130
129
|
# @param file_name [String] The name of the file to be read.
|
data/lib/utils/question.rb
CHANGED
@@ -3,9 +3,9 @@
|
|
3
3
|
require_relative 'message'
|
4
4
|
require_relative 'array'
|
5
5
|
|
6
|
-
# The Question class facilitates the creation and management of interactive questions in the console.
|
6
|
+
# The Question class facilitates the creation and management of interactive questions in the console.
|
7
7
|
# It provides methods to validate and return user input as various data types including boolean,
|
8
|
-
# float, integer, options (from a list), and string.
|
8
|
+
# float, integer, options (from a list), and string.
|
9
9
|
class Question
|
10
10
|
# Initializes a new instance of the Question class.
|
11
11
|
#
|
@@ -93,11 +93,11 @@ class Question
|
|
93
93
|
end
|
94
94
|
end
|
95
95
|
|
96
|
-
# Reads an index input from the user, ensuring it falls within a specified range.
|
96
|
+
# Reads an index input from the user, ensuring it falls within a specified range.
|
97
97
|
#
|
98
98
|
# This method prompts the user to enter an index number. It validates the input to ensure
|
99
99
|
# it is an integer within the range of 0 to (count - 1). If the input is invalid, an error
|
100
|
-
# message is displayed, and the user is prompted again.
|
100
|
+
# message is displayed, and the user is prompted again.
|
101
101
|
#
|
102
102
|
# @param count [Integer] The count of items, setting the upper limit of the valid index range.
|
103
103
|
# @param error_message [String, nil] Custom error message for invalid index inputs.
|
data/lib/utils/string.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'question'
|
4
|
+
require_relative 'message'
|
5
|
+
require_relative 'ansi'
|
6
|
+
require_relative 'key'
|
7
|
+
|
8
|
+
# This class provides additional methods to the standard Ruby String class,
|
9
|
+
# allowing for the removal of ANSI codes, and conversion to Key, Question,
|
10
|
+
# and Message objects.
|
11
|
+
class String
|
12
|
+
# Removes ANSI escape codes from the string.
|
13
|
+
#
|
14
|
+
# @return [String] a new string with ANSI codes removed.
|
15
|
+
def remove_ansi
|
16
|
+
ANSI.remove_from_string(self)
|
17
|
+
end
|
18
|
+
|
19
|
+
# Converts the string to a Key object.
|
20
|
+
#
|
21
|
+
# @return [Key] a new Key object initialized with the string.
|
22
|
+
def to_key
|
23
|
+
Key.new(self)
|
24
|
+
end
|
25
|
+
|
26
|
+
# Converts the string to a Question object.
|
27
|
+
#
|
28
|
+
# @return [Question] a new Question object initialized with the string.
|
29
|
+
def to_question
|
30
|
+
Question.new(self)
|
31
|
+
end
|
32
|
+
|
33
|
+
# Converts the string to a Message object.
|
34
|
+
#
|
35
|
+
# @param replaces [Hash, nil] optional replacements to be applied in the message.
|
36
|
+
# @return [Message] a new Message object initialized with the string and optional replacements.
|
37
|
+
def to_message(replaces: nil)
|
38
|
+
Message.new(self, replaces: replaces)
|
39
|
+
end
|
40
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mp-utils
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marcio F Paludo
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-10-24 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: |
|
14
14
|
Helpers to facilitate scripts Writing.
|
@@ -32,9 +32,11 @@ files:
|
|
32
32
|
- lib/utils/ansi_style_manager.rb
|
33
33
|
- lib/utils/array.rb
|
34
34
|
- lib/utils/constants.rb
|
35
|
+
- lib/utils/directory_structure.rb
|
35
36
|
- lib/utils/key.rb
|
36
37
|
- lib/utils/message.rb
|
37
38
|
- lib/utils/question.rb
|
39
|
+
- lib/utils/string.rb
|
38
40
|
- lib/utils/version_manager.rb
|
39
41
|
homepage: https://github.com/MarcioFPaludo/ruby-mp-utils
|
40
42
|
licenses:
|
@@ -42,6 +44,7 @@ licenses:
|
|
42
44
|
metadata:
|
43
45
|
homepage_uri: https://github.com/MarcioFPaludo/ruby-mp-utils
|
44
46
|
source_code_uri: https://github.com/MarcioFPaludo/ruby-mp-utils
|
47
|
+
documentation_uri: https://marciofpaludo.github.io/ruby-mp-utils
|
45
48
|
rubygems_mfa_required: 'true'
|
46
49
|
post_install_message:
|
47
50
|
rdoc_options: []
|