greenhat 0.1.5 → 0.3.2
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/lib/greenhat/accessors/disk.rb +58 -2
- data/lib/greenhat/accessors/gitlab.rb +75 -0
- data/lib/greenhat/accessors/memory.rb +10 -10
- data/lib/greenhat/accessors/process.rb +10 -1
- data/lib/greenhat/cli.rb +148 -63
- data/lib/greenhat/color.rb +27 -0
- data/lib/greenhat/logbot.rb +9 -9
- data/lib/greenhat/settings.rb +51 -3
- data/lib/greenhat/shell/args.rb +146 -0
- data/lib/greenhat/shell/cat.rb +25 -73
- data/lib/greenhat/shell/color_string.rb +43 -0
- data/lib/greenhat/shell/disk.rb +30 -42
- data/lib/greenhat/shell/faststats.rb +104 -58
- data/lib/greenhat/shell/field_helper.rb +75 -0
- data/lib/greenhat/shell/filter_help.rb +162 -0
- data/lib/greenhat/shell/gitlab.rb +61 -2
- data/lib/greenhat/shell/help.rb +98 -15
- data/lib/greenhat/shell/list.rb +46 -0
- data/lib/greenhat/shell/log.rb +115 -209
- data/lib/greenhat/shell/page.rb +39 -0
- data/lib/greenhat/shell/process.rb +57 -2
- data/lib/greenhat/shell/report.rb +70 -60
- data/lib/greenhat/shell/shell_helper.rb +654 -0
- data/lib/greenhat/shell.rb +27 -13
- data/lib/greenhat/thing/file_types.rb +54 -7
- data/lib/greenhat/thing/formatters/json_shellwords.rb +0 -3
- data/lib/greenhat/thing/formatters/nginx.rb +44 -0
- data/lib/greenhat/thing/formatters/syslog.rb +39 -0
- data/lib/greenhat/thing/helpers.rb +4 -4
- data/lib/greenhat/thing/kind.rb +9 -2
- data/lib/greenhat/thing/spinner.rb +3 -3
- data/lib/greenhat/thing.rb +25 -3
- data/lib/greenhat/tty/columns.rb +44 -0
- data/lib/greenhat/version.rb +1 -1
- data/lib/greenhat.rb +16 -14
- metadata +42 -17
- data/lib/greenhat/shell/helper.rb +0 -541
data/lib/greenhat/settings.rb
CHANGED
@@ -4,13 +4,61 @@ module GreenHat
|
|
4
4
|
module Settings
|
5
5
|
def self.settings
|
6
6
|
@settings ||= {
|
7
|
-
history: []
|
7
|
+
history: [],
|
8
|
+
assume_json: true,
|
9
|
+
fuzzy_file_match: true,
|
10
|
+
|
11
|
+
# round: [2],
|
12
|
+
# page: [:true] Automatic,
|
13
|
+
truncate: TTY::Screen.width * 4,
|
14
|
+
color: true
|
8
15
|
}
|
9
16
|
end
|
10
17
|
|
18
|
+
def self.assume_json?
|
19
|
+
settings.assume_json
|
20
|
+
end
|
21
|
+
|
22
|
+
# Allow for future disabling of color output
|
23
|
+
def self.color?
|
24
|
+
settings.color
|
25
|
+
end
|
26
|
+
|
27
|
+
# Load User Settings and drop them into settings
|
28
|
+
def self.settings_load
|
29
|
+
return true unless File.exist?(settings_file)
|
30
|
+
|
31
|
+
Oj.load(File.read(settings_file)).each do |key, value|
|
32
|
+
settings[key] = value
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.settings_file
|
37
|
+
"#{dir}/settings.json"
|
38
|
+
end
|
39
|
+
|
40
|
+
# Set any Log Arguments that weren't set otherwise | Conditional assign applied on bool
|
41
|
+
# rubocop:disable Style/GuardClause
|
42
|
+
def self.default_log_flags(flags, skip_flags)
|
43
|
+
flags[:round] = settings.round if !(skip_flags.include?(:round) || flags.key?(:round)) && settings.round
|
44
|
+
|
45
|
+
flags[:page] = settings.page if !(skip_flags.include?(:page) || flags.key?(:page)) && settings.page
|
46
|
+
|
47
|
+
flags[:truncate] = settings.truncate unless skip_flags.include?(:truncate) || flags.key?(:truncate)
|
48
|
+
|
49
|
+
# Fuzzy File Match
|
50
|
+
unless skip_flags.include?(:fuzzy_file_match) || flags.key?(:fuzzy_file_match)
|
51
|
+
flags[:fuzzy_file_match] = settings.fuzzy_file_match
|
52
|
+
end
|
53
|
+
end
|
54
|
+
# rubocop:enable Style/GuardClause
|
55
|
+
|
11
56
|
def self.start
|
12
57
|
Dir.mkdir dir unless Dir.exist? dir
|
13
58
|
|
59
|
+
# Load User Settings
|
60
|
+
settings_load
|
61
|
+
|
14
62
|
# CMD History Loading / Tracking
|
15
63
|
File.write(cmd_file, "\n") unless File.exist? cmd_file
|
16
64
|
end
|
@@ -33,8 +81,8 @@ module GreenHat
|
|
33
81
|
File.read(cmd_file).split("\n")
|
34
82
|
end
|
35
83
|
|
36
|
-
def self.
|
37
|
-
File.write(cmd_file,
|
84
|
+
def self.cmd_history_clear
|
85
|
+
File.write(cmd_file, "\n")
|
38
86
|
end
|
39
87
|
|
40
88
|
def self.cmd_add(line)
|
@@ -0,0 +1,146 @@
|
|
1
|
+
module GreenHat
|
2
|
+
# Module for Argument Parsing
|
3
|
+
# Possible Args
|
4
|
+
# --value=thing
|
5
|
+
# --value / Default => --value=thing
|
6
|
+
# --flag
|
7
|
+
# --slice=value,value2
|
8
|
+
# files
|
9
|
+
|
10
|
+
# Variable Breakdown
|
11
|
+
# Args:Array supplied or default values for entry looping action
|
12
|
+
# Flags:Hash Key/Value filter Actionables
|
13
|
+
# Files:Array/String are any non start `-` dash entries
|
14
|
+
module Args
|
15
|
+
def self.parse(raw, skip_flags = [])
|
16
|
+
# Don't affect original object / Better deep clone?
|
17
|
+
cmd = raw.clone
|
18
|
+
# cmd = Marshal.load(Marshal.dump(raw))
|
19
|
+
|
20
|
+
# Extract Files
|
21
|
+
files = cmd.grep_v(/^-+([^=]+)/)
|
22
|
+
|
23
|
+
# Collect and Naturalize Arguments
|
24
|
+
args = cmd.flat_map { |arg| arg_scan(arg) }
|
25
|
+
|
26
|
+
# Collect all Flags to Hash
|
27
|
+
flags = cmd.flat_map { |flag| flag_scan(flag) }.to_h
|
28
|
+
|
29
|
+
# Move Flags to Args
|
30
|
+
arg_to_flag(flags, args)
|
31
|
+
|
32
|
+
# Logic
|
33
|
+
# And / Or
|
34
|
+
flag_defaults(flags, skip_flags)
|
35
|
+
|
36
|
+
[files, flags, args]
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.flag_defaults(flags, skip_flags)
|
40
|
+
# Update other user defaults
|
41
|
+
Settings.default_log_flags(flags, skip_flags)
|
42
|
+
|
43
|
+
# FastStats / Don't set default flags
|
44
|
+
return if skip_flags.include? :logic
|
45
|
+
|
46
|
+
# Default Logic
|
47
|
+
if flags.key?(:or)
|
48
|
+
flags.logic = :any?
|
49
|
+
flags.delete(:or)
|
50
|
+
else
|
51
|
+
flags.logic = :all?
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Move Valued Flags to arguments (--truncate=5)
|
56
|
+
def self.arg_to_flag(flags, args)
|
57
|
+
args.reject! do |arg|
|
58
|
+
# Entries specifically to move to Args
|
59
|
+
if arg_to_flag_list.include?(arg.field)
|
60
|
+
flags[arg.field] = arg.value
|
61
|
+
|
62
|
+
true
|
63
|
+
# Ignore Good Entries
|
64
|
+
else
|
65
|
+
false
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# Flags Anything that isn't sent as a key/filter
|
71
|
+
def self.arg_to_flag_list
|
72
|
+
%i[
|
73
|
+
archive end except exists json limit pluck reverse round slice sort start
|
74
|
+
stats truncate uniq page time_zone table_style
|
75
|
+
]
|
76
|
+
end
|
77
|
+
|
78
|
+
# Arg Scan (Split -- values into keys)
|
79
|
+
def self.arg_scan(arg)
|
80
|
+
arg.scan(/^-+([^=]+)=(.*)/).map do |field, value|
|
81
|
+
bang = false
|
82
|
+
if field.include? '!'
|
83
|
+
field.delete!('!')
|
84
|
+
bang = true
|
85
|
+
end
|
86
|
+
|
87
|
+
# Symbolize
|
88
|
+
field = field.to_sym
|
89
|
+
|
90
|
+
{
|
91
|
+
field: field,
|
92
|
+
value: arg_normalize(field, value),
|
93
|
+
bang: bang
|
94
|
+
}
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
# Collect All Flags
|
99
|
+
def self.flag_scan(arg)
|
100
|
+
arg.scan(/^-+([^=]+)$/).map do |field, _val|
|
101
|
+
# Symbolize
|
102
|
+
field = field.to_sym
|
103
|
+
|
104
|
+
[field, flag_arg_defaults(field)]
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
# Naturlalize Values, Manipluate Special Values
|
109
|
+
def self.arg_normalize(field, value)
|
110
|
+
# Special Comma Params With Symbol
|
111
|
+
return value.split(',').map(&:to_sym) if arg_special_split.include?(field)
|
112
|
+
|
113
|
+
# Integer Arguments
|
114
|
+
return value.to_i if value.numeric?
|
115
|
+
|
116
|
+
# Other Field Manipulation
|
117
|
+
case field
|
118
|
+
when :page then value == 'true'
|
119
|
+
else
|
120
|
+
|
121
|
+
# Default Original
|
122
|
+
value
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
# Arguments that Accept multiple options / Comma Delimted
|
127
|
+
def self.arg_special_split
|
128
|
+
%i[
|
129
|
+
slice except uniq pluck sort archive stats exists
|
130
|
+
]
|
131
|
+
end
|
132
|
+
|
133
|
+
# Arg Defaults
|
134
|
+
def self.flag_arg_defaults(field)
|
135
|
+
case field
|
136
|
+
when :round then 2
|
137
|
+
when :limit then (TTY::Screen.height / 3) - 3
|
138
|
+
when :truncate then TTY::Screen.width * 4
|
139
|
+
# when :page, :case, :exact then :true # Override Specials
|
140
|
+
when *arg_special_split then []
|
141
|
+
else
|
142
|
+
true
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
data/lib/greenhat/shell/cat.rb
CHANGED
@@ -3,60 +3,38 @@ module GreenHat
|
|
3
3
|
module Shell
|
4
4
|
# Common File Reader File
|
5
5
|
module Cat
|
6
|
-
# rubocop:disable Metrics/MethodLength
|
7
6
|
def self.help
|
8
|
-
puts "\u2500".
|
9
|
-
puts "#{'Cat'.
|
10
|
-
puts "\u2500".
|
7
|
+
puts "\u2500".pastel(:cyan) * 20
|
8
|
+
puts "#{'Cat'.pastel(:yellow)} All the files"
|
9
|
+
puts "\u2500".pastel(:cyan) * 20
|
11
10
|
puts 'Print raw file by just entering the file name'
|
12
11
|
puts
|
13
12
|
|
14
|
-
|
15
|
-
puts ' --raw'.colorize(:green)
|
16
|
-
puts ' Do not use less/paging'
|
17
|
-
puts
|
18
|
-
puts ' --archive'.colorize(:green)
|
19
|
-
puts ' Limit to specific archvie name (inclusive). Matching SOS tar.gz name'
|
20
|
-
puts ' Ex: --archive=dev-gitlab_20210622154626, --archive=202106,202107'
|
21
|
-
puts ' cat mount --archive=dev-gitlab_202106221546'
|
22
|
-
puts
|
13
|
+
ShellHelper.common_opts
|
23
14
|
|
24
|
-
puts 'Commands'.
|
25
|
-
puts
|
26
|
-
puts ' List available files'
|
27
|
-
puts ' Options'
|
28
|
-
puts ' -a, --all, show all files including source'
|
29
|
-
puts
|
15
|
+
puts 'Commands'.pastel(:blue)
|
16
|
+
puts ShellHelper::List.help
|
30
17
|
|
31
|
-
puts '<file names+>'.
|
32
|
-
puts '
|
33
|
-
puts '
|
34
|
-
puts '
|
18
|
+
puts ' <file names+>'.pastel(:green)
|
19
|
+
puts ' Print any file names'
|
20
|
+
puts ' Ex: `free_m`'
|
21
|
+
puts ' Ex: `ps mount --raw`'
|
35
22
|
puts
|
36
23
|
|
37
|
-
puts "#{'show'.
|
38
|
-
puts '
|
39
|
-
puts '
|
40
|
-
|
41
|
-
puts '--archive'.colorize(:green)
|
42
|
-
puts ' Limit to specific archvie name (inclusive). Matching SOS tar.gz name'
|
43
|
-
puts ' Ex: --archive=dev-gitlab_20210622154626, --archive=202106,202107'
|
44
|
-
puts
|
24
|
+
puts " #{'show'.pastel(:green)} <file names>"
|
25
|
+
puts ' Attempt to print formatted output'
|
26
|
+
puts ' Ex: show `free_m`'
|
45
27
|
end
|
46
|
-
# rubocop:enable Metrics/MethodLength
|
47
28
|
|
48
29
|
# ========================================================================
|
49
30
|
# Default
|
50
31
|
# ========================================================================
|
51
|
-
def self.default(
|
32
|
+
def self.default(raw)
|
52
33
|
# Extract Args
|
53
|
-
|
54
|
-
|
55
|
-
# Prepare Log List
|
56
|
-
file_list = ShellHelper.prepare_list(file_list, Thing.all)
|
34
|
+
files_list, flags, _args = Args.parse(raw)
|
57
35
|
|
58
|
-
#
|
59
|
-
files = ShellHelper.
|
36
|
+
# Collect Files
|
37
|
+
files = ShellHelper.files(files_list, Thing.all, flags)
|
60
38
|
|
61
39
|
results = ShellHelper.file_process(files) do |file|
|
62
40
|
[
|
@@ -66,58 +44,32 @@ module GreenHat
|
|
66
44
|
]
|
67
45
|
end
|
68
46
|
|
69
|
-
ShellHelper.show(results.flatten,
|
47
|
+
ShellHelper.show(results.flatten, flags)
|
70
48
|
end
|
71
49
|
|
72
50
|
# ========================================================================
|
73
51
|
# Show Attempted Formatting
|
74
52
|
# ========================================================================
|
75
|
-
def self.show(
|
53
|
+
def self.show(raw)
|
76
54
|
# Extract Args
|
77
|
-
|
55
|
+
files_list, flags, _args = Args.parse(raw)
|
78
56
|
|
79
|
-
#
|
80
|
-
|
81
|
-
|
82
|
-
# Convert to Things
|
83
|
-
files = ShellHelper.find_things(file_list, args)
|
57
|
+
# Collect Files
|
58
|
+
files = ShellHelper.files(files_list, Thing.all, flags)
|
84
59
|
|
85
60
|
results = ShellHelper.file_process(files) do |file|
|
86
61
|
[
|
87
62
|
file.friendly_name,
|
88
|
-
file.
|
63
|
+
file.data,
|
89
64
|
"\n"
|
90
65
|
]
|
91
66
|
end
|
92
67
|
|
93
|
-
ShellHelper.show(results.flatten,
|
94
|
-
end
|
95
|
-
|
96
|
-
# List Files Helpers
|
97
|
-
def self.list(args = [])
|
98
|
-
all = false
|
99
|
-
all = true if args.include?('-a') || args.include?('--all')
|
100
|
-
|
101
|
-
files = Thing.all
|
102
|
-
|
103
|
-
# Sort
|
104
|
-
files.sort_by!(&:name)
|
105
|
-
|
106
|
-
# Short & Uniq
|
107
|
-
files.uniq!(&:name) unless all
|
108
|
-
|
109
|
-
# Print
|
110
|
-
files.each do |log|
|
111
|
-
if all
|
112
|
-
puts "- #{log.friendly_name}"
|
113
|
-
else
|
114
|
-
puts "- #{log.name.colorize(:yellow)}"
|
115
|
-
end
|
116
|
-
end
|
68
|
+
ShellHelper.show(results.flatten, flags)
|
117
69
|
end
|
118
70
|
|
119
71
|
def self.ls(args = [])
|
120
|
-
list(args)
|
72
|
+
ShellHelper::List.list(args, Thing.all)
|
121
73
|
end
|
122
74
|
# ------------------------------------------------------------------------
|
123
75
|
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module GreenHat
|
2
|
+
module ShellHelper
|
3
|
+
# Helper to colorize and make outtput easier to read
|
4
|
+
module StringColor
|
5
|
+
def self.do(key, entry)
|
6
|
+
LogBot.debug('Unknown Format', entry.class) if ENV['DEBUG'] && !entry.instance_of?(String)
|
7
|
+
|
8
|
+
# Other Helpful colorizers
|
9
|
+
if pastel?(key)
|
10
|
+
pastel(key, entry)
|
11
|
+
else
|
12
|
+
entry.to_s
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# Add Color?
|
17
|
+
def self.pastel?(key)
|
18
|
+
[:severity].any? key
|
19
|
+
end
|
20
|
+
|
21
|
+
# General Key/Value Coloring
|
22
|
+
def self.pastel(key, value)
|
23
|
+
case key
|
24
|
+
when :severity then severity(value)
|
25
|
+
else
|
26
|
+
value.to_s
|
27
|
+
end
|
28
|
+
end
|
29
|
+
# ----
|
30
|
+
|
31
|
+
def self.severity(value)
|
32
|
+
case value.to_s.downcase.to_sym
|
33
|
+
when :debug then value.pastel(:blue)
|
34
|
+
when :info then value.pastel(:cyan)
|
35
|
+
when :warn then value.pastel(:yellow)
|
36
|
+
when :fatal, :error then value.pastel(:bright_red)
|
37
|
+
else
|
38
|
+
value.to_s
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/lib/greenhat/shell/disk.rb
CHANGED
@@ -8,60 +8,48 @@ module GreenHat
|
|
8
8
|
Cli.help
|
9
9
|
end
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
def self.help
|
12
|
+
puts "\u2500".pastel(:cyan) * 22
|
13
|
+
puts "#{'Disk'.pastel(:yellow)} - Storage Helper"
|
14
|
+
puts "\u2500".pastel(:cyan) * 22
|
15
|
+
|
16
|
+
ShellHelper.common_opts
|
17
|
+
|
18
|
+
puts 'Command Summary'.pastel(:blue)
|
19
|
+
puts ' df'.pastel(:green)
|
20
|
+
puts " Raw #{'df'.pastel(:cyan)} output"
|
21
|
+
puts
|
22
|
+
puts ' free'.pastel(:green)
|
23
|
+
puts ' Formatted / Bar Output'
|
24
|
+
puts
|
14
25
|
end
|
15
26
|
|
16
|
-
#
|
17
|
-
def self.
|
18
|
-
|
19
|
-
|
20
|
-
puts file.friendly_name
|
21
|
-
disks = file.data.sort_by { |x| x.use.to_i }.reverse.reject { |x| x.filesystem.include? 'tmpfs' }
|
27
|
+
# Easy Show All
|
28
|
+
def self.df(raw = {})
|
29
|
+
# Extract Args
|
30
|
+
files_list, flags, _args = Args.parse(raw)
|
22
31
|
|
23
|
-
|
24
|
-
|
25
|
-
# pad_used = GreenHat::Disk.max_padding(disks, :used)
|
26
|
-
# pad_avail = GreenHat::Disk.max_padding(disks, :avail)
|
32
|
+
# Collect Files
|
33
|
+
files = ShellHelper.files(files_list, GreenHat::Disk.df, flags)
|
27
34
|
|
28
|
-
|
35
|
+
# Output
|
36
|
+
ShellHelper.file_output(files, flags)
|
37
|
+
end
|
29
38
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
'Size'.ljust(pad_size).colorize(:magenta),
|
34
|
-
'Used'.ljust(pad_used).colorize(:cyan),
|
35
|
-
'Avail'.ljust(pad_avail).colorize(:white),
|
36
|
-
'% Use'.ljust(pad_avail).colorize(:green)
|
37
|
-
].join
|
39
|
+
def self.free(raw = {})
|
40
|
+
# Extract Args
|
41
|
+
files_list, flags, _args = Args.parse(raw)
|
38
42
|
|
39
|
-
|
40
|
-
|
41
|
-
# Pretty Disk Use
|
42
|
-
use = [
|
43
|
-
disk.use.rjust(5).ljust(5).colorize(:green),
|
44
|
-
' ['.colorize(:blue),
|
45
|
-
('=' * (disk.use.to_i / 2)).colorize(:green),
|
46
|
-
' ' * (50 - disk.use.to_i / 2),
|
47
|
-
']'.colorize(:blue)
|
48
|
-
].join
|
43
|
+
# Collect Files
|
44
|
+
files = ShellHelper.files(files_list, GreenHat::Disk.df, flags)
|
49
45
|
|
50
|
-
|
51
|
-
|
52
|
-
disk.mounted_on.ljust(pad_mount).colorize(:blue),
|
53
|
-
disk[:size].to_s.ljust(pad_size).colorize(:magenta),
|
54
|
-
disk.used.to_s.ljust(pad_used).colorize(:cyan),
|
55
|
-
disk.avail.to_s.ljust(pad_avail).colorize(:white),
|
56
|
-
use
|
57
|
-
].join
|
58
|
-
end
|
46
|
+
files.each do |file|
|
47
|
+
puts GreenHat::Disk.format_output(file, true)
|
59
48
|
|
60
49
|
# File End Loop / Break
|
61
50
|
puts
|
62
51
|
end
|
63
52
|
end
|
64
|
-
# rubocop:enable Metrics/MethodLength,Metrics/BlockLength
|
65
53
|
# ------------------------------------------------------------------------
|
66
54
|
end
|
67
55
|
end
|