foobara-util 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -0
  3. data/lib/foobara/util/tree.rb +144 -0
  4. metadata +3 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 85a512d24b80d3764d64162a9a0307980b4c5b4208fd446ca5eb61e45c12e9d7
4
- data.tar.gz: 1830f90dc6c33596d1a66c4971f148ebbb16846e2d1bb07340598ecc2ff38908
3
+ metadata.gz: f28088a767f0c73ceb7c9bdbe17633935233872900c51bc17a6815e3b2b6e802
4
+ data.tar.gz: a477c70c401057348f9c3539ffb26e5927ab3b128b51d2c1bba65c64d1fa7432
5
5
  SHA512:
6
- metadata.gz: aa086713f6a0d871cd43d1884d66b1c009073853cdcaabbbee1b6b2c5099b08c34652dde426030d868267307313df912b549965d40a1d3d07c1724534e716304
7
- data.tar.gz: 8a1e198c1b944adc46a54d67981bd724b19e206fec5395eca350a0dffa4a6ab996eb2ad339cb379ec76848d00d41f36c148fcefe6b7ae3ecfe48a5dc53e2365a
6
+ metadata.gz: b914e2155dcd1b0b4b7dff98555f68cd63b185e6d687b9f6402006b94ab56f572a3322e770f92f163f8ff4dd34e591e0e5e9bb4ec9a75ef7261153f76e7b478d
7
+ data.tar.gz: 194304d9e788206cb754450244a9b9de6fdec23bbe49ae5534f12f9718669c02027d9cc0c5bbd42208ab7317e7edc5d01a9929e7a2f8db30d77dd57787737ae3
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## [0.0.8] - 2024-12-05
2
+
3
+ * Add .print_tree for displaying dependencies/graphs via ASCII art
4
+
1
5
  ## [0.0.7] - 2024-11-30
2
6
 
3
7
  * Handle kebab-cased strings as expected in .classify
@@ -0,0 +1,144 @@
1
+ module Foobara
2
+ module Util
3
+ class SubTree
4
+ attr_accessor :value, :parent_tree, :to_parent
5
+
6
+ def initialize(value, to_parent = nil, &block)
7
+ self.value = value
8
+ self.to_parent = to_parent.nil? ? block : to_parent.to_proc
9
+ end
10
+
11
+ def root?
12
+ parent_tree.is_a?(Tree)
13
+ end
14
+
15
+ def children_trees
16
+ @children_trees ||= []
17
+ end
18
+
19
+ def add(object)
20
+ return if include?(object)
21
+
22
+ parent = to_parent.call(object)
23
+
24
+ parent_node = if parent
25
+ node_for(parent) || add(parent)
26
+ else
27
+ self
28
+ end
29
+
30
+ child_tree = SubTree.new(object, to_parent)
31
+ child_tree.parent_tree = parent_node
32
+ parent_node.children_trees << child_tree
33
+
34
+ child_tree
35
+ end
36
+
37
+ def node_for(value)
38
+ return self if value == self.value
39
+
40
+ children_trees.each do |child|
41
+ node = child.node_for(value)
42
+ return node if node
43
+ end
44
+
45
+ nil
46
+ end
47
+
48
+ def include?(value)
49
+ !!node_for(value)
50
+ end
51
+
52
+ # TODO: try to break this up a bit
53
+ def to_s(to_name, padding: "", last_child: true)
54
+ output = StringIO.new
55
+ name = to_name.call(value)
56
+
57
+ padding = puts_box(output, name, padding, last_child)
58
+
59
+ children = children_trees.sort_by { |child_tree| to_name.call(child_tree.value) }
60
+ last = children.last
61
+
62
+ children.each do |child_tree|
63
+ output.puts child_tree.to_s(to_name, padding:, last_child: child_tree == last)
64
+ end
65
+
66
+ output.string
67
+ end
68
+
69
+ private
70
+
71
+ def puts_box(output, name, padding, last_child)
72
+ name_size = name.size + 1
73
+ name_size_left = name_size / 2
74
+ name_size_right = name_size - name_size_left
75
+
76
+ bottom_connector = children_trees.any? ? "┬" : "─"
77
+
78
+ if root?
79
+ output.puts "╭#{"─" * (name.size + 2)}╮"
80
+ output.puts "│ #{name} │"
81
+ output.puts "╰#{"─" * name_size_left}#{bottom_connector}#{"─" * name_size_right}╯"
82
+ else
83
+ padding += " "
84
+
85
+ connector = last_child ? "└" : "├"
86
+ padding_end = last_child ? " " : "│ "
87
+
88
+ output.print padding
89
+ output.print "│ "
90
+
91
+ output.puts "╭#{"─" * (name.size + 2)}╮"
92
+ output.print "#{padding}#{connector}"
93
+ output.puts "─┤ #{name} │"
94
+
95
+ padding += padding_end
96
+
97
+ output.puts "#{padding}╰#{"─" * name_size_left}#{bottom_connector}#{"─" * name_size_right}╯"
98
+ end
99
+
100
+ padding + (" " * (name_size / 2))
101
+ end
102
+ end
103
+
104
+ class Tree < SubTree
105
+ def initialize(data, to_parent = nil, &)
106
+ super(nil, to_parent, &)
107
+
108
+ data.each do |object|
109
+ add(object)
110
+ end
111
+ end
112
+
113
+ def to_s(to_name = nil, &block)
114
+ to_name = if to_name
115
+ to_name.to_proc
116
+ elsif block_given?
117
+ block
118
+ else
119
+ :to_s.to_proc
120
+ end
121
+
122
+ children_trees.map { |child| child.to_s(to_name) }.join("\n")
123
+ end
124
+ end
125
+
126
+ module_function
127
+
128
+ def print_tree(data, io: $stdout, to_name: nil, to_parent: nil)
129
+ data = data.to_a if data.is_a?(::Hash)
130
+
131
+ if to_name.nil? && to_parent.nil?
132
+ to_name = :first.to_proc
133
+ to_parent = proc do |object|
134
+ parent_name = object.last
135
+ data.find { |pair| pair.first == parent_name }
136
+ end
137
+ end
138
+
139
+ tree = Util::Tree.new(data, to_parent)
140
+
141
+ io.puts tree.to_s(to_name)
142
+ end
143
+ end
144
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foobara-util
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Miles Georgi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-12-01 00:00:00.000000000 Z
11
+ date: 2024-12-05 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email:
@@ -33,6 +33,7 @@ files:
33
33
  - lib/foobara/util/require.rb
34
34
  - lib/foobara/util/string.rb
35
35
  - lib/foobara/util/structured.rb
36
+ - lib/foobara/util/tree.rb
36
37
  homepage: https://github.com/foobara/util
37
38
  licenses:
38
39
  - Apache-2.0