diff options
author | matthieu <matthieu.cneude@gmail.com> | 2020-06-07 13:30:27 +0200 |
---|---|---|
committer | matthieu <matthieu.cneude@gmail.com> | 2020-06-07 13:30:27 +0200 |
commit | 577c36ff06f765122c743616865d701e8fb431b1 (patch) | |
tree | fa42a97894cdaaf6beec9506b109f9751b4c3296 | |
parent | 70df0f0fc7b7611b6dac09486c705ccaf15a692d (diff) |
Add generic output as a bar diagram from any command line input
-rw-r--r-- | internal/host_widget.go | 44 | ||||
-rw-r--r-- | internal/platform/host.go | 90 | ||||
-rw-r--r-- | internal/platform/host_test.go | 65 |
3 files changed, 167 insertions, 32 deletions
diff --git a/internal/host_widget.go b/internal/host_widget.go index 11de304..8d94fe9 100644 --- a/internal/host_widget.go +++ b/internal/host_widget.go @@ -28,6 +28,7 @@ const ( rhTable = "rh.table" rhBox = "rh.box" rhGauge = "rh.gauge" + rhBar = "rh.bar" ) type HostWidget struct { @@ -87,6 +88,8 @@ func (ms *HostWidget) CreateWidgets(widget Widget, tui *Tui) (f func() error, er f, err = ms.box(widget) case rhGauge: f, err = ms.gauge(widget) + case rhBar: + f, err = ms.bar(widget) default: return nil, errors.Errorf("can't find the widget %s", widget.Name) } @@ -409,6 +412,12 @@ func (ms *HostWidget) tableDisk(widget Widget) (f func() error, err error) { } headers := []string{"Filesystem", "Size", "Used", "Available", "Use%", "Mount"} + if _, ok := widget.Options[optionHeaders]; ok { + if len(widget.Options[optionHeaders]) > 0 { + headers = strings.Split(strings.TrimSpace(widget.Options[optionHeaders]), ",") + } + } + data, err := platform.HostDisk(ms.service.Runner, headers, unit) if err != nil { return nil, err @@ -501,3 +510,38 @@ func (ms *HostWidget) gauge(widget Widget) (f func() error, err error) { return } + +func (ms *HostWidget) bar(widget Widget) (f func() error, err error) { + title := " Example of bar " + if _, ok := widget.Options[optionTitle]; ok { + title = widget.Options[optionTitle] + } + + headers := []string{"small", "bigger", "big", "insane"} + if _, ok := widget.Options[optionHeaders]; ok { + if len(widget.Options[optionHeaders]) > 0 { + headers = strings.Split(strings.TrimSpace(widget.Options[optionHeaders]), ",") + } + } + + cmd := "echo -e 20 30 40 50" + if _, ok := widget.Options[optionCommand]; ok { + cmd = widget.Options[optionCommand] + } + + data, err := platform.HostBar(ms.service.Runner, cmd) + if err != nil { + return nil, err + } + + f = func() error { + return ms.tui.AddBarChart( + data, + headers, + title, + widget.Options, + ) + } + + return +} diff --git a/internal/platform/host.go b/internal/platform/host.go index df3b503..8daf632 100644 --- a/internal/platform/host.go +++ b/internal/platform/host.go @@ -364,37 +364,6 @@ func HostNetIO(runner runnerFunc, unit string) (string, error) { return rx + " / " + tx, nil } -func HostTable(runner runnerFunc, command string, headers []string) (cells [][]string, err error) { - lines, err := runner(command) - if err != nil { - return nil, err - } - - scanner := bufio.NewScanner(strings.NewReader(lines)) - data := "" - - lineNumber := 0 - for scanner.Scan() { - line := scanner.Text() - parts := strings.Fields(line) - - if len(headers) == 0 { - headers = parts - lineNumber++ - continue - } - - data += strings.Join(parts, ",") + "," - lineNumber++ - } - data = strings.Trim(data, ",") - - cells = [][]string{headers} - cells = append(cells, formatToTable(len(headers), data)...) - - return -} - func HostDisk(runner runnerFunc, headers []string, unit string) ([][]string, error) { // GetIOStat returns io stat lines, err := runner("/bin/df -x devtmpfs -x tmpfs -x debugfs") @@ -448,7 +417,6 @@ func HostDisk(runner runnerFunc, headers []string, unit string) ([][]string, err return c, nil } - func HostDiskIO(runner runnerFunc, unit string) (string, error) { // GetIOStat returns io stat lines, err := runner("/bin/cat /proc/diskstats") @@ -485,6 +453,33 @@ func HostDiskIO(runner runnerFunc, unit string) (string, error) { return strconv.FormatFloat(fr, 'f', 2, strconv.IntSize) + " / " + strconv.FormatFloat(fw, 'f', 2, strconv.IntSize), nil } +func HostBar(runner runnerFunc, command string) (data []int, err error) { + lines, err := runner(command) + if err != nil { + return nil, err + } + + scanner := bufio.NewScanner(strings.NewReader(lines)) + lineNumber := 0 + str := "" + for scanner.Scan() { + line := scanner.Text() + parts := strings.Fields(line) + + for _, v := range parts { + str += v + "," + } + lineNumber++ + } + + f := formatToBar(str) + result := []int{} + for _, f := range f { + result = append(result, int(f)) + } + return result, nil +} + func HostBox(runner runnerFunc, command string) (string, error) { lines, err := runner(command) if err != nil { @@ -516,6 +511,37 @@ func HostGauge(runner runnerFunc, command string) (float64, error) { return 0, nil } +func HostTable(runner runnerFunc, command string, headers []string) (cells [][]string, err error) { + lines, err := runner(command) + if err != nil { + return nil, err + } + + scanner := bufio.NewScanner(strings.NewReader(lines)) + data := "" + + lineNumber := 0 + for scanner.Scan() { + line := scanner.Text() + parts := strings.Fields(line) + + if len(headers) == 0 { + headers = parts + lineNumber++ + continue + } + + data += strings.Join(parts, ",") + "," + lineNumber++ + } + data = strings.Trim(data, ",") + + cells = [][]string{headers} + cells = append(cells, formatToTable(len(headers), data)...) + + return +} + func formatToBar(data string) (val []uint64) { data = strings.Trim(data, ",") s := strings.Split(data, ",") diff --git a/internal/platform/host_test.go b/internal/platform/host_test.go index 42c5a23..4d1c6dd 100644 --- a/internal/platform/host_test.go +++ b/internal/platform/host_test.go @@ -724,3 +724,68 @@ func Test_HostGauge(t *testing.T) { }) } } +func Test_HostBar(t *testing.T) { + testCases := []struct { + name string + runner runnerFunc + expected []int + command string + wantErr bool + }{ + { + name: "happy case", + expected: []int{40, 50, 60, 70}, + runner: func(cmd string) (string, error) { + return "40 50 60 70", nil + }, + wantErr: false, + }, + { + name: "on multiple lines", + expected: []int{40, 50, 60, 70}, + runner: func(cmd string) (string, error) { + return `40 50 + 60 70`, nil + }, + wantErr: false, + }, + { + name: "empty result", + expected: []int{0}, + runner: func(cmd string) (string, error) { + return "", nil + }, + wantErr: false, + }, + { + name: "runner return wrong result", + expected: []int{0}, + runner: func(cmd string) (string, error) { + return "ldfsjsdf", nil + }, + wantErr: false, + }, + { + name: "runner return error", + command: "kb", + runner: func(cmd string) (string, error) { + return "60", errors.New("Error") + }, + wantErr: true, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + actual, err := HostBar(tc.runner, tc.command) + if (err != nil) != tc.wantErr { + t.Errorf("Error '%v' even if wantErr is %t", err, tc.wantErr) + return + } + + if tc.wantErr == false && !reflect.DeepEqual(actual, tc.expected) { + t.Errorf("Expected %v, actual %v", tc.expected, actual) + } + }) + } +} |