dev_suite 0.2.0 → 0.2.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/Gemfile.lock +1 -1
- data/lib/dev_suite/directory_tree/builder/base.rb +38 -0
- data/lib/dev_suite/directory_tree/builder.rb +20 -0
- data/lib/dev_suite/directory_tree/config.rb +6 -27
- data/lib/dev_suite/directory_tree/node/base.rb +13 -1
- data/lib/dev_suite/directory_tree/node/directory.rb +14 -2
- data/lib/dev_suite/directory_tree/node/file.rb +2 -2
- data/lib/dev_suite/directory_tree/renderer/base.rb +5 -31
- data/lib/dev_suite/directory_tree/renderer/simple.rb +57 -42
- data/lib/dev_suite/directory_tree/settings.rb +29 -0
- data/lib/dev_suite/directory_tree/visualizer.rb +3 -9
- data/lib/dev_suite/directory_tree.rb +5 -1
- data/lib/dev_suite/performance/analyzer.rb +5 -5
- data/lib/dev_suite/performance/config.rb +16 -0
- data/lib/dev_suite/performance/profiler/benchmark.rb +0 -2
- data/lib/dev_suite/performance/reportor/simple.rb +52 -27
- data/lib/dev_suite/performance/reportor.rb +12 -1
- data/lib/dev_suite/performance.rb +4 -0
- data/lib/dev_suite/utils/color/colorizer.rb +1 -7
- data/lib/dev_suite/utils/config_tools/configuration.rb +41 -0
- data/lib/dev_suite/utils/config_tools/settings.rb +75 -0
- data/lib/dev_suite/utils/config_tools.rb +10 -0
- data/lib/dev_suite/utils/table/config.rb +8 -42
- data/lib/dev_suite/utils/table/renderer/base.rb +4 -2
- data/lib/dev_suite/utils/table/renderer/simple.rb +5 -5
- data/lib/dev_suite/utils/table/renderer.rb +11 -0
- data/lib/dev_suite/utils/table/settings.rb +34 -0
- data/lib/dev_suite/utils/table/table.rb +2 -8
- data/lib/dev_suite/utils/table.rb +1 -0
- data/lib/dev_suite/utils.rb +1 -0
- data/lib/dev_suite/version.rb +1 -1
- metadata +10 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 61551856599e246df8b5d7e66bf7ada17cf7ed03147c9c846fcd1f4ed2fcaf5d
|
4
|
+
data.tar.gz: f36513a7e8afa78bd04c9a9d9cd893e9a75b79006ff2ba41f8aa0245f06cc0fa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 533af36d8beb9efbe20c5f8135d6c7255265c6e8ff7b0b2fc35f57da5572803cead32a69bcda9e672f4de5373b0a6f41e678241042c0ce16c0a06cbe681ead4d
|
7
|
+
data.tar.gz: 66729b4045f43b20029c6ad81365e51505489c3a6f99f241cfbb7acd9e31bd5951004e3faf2f0715878ac386a2c1d8108701142fdb87ebed72b63b1d7263b423
|
data/Gemfile.lock
CHANGED
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DevSuite
|
4
|
+
module DirectoryTree
|
5
|
+
module Builder
|
6
|
+
class Base
|
7
|
+
#
|
8
|
+
# Recursive method to build the tree
|
9
|
+
#
|
10
|
+
def build(path)
|
11
|
+
return build_permission_denied_node(path) unless path.readable?
|
12
|
+
|
13
|
+
path.directory? ? construct_directory_node(path) : build_file_node(path)
|
14
|
+
rescue Errno::EACCES
|
15
|
+
build_permission_denied_node(path)
|
16
|
+
end
|
17
|
+
|
18
|
+
protected
|
19
|
+
|
20
|
+
def construct_directory_node(path)
|
21
|
+
directory = Node::Directory.new(path.basename.to_s)
|
22
|
+
path.children.each do |child|
|
23
|
+
directory.add_child(build(child))
|
24
|
+
end
|
25
|
+
directory
|
26
|
+
end
|
27
|
+
|
28
|
+
def build_file_node(path)
|
29
|
+
Node::File.new(path.basename.to_s)
|
30
|
+
end
|
31
|
+
|
32
|
+
def build_permission_denied_node(path)
|
33
|
+
Node::PermissionDenied.new(path.basename.to_s, path.directory?)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DevSuite
|
4
|
+
module DirectoryTree
|
5
|
+
module Builder
|
6
|
+
require_relative "builder/base"
|
7
|
+
|
8
|
+
class << self
|
9
|
+
def create(type)
|
10
|
+
case type
|
11
|
+
when :base
|
12
|
+
Base.new
|
13
|
+
else
|
14
|
+
raise ArgumentError, "Unknown renderer type: #{type}"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -3,37 +3,16 @@
|
|
3
3
|
module DevSuite
|
4
4
|
module DirectoryTree
|
5
5
|
class Config
|
6
|
-
|
6
|
+
include Utils::ConfigTools::Configuration
|
7
7
|
|
8
|
-
|
8
|
+
attr_reader :settings, :builder, :renderer
|
9
|
+
|
10
|
+
def initialize(settings: {}, builder: :base, renderer: :simple)
|
11
|
+
@settings = Settings.new(settings)
|
12
|
+
@builder = Builder.create(builder)
|
9
13
|
@renderer = Renderer.create(renderer)
|
10
14
|
freeze # Make the instance of this class immutable as well
|
11
15
|
end
|
12
|
-
|
13
|
-
class << self
|
14
|
-
#
|
15
|
-
# Provide global access to a single instance of Config
|
16
|
-
#
|
17
|
-
def configuration
|
18
|
-
@configuration ||= new
|
19
|
-
end
|
20
|
-
|
21
|
-
#
|
22
|
-
# Allow block-based configuration
|
23
|
-
#
|
24
|
-
def configure
|
25
|
-
yield(configuration)
|
26
|
-
rescue StandardError => e
|
27
|
-
handle_configuration_error(e)
|
28
|
-
raise
|
29
|
-
end
|
30
|
-
|
31
|
-
private
|
32
|
-
|
33
|
-
def handle_configuration_error(error)
|
34
|
-
puts "Configuration error: #{error.message}"
|
35
|
-
end
|
36
|
-
end
|
37
16
|
end
|
38
17
|
end
|
39
18
|
end
|
@@ -11,7 +11,19 @@ module DevSuite
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def directory?
|
14
|
-
|
14
|
+
false
|
15
|
+
end
|
16
|
+
|
17
|
+
def file?
|
18
|
+
false
|
19
|
+
end
|
20
|
+
|
21
|
+
def children
|
22
|
+
[]
|
23
|
+
end
|
24
|
+
|
25
|
+
def hidden?
|
26
|
+
@name.start_with?(".")
|
15
27
|
end
|
16
28
|
end
|
17
29
|
end
|
@@ -15,8 +15,20 @@ module DevSuite
|
|
15
15
|
true
|
16
16
|
end
|
17
17
|
|
18
|
-
def add_child(
|
19
|
-
@children <<
|
18
|
+
def add_child(node)
|
19
|
+
@children << node
|
20
|
+
sort_children!
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def sort_children!
|
26
|
+
@children.sort_by! do |node|
|
27
|
+
[
|
28
|
+
node.hidden? ? 1 : 0, # Hidden nodes should be at the end
|
29
|
+
node.name.downcase, # Alphabetical order
|
30
|
+
]
|
31
|
+
end
|
20
32
|
end
|
21
33
|
end
|
22
34
|
end
|
@@ -1,43 +1,17 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "pathname"
|
4
|
-
|
5
3
|
module DevSuite
|
6
4
|
module DirectoryTree
|
7
5
|
module Renderer
|
8
6
|
class Base
|
9
|
-
|
10
|
-
raise ArgumentError, "Invalid path" unless valid_path?(path)
|
11
|
-
|
12
|
-
root = build_tree(Pathname.new(path))
|
13
|
-
render_node(root, "", true)
|
14
|
-
end
|
15
|
-
|
16
|
-
private
|
17
|
-
|
18
|
-
def valid_path?(path)
|
19
|
-
[
|
20
|
-
path.is_a?(String),
|
21
|
-
::File.exist?(path),
|
22
|
-
::File.directory?(path),
|
23
|
-
::File.readable?(path),
|
24
|
-
].all?
|
25
|
-
end
|
7
|
+
attr_reader :settings
|
26
8
|
|
27
|
-
|
28
|
-
|
29
|
-
# @return [Node::Base] The root node of the tree
|
30
|
-
def build_tree(path)
|
31
|
-
raise NotImplementedError, "You must implement the build_tree method"
|
9
|
+
def initialize(settings: Settings.new)
|
10
|
+
@settings = settings
|
32
11
|
end
|
33
12
|
|
34
|
-
|
35
|
-
|
36
|
-
# @param prefix [String] The prefix to add to the node
|
37
|
-
# @param is_last [Boolean] Whether this is the last node in the list
|
38
|
-
# @return [String] The rendered node
|
39
|
-
def render_node(node, prefix, is_last)
|
40
|
-
raise NotImplementedError, "You must implement the render_node method"
|
13
|
+
def render
|
14
|
+
raise NotImplementedError
|
41
15
|
end
|
42
16
|
end
|
43
17
|
end
|
@@ -4,69 +4,84 @@ module DevSuite
|
|
4
4
|
module DirectoryTree
|
5
5
|
module Renderer
|
6
6
|
class Simple < Base
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
7
|
+
# The characters are used to draw the tree structure
|
8
|
+
#
|
9
|
+
# └ (U+2514) is the L-shaped corner character
|
10
|
+
# ├ (U+251C) is the L-shaped corner character
|
11
|
+
# │ (U+2502) is the vertical line character
|
12
|
+
# ─ (U+2500) is the horizontal line character
|
13
|
+
# (U+00A0) is the non-breaking space character
|
14
|
+
# | (U+007C) is the vertical line character
|
15
|
+
# (U+0020) is the space character
|
16
|
+
LAST_NODE_CONNECTOR = "└── "
|
17
|
+
NODE_CONNECTOR = "├── "
|
18
|
+
INDENT = " "
|
19
|
+
PIPE = "│ "
|
20
|
+
|
21
|
+
def render(node:, prefix: "", is_last: true, depth: 0)
|
22
|
+
return "" if skip_node?(node) || exceeds_max_depth?(depth)
|
23
|
+
|
24
|
+
output = node_line(node: node, prefix: prefix, is_last: is_last)
|
25
25
|
if node.directory? && node.children.any?
|
26
|
-
node
|
27
|
-
output += render_node(child, new_prefix, index == node.children.size - 1)
|
28
|
-
end
|
26
|
+
output += render_children(node: node, prefix: prefix, is_last: is_last, depth: depth)
|
29
27
|
end
|
30
28
|
|
31
29
|
output
|
32
30
|
end
|
33
31
|
|
34
|
-
|
35
|
-
return "" if is_root
|
32
|
+
private
|
36
33
|
|
37
|
-
|
34
|
+
def settings
|
35
|
+
Config.configuration.settings
|
38
36
|
end
|
39
37
|
|
40
|
-
def
|
41
|
-
|
38
|
+
def skip_node?(node)
|
39
|
+
hidden_file_skipped?(node) || filetype_skipped?(node)
|
42
40
|
end
|
43
41
|
|
44
|
-
def
|
45
|
-
|
42
|
+
def hidden_file_skipped?(node)
|
43
|
+
settings.skip_hidden? && node.hidden?
|
46
44
|
end
|
47
45
|
|
48
|
-
def
|
49
|
-
node.
|
46
|
+
def filetype_skipped?(node)
|
47
|
+
node.file? && settings.skip_types.include?(::File.extname(node.name))
|
50
48
|
end
|
51
49
|
|
52
|
-
def
|
53
|
-
|
54
|
-
|
55
|
-
dir.add_child(build_tree(child))
|
56
|
-
end
|
57
|
-
dir
|
50
|
+
def exceeds_max_depth?(depth)
|
51
|
+
max_depth = settings.max_depth
|
52
|
+
max_depth && depth > max_depth
|
58
53
|
end
|
59
54
|
|
60
|
-
def
|
61
|
-
|
55
|
+
def node_line(node:, prefix:, is_last:)
|
56
|
+
connector = determine_connector(is_root: prefix.empty?, is_last: is_last)
|
57
|
+
"#{prefix}#{connector}#{node.name}#{suffix_for(node)}"
|
58
|
+
end
|
59
|
+
|
60
|
+
def determine_connector(is_root:, is_last:)
|
61
|
+
return "" if is_root
|
62
|
+
|
63
|
+
is_last ? LAST_NODE_CONNECTOR : NODE_CONNECTOR
|
64
|
+
end
|
65
|
+
|
66
|
+
def suffix_for(node)
|
67
|
+
node.directory? ? "/\n" : "\n"
|
62
68
|
end
|
63
69
|
|
64
|
-
def
|
65
|
-
|
70
|
+
def render_children(node:, prefix:, is_last:, depth:)
|
71
|
+
new_prefix = updated_prefix(prefix: prefix, is_last: is_last)
|
72
|
+
visible_children = node.children.reject { |child| skip_node?(child) }
|
73
|
+
visible_children.each_with_index.map do |child, index|
|
74
|
+
render(
|
75
|
+
node: child,
|
76
|
+
prefix: new_prefix,
|
77
|
+
is_last: index == visible_children.size - 1,
|
78
|
+
depth: depth + 1,
|
79
|
+
)
|
80
|
+
end.join
|
66
81
|
end
|
67
82
|
|
68
|
-
def
|
69
|
-
|
83
|
+
def updated_prefix(prefix:, is_last:)
|
84
|
+
"#{prefix}#{is_last ? INDENT : PIPE}"
|
70
85
|
end
|
71
86
|
end
|
72
87
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DevSuite
|
4
|
+
module DirectoryTree
|
5
|
+
class Settings
|
6
|
+
include Utils::ConfigTools::Settings
|
7
|
+
|
8
|
+
def default_settings
|
9
|
+
{
|
10
|
+
skip_hidden: false,
|
11
|
+
skip_types: [],
|
12
|
+
max_depth: nil,
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
def skip_hidden?
|
17
|
+
get(:skip_hidden)
|
18
|
+
end
|
19
|
+
|
20
|
+
def skip_types
|
21
|
+
get(:skip_types)
|
22
|
+
end
|
23
|
+
|
24
|
+
def max_depth
|
25
|
+
get(:max_depth)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -1,20 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "pathname"
|
4
|
-
|
5
3
|
module DevSuite
|
6
4
|
module DirectoryTree
|
7
5
|
class Visualizer
|
8
|
-
attr_reader :config
|
9
|
-
|
10
|
-
def initialize(config = Config.configuration)
|
11
|
-
@config = config
|
12
|
-
end
|
13
|
-
|
14
6
|
# Visualizes the directory tree
|
15
7
|
# @param path [String] The base path of the directory
|
16
8
|
def visualize(path)
|
17
|
-
|
9
|
+
root = Config.configuration.builder.build(Pathname.new(path))
|
10
|
+
renderer = Config.configuration.renderer
|
11
|
+
puts renderer.render(node: root)
|
18
12
|
end
|
19
13
|
end
|
20
14
|
|
@@ -2,9 +2,13 @@
|
|
2
2
|
|
3
3
|
module DevSuite
|
4
4
|
module DirectoryTree
|
5
|
+
require "pathname"
|
6
|
+
|
5
7
|
require_relative "directory_tree/node"
|
8
|
+
require_relative "directory_tree/config"
|
9
|
+
require_relative "directory_tree/settings"
|
6
10
|
require_relative "directory_tree/renderer"
|
11
|
+
require_relative "directory_tree/builder"
|
7
12
|
require_relative "directory_tree/visualizer"
|
8
|
-
require_relative "directory_tree/config"
|
9
13
|
end
|
10
14
|
end
|
@@ -5,6 +5,7 @@ module DevSuite
|
|
5
5
|
class Analyzer
|
6
6
|
def initialize(description: "Block")
|
7
7
|
@description = description
|
8
|
+
|
8
9
|
@benchmark_profiler = Profiler::Benchmark.new
|
9
10
|
@memory_profiler = Profiler::Memory.new
|
10
11
|
@memory_usage = Data::MemoryUsage.new
|
@@ -40,12 +41,11 @@ module DevSuite
|
|
40
41
|
# @param benchmark_result [Benchmark::Tms] The benchmark result
|
41
42
|
# @param memory_stats [Hash] The memory statistics
|
42
43
|
def generate_report(benchmark_result, memory_stats)
|
43
|
-
reportor
|
44
|
-
@description,
|
45
|
-
benchmark_result,
|
46
|
-
memory_stats,
|
44
|
+
Config.configuration.reportor.generate(
|
45
|
+
description: @description,
|
46
|
+
benchmark_result: benchmark_result,
|
47
|
+
memory_stats: memory_stats,
|
47
48
|
)
|
48
|
-
reportor.generate
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DevSuite
|
4
|
+
module Performance
|
5
|
+
class Config
|
6
|
+
include Utils::ConfigTools::Configuration
|
7
|
+
|
8
|
+
attr_reader :reportor
|
9
|
+
|
10
|
+
def initialize(reportor: :simple)
|
11
|
+
@reportor = Reportor.create(reportor)
|
12
|
+
freeze # Make the instance of this class immutable
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -4,17 +4,17 @@ module DevSuite
|
|
4
4
|
module Performance
|
5
5
|
module Reportor
|
6
6
|
class Simple < Base
|
7
|
-
|
8
|
-
super()
|
9
|
-
@description = description
|
10
|
-
@benchmark_result = benchmark_result
|
11
|
-
@memory_stats = memory_stats
|
12
|
-
end
|
13
|
-
|
7
|
+
#
|
14
8
|
# Generates the performance report
|
15
|
-
|
9
|
+
#
|
10
|
+
def generate(description:, benchmark_result:, memory_stats:)
|
16
11
|
table = create_table
|
17
|
-
populate_table(
|
12
|
+
populate_table(
|
13
|
+
table,
|
14
|
+
description: description,
|
15
|
+
benchmark_result: benchmark_result,
|
16
|
+
memory_stats: memory_stats,
|
17
|
+
)
|
18
18
|
render_table(table)
|
19
19
|
end
|
20
20
|
|
@@ -24,36 +24,61 @@ module DevSuite
|
|
24
24
|
# Creates a new table with the specified configuration
|
25
25
|
#
|
26
26
|
def create_table
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
27
|
+
table = Utils::Table::Table.new
|
28
|
+
table.tap do |t|
|
29
|
+
t.title = "Performance Analysis"
|
30
|
+
t.add_columns("Metric", "Value")
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
34
|
#
|
35
35
|
# Populates the table with benchmark and memory statistics
|
36
36
|
#
|
37
|
-
def populate_table(table)
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
table.add_row(["
|
42
|
-
table.add_row(["
|
43
|
-
table.add_row(["
|
44
|
-
table.add_row(["
|
45
|
-
table.add_row(["
|
46
|
-
table.add_row(["
|
47
|
-
table.add_row(["
|
48
|
-
table.add_row(["
|
37
|
+
def populate_table(table, description: "", benchmark_result: nil, memory_stats: {})
|
38
|
+
validate_benchmark_result(benchmark_result)
|
39
|
+
validate_memory_stats(memory_stats)
|
40
|
+
|
41
|
+
table.add_row(["Description", description])
|
42
|
+
table.add_row(["Total Time (s)", format("%.6f", benchmark_result.real)])
|
43
|
+
table.add_row(["User CPU Time (s)", format("%.6f", benchmark_result.utime)])
|
44
|
+
table.add_row(["System CPU Time (s)", format("%.6f", benchmark_result.stime)])
|
45
|
+
table.add_row(["User + System CPU Time (s)", format("%.6f", benchmark_result.total)])
|
46
|
+
table.add_row(["Memory Before (MB)", format("%.2f", memory_stats[:before])])
|
47
|
+
table.add_row(["Memory After (MB)", format("%.2f", memory_stats[:after])])
|
48
|
+
table.add_row(["Memory Used (MB)", format("%.2f", memory_stats[:used])])
|
49
|
+
table.add_row(["Max Memory Used (MB)", format("%.2f", memory_stats[:max])])
|
50
|
+
table.add_row(["Min Memory Used (MB)", format("%.2f", memory_stats[:min])])
|
51
|
+
table.add_row(["Avg Memory Used (MB)", format("%.2f", memory_stats[:avg])])
|
49
52
|
end
|
50
53
|
|
51
54
|
#
|
52
55
|
# Renders the table using the specified renderer
|
53
56
|
#
|
54
57
|
def render_table(table)
|
55
|
-
renderer = Utils::Table::
|
56
|
-
puts
|
58
|
+
renderer = Utils::Table::Config.configuration.renderer
|
59
|
+
puts renderer.render(table)
|
60
|
+
end
|
61
|
+
|
62
|
+
#
|
63
|
+
# Validates the benchmark_result object
|
64
|
+
#
|
65
|
+
def validate_benchmark_result(benchmark_result)
|
66
|
+
required_methods = [:real, :utime, :stime, :total]
|
67
|
+
missing_methods = required_methods.reject { |method| benchmark_result.respond_to?(method) }
|
68
|
+
unless missing_methods.empty?
|
69
|
+
raise ArgumentError, "benchmark_result is missing required methods: #{missing_methods.join(", ")}"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
#
|
74
|
+
# Validates the memory_stats hash
|
75
|
+
#
|
76
|
+
def validate_memory_stats(memory_stats)
|
77
|
+
required_keys = [:before, :after, :used, :max, :min, :avg]
|
78
|
+
missing_keys = required_keys.reject { |key| memory_stats.key?(key) }
|
79
|
+
unless missing_keys.empty?
|
80
|
+
raise ArgumentError, "memory_stats is missing required keys: #{missing_keys.join(", ")}"
|
81
|
+
end
|
57
82
|
end
|
58
83
|
end
|
59
84
|
end
|
@@ -2,9 +2,20 @@
|
|
2
2
|
|
3
3
|
module DevSuite
|
4
4
|
module Performance
|
5
|
-
module
|
5
|
+
module Reportor
|
6
6
|
require_relative "reportor/base"
|
7
7
|
require_relative "reportor/simple"
|
8
|
+
|
9
|
+
class << self
|
10
|
+
def create(reportor)
|
11
|
+
case reportor
|
12
|
+
when :simple
|
13
|
+
Simple.new
|
14
|
+
else
|
15
|
+
raise ArgumentError, "Invalid reportor: #{reportor}"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
8
19
|
end
|
9
20
|
end
|
10
21
|
end
|
@@ -2,9 +2,13 @@
|
|
2
2
|
|
3
3
|
module DevSuite
|
4
4
|
module Performance
|
5
|
+
require "benchmark"
|
6
|
+
require "get_process_mem"
|
7
|
+
|
5
8
|
require_relative "performance/data"
|
6
9
|
require_relative "performance/profiler"
|
7
10
|
require_relative "performance/reportor"
|
8
11
|
require_relative "performance/analyzer"
|
12
|
+
require_relative "performance/config"
|
9
13
|
end
|
10
14
|
end
|
@@ -4,14 +4,8 @@ module DevSuite
|
|
4
4
|
module Utils
|
5
5
|
module Color
|
6
6
|
class Colorizer
|
7
|
-
attr_reader :config
|
8
|
-
|
9
|
-
def initialize(config = Config.configuration)
|
10
|
-
@config = config
|
11
|
-
end
|
12
|
-
|
13
7
|
def colorize(text, **kargs)
|
14
|
-
puts
|
8
|
+
puts Config.configuration.strategy.colorize(text, **kargs)
|
15
9
|
end
|
16
10
|
end
|
17
11
|
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DevSuite
|
4
|
+
module Utils
|
5
|
+
module ConfigTools
|
6
|
+
module Configuration
|
7
|
+
# Module for global configuration
|
8
|
+
class << self
|
9
|
+
def included(base)
|
10
|
+
base.extend(ClassMethods)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
module ClassMethods
|
15
|
+
#
|
16
|
+
# Provide global access to a single instance of Config
|
17
|
+
#
|
18
|
+
def configuration
|
19
|
+
@configuration ||= new
|
20
|
+
end
|
21
|
+
|
22
|
+
#
|
23
|
+
# Allow block-based configuration
|
24
|
+
#
|
25
|
+
def configure
|
26
|
+
yield(configuration)
|
27
|
+
rescue StandardError => e
|
28
|
+
handle_configuration_error(e)
|
29
|
+
raise
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def handle_configuration_error(error)
|
35
|
+
puts "Configuration error: #{error.message}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DevSuite
|
4
|
+
module Utils
|
5
|
+
module ConfigTools
|
6
|
+
# Module for managing instance settings
|
7
|
+
module Settings
|
8
|
+
class << self
|
9
|
+
def included(base)
|
10
|
+
base.include(InstanceMethods)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
module InstanceMethods
|
15
|
+
def initialize(settings = {})
|
16
|
+
@settings = merge_settings(default_settings, settings)
|
17
|
+
end
|
18
|
+
|
19
|
+
def set(*keys, value)
|
20
|
+
key_path = normalize_keys(keys)
|
21
|
+
last_key = key_path.pop
|
22
|
+
target = key_path.each_with_object(@settings) do |key, nested|
|
23
|
+
nested[key] ||= {}
|
24
|
+
end
|
25
|
+
target[last_key] = value
|
26
|
+
end
|
27
|
+
|
28
|
+
def get(*keys)
|
29
|
+
key_path = normalize_keys(keys)
|
30
|
+
key_path.reduce(@settings) do |nested, key|
|
31
|
+
nested.is_a?(Hash) ? nested[key] : nil
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def apply
|
36
|
+
#
|
37
|
+
# Implement logic to apply settings in the including class
|
38
|
+
# TODO: need to review this method
|
39
|
+
#
|
40
|
+
raise NotImplementedError, "#{self.class} must implement the #apply method"
|
41
|
+
end
|
42
|
+
|
43
|
+
def reset!
|
44
|
+
@settings = default_settings
|
45
|
+
end
|
46
|
+
|
47
|
+
def default_settings
|
48
|
+
raise NotImplementedError, "#{self.class} must implement the #default_settings method"
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def normalize_keys(keys)
|
54
|
+
key_path = keys.flatten
|
55
|
+
if key_path.size == 1 && key_path.first.is_a?(String)
|
56
|
+
key_path.first.to_s.split(".").map(&:to_sym)
|
57
|
+
else
|
58
|
+
key_path.map(&:to_sym)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def merge_settings(defaults, overrides)
|
63
|
+
defaults.merge(overrides) do |_key, oldval, newval|
|
64
|
+
if oldval.is_a?(Hash) && newval.is_a?(Hash)
|
65
|
+
merge_settings(oldval, newval)
|
66
|
+
else
|
67
|
+
newval
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -4,7 +4,9 @@ module DevSuite
|
|
4
4
|
module Utils
|
5
5
|
module Table
|
6
6
|
class Config
|
7
|
-
|
7
|
+
include ConfigTools::Configuration
|
8
|
+
|
9
|
+
DEFAULT_SETTING = {
|
8
10
|
colors: {
|
9
11
|
title: :cyan,
|
10
12
|
column: :yellow,
|
@@ -17,48 +19,12 @@ module DevSuite
|
|
17
19
|
},
|
18
20
|
}.freeze
|
19
21
|
|
20
|
-
attr_reader :settings
|
21
|
-
|
22
|
-
def initialize(settings = {})
|
23
|
-
@settings = deep_merge(DEFAULTS, settings)
|
24
|
-
end
|
25
|
-
|
26
|
-
class << self
|
27
|
-
#
|
28
|
-
# Provide global access to a single instance of Config
|
29
|
-
#
|
30
|
-
def configuration
|
31
|
-
@configuration ||= new
|
32
|
-
end
|
33
|
-
|
34
|
-
# Allow block-based configuration
|
35
|
-
def configure
|
36
|
-
yield(configuration)
|
37
|
-
rescue StandardError => e
|
38
|
-
handle_configuration_error(e)
|
39
|
-
end
|
40
|
-
|
41
|
-
private
|
42
|
-
|
43
|
-
def handle_configuration_error(error)
|
44
|
-
puts "Configuration error: #{error.message}"
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
def color_for(key)
|
49
|
-
@settings[:colors][key] || DEFAULTS[:colors][:row]
|
50
|
-
end
|
51
|
-
|
52
|
-
def alignment_for(key)
|
53
|
-
@settings[:alignments][key] || :left
|
54
|
-
end
|
55
|
-
|
56
|
-
private
|
22
|
+
attr_reader :settings, :renderer
|
57
23
|
|
58
|
-
def
|
59
|
-
|
60
|
-
|
61
|
-
|
24
|
+
def initialize(settings: {}, renderer: :simple)
|
25
|
+
@settings = Settings.new(settings)
|
26
|
+
@renderer = Renderer.create(renderer, settings: @settings)
|
27
|
+
freeze
|
62
28
|
end
|
63
29
|
end
|
64
30
|
end
|
@@ -45,7 +45,7 @@ module DevSuite
|
|
45
45
|
|
46
46
|
total_width = column_widths.sum + column_widths.size * 3 - 1
|
47
47
|
title_str = "| #{table.title.center(total_width - 2)} |"
|
48
|
-
colorize(title_str,
|
48
|
+
colorize(title_str, settings.color_for(:title))
|
49
49
|
end
|
50
50
|
|
51
51
|
def render_header(table, column_widths)
|
@@ -55,13 +55,13 @@ module DevSuite
|
|
55
55
|
text_align(column.name, column_widths[index])
|
56
56
|
end
|
57
57
|
header_str = "| #{header.join(" | ")} |"
|
58
|
-
colorize(header_str,
|
58
|
+
colorize(header_str, settings.color_for(:column))
|
59
59
|
end
|
60
60
|
|
61
61
|
def render_separator(column_widths)
|
62
62
|
separator = column_widths.map { |width| "-" * width }.join("-+-")
|
63
63
|
separator_str = "+-#{separator}-+"
|
64
|
-
colorize(separator_str,
|
64
|
+
colorize(separator_str, settings.color_for(:border))
|
65
65
|
end
|
66
66
|
|
67
67
|
def render_rows(table, column_widths)
|
@@ -69,7 +69,7 @@ module DevSuite
|
|
69
69
|
render_row(row, column_widths)
|
70
70
|
end
|
71
71
|
cells_str = cells.join("\n")
|
72
|
-
colorize(cells_str,
|
72
|
+
colorize(cells_str, settings.color_for(:row))
|
73
73
|
end
|
74
74
|
|
75
75
|
def render_row(row, column_widths)
|
@@ -77,7 +77,7 @@ module DevSuite
|
|
77
77
|
text_align(cell.to_s, column_widths[index])
|
78
78
|
end
|
79
79
|
cell_str = "| #{cell.join(" | ")} |"
|
80
|
-
colorize(cell_str,
|
80
|
+
colorize(cell_str, settings.color_for(:row))
|
81
81
|
end
|
82
82
|
end
|
83
83
|
end
|
@@ -6,6 +6,17 @@ module DevSuite
|
|
6
6
|
module Renderer
|
7
7
|
require_relative "renderer/base"
|
8
8
|
require_relative "renderer/simple"
|
9
|
+
|
10
|
+
class << self
|
11
|
+
def create(type, settings: Settings.new)
|
12
|
+
case type
|
13
|
+
when :simple
|
14
|
+
Simple.new(settings: settings)
|
15
|
+
else
|
16
|
+
raise ArgumentError, "Unknown renderer type: #{type}"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
9
20
|
end
|
10
21
|
end
|
11
22
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DevSuite
|
4
|
+
module Utils
|
5
|
+
module Table
|
6
|
+
class Settings
|
7
|
+
include ConfigTools::Settings
|
8
|
+
|
9
|
+
def default_settings
|
10
|
+
{
|
11
|
+
colors: {
|
12
|
+
title: :cyan,
|
13
|
+
column: :yellow,
|
14
|
+
row: :default,
|
15
|
+
border: :blue,
|
16
|
+
},
|
17
|
+
alignments: {
|
18
|
+
column: :left,
|
19
|
+
row: :left,
|
20
|
+
},
|
21
|
+
}
|
22
|
+
end
|
23
|
+
|
24
|
+
def color_for(key)
|
25
|
+
get(:colors, key)
|
26
|
+
end
|
27
|
+
|
28
|
+
def alignment_for(key)
|
29
|
+
get(:alignments, key)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -5,13 +5,11 @@ module DevSuite
|
|
5
5
|
module Table
|
6
6
|
class Table
|
7
7
|
attr_accessor :title
|
8
|
-
attr_reader :columns, :rows
|
8
|
+
attr_reader :columns, :rows
|
9
9
|
|
10
|
-
def initialize
|
10
|
+
def initialize
|
11
11
|
@columns = []
|
12
12
|
@rows = []
|
13
|
-
@title = ""
|
14
|
-
@config = config
|
15
13
|
end
|
16
14
|
|
17
15
|
def add_columns(*names)
|
@@ -25,10 +23,6 @@ module DevSuite
|
|
25
23
|
def add_row(data)
|
26
24
|
@rows << Row.new(data)
|
27
25
|
end
|
28
|
-
|
29
|
-
def render(renderer: Renderer::Simple.new(config))
|
30
|
-
renderer.render(self)
|
31
|
-
end
|
32
26
|
end
|
33
27
|
end
|
34
28
|
end
|
data/lib/dev_suite/utils.rb
CHANGED
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.1
|
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-08-
|
11
|
+
date: 2024-08-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: benchmark
|
@@ -62,6 +62,8 @@ files:
|
|
62
62
|
- dev_suite.gemspec
|
63
63
|
- lib/dev_suite.rb
|
64
64
|
- lib/dev_suite/directory_tree.rb
|
65
|
+
- lib/dev_suite/directory_tree/builder.rb
|
66
|
+
- lib/dev_suite/directory_tree/builder/base.rb
|
65
67
|
- lib/dev_suite/directory_tree/config.rb
|
66
68
|
- lib/dev_suite/directory_tree/node.rb
|
67
69
|
- lib/dev_suite/directory_tree/node/base.rb
|
@@ -71,9 +73,11 @@ files:
|
|
71
73
|
- lib/dev_suite/directory_tree/renderer.rb
|
72
74
|
- lib/dev_suite/directory_tree/renderer/base.rb
|
73
75
|
- lib/dev_suite/directory_tree/renderer/simple.rb
|
76
|
+
- lib/dev_suite/directory_tree/settings.rb
|
74
77
|
- lib/dev_suite/directory_tree/visualizer.rb
|
75
78
|
- lib/dev_suite/performance.rb
|
76
79
|
- lib/dev_suite/performance/analyzer.rb
|
80
|
+
- lib/dev_suite/performance/config.rb
|
77
81
|
- lib/dev_suite/performance/data.rb
|
78
82
|
- lib/dev_suite/performance/data/memory_usage.rb
|
79
83
|
- lib/dev_suite/performance/profiler.rb
|
@@ -95,6 +99,9 @@ files:
|
|
95
99
|
- lib/dev_suite/utils/color/strategy/basic.rb
|
96
100
|
- lib/dev_suite/utils/color/strategy/rgb.rb
|
97
101
|
- lib/dev_suite/utils/color/strategy/theme.rb
|
102
|
+
- lib/dev_suite/utils/config_tools.rb
|
103
|
+
- lib/dev_suite/utils/config_tools/configuration.rb
|
104
|
+
- lib/dev_suite/utils/config_tools/settings.rb
|
98
105
|
- lib/dev_suite/utils/table.rb
|
99
106
|
- lib/dev_suite/utils/table/column.rb
|
100
107
|
- lib/dev_suite/utils/table/config.rb
|
@@ -105,6 +112,7 @@ files:
|
|
105
112
|
- lib/dev_suite/utils/table/renderer/base.rb
|
106
113
|
- lib/dev_suite/utils/table/renderer/simple.rb
|
107
114
|
- lib/dev_suite/utils/table/row.rb
|
115
|
+
- lib/dev_suite/utils/table/settings.rb
|
108
116
|
- lib/dev_suite/utils/table/table.rb
|
109
117
|
- lib/dev_suite/version.rb
|
110
118
|
homepage: https://patrick204nqh.github.io
|