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.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +1 -1
  3. data/lib/dev_suite/directory_tree/builder/base.rb +38 -0
  4. data/lib/dev_suite/directory_tree/builder.rb +20 -0
  5. data/lib/dev_suite/directory_tree/config.rb +6 -27
  6. data/lib/dev_suite/directory_tree/node/base.rb +13 -1
  7. data/lib/dev_suite/directory_tree/node/directory.rb +14 -2
  8. data/lib/dev_suite/directory_tree/node/file.rb +2 -2
  9. data/lib/dev_suite/directory_tree/renderer/base.rb +5 -31
  10. data/lib/dev_suite/directory_tree/renderer/simple.rb +57 -42
  11. data/lib/dev_suite/directory_tree/settings.rb +29 -0
  12. data/lib/dev_suite/directory_tree/visualizer.rb +3 -9
  13. data/lib/dev_suite/directory_tree.rb +5 -1
  14. data/lib/dev_suite/performance/analyzer.rb +5 -5
  15. data/lib/dev_suite/performance/config.rb +16 -0
  16. data/lib/dev_suite/performance/profiler/benchmark.rb +0 -2
  17. data/lib/dev_suite/performance/reportor/simple.rb +52 -27
  18. data/lib/dev_suite/performance/reportor.rb +12 -1
  19. data/lib/dev_suite/performance.rb +4 -0
  20. data/lib/dev_suite/utils/color/colorizer.rb +1 -7
  21. data/lib/dev_suite/utils/config_tools/configuration.rb +41 -0
  22. data/lib/dev_suite/utils/config_tools/settings.rb +75 -0
  23. data/lib/dev_suite/utils/config_tools.rb +10 -0
  24. data/lib/dev_suite/utils/table/config.rb +8 -42
  25. data/lib/dev_suite/utils/table/renderer/base.rb +4 -2
  26. data/lib/dev_suite/utils/table/renderer/simple.rb +5 -5
  27. data/lib/dev_suite/utils/table/renderer.rb +11 -0
  28. data/lib/dev_suite/utils/table/settings.rb +34 -0
  29. data/lib/dev_suite/utils/table/table.rb +2 -8
  30. data/lib/dev_suite/utils/table.rb +1 -0
  31. data/lib/dev_suite/utils.rb +1 -0
  32. data/lib/dev_suite/version.rb +1 -1
  33. metadata +10 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 76f0e8870b8fe2bb1c8af41e541bd09f792662f49c1a869d5ddcf5fd4ae94584
4
- data.tar.gz: 17a921feedc29e07133ce357fbb3b37ecd15800cd30f4fd3087d62f4a810970d
3
+ metadata.gz: 61551856599e246df8b5d7e66bf7ada17cf7ed03147c9c846fcd1f4ed2fcaf5d
4
+ data.tar.gz: f36513a7e8afa78bd04c9a9d9cd893e9a75b79006ff2ba41f8aa0245f06cc0fa
5
5
  SHA512:
6
- metadata.gz: a32bb7865ee17f49b639d687950cfafeecc51df0dc9e2e7a7ef62018ea185fd522081f8c7b70c0346d0b77ec4d119030c7e9464cf38f4928dad11ee756baa01a
7
- data.tar.gz: 668586bdbd2339888ef486a5e2fb424aa0f3532d8fa80e27f92f569e59506b2237852683725560e55109eb93c5af63d51e6333aceea5dcb018604574733be5ef
6
+ metadata.gz: 533af36d8beb9efbe20c5f8135d6c7255265c6e8ff7b0b2fc35f57da5572803cead32a69bcda9e672f4de5373b0a6f41e678241042c0ce16c0a06cbe681ead4d
7
+ data.tar.gz: 66729b4045f43b20029c6ad81365e51505489c3a6f99f241cfbb7acd9e31bd5951004e3faf2f0715878ac386a2c1d8108701142fdb87ebed72b63b1d7263b423
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- dev_suite (0.2.0)
4
+ dev_suite (0.2.1)
5
5
  benchmark (~> 0.1)
6
6
  get_process_mem (~> 0.2)
7
7
 
@@ -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
- attr_reader :renderer
6
+ include Utils::ConfigTools::Configuration
7
7
 
8
- def initialize(renderer: :simple)
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
- raise NotImplementedError, "Must implement in subclass"
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(child)
19
- @children << child
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
@@ -4,8 +4,8 @@ module DevSuite
4
4
  module DirectoryTree
5
5
  module Node
6
6
  class File < Base
7
- def directory?
8
- false
7
+ def file?
8
+ true
9
9
  end
10
10
  end
11
11
  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
- def render(path)
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
- # Builds the tree structure
28
- # @param path [Pathname] The path to build the tree from
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
- # Renders a node in the tree
35
- # @param node [Node::Base] The node to render
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
- private
8
-
9
- def build_tree(path)
10
- return permission_denied_node(path) unless path.readable?
11
-
12
- path.directory? ? directory_node(path) : file_node(path)
13
- rescue Errno::EACCES
14
- permission_denied_node(path)
15
- end
16
-
17
- def render_node(node, prefix = "", is_last = true)
18
- is_root = prefix.empty?
19
- connector = determine_connector(is_root, is_last)
20
- new_prefix = update_prefix(prefix, is_last)
21
-
22
- output = construct_output(node, prefix, connector)
23
- output += node_suffix(node)
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.children.each_with_index do |child, index|
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
- def determine_connector(is_root, is_last)
35
- return "" if is_root
32
+ private
36
33
 
37
- is_last ? "└── " : "├── "
34
+ def settings
35
+ Config.configuration.settings
38
36
  end
39
37
 
40
- def update_prefix(prefix, is_last)
41
- "#{prefix}#{is_last ? " " : "| "}"
38
+ def skip_node?(node)
39
+ hidden_file_skipped?(node) || filetype_skipped?(node)
42
40
  end
43
41
 
44
- def construct_output(node, prefix, connector)
45
- "#{prefix}#{connector}#{node.name}"
42
+ def hidden_file_skipped?(node)
43
+ settings.skip_hidden? && node.hidden?
46
44
  end
47
45
 
48
- def node_suffix(node)
49
- node.directory? ? "/\n" : "\n"
46
+ def filetype_skipped?(node)
47
+ node.file? && settings.skip_types.include?(::File.extname(node.name))
50
48
  end
51
49
 
52
- def directory_node(path)
53
- dir = Node::Directory.new(path.basename.to_s)
54
- sorted_children(path).each do |child|
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 file_node(path)
61
- Node::File.new(path.basename.to_s)
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 permission_denied_node(path)
65
- Node::PermissionDenied.new(path.basename.to_s, path.directory?)
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 sorted_children(path)
69
- path.children.sort_by { |child| child.basename.to_s.downcase }
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
- puts @config.renderer.render(path)
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 = Reportor::Simple.new(
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
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "benchmark"
4
-
5
3
  module DevSuite
6
4
  module Performance
7
5
  module Profiler
@@ -4,17 +4,17 @@ module DevSuite
4
4
  module Performance
5
5
  module Reportor
6
6
  class Simple < Base
7
- def initialize(description, benchmark_result, memory_stats)
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
- def generate
9
+ #
10
+ def generate(description:, benchmark_result:, memory_stats:)
16
11
  table = create_table
17
- populate_table(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
- config = Utils::Table::Config.new
28
- Utils::Table::Table.new(config).tap do |table|
29
- table.title = "Performance Analysis"
30
- table.add_columns("Metric", "Value")
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
- table.add_row(["Description", @description])
39
- table.add_row(["Total Time (s)", format("%.6f", @benchmark_result.real)])
40
- table.add_row(["User CPU Time (s)", format("%.6f", @benchmark_result.utime)])
41
- table.add_row(["System CPU Time (s)", format("%.6f", @benchmark_result.stime)])
42
- table.add_row(["User + System CPU Time (s)", format("%.6f", @benchmark_result.total)])
43
- table.add_row(["Memory Before (MB)", format("%.2f", @memory_stats[:before])])
44
- table.add_row(["Memory After (MB)", format("%.2f", @memory_stats[:after])])
45
- table.add_row(["Memory Used (MB)", format("%.2f", @memory_stats[:used])])
46
- table.add_row(["Max Memory Used (MB)", format("%.2f", @memory_stats[:max])])
47
- table.add_row(["Min Memory Used (MB)", format("%.2f", @memory_stats[:min])])
48
- table.add_row(["Avg Memory Used (MB)", format("%.2f", @memory_stats[:avg])])
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::Renderer::Simple.new
56
- puts table.render(renderer: renderer)
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 Reporting
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 @config.strategy.colorize(text, **kargs)
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
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DevSuite
4
+ module Utils
5
+ module ConfigTools
6
+ require_relative "config_tools/configuration"
7
+ require_relative "config_tools/settings"
8
+ end
9
+ end
10
+ end
@@ -4,7 +4,9 @@ module DevSuite
4
4
  module Utils
5
5
  module Table
6
6
  class Config
7
- DEFAULTS = {
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 deep_merge(original, override)
59
- original.merge(override) do |_key, oldval, newval|
60
- oldval.is_a?(Hash) ? deep_merge(oldval, newval) : newval
61
- end
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
@@ -5,8 +5,10 @@ module DevSuite
5
5
  module Table
6
6
  module Renderer
7
7
  class Base
8
- def initialize(config = Config.new)
9
- @config = config
8
+ attr_reader :settings
9
+
10
+ def initialize(settings: Settings.new)
11
+ @settings = settings
10
12
  end
11
13
 
12
14
  def render(table)
@@ -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, @config.color_for(:title))
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, @config.color_for(:column))
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, @config.color_for(:border))
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, @config.color_for(:row))
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, @config.color_for(:row))
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, :config
8
+ attr_reader :columns, :rows
9
9
 
10
- def initialize(config = Config.new)
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
@@ -7,6 +7,7 @@ module DevSuite
7
7
  require_relative "table/column"
8
8
  require_relative "table/row"
9
9
  require_relative "table/config"
10
+ require_relative "table/settings"
10
11
  require_relative "table/formatter"
11
12
  require_relative "table/renderer"
12
13
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  module DevSuite
4
4
  module Utils
5
+ require_relative "utils/config_tools"
5
6
  require_relative "utils/color"
6
7
  require_relative "utils/table"
7
8
  end
@@ -1,3 +1,3 @@
1
1
  module DevSuite
2
- VERSION = "0.2.0"
2
+ VERSION = "0.2.1"
3
3
  end
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.0
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-10 00:00:00.000000000 Z
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