greenhat 0.3.1 → 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/greenhat/cli.rb +20 -6
- data/lib/greenhat/shell/args.rb +2 -2
- data/lib/greenhat/shell/faststats.rb +27 -0
- data/lib/greenhat/shell/field_helper.rb +75 -0
- data/lib/greenhat/shell/filter_help.rb +21 -2
- data/lib/greenhat/shell/log.rb +41 -0
- data/lib/greenhat/shell/shell_helper.rb +66 -13
- data/lib/greenhat/thing/formatters/nginx.rb +2 -2
- data/lib/greenhat/thing.rb +22 -0
- data/lib/greenhat/version.rb +1 -1
- data/lib/greenhat.rb +1 -0
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: db336e98cd2a446c371d866d068eb9b485f9782b2ea7182f4b4da651011e2083
|
4
|
+
data.tar.gz: 90b1858171c14ebe93e3a0ff42dffe2965602835f8f2cc98178f6a81ec816352
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 94d78c52d3e4b800ac90798d8030dfa9962c7e7c628bd8b636f5471fcf2c35044aa044a91edbd412827db2daf36117ab47cfecc4c6a85e49875e3e6d7756e1d0
|
7
|
+
data.tar.gz: fad9f87be4735b5d028ccc7e251fce423de9cf0d440253b65dbaddbc36b268234ffedc7277f9207131692bcf8ea74cd9a4b70c433f55e158b6cd30aae73edf1d
|
data/lib/greenhat/cli.rb
CHANGED
@@ -65,7 +65,9 @@ module GreenHat
|
|
65
65
|
# Auto Complete
|
66
66
|
# =========================================================
|
67
67
|
def self.auto
|
68
|
-
word =
|
68
|
+
word = @list.last
|
69
|
+
# This is being weird with auto complete
|
70
|
+
# word = reader.line.word
|
69
71
|
|
70
72
|
if word.blank?
|
71
73
|
help
|
@@ -74,6 +76,10 @@ module GreenHat
|
|
74
76
|
end
|
75
77
|
end
|
76
78
|
|
79
|
+
def self.file_matches(word)
|
80
|
+
files.select { |x| x[/^#{Regexp.escape(word)}/] }
|
81
|
+
end
|
82
|
+
|
77
83
|
def self.auto_match(matches, word)
|
78
84
|
matches.select! { |x| x[/^#{Regexp.escape(word)}/] }
|
79
85
|
|
@@ -88,11 +94,14 @@ module GreenHat
|
|
88
94
|
elsif matches.count > 1
|
89
95
|
puts matches.join("\t").pastel(:bright_green)
|
90
96
|
|
91
|
-
#
|
92
|
-
|
93
|
-
file_matches
|
94
|
-
auto_files(file_matches, word) unless file_matches.empty?
|
97
|
+
# General Filename Matching
|
98
|
+
elsif !file_matches(word).empty?
|
99
|
+
auto_files(file_matches(word), word)
|
95
100
|
|
101
|
+
# Submodule Autocompletion
|
102
|
+
elsif current_methods.include?('auto_complete')
|
103
|
+
update_text = current_location.auto_complete(@list, word)
|
104
|
+
auto_update(update_text, word) unless update_text.blank?
|
96
105
|
end
|
97
106
|
end
|
98
107
|
|
@@ -237,13 +246,17 @@ module GreenHat
|
|
237
246
|
@list.any? { |x| x.include?(cmd) } && current_methods.include?('default')
|
238
247
|
end
|
239
248
|
|
249
|
+
def self.current_commands
|
250
|
+
current_location.methods(false).map(&:to_s).sort - %w[auto_complete]
|
251
|
+
end
|
252
|
+
|
240
253
|
# General Helper
|
241
254
|
def self.help(long = true)
|
242
255
|
if current_location.methods(false).count.zero?
|
243
256
|
puts 'No Commands'.pastel(:red)
|
244
257
|
else
|
245
258
|
puts 'Commands: '
|
246
|
-
|
259
|
+
current_commands.each do |item|
|
247
260
|
next if %w[default help].any? { |x| x == item }
|
248
261
|
|
249
262
|
puts "=> #{item.to_s.pastel(:blue)}"
|
@@ -340,6 +353,7 @@ module GreenHat
|
|
340
353
|
puts
|
341
354
|
puts 'Usage'.pastel(:yellow)
|
342
355
|
puts ' greenhat <sos-archive.tgz> <sos-archive2.tgz> '
|
356
|
+
puts ' greenhat <sos-archive.tgz> -q --command=df'
|
343
357
|
puts
|
344
358
|
|
345
359
|
puts 'Options'.pastel(:yellow)
|
data/lib/greenhat/shell/args.rb
CHANGED
@@ -70,8 +70,8 @@ module GreenHat
|
|
70
70
|
# Flags Anything that isn't sent as a key/filter
|
71
71
|
def self.arg_to_flag_list
|
72
72
|
%i[
|
73
|
-
archive end except exists json limit pluck reverse round slice sort start
|
74
|
-
truncate uniq page
|
73
|
+
archive end except exists json limit pluck reverse round slice sort start
|
74
|
+
stats truncate uniq page time_zone table_style
|
75
75
|
]
|
76
76
|
end
|
77
77
|
|
@@ -67,8 +67,20 @@ module GreenHat
|
|
67
67
|
end
|
68
68
|
# rubocop:enable Metrics/MethodLength)
|
69
69
|
|
70
|
+
def self.faststats_installation
|
71
|
+
puts "#{'Unable to find'.pastel(:red)} #{'fast-stats'.pastel(:blue)}"
|
72
|
+
puts ' Release Downloads here'
|
73
|
+
puts ' - https://gitlab.com/gitlab-com/support/toolbox/fast-stats/-/releases'.pastel(:yellow)
|
74
|
+
puts ''
|
75
|
+
end
|
76
|
+
|
70
77
|
# List Files Helpers
|
71
78
|
def self.list(args = [])
|
79
|
+
unless TTY::Which.exist? 'fast-stats'
|
80
|
+
faststats_installation
|
81
|
+
return false
|
82
|
+
end
|
83
|
+
|
72
84
|
all = false
|
73
85
|
all = true if args.include?('-a') || args.include?('--all')
|
74
86
|
|
@@ -96,6 +108,11 @@ module GreenHat
|
|
96
108
|
|
97
109
|
# Vanilla Fast Stats
|
98
110
|
def self.default(raw, _other = nil)
|
111
|
+
unless TTY::Which.exist? 'fast-stats'
|
112
|
+
faststats_installation
|
113
|
+
return false
|
114
|
+
end
|
115
|
+
|
99
116
|
files, flags, cmd = ShellHelper::Faststats.parse(raw)
|
100
117
|
|
101
118
|
LogBot.debug('FastStats CMD', cmd) if ENV['DEBUG']
|
@@ -121,6 +138,11 @@ module GreenHat
|
|
121
138
|
# --sort=count,fail,max,median,min,p95,p99,rps,score
|
122
139
|
# ========================================================================
|
123
140
|
def self.top(raw)
|
141
|
+
unless TTY::Which.exist? 'fast-stats'
|
142
|
+
faststats_installation
|
143
|
+
return false
|
144
|
+
end
|
145
|
+
|
124
146
|
files, flags, cmd = ShellHelper::Faststats.parse(raw)
|
125
147
|
|
126
148
|
LogBot.debug('FastStats CMD', cmd) if ENV['DEBUG']
|
@@ -141,6 +163,11 @@ module GreenHat
|
|
141
163
|
# ===== [ Fast Stats - Errors ] ====================
|
142
164
|
# ========================================================================
|
143
165
|
def self.errors(raw)
|
166
|
+
unless TTY::Which.exist? 'fast-stats'
|
167
|
+
faststats_installation
|
168
|
+
return false
|
169
|
+
end
|
170
|
+
|
144
171
|
# Add Color Output
|
145
172
|
raw.push '--color-output'
|
146
173
|
files, flags, cmd = ShellHelper::Faststats.parse(raw)
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module GreenHat
|
2
|
+
# Common Helpers
|
3
|
+
module FieldHelper
|
4
|
+
def self.fields_find(files, word, flags = {})
|
5
|
+
fields = ShellHelper.find_things(files, flags).map(&:fields).flatten.uniq
|
6
|
+
|
7
|
+
if word.blank?
|
8
|
+
puts 'Possible Fields:'.pastel(:bright_blue)
|
9
|
+
puts ShellHelper.field_table(fields)
|
10
|
+
|
11
|
+
return [] # Empty Result
|
12
|
+
end
|
13
|
+
|
14
|
+
list_select(fields, word)
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.list_select(list, word)
|
18
|
+
list.select! { |x| x[/^#{Regexp.escape(word)}/] }
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.filter_flags(word)
|
22
|
+
if word.blank?
|
23
|
+
puts 'Filter Options:'.pastel(:bright_blue)
|
24
|
+
puts ShellHelper.field_table(filter_opts, 6)
|
25
|
+
puts
|
26
|
+
|
27
|
+
return []
|
28
|
+
end
|
29
|
+
|
30
|
+
list_select(filter_opts, word)
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.filter_opts
|
34
|
+
%w[
|
35
|
+
archive case combine end exact except exists json limit or page pluck
|
36
|
+
raw reverse round slice sort start stats table_style text time_zone
|
37
|
+
total truncate uniq
|
38
|
+
]
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.filter_auto_completes
|
42
|
+
%w[
|
43
|
+
except exists pluck slice sort stats uniq
|
44
|
+
]
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.field_auto_complete?(word)
|
48
|
+
return false if word.blank?
|
49
|
+
|
50
|
+
filter_auto_completes.include? word.split('=', 2).first
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.field_auto_complete(word, files, flags = {})
|
54
|
+
# Prevent weird dupes
|
55
|
+
return nil if word[-1] == ','
|
56
|
+
|
57
|
+
# Command Manipulation
|
58
|
+
cmd, fields = word.split('=', 2)
|
59
|
+
complete = fields.split(',')[0..-2]
|
60
|
+
auto = fields.split(',').last
|
61
|
+
|
62
|
+
# Field Finder
|
63
|
+
matches = fields_find(files, auto, flags)
|
64
|
+
|
65
|
+
if matches.count == 1
|
66
|
+
"--#{cmd}=#{(complete + matches).join(',')}"
|
67
|
+
elsif matches.count > 1
|
68
|
+
puts "#{'Field Options:'.pastel(:bright_blue)} #{matches.join(' ').pastel(:bright_green)}"
|
69
|
+
|
70
|
+
list = [Cli.common_substr(matches.map(&:to_s))]
|
71
|
+
"--#{cmd}=#{(complete + list).join(',')}"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -11,7 +11,7 @@ module GreenHat
|
|
11
11
|
|
12
12
|
puts 'Options'.pastel(:blue)
|
13
13
|
puts '--raw'.pastel(:green)
|
14
|
-
puts '
|
14
|
+
puts ' Disable formatting and page/less'
|
15
15
|
puts
|
16
16
|
|
17
17
|
puts '--page'.pastel(:green)
|
@@ -41,6 +41,10 @@ module GreenHat
|
|
41
41
|
puts ' Print only total count of matching entries'
|
42
42
|
puts
|
43
43
|
|
44
|
+
puts '--fields'.pastel(:green)
|
45
|
+
puts ' Print only Available fields for selected files'
|
46
|
+
puts
|
47
|
+
|
44
48
|
puts '--slice'.pastel(:green)
|
45
49
|
puts ' Extract specific fields from entries (slice multiple with comma)'
|
46
50
|
puts ' Ex: --slice=path or --slice=path,params'
|
@@ -57,7 +61,7 @@ module GreenHat
|
|
57
61
|
puts
|
58
62
|
|
59
63
|
puts '--stats'.pastel(:green)
|
60
|
-
puts ' Order/Count occurrances by field'
|
64
|
+
puts ' Order/Count occurrances by field. Combine with `truncate` for key names'
|
61
65
|
puts ' Ex: --stats=params --except=params,path'
|
62
66
|
puts
|
63
67
|
|
@@ -113,6 +117,21 @@ module GreenHat
|
|
113
117
|
puts ' Ex: log filter --end="2021-06-22"'
|
114
118
|
puts
|
115
119
|
|
120
|
+
puts '--time_zone'.pastel(:green)
|
121
|
+
puts ' Manipulate the `time` field into a specific timezone'
|
122
|
+
puts ' Ex: log filter --time_zone=EDT'
|
123
|
+
puts
|
124
|
+
|
125
|
+
puts '--text'.pastel(:green)
|
126
|
+
puts ' Full entry text searching (slow)'
|
127
|
+
puts ' --text="anything here"'
|
128
|
+
puts
|
129
|
+
|
130
|
+
puts '--table_style'.pastel(:green)
|
131
|
+
puts ' Renderer used for formatted output. basic, ascii, or unicode(default)'
|
132
|
+
puts ' Ex: log filter --table_style=base'
|
133
|
+
puts
|
134
|
+
|
116
135
|
puts '--truncate'.pastel(:green)
|
117
136
|
puts ' Truncate field length. On by default (4 rows). Performance issues!'
|
118
137
|
puts ' Disable with --truncate=0'.pastel(:bright_red)
|
data/lib/greenhat/shell/log.rb
CHANGED
@@ -3,6 +3,41 @@ module GreenHat
|
|
3
3
|
module Shell
|
4
4
|
# Logs
|
5
5
|
module Log
|
6
|
+
def self.auto_complete(list, word)
|
7
|
+
# Argument Parsing
|
8
|
+
files, flags, _args = Args.parse(list)
|
9
|
+
|
10
|
+
# Don't try to autocomplete anything else
|
11
|
+
return nil unless word =~ /^-/
|
12
|
+
|
13
|
+
# Clean Up
|
14
|
+
word.delete!('-')
|
15
|
+
matches = FieldHelper.filter_flags(word)
|
16
|
+
|
17
|
+
if matches.count == 1
|
18
|
+
"--#{matches.first}"
|
19
|
+
elsif matches.count > 1
|
20
|
+
puts "#{'Filter Options:'.pastel(:bright_blue)} #{matches.join(' ').pastel(:bright_green)}"
|
21
|
+
"--#{Cli.common_substr(matches)}"
|
22
|
+
# -----------------------------------
|
23
|
+
# TODO: Fix Icky Double Nesting
|
24
|
+
elsif files.count.nonzero?
|
25
|
+
matches = FieldHelper.fields_find(files, word, flags)
|
26
|
+
|
27
|
+
return nil if matches.nil?
|
28
|
+
|
29
|
+
if matches.count == 1
|
30
|
+
"--#{matches.first}"
|
31
|
+
elsif matches.count > 1
|
32
|
+
puts "#{'Field Options:'.pastel(:bright_blue)} #{matches.join(' ').pastel(:bright_green)}"
|
33
|
+
"--#{Cli.common_substr(matches.map(&:to_s))}"
|
34
|
+
elsif FieldHelper.field_auto_complete?(word)
|
35
|
+
FieldHelper.field_auto_complete(word, files, flags)
|
36
|
+
end
|
37
|
+
# -----------------------------------
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
6
41
|
def self.help
|
7
42
|
puts "\u2500".pastel(:cyan) * 20
|
8
43
|
puts "#{'Logs'.pastel(:yellow)} find stuff"
|
@@ -73,6 +108,12 @@ module GreenHat
|
|
73
108
|
return true
|
74
109
|
end
|
75
110
|
|
111
|
+
# Skip and Print Total if set
|
112
|
+
if flags[:fields]
|
113
|
+
ShellHelper.fields_print(results)
|
114
|
+
return true
|
115
|
+
end
|
116
|
+
|
76
117
|
# Check Search Results
|
77
118
|
if results.instance_of?(Hash) && results.values.flatten.empty?
|
78
119
|
puts 'No results'.pastel(:red)
|
@@ -120,10 +120,12 @@ module GreenHat
|
|
120
120
|
entry = entry.map { |k, v| [k, format_table_entry(flags, v, k)] }.to_h
|
121
121
|
# Pre-format Entry
|
122
122
|
|
123
|
+
table_style = flags[:table_style]&.to_sym || :unicode
|
124
|
+
|
123
125
|
table = TTY::Table.new(header: entry.keys, rows: [entry], orientation: :vertical)
|
124
126
|
|
125
127
|
LogBot.debug('Rendering Entries') if ENV['DEBUG']
|
126
|
-
table.render(
|
128
|
+
table.render(table_style, padding: [0, 1, 0, 1], multiline: true) do |renderer|
|
127
129
|
renderer.border.style = :cyan
|
128
130
|
end
|
129
131
|
|
@@ -182,7 +184,10 @@ module GreenHat
|
|
182
184
|
# TODO: Simplify
|
183
185
|
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
184
186
|
def self.filter(data, flags = {}, args = {})
|
185
|
-
results = data.clone.flatten.compact
|
187
|
+
# results = data.clone.flatten.compact
|
188
|
+
|
189
|
+
# Experimenting with deep clone
|
190
|
+
results = Marshal.load(Marshal.dump(data))
|
186
191
|
results.select! do |row|
|
187
192
|
args.send(flags.logic) do |arg|
|
188
193
|
filter_row_key(row, arg, flags)
|
@@ -192,6 +197,9 @@ module GreenHat
|
|
192
197
|
# Ensure presecense of a specific field
|
193
198
|
results = filter_exists(results, flags[:exists]) if flags.key?(:exists)
|
194
199
|
|
200
|
+
# Time Zone
|
201
|
+
results = filter_modify_timezone(results, flags[:time_zone]) if flags.key?(:time_zone)
|
202
|
+
|
195
203
|
# Time Filtering
|
196
204
|
results = filter_time(results, flags) if flags.key?(:start) || flags.key?(:end)
|
197
205
|
|
@@ -217,24 +225,34 @@ module GreenHat
|
|
217
225
|
results.reverse! if flags[:reverse]
|
218
226
|
|
219
227
|
# Count occurrences / Skip Results
|
220
|
-
return filter_stats(results, flags
|
228
|
+
return filter_stats(results, flags) if flags.key?(:stats)
|
229
|
+
|
230
|
+
# Limit before Pluck / Flattening
|
231
|
+
results = filter_limit(results, flags[:limit]) if flags.key?(:limit)
|
221
232
|
|
222
233
|
# Pluck
|
223
234
|
results = filter_pluck(results, flags[:pluck]) if flags.key?(:pluck)
|
224
235
|
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
# results[0..flags[:limit].map(&:to_s).join.to_i - 1]
|
236
|
+
results
|
237
|
+
end
|
238
|
+
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
229
239
|
|
230
|
-
|
231
|
-
|
240
|
+
# Limit / Ensure Exists and Valid Number
|
241
|
+
def self.filter_limit(results, limit)
|
242
|
+
return results unless limit.integer? && limit.positive?
|
232
243
|
|
233
|
-
|
234
|
-
|
244
|
+
results.shift limit
|
245
|
+
end
|
246
|
+
|
247
|
+
def self.filter_modify_timezone(results, time_zone)
|
248
|
+
results.each do |x|
|
249
|
+
next unless x.key? :time
|
250
|
+
|
251
|
+
x[:time] = x[:time].in_time_zone time_zone
|
235
252
|
end
|
253
|
+
|
254
|
+
results
|
236
255
|
end
|
237
|
-
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
238
256
|
|
239
257
|
# Filter Start and End Times
|
240
258
|
# rubocop:disable Metrics/MethodLength
|
@@ -339,7 +357,9 @@ module GreenHat
|
|
339
357
|
end.inject(:&)
|
340
358
|
end
|
341
359
|
|
342
|
-
def self.filter_stats(results,
|
360
|
+
def self.filter_stats(results, flags)
|
361
|
+
stats = flags[:stats]
|
362
|
+
|
343
363
|
# Avoid Empty Results
|
344
364
|
if stats.empty?
|
345
365
|
filter_empty_arg('stats')
|
@@ -367,6 +387,13 @@ module GreenHat
|
|
367
387
|
# Append Header / Total with field name
|
368
388
|
output.unshift([field.to_s.pastel(:bright_black), total])
|
369
389
|
|
390
|
+
# Use Truncate For Long Keys
|
391
|
+
if flags[:truncate]
|
392
|
+
output.map! do |key, value|
|
393
|
+
[key.to_s[0..flags[:truncate]], value]
|
394
|
+
end
|
395
|
+
end
|
396
|
+
|
370
397
|
# Format
|
371
398
|
output.to_h
|
372
399
|
end
|
@@ -440,6 +467,32 @@ module GreenHat
|
|
440
467
|
end
|
441
468
|
end
|
442
469
|
|
470
|
+
# Total Count Helper
|
471
|
+
def self.fields_print(results)
|
472
|
+
results.each do |k, v|
|
473
|
+
puts k
|
474
|
+
puts field_table(v.map(&:keys).flatten.uniq.sort)
|
475
|
+
puts
|
476
|
+
end
|
477
|
+
end
|
478
|
+
|
479
|
+
def self.field_table(list, columns = 4)
|
480
|
+
return nil if list.size.zero?
|
481
|
+
|
482
|
+
# Keep Alphabetical Sort
|
483
|
+
groups = list.each_slice((list.size / columns.to_f).round).to_a
|
484
|
+
|
485
|
+
table = TTY::Table.new do |t|
|
486
|
+
loop do
|
487
|
+
break if groups.all?(&:empty?)
|
488
|
+
|
489
|
+
t << groups.map(&:shift)
|
490
|
+
end
|
491
|
+
end
|
492
|
+
|
493
|
+
table.render(:unicode, padding: [0, 1, 0, 1])
|
494
|
+
end
|
495
|
+
|
443
496
|
# Unified Files Interface
|
444
497
|
def self.files(file_list, base_list = nil, flags = {})
|
445
498
|
base_list ||= Thing.all
|
@@ -34,10 +34,10 @@ module GreenHat
|
|
34
34
|
:ok
|
35
35
|
end
|
36
36
|
|
37
|
-
# rubocop:disable
|
37
|
+
# rubocop:disable Layout/LineLength
|
38
38
|
# NGINX Conf: /var/opt/gitlab/nginx/conf/nginx.conf
|
39
39
|
# log_format gitlab_access '$remote_addr - $remote_user [$time_local] "$request_method $filtered_request_uri $server_protocol" $status $body_bytes_sent "$filtered_http_referer" "$http_user_agent" $gzip_ratio';
|
40
|
-
# rubocop:enable
|
40
|
+
# rubocop:enable Layout/LineLength
|
41
41
|
|
42
42
|
# ==========================================================================
|
43
43
|
end
|
data/lib/greenhat/thing.rb
CHANGED
@@ -26,6 +26,7 @@ class Thing < Teron
|
|
26
26
|
field :parsed # Flag for Parsing
|
27
27
|
field :result # Processed Data
|
28
28
|
field :raw_result # Flag for reading raw data
|
29
|
+
field :result_fields # All available fields
|
29
30
|
|
30
31
|
def friendly_name
|
31
32
|
"#{archive.friendly_name.pastel(:blue)} #{name.pastel(:green)}"
|
@@ -49,6 +50,13 @@ class Thing < Teron
|
|
49
50
|
result
|
50
51
|
end
|
51
52
|
|
53
|
+
# Processor
|
54
|
+
def fields
|
55
|
+
process unless parsed
|
56
|
+
|
57
|
+
result_fields
|
58
|
+
end
|
59
|
+
|
52
60
|
def raw
|
53
61
|
raw_read if raw_result.nil?
|
54
62
|
|
@@ -116,6 +124,20 @@ class Thing < Teron
|
|
116
124
|
|
117
125
|
self.parsed = true
|
118
126
|
|
127
|
+
self.result_fields = field_processing
|
128
|
+
|
119
129
|
save!
|
120
130
|
end
|
131
|
+
|
132
|
+
def field_processing
|
133
|
+
if data.instance_of?(Array)
|
134
|
+
data.select { |x| x.instance_of?(Hash) }.map(&:keys).flatten.uniq
|
135
|
+
else
|
136
|
+
[]
|
137
|
+
end
|
138
|
+
rescue StandardError => e
|
139
|
+
LogBot.fatal('Process', message: e.message, backtrace: e.backtrace.first)
|
140
|
+
|
141
|
+
[]
|
142
|
+
end
|
121
143
|
end
|
data/lib/greenhat/version.rb
CHANGED
data/lib/greenhat.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: greenhat
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Davin Walker
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-09-
|
11
|
+
date: 2021-09-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: amazing_print
|
@@ -360,6 +360,20 @@ dependencies:
|
|
360
360
|
- - "~>"
|
361
361
|
- !ruby/object:Gem::Version
|
362
362
|
version: '0.12'
|
363
|
+
- !ruby/object:Gem::Dependency
|
364
|
+
name: tty-which
|
365
|
+
requirement: !ruby/object:Gem::Requirement
|
366
|
+
requirements:
|
367
|
+
- - "~>"
|
368
|
+
- !ruby/object:Gem::Version
|
369
|
+
version: '0.5'
|
370
|
+
type: :runtime
|
371
|
+
prerelease: false
|
372
|
+
version_requirements: !ruby/object:Gem::Requirement
|
373
|
+
requirements:
|
374
|
+
- - "~>"
|
375
|
+
- !ruby/object:Gem::Version
|
376
|
+
version: '0.5'
|
363
377
|
- !ruby/object:Gem::Dependency
|
364
378
|
name: warning
|
365
379
|
requirement: !ruby/object:Gem::Requirement
|
@@ -405,6 +419,7 @@ files:
|
|
405
419
|
- lib/greenhat/shell/color_string.rb
|
406
420
|
- lib/greenhat/shell/disk.rb
|
407
421
|
- lib/greenhat/shell/faststats.rb
|
422
|
+
- lib/greenhat/shell/field_helper.rb
|
408
423
|
- lib/greenhat/shell/filter_help.rb
|
409
424
|
- lib/greenhat/shell/gitlab.rb
|
410
425
|
- lib/greenhat/shell/help.rb
|