ectoplasm 1.1.0 → 1.2.0
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/README.md +21 -1
- data/lib/ectoplasm.rb +174 -149
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 69c7041d0fc4715ade4a7e713b8ecf038d22a2bda97c2880832e419f36330ac9
|
4
|
+
data.tar.gz: 26a379a4c5853649520349128a3e92686bb2debdb07c94b57f146e57e49aec93
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 69fce6d5ba25a8d5d4768a47f0e640761d0aef69c0c8d7f653a053ef6360556f3cd38758af6bd1b58384206137340fb597dfe7579e82b4640cf9c3da31869a0f
|
7
|
+
data.tar.gz: 279baa2b4db4360b9f4cb0a29b40a77e891157c221189067f81f9cf9c1e1b3c56b41d4479c22a7139ed8e2ab48ed6af19fe69793b2a41538b739d8f727ae3e68
|
data/README.md
CHANGED
@@ -1,3 +1,23 @@
|
|
1
1
|
# Ectoplasm
|
2
2
|
|
3
|
-
A helper library for console output
|
3
|
+
A helper library for prettier console output
|
4
|
+
|
5
|
+
## Added Methods
|
6
|
+
|
7
|
+
| Type | Method | Arguments | Description |
|
8
|
+
| ---- | ------ | --------- | ----------- |
|
9
|
+
| `String` | `colored!` | _none_ | Enables colored string output |
|
10
|
+
| `string` | `white` | _none_ | Prints the text in white |
|
11
|
+
| `string` | `red` | _none_ | Prints the text in red. Alias: `error` |
|
12
|
+
| `string` | `green` | _none_ | Prints the text in green. Alias: `ok` |
|
13
|
+
| `string` | `yellow` | _none_ | Prints the text in yellow. Alias: `warn` |
|
14
|
+
| `string` | `blue` | _none_ | Prints the text in blue. Alias: `info` |
|
15
|
+
| `string` | `magenta` | _none_ | Prints the text in magenta |
|
16
|
+
| `string` | `cyan` | _none_ | Prints the text in cyan |
|
17
|
+
| `string` | `grey` | _none_ | Prints the text in grey. Alias: `dim` |
|
18
|
+
| `string` | `indent` | `amount, char: ' '` | Indents all lines of the string by the given amount with the provided character |
|
19
|
+
| `string` | `frmt` | `prefix_suffix=['<', '>']` | Named string substitution |
|
20
|
+
| `Hash` | `pretty` | `width: 25` | Outputs a `Hash` in a pretty structure |
|
21
|
+
| `Hash` | `obfuscate` | `secure_keys=['password', 'secret', 'token', 'secure']` | Obfuscates the values of a `Hash`, when the key is like the given ones |
|
22
|
+
| `Float` | `duration` | _none_ | Formats the `Float` as a duration string e.g. `1h 42m 2s` |
|
23
|
+
|
data/lib/ectoplasm.rb
CHANGED
@@ -1,219 +1,244 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
|
1
3
|
module Ectoplasm
|
2
4
|
module Version
|
3
5
|
MAJOR = 1
|
4
|
-
MINOR =
|
6
|
+
MINOR = 2
|
5
7
|
TINY = 0
|
6
8
|
end
|
7
9
|
|
8
10
|
VERSION = [Version::MAJOR, Version::MINOR, Version::TINY].compact * '.'
|
9
|
-
end
|
10
11
|
|
11
|
-
|
12
|
-
@@colored = false
|
12
|
+
DEFUALT_SECURE_KEYS = ['password', 'secret', 'token', 'secure']
|
13
13
|
|
14
|
-
|
15
|
-
@@colored =
|
16
|
-
end
|
14
|
+
class ::String
|
15
|
+
@@colored = false
|
17
16
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
def yellow; colored '33'; end
|
22
|
-
def blue; colored '34'; end
|
23
|
-
def magenta; colored '35'; end
|
24
|
-
def cyan; colored '36'; end
|
25
|
-
def grey; colored '90'; end
|
26
|
-
|
27
|
-
alias ok green
|
28
|
-
alias error red
|
29
|
-
alias warn yellow
|
30
|
-
alias info blue
|
31
|
-
alias dim grey
|
32
|
-
|
33
|
-
def indent amount, char: ' '
|
34
|
-
self.lines.map { |line| char * amount + line }.join "\n"
|
35
|
-
end
|
17
|
+
def self.colored!
|
18
|
+
@@colored = true
|
19
|
+
end
|
36
20
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
21
|
+
def white; self; end
|
22
|
+
def red; colored '31'; end
|
23
|
+
def green; colored '32'; end
|
24
|
+
def yellow; colored '33'; end
|
25
|
+
def blue; colored '34'; end
|
26
|
+
def magenta; colored '35'; end
|
27
|
+
def cyan; colored '36'; end
|
28
|
+
def grey; colored '90'; end
|
29
|
+
|
30
|
+
alias ok green
|
31
|
+
alias error red
|
32
|
+
alias warn yellow
|
33
|
+
alias info blue
|
34
|
+
alias dim grey
|
35
|
+
|
36
|
+
def indent amount, char: ' '
|
37
|
+
self.split("\n").map { |line| char * amount + line }.join "\n"
|
38
|
+
end
|
42
39
|
|
43
|
-
|
44
|
-
|
45
|
-
|
40
|
+
def length
|
41
|
+
m = /\e\[\d{2}m(.*)\e\[0m/.match self
|
42
|
+
return self.chars.count - 9 if m
|
43
|
+
self.chars.count
|
44
|
+
end
|
45
|
+
|
46
|
+
def frmt props, prefix_suffix=['<', '>']
|
47
|
+
str = self
|
46
48
|
|
47
|
-
|
48
|
-
|
49
|
+
props.keys.each do |key|
|
50
|
+
placeholder = prefix_suffix[0] + key.to_s + prefix_suffix[1]
|
51
|
+
str = str.gsub(placeholder, props[key])
|
52
|
+
end
|
49
53
|
|
50
|
-
|
51
|
-
placeholder = prefix_suffix[0] + key.to_s + prefix_suffix[1]
|
52
|
-
str = str.gsub(placeholder, props[key])
|
54
|
+
str
|
53
55
|
end
|
54
56
|
|
55
|
-
|
57
|
+
private
|
58
|
+
|
59
|
+
def colored ansi_color
|
60
|
+
return self if !@@colored
|
61
|
+
"\e[#{ansi_color}m#{self}\e[0m"
|
62
|
+
end
|
56
63
|
end
|
57
64
|
|
58
|
-
private
|
59
65
|
|
60
|
-
|
61
|
-
|
62
|
-
|
66
|
+
class ::Object
|
67
|
+
def pretty width: nil
|
68
|
+
self.to_s
|
69
|
+
end
|
70
|
+
|
71
|
+
def obfuscate! secure_keys
|
72
|
+
self
|
73
|
+
end
|
63
74
|
end
|
64
|
-
end
|
65
75
|
|
66
76
|
|
67
|
-
class
|
68
|
-
|
69
|
-
|
77
|
+
class ::TrueClass
|
78
|
+
def pretty width: nil
|
79
|
+
'yes'.green
|
80
|
+
end
|
70
81
|
end
|
71
|
-
end
|
72
82
|
|
73
83
|
|
74
|
-
class
|
75
|
-
|
76
|
-
|
84
|
+
class ::FalseClass
|
85
|
+
def pretty width: nil
|
86
|
+
'no'.yellow
|
87
|
+
end
|
77
88
|
end
|
78
|
-
end
|
79
89
|
|
80
90
|
|
81
|
-
class
|
82
|
-
|
83
|
-
|
91
|
+
class ::NilClass
|
92
|
+
def pretty width: nil
|
93
|
+
'n/a'.grey
|
94
|
+
end
|
84
95
|
end
|
85
|
-
end
|
86
96
|
|
87
97
|
|
88
|
-
class
|
89
|
-
|
90
|
-
|
91
|
-
end
|
92
|
-
end
|
98
|
+
class ::Array
|
99
|
+
def pretty width: 25
|
100
|
+
return 'empty'.grey if self.length == 0
|
93
101
|
|
102
|
+
list_length = self.map { |x| x.to_s.length }.reduce(:+)
|
103
|
+
return self.join ', ' if list_length && list_length < 30
|
94
104
|
|
95
|
-
|
96
|
-
|
97
|
-
|
105
|
+
self
|
106
|
+
.select { |x| x != nil && x != '' }
|
107
|
+
.map do |x|
|
108
|
+
' - ' + x.pretty(width: width-3).strip.gsub(/\n/, "\n ")
|
109
|
+
end
|
110
|
+
.join "\n"
|
111
|
+
end
|
98
112
|
|
99
|
-
|
100
|
-
|
113
|
+
def table header: nil, mappings: {}, with_index: false, limit: 50
|
114
|
+
header = self[0].keys if header == nil
|
115
|
+
heading = header.is_a?(Array) ? header : self[0].keys
|
101
116
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
117
|
+
table_data = self.slice(0, limit).map do |row|
|
118
|
+
heading.map do |key|
|
119
|
+
mappings.has_key?(key) ? mappings[key][row, row[key]] : row[key]
|
120
|
+
end
|
106
121
|
end
|
107
|
-
.join "\n"
|
108
|
-
end
|
109
122
|
|
110
|
-
|
111
|
-
header = self[0].keys if header == nil
|
112
|
-
heading = header.is_a?(Array) ? header : self[0].keys
|
123
|
+
table_data.insert(0, heading) if header != false
|
113
124
|
|
114
|
-
|
115
|
-
|
116
|
-
mappings.has_key?(key) ? mappings[key][row, row[key]] : row[key]
|
125
|
+
data_sizes = table_data.map do |row|
|
126
|
+
row.map { |data| data.to_s.length }
|
117
127
|
end
|
118
|
-
end
|
119
|
-
|
120
|
-
table_data.insert(0, heading) if header != false
|
121
128
|
|
122
|
-
|
123
|
-
|
124
|
-
|
129
|
+
column_sizes = data_sizes[0]
|
130
|
+
.zip(*data_sizes[1..-1])
|
131
|
+
.map { |row| row.max }
|
125
132
|
|
126
|
-
|
127
|
-
.zip(*data_sizes[1..-1])
|
128
|
-
.map { |row| row.max }
|
133
|
+
table = table_data.map { |row| column_sizes.zip row }
|
129
134
|
|
130
|
-
|
135
|
+
table_str = ''
|
136
|
+
table.each_with_index do |row, index|
|
137
|
+
if with_index
|
138
|
+
if index == 0
|
139
|
+
table_str += ' '
|
140
|
+
else
|
141
|
+
table_str += "[#{index}] "
|
142
|
+
end
|
143
|
+
end
|
131
144
|
|
132
|
-
|
133
|
-
|
134
|
-
if with_index
|
135
|
-
if index == 0
|
136
|
-
table_str += ' '
|
137
|
-
else
|
138
|
-
table_str += "[#{index}] "
|
145
|
+
row.each do |col_size, data|
|
146
|
+
table_str += (data.to_s + ' ' * (col_size - data.to_s.length)) + ' '
|
139
147
|
end
|
140
|
-
end
|
141
148
|
|
142
|
-
|
143
|
-
table_str += (data.to_s + ' ' * (col_size - data.to_s.length)) + ' '
|
149
|
+
table_str += "\n"
|
144
150
|
end
|
151
|
+
table_str += '[...]' if self.count > limit
|
152
|
+
print table_str
|
153
|
+
end
|
145
154
|
|
146
|
-
|
155
|
+
def obfuscate! secure_keys = DEFAULT_SECURE_KEYS
|
156
|
+
self.map { |x| x.obfuscate!(secure_keys) }
|
147
157
|
end
|
148
|
-
table_str += '[...]' if self.count > limit
|
149
|
-
print table_str
|
150
158
|
end
|
151
|
-
end
|
152
159
|
|
153
160
|
|
154
|
-
class Hash
|
155
|
-
|
156
|
-
|
161
|
+
class ::Hash
|
162
|
+
def pretty indent: 0, width: 25
|
163
|
+
s = ''
|
157
164
|
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
165
|
+
self
|
166
|
+
.select { |key, value| value != nil || value != '' }
|
167
|
+
.map do |key, value|
|
168
|
+
value = true if value == 'true'
|
169
|
+
value = false if value == 'false'
|
170
|
+
value = '********' if /password|pwd|pass|passwd|secret/ =~ key.to_s
|
164
171
|
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
172
|
+
if value.is_a? Hash
|
173
|
+
s += key.to_s.cyan.indent(indent) + "\n"
|
174
|
+
s += value.pretty(width: width-indent-2).indent(indent+2)
|
175
|
+
s += "\n"
|
176
|
+
next
|
177
|
+
end
|
171
178
|
|
172
|
-
|
179
|
+
s += ' ' * indent
|
173
180
|
|
174
|
-
|
175
|
-
|
181
|
+
if value.is_a? Array
|
182
|
+
list = value.pretty(width: width)
|
176
183
|
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
184
|
+
if list.split("\n").count > 1
|
185
|
+
s += key.to_s.cyan + "\n"
|
186
|
+
s += value.pretty(width: width).indent(indent)
|
187
|
+
s += "\n"
|
188
|
+
next
|
189
|
+
end
|
190
|
+
|
191
|
+
value = list
|
182
192
|
end
|
183
193
|
|
184
|
-
|
194
|
+
s += key.to_s.cyan
|
195
|
+
s += ' ' + '.' * (width-key.to_s.length-indent) if width-key.to_s.length > indent
|
196
|
+
s += ': '
|
197
|
+
s += value.pretty + "\n"
|
185
198
|
end
|
186
199
|
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
200
|
+
s
|
201
|
+
end
|
202
|
+
|
203
|
+
def obfuscate! secure_keys = DEFAULT_SECURE_KEYS
|
204
|
+
self.each do |k, v|
|
205
|
+
if v.is_a? Hash
|
206
|
+
v.obfuscate!(secure_keys)
|
207
|
+
elsif secure_keys.any? { |x| k.to_s.downcase.include? x.downcase }
|
208
|
+
self[k] = '*****'
|
209
|
+
end
|
191
210
|
end
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
192
214
|
|
193
|
-
|
215
|
+
class ::OpenStruct
|
216
|
+
def obfuscate! secure_keys = ['password', 'secret', 'token', 'secure']
|
217
|
+
OpenStruct.new(self.to_h.obfuscate! secure_keys)
|
218
|
+
end
|
194
219
|
end
|
195
|
-
end
|
196
220
|
|
197
221
|
|
198
|
-
class Float
|
199
|
-
|
200
|
-
|
222
|
+
class ::Float
|
223
|
+
def duration
|
224
|
+
seconds = self
|
201
225
|
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
226
|
+
if seconds > 60
|
227
|
+
seconds = seconds.to_i
|
228
|
+
minutes = seconds / 60
|
229
|
+
seconds = seconds % 60
|
230
|
+
end
|
207
231
|
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
232
|
+
if minutes && minutes > 60
|
233
|
+
hours = minutes / 60
|
234
|
+
minutes = minutes % 60
|
235
|
+
end
|
212
236
|
|
213
|
-
|
214
|
-
|
215
|
-
|
237
|
+
duration_str = "#{seconds}s"
|
238
|
+
duration_str = "#{minutes}m #{duration_str}" if minutes
|
239
|
+
duration_str = "#{hours}h #{duration_str}" if hours
|
216
240
|
|
217
|
-
|
241
|
+
duration_str
|
242
|
+
end
|
218
243
|
end
|
219
|
-
end
|
244
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ectoplasm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Christian Neubauer
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-06-10 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Adds some extension methods to build in types to add prettier console
|
14
14
|
output
|
@@ -34,7 +34,7 @@ metadata:
|
|
34
34
|
homepage_uri: https://bitbucket.org/cneubaur/ectoplasm-ruby
|
35
35
|
source_code_uri: https://bitbucket.org/cneubaur/ectoplasm-ruby
|
36
36
|
changelog_uri: https://bitbucket.org/cneubaur/ectoplasm-ruby/src/master/CHANGELOG.md
|
37
|
-
post_install_message:
|
37
|
+
post_install_message:
|
38
38
|
rdoc_options: []
|
39
39
|
require_paths:
|
40
40
|
- lib
|
@@ -49,8 +49,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
49
49
|
- !ruby/object:Gem::Version
|
50
50
|
version: '0'
|
51
51
|
requirements: []
|
52
|
-
rubygems_version: 3.
|
53
|
-
signing_key:
|
52
|
+
rubygems_version: 3.2.3
|
53
|
+
signing_key:
|
54
54
|
specification_version: 4
|
55
55
|
summary: A helper library for console output
|
56
56
|
test_files: []
|