dev_suite 0.1.3 → 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/README.md +2 -2
- 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 +18 -0
- data/lib/dev_suite/directory_tree/node/base.rb +13 -1
- data/lib/dev_suite/directory_tree/node/directory.rb +14 -4
- data/lib/dev_suite/directory_tree/node/file.rb +2 -4
- data/lib/dev_suite/directory_tree/node/permission_denied.rb +0 -2
- data/lib/dev_suite/directory_tree/node.rb +1 -0
- data/lib/dev_suite/directory_tree/renderer/base.rb +5 -24
- data/lib/dev_suite/directory_tree/renderer/simple.rb +57 -45
- data/lib/dev_suite/directory_tree/renderer.rb +12 -0
- data/lib/dev_suite/directory_tree/settings.rb +29 -0
- data/lib/dev_suite/directory_tree/visualizer.rb +11 -15
- data/lib/dev_suite/directory_tree.rb +7 -0
- data/lib/dev_suite/performance/analyzer.rb +14 -20
- data/lib/dev_suite/performance/config.rb +16 -0
- data/lib/dev_suite/performance/profiler/benchmark.rb +0 -3
- data/lib/dev_suite/performance/profiler/memory.rb +0 -3
- data/lib/dev_suite/performance/profiler.rb +1 -0
- data/lib/dev_suite/performance/reportor/simple.rb +52 -29
- data/lib/dev_suite/performance/reportor.rb +13 -1
- data/lib/dev_suite/performance.rb +7 -0
- data/lib/dev_suite/utils/color/colorizer.rb +7 -10
- 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 +11 -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
data/README.md
CHANGED
@@ -51,7 +51,7 @@ DevSuite::SomeUtility.do_something
|
|
51
51
|
```ruby
|
52
52
|
require 'dev_suite'
|
53
53
|
|
54
|
-
DevSuite::Performance
|
54
|
+
DevSuite::Performance.analyze(description: "My Code Block") do
|
55
55
|
sum = 0
|
56
56
|
1_000_000.times do |i|
|
57
57
|
sum += i
|
@@ -93,7 +93,7 @@ DevSuite::SomeUtility.do_something
|
|
93
93
|
base_path = "/path/to/your/directory"
|
94
94
|
|
95
95
|
# Perform the visualization
|
96
|
-
DevSuite::DirectoryTree
|
96
|
+
DevSuite::DirectoryTree.visualize(base_path)
|
97
97
|
```
|
98
98
|
|
99
99
|
**Example output**
|
@@ -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
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DevSuite
|
4
|
+
module DirectoryTree
|
5
|
+
class Config
|
6
|
+
include Utils::ConfigTools::Configuration
|
7
|
+
|
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)
|
13
|
+
@renderer = Renderer.create(renderer)
|
14
|
+
freeze # Make the instance of this class immutable as well
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
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
|
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative "base"
|
4
|
-
|
5
3
|
module DevSuite
|
6
4
|
module DirectoryTree
|
7
5
|
module Node
|
@@ -17,8 +15,20 @@ module DevSuite
|
|
17
15
|
true
|
18
16
|
end
|
19
17
|
|
20
|
-
def add_child(
|
21
|
-
@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
|
22
32
|
end
|
23
33
|
end
|
24
34
|
end
|
@@ -1,36 +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
|
-
@base_path = Pathname.new(base_path)
|
11
|
-
end
|
7
|
+
attr_reader :settings
|
12
8
|
|
13
|
-
def
|
14
|
-
|
15
|
-
render_node(root, "", true)
|
9
|
+
def initialize(settings: Settings.new)
|
10
|
+
@settings = settings
|
16
11
|
end
|
17
12
|
|
18
|
-
|
19
|
-
|
20
|
-
# Builds the tree structure
|
21
|
-
# @param path [Pathname] The path to build the tree from
|
22
|
-
# @return [Node::Base] The root node of the tree
|
23
|
-
def build_tree(path)
|
24
|
-
raise NotImplementedError, "You must implement the build_tree method"
|
25
|
-
end
|
26
|
-
|
27
|
-
# Renders a node in the tree
|
28
|
-
# @param node [Node::Base] The node to render
|
29
|
-
# @param prefix [String] The prefix to add to the node
|
30
|
-
# @param is_last [Boolean] Whether this is the last node in the list
|
31
|
-
# @return [String] The rendered node
|
32
|
-
def render_node(node, prefix, is_last)
|
33
|
-
raise NotImplementedError, "You must implement the render_node method"
|
13
|
+
def render
|
14
|
+
raise NotImplementedError
|
34
15
|
end
|
35
16
|
end
|
36
17
|
end
|
@@ -1,75 +1,87 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative "base"
|
4
|
-
require_relative "../node"
|
5
|
-
|
6
3
|
module DevSuite
|
7
4
|
module DirectoryTree
|
8
5
|
module Renderer
|
9
6
|
class Simple < Base
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
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)
|
28
25
|
if node.directory? && node.children.any?
|
29
|
-
node
|
30
|
-
output += render_node(child, new_prefix, index == node.children.size - 1)
|
31
|
-
end
|
26
|
+
output += render_children(node: node, prefix: prefix, is_last: is_last, depth: depth)
|
32
27
|
end
|
33
28
|
|
34
29
|
output
|
35
30
|
end
|
36
31
|
|
37
|
-
|
38
|
-
return "" if is_root
|
32
|
+
private
|
39
33
|
|
40
|
-
|
34
|
+
def settings
|
35
|
+
Config.configuration.settings
|
41
36
|
end
|
42
37
|
|
43
|
-
def
|
44
|
-
|
38
|
+
def skip_node?(node)
|
39
|
+
hidden_file_skipped?(node) || filetype_skipped?(node)
|
45
40
|
end
|
46
41
|
|
47
|
-
def
|
48
|
-
|
42
|
+
def hidden_file_skipped?(node)
|
43
|
+
settings.skip_hidden? && node.hidden?
|
49
44
|
end
|
50
45
|
|
51
|
-
def
|
52
|
-
node.
|
46
|
+
def filetype_skipped?(node)
|
47
|
+
node.file? && settings.skip_types.include?(::File.extname(node.name))
|
53
48
|
end
|
54
49
|
|
55
|
-
def
|
56
|
-
|
57
|
-
|
58
|
-
dir.add_child(build_tree(child))
|
59
|
-
end
|
60
|
-
dir
|
50
|
+
def exceeds_max_depth?(depth)
|
51
|
+
max_depth = settings.max_depth
|
52
|
+
max_depth && depth > max_depth
|
61
53
|
end
|
62
54
|
|
63
|
-
def
|
64
|
-
|
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"
|
65
68
|
end
|
66
69
|
|
67
|
-
def
|
68
|
-
|
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
|
69
81
|
end
|
70
82
|
|
71
|
-
def
|
72
|
-
|
83
|
+
def updated_prefix(prefix:, is_last:)
|
84
|
+
"#{prefix}#{is_last ? INDENT : PIPE}"
|
73
85
|
end
|
74
86
|
end
|
75
87
|
end
|
@@ -3,7 +3,19 @@
|
|
3
3
|
module DevSuite
|
4
4
|
module DirectoryTree
|
5
5
|
module Renderer
|
6
|
+
require_relative "renderer/base"
|
6
7
|
require_relative "renderer/simple"
|
8
|
+
|
9
|
+
class << self
|
10
|
+
def create(type)
|
11
|
+
case type
|
12
|
+
when :simple
|
13
|
+
Simple.new
|
14
|
+
else
|
15
|
+
raise ArgumentError, "Unknown renderer type: #{type}"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
7
19
|
end
|
8
20
|
end
|
9
21
|
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,25 +1,21 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "pathname"
|
4
|
-
require_relative "renderer"
|
5
|
-
|
6
3
|
module DevSuite
|
7
4
|
module DirectoryTree
|
8
5
|
class Visualizer
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
end
|
16
|
-
|
17
|
-
def initialize(base_path, renderer: Renderer::Simple.new(base_path))
|
18
|
-
@renderer = renderer
|
6
|
+
# Visualizes the directory tree
|
7
|
+
# @param path [String] The base path of the directory
|
8
|
+
def visualize(path)
|
9
|
+
root = Config.configuration.builder.build(Pathname.new(path))
|
10
|
+
renderer = Config.configuration.renderer
|
11
|
+
puts renderer.render(node: root)
|
19
12
|
end
|
13
|
+
end
|
20
14
|
|
21
|
-
|
22
|
-
|
15
|
+
class << self
|
16
|
+
def visualize(path)
|
17
|
+
visualizer = Visualizer.new
|
18
|
+
visualizer.visualize(path)
|
23
19
|
end
|
24
20
|
end
|
25
21
|
end
|
@@ -2,6 +2,13 @@
|
|
2
2
|
|
3
3
|
module DevSuite
|
4
4
|
module DirectoryTree
|
5
|
+
require "pathname"
|
6
|
+
|
7
|
+
require_relative "directory_tree/node"
|
8
|
+
require_relative "directory_tree/config"
|
9
|
+
require_relative "directory_tree/settings"
|
10
|
+
require_relative "directory_tree/renderer"
|
11
|
+
require_relative "directory_tree/builder"
|
5
12
|
require_relative "directory_tree/visualizer"
|
6
13
|
end
|
7
14
|
end
|
@@ -1,25 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative "reportor"
|
4
|
-
require_relative "profiler"
|
5
|
-
|
6
3
|
module DevSuite
|
7
4
|
module Performance
|
8
5
|
class Analyzer
|
9
|
-
class << self
|
10
|
-
# Generates a performance report
|
11
|
-
# @param benchmark_result [Benchmark::Tms] The benchmark result
|
12
|
-
# @param memory_stats [Hash] The memory statistics
|
13
|
-
def analyze(description: "Block", &block)
|
14
|
-
raise ArgumentError, "No block given" unless block_given?
|
15
|
-
|
16
|
-
analyzer = new(description: description)
|
17
|
-
analyzer.analyze(&block)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
6
|
def initialize(description: "Block")
|
22
7
|
@description = description
|
8
|
+
|
23
9
|
@benchmark_profiler = Profiler::Benchmark.new
|
24
10
|
@memory_profiler = Profiler::Memory.new
|
25
11
|
@memory_usage = Data::MemoryUsage.new
|
@@ -29,6 +15,8 @@ module DevSuite
|
|
29
15
|
# @param block [Proc] The block to be analyzed
|
30
16
|
# @raise [ArgumentError] If no block is given
|
31
17
|
def analyze(&block)
|
18
|
+
raise ArgumentError, "No block given" unless block_given?
|
19
|
+
|
32
20
|
memory_before = @memory_usage.current
|
33
21
|
benchmark_result = profile_benchmark(&block)
|
34
22
|
memory_after = @memory_usage.current
|
@@ -53,12 +41,18 @@ module DevSuite
|
|
53
41
|
# @param benchmark_result [Benchmark::Tms] The benchmark result
|
54
42
|
# @param memory_stats [Hash] The memory statistics
|
55
43
|
def generate_report(benchmark_result, memory_stats)
|
56
|
-
reportor
|
57
|
-
@description,
|
58
|
-
benchmark_result,
|
59
|
-
memory_stats,
|
44
|
+
Config.configuration.reportor.generate(
|
45
|
+
description: @description,
|
46
|
+
benchmark_result: benchmark_result,
|
47
|
+
memory_stats: memory_stats,
|
60
48
|
)
|
61
|
-
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
class << self
|
53
|
+
def analyze(description: "Block", &block)
|
54
|
+
analyzer = Analyzer.new(description: description)
|
55
|
+
analyzer.analyze(&block)
|
62
56
|
end
|
63
57
|
end
|
64
58
|
end
|
@@ -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
|
@@ -1,22 +1,20 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative "base"
|
4
|
-
|
5
3
|
module DevSuite
|
6
4
|
module Performance
|
7
5
|
module Reportor
|
8
6
|
class Simple < Base
|
9
|
-
|
10
|
-
super()
|
11
|
-
@description = description
|
12
|
-
@benchmark_result = benchmark_result
|
13
|
-
@memory_stats = memory_stats
|
14
|
-
end
|
15
|
-
|
7
|
+
#
|
16
8
|
# Generates the performance report
|
17
|
-
|
9
|
+
#
|
10
|
+
def generate(description:, benchmark_result:, memory_stats:)
|
18
11
|
table = create_table
|
19
|
-
populate_table(
|
12
|
+
populate_table(
|
13
|
+
table,
|
14
|
+
description: description,
|
15
|
+
benchmark_result: benchmark_result,
|
16
|
+
memory_stats: memory_stats,
|
17
|
+
)
|
20
18
|
render_table(table)
|
21
19
|
end
|
22
20
|
|
@@ -26,36 +24,61 @@ module DevSuite
|
|
26
24
|
# Creates a new table with the specified configuration
|
27
25
|
#
|
28
26
|
def create_table
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
27
|
+
table = Utils::Table::Table.new
|
28
|
+
table.tap do |t|
|
29
|
+
t.title = "Performance Analysis"
|
30
|
+
t.add_columns("Metric", "Value")
|
33
31
|
end
|
34
32
|
end
|
35
33
|
|
36
34
|
#
|
37
35
|
# Populates the table with benchmark and memory statistics
|
38
36
|
#
|
39
|
-
def populate_table(table)
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
table.add_row(["
|
44
|
-
table.add_row(["
|
45
|
-
table.add_row(["
|
46
|
-
table.add_row(["
|
47
|
-
table.add_row(["
|
48
|
-
table.add_row(["
|
49
|
-
table.add_row(["
|
50
|
-
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])])
|
51
52
|
end
|
52
53
|
|
53
54
|
#
|
54
55
|
# Renders the table using the specified renderer
|
55
56
|
#
|
56
57
|
def render_table(table)
|
57
|
-
renderer = Utils::Table::
|
58
|
-
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
|
59
82
|
end
|
60
83
|
end
|
61
84
|
end
|
@@ -2,8 +2,20 @@
|
|
2
2
|
|
3
3
|
module DevSuite
|
4
4
|
module Performance
|
5
|
-
module
|
5
|
+
module Reportor
|
6
|
+
require_relative "reportor/base"
|
6
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
|
7
19
|
end
|
8
20
|
end
|
9
21
|
end
|
@@ -2,6 +2,13 @@
|
|
2
2
|
|
3
3
|
module DevSuite
|
4
4
|
module Performance
|
5
|
+
require "benchmark"
|
6
|
+
require "get_process_mem"
|
7
|
+
|
8
|
+
require_relative "performance/data"
|
9
|
+
require_relative "performance/profiler"
|
10
|
+
require_relative "performance/reportor"
|
5
11
|
require_relative "performance/analyzer"
|
12
|
+
require_relative "performance/config"
|
6
13
|
end
|
7
14
|
end
|
@@ -3,21 +3,18 @@
|
|
3
3
|
module DevSuite
|
4
4
|
module Utils
|
5
5
|
module Color
|
6
|
-
class
|
6
|
+
class Colorizer
|
7
7
|
def colorize(text, **kargs)
|
8
|
-
|
8
|
+
puts Config.configuration.strategy.colorize(text, **kargs)
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
12
|
-
class
|
13
|
-
attr_reader :config
|
14
|
-
|
15
|
-
def initialize(config = Config.configuration)
|
16
|
-
@config = config
|
17
|
-
end
|
18
|
-
|
12
|
+
class << self
|
19
13
|
def colorize(text, **kargs)
|
20
|
-
|
14
|
+
raise ArgumentError, "Text to colorize must be a string" unless text.is_a?(String)
|
15
|
+
|
16
|
+
colorizer = Colorizer.new
|
17
|
+
colorizer.colorize(text, **kargs)
|
21
18
|
end
|
22
19
|
end
|
23
20
|
end
|
@@ -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.1
|
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,9 @@ 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
|
67
|
+
- lib/dev_suite/directory_tree/config.rb
|
65
68
|
- lib/dev_suite/directory_tree/node.rb
|
66
69
|
- lib/dev_suite/directory_tree/node/base.rb
|
67
70
|
- lib/dev_suite/directory_tree/node/directory.rb
|
@@ -70,9 +73,11 @@ files:
|
|
70
73
|
- lib/dev_suite/directory_tree/renderer.rb
|
71
74
|
- lib/dev_suite/directory_tree/renderer/base.rb
|
72
75
|
- lib/dev_suite/directory_tree/renderer/simple.rb
|
76
|
+
- lib/dev_suite/directory_tree/settings.rb
|
73
77
|
- lib/dev_suite/directory_tree/visualizer.rb
|
74
78
|
- lib/dev_suite/performance.rb
|
75
79
|
- lib/dev_suite/performance/analyzer.rb
|
80
|
+
- lib/dev_suite/performance/config.rb
|
76
81
|
- lib/dev_suite/performance/data.rb
|
77
82
|
- lib/dev_suite/performance/data/memory_usage.rb
|
78
83
|
- lib/dev_suite/performance/profiler.rb
|
@@ -94,6 +99,9 @@ files:
|
|
94
99
|
- lib/dev_suite/utils/color/strategy/basic.rb
|
95
100
|
- lib/dev_suite/utils/color/strategy/rgb.rb
|
96
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
|
97
105
|
- lib/dev_suite/utils/table.rb
|
98
106
|
- lib/dev_suite/utils/table/column.rb
|
99
107
|
- lib/dev_suite/utils/table/config.rb
|
@@ -104,6 +112,7 @@ files:
|
|
104
112
|
- lib/dev_suite/utils/table/renderer/base.rb
|
105
113
|
- lib/dev_suite/utils/table/renderer/simple.rb
|
106
114
|
- lib/dev_suite/utils/table/row.rb
|
115
|
+
- lib/dev_suite/utils/table/settings.rb
|
107
116
|
- lib/dev_suite/utils/table/table.rb
|
108
117
|
- lib/dev_suite/version.rb
|
109
118
|
homepage: https://patrick204nqh.github.io
|