ectoplasm 1.1.0 → 1.2.2

Sign up to get free protection for your applications and to get access to all the features.
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,246 @@
1
+ require 'ostruct'
2
+
1
3
  module Ectoplasm
2
4
  module Version
3
5
  MAJOR = 1
4
- MINOR = 1
5
- TINY = 0
6
+ MINOR = 2
7
+ TINY = 2
6
8
  end
7
9
 
8
10
  VERSION = [Version::MAJOR, Version::MINOR, Version::TINY].compact * '.'
9
- end
10
11
 
11
- class String
12
- @@colored = false
12
+ DEFAULT_SECURE_KEYS = ['password', 'secret', 'token', 'secure']
13
13
 
14
- def self.colored!
15
- @@colored = true
16
- end
14
+ class ::String
15
+ @@colored = false
17
16
 
18
- def white; self; end
19
- def red; colored '31'; end
20
- def green; colored '32'; end
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
- def length
38
- m = /\e\[\d{2}m(.*)\e\[0m/.match self
39
- return self.chars.count - 9 if m
40
- self.chars.count
41
- end
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
- def lines separator="\n"
44
- self.split separator
45
- end
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
- def frmt props, prefix_suffix=['<', '>']
48
- str = self
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
- props.keys.each do |key|
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
- str
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
- def colored ansi_color
61
- return self if !@@colored
62
- "\e[#{ansi_color}m#{self}\e[0m"
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 Object
68
- def pretty width: nil
69
- self.to_s
77
+ class ::TrueClass
78
+ def pretty width: nil
79
+ 'yes'.green
80
+ end
70
81
  end
71
- end
72
82
 
73
83
 
74
- class TrueClass
75
- def pretty width: nil
76
- 'yes'.green
84
+ class ::FalseClass
85
+ def pretty width: nil
86
+ 'no'.yellow
87
+ end
77
88
  end
78
- end
79
89
 
80
90
 
81
- class FalseClass
82
- def pretty width: nil
83
- 'no'.yellow
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 NilClass
89
- def pretty width: nil
90
- 'n/a'.grey
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
- class Array
96
- def pretty width: 25
97
- return 'empty'.grey if self.length == 0
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
- list_length = self.map { |x| x.to_s.length }.reduce(:+)
100
- return self.join ', ' if list_length && list_length < 30
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
- self
103
- .select { |x| x != nil && x != '' }
104
- .map do |x|
105
- ' - ' + x.pretty(width: width-3).strip.gsub(/\n/, "\n ")
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
- def table header: nil, mappings: {}, with_index: false, limit: 50
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
- table_data = self.slice(0, limit).map do |row|
115
- heading.map do |key|
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
- data_sizes = table_data.map do |row|
123
- row.map { |data| data.to_s.length }
124
- end
129
+ column_sizes = data_sizes[0]
130
+ .zip(*data_sizes[1..-1])
131
+ .map { |row| row.max }
125
132
 
126
- column_sizes = data_sizes[0]
127
- .zip(*data_sizes[1..-1])
128
- .map { |row| row.max }
133
+ table = table_data.map { |row| column_sizes.zip row }
129
134
 
130
- table = table_data.map { |row| column_sizes.zip row }
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
- table_str = ''
133
- table.each_with_index do |row, index|
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
- row.each do |col_size, data|
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
- table_str += "\n"
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
- def pretty indent: 0, width: 25
156
- s = ''
161
+ class ::Hash
162
+ def pretty indent: 0, width: 25
163
+ s = ''
157
164
 
158
- self
159
- .select { |key, value| value != nil || value != '' }
160
- .map do |key, value|
161
- value = true if value == 'true'
162
- value = false if value == 'false'
163
- value = '********' if /password|pwd|pass|passwd|secret/ =~ key.to_s
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
- if value.is_a? Hash
166
- s += key.to_s.cyan.indent(indent) + "\n"
167
- s += value.pretty(width: width-indent-2).indent(indent+2)
168
- s += "\n"
169
- next
170
- end
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
- s += ' ' * indent
179
+ s += ' ' * indent
173
180
 
174
- if value.is_a? Array
175
- list = value.pretty(width: width)
181
+ if value.is_a? Array
182
+ list = value.pretty(width: width)
176
183
 
177
- if list.lines.count > 1
178
- s += key.to_s.cyan + "\n"
179
- s += value.pretty(width: width).indent(indent)
180
- s += "\n"
181
- next
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
- value = list
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
- s += key.to_s.cyan
188
- s += ' ' + '.' * (width-key.to_s.length-indent) if width-key.to_s.length > indent
189
- s += ': '
190
- s += value.pretty + "\n"
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 v.is_a? Array
208
+ v.each { |x| v.obfuscate!(secure_keys) }
209
+ elsif secure_keys.any? { |x| k.to_s.downcase.include? x.downcase }
210
+ self[k] = '*****'
211
+ end
191
212
  end
213
+ end
214
+ end
215
+
192
216
 
193
- s
217
+ class ::OpenStruct
218
+ def obfuscate! secure_keys = ['password', 'secret', 'token', 'secure', 'pass', 'key', 'cert']
219
+ OpenStruct.new(self.to_h.obfuscate! secure_keys)
220
+ end
194
221
  end
195
- end
196
222
 
197
223
 
198
- class Float
199
- def duration
200
- seconds = self
224
+ class ::Float
225
+ def duration
226
+ seconds = self
201
227
 
202
- if seconds > 60
203
- seconds = seconds.to_i
204
- minutes = seconds / 60
205
- seconds = seconds % 60
206
- end
228
+ if seconds > 60
229
+ seconds = seconds.to_i
230
+ minutes = seconds / 60
231
+ seconds = seconds % 60
232
+ end
207
233
 
208
- if minutes && minutes > 60
209
- hours = minutes / 60
210
- minutes = minutes % 60
211
- end
234
+ if minutes && minutes > 60
235
+ hours = minutes / 60
236
+ minutes = minutes % 60
237
+ end
212
238
 
213
- duration_str = "#{seconds}s"
214
- duration_str = "#{minutes}m #{duration_str}" if minutes
215
- duration_str = "#{hours}h #{duration_str}" if hours
239
+ duration_str = "#{seconds}s"
240
+ duration_str = "#{minutes}m #{duration_str}" if minutes
241
+ duration_str = "#{hours}h #{duration_str}" if hours
216
242
 
217
- duration_str
243
+ duration_str
244
+ end
218
245
  end
219
- end
246
+ 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.1.0
4
+ version: 1.2.2
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: 2020-11-30 00:00:00.000000000 Z
11
+ date: 2022-08-01 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
@@ -18,7 +18,11 @@ executables: []
18
18
  extensions: []
19
19
  extra_rdoc_files: []
20
20
  files:
21
+ - ".github/workflows/build.yml"
22
+ - ".github/workflows/gem-push.yml"
21
23
  - ".gitignore"
24
+ - ".rubocop.yml"
25
+ - CHANGELOG.md
22
26
  - Gemfile
23
27
  - LICENSE.txt
24
28
  - README.md
@@ -34,7 +38,7 @@ metadata:
34
38
  homepage_uri: https://bitbucket.org/cneubaur/ectoplasm-ruby
35
39
  source_code_uri: https://bitbucket.org/cneubaur/ectoplasm-ruby
36
40
  changelog_uri: https://bitbucket.org/cneubaur/ectoplasm-ruby/src/master/CHANGELOG.md
37
- post_install_message:
41
+ post_install_message:
38
42
  rdoc_options: []
39
43
  require_paths:
40
44
  - lib
@@ -49,8 +53,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
49
53
  - !ruby/object:Gem::Version
50
54
  version: '0'
51
55
  requirements: []
52
- rubygems_version: 3.1.2
53
- signing_key:
56
+ rubygems_version: 3.3.7
57
+ signing_key:
54
58
  specification_version: 4
55
59
  summary: A helper library for console output
56
60
  test_files: []