From d54826327e11a576194e26352886814a5262b6db Mon Sep 17 00:00:00 2001 From: derailed Date: Thu, 20 Jun 2019 12:36:30 -0600 Subject: [PATCH] refact table --- internal/views/resource.go | 2 +- internal/views/table.go | 70 ++++------------------------------ internal/views/table_helper.go | 64 +++++++++++++++++++++++++++++-- 3 files changed, 69 insertions(+), 67 deletions(-) diff --git a/internal/views/resource.go b/internal/views/resource.go index fb568d0d..7c0e905c 100644 --- a/internal/views/resource.go +++ b/internal/views/resource.go @@ -37,7 +37,7 @@ func newResourceView(title string, app *appView, list resource.List) resourceVie masterDetail: newMasterDetail(title, app, list.GetNamespace()), list: list, } - v.masterPage().filterChanged(v.filterResource) + v.masterPage().setFilterFn(v.filterResource) return &v } diff --git a/internal/views/table.go b/internal/views/table.go index 90052369..82f6c030 100644 --- a/internal/views/table.go +++ b/internal/views/table.go @@ -1,11 +1,8 @@ package views import ( - "encoding/csv" "errors" "fmt" - "os" - "path/filepath" "regexp" "strings" "time" @@ -18,21 +15,7 @@ import ( "k8s.io/apimachinery/pkg/util/duration" ) -const ( - titleFmt = "[fg:bg:b] %s[fg:bg:-][[count:bg:b]%d[fg:bg:-]] " - searchFmt = "<[filter:bg:b]/%s[fg:bg:]> " - nsTitleFmt = "[fg:bg:b] %s([hilite:bg:b]%s[fg:bg:-])[fg:bg:-][[count:bg:b]%d[fg:bg:-]][fg:bg:-] " - labelSelIndicator = "-l" -) - -var ( - cpuRX = regexp.MustCompile(`\A.{0,1}CPU`) - memRX = regexp.MustCompile(`\A.{0,1}MEM`) -) - type ( - cleanseFn func(string) string - resTable struct { *tview.Table @@ -73,14 +56,15 @@ func newTableView(app *appView, title string) *tableView { v.SetBorderFocusColor(config.AsColor(app.styles.Frame().Border.FocusColor)) v.SetBorderAttributes(tcell.AttrBold) v.SetBorderPadding(0, 0, 1, 1) - v.cmdBuff.addListener(app.cmd()) - v.cmdBuff.reset() v.SetSelectable(true, false) v.SetSelectedStyle( tcell.ColorBlack, config.AsColor(app.styles.Table().CursorColor), tcell.AttrBold, ) + v.cmdBuff.addListener(app.cmd()) + v.cmdBuff.reset() + v.SetInputCapture(v.keyboard) v.bindKeys() @@ -102,7 +86,7 @@ func (v *tableView) bindKeys() { } } -func (v *tableView) filterChanged(fn func(string)) { +func (v *tableView) setFilterFn(fn func(string)) { v.filterFn = fn } @@ -141,51 +125,13 @@ func (v *tableView) selectFirstRow() { } } -const ( - fullFmat = "%s-%s-%d.csv" - noNSFmat = "%s-%d.csv" -) - func (v *tableView) saveCmd(evt *tcell.EventKey) *tcell.EventKey { - dir := filepath.Join(config.K9sDumpDir, v.app.config.K9s.CurrentCluster) - if err := ensureDir(dir); err != nil { - log.Error().Err(err).Msgf("Mkdir K9s dump") - return nil + if path, err := saveTable(v.app.config.K9s.CurrentCluster, v.baseTitle, v.data); err != nil { + v.app.flash().err(err) + } else { + v.app.flash().infof("File %s saved successfully!", path) } - ns, now := v.data.Namespace, time.Now().UnixNano() - if ns == resource.AllNamespaces { - ns = resource.AllNamespace - } - fName := fmt.Sprintf(fullFmat, v.baseTitle, ns, now) - if ns == resource.NotNamespaced { - fName = fmt.Sprintf(noNSFmat, v.baseTitle, now) - } - - path := filepath.Join(dir, fName) - mod := os.O_CREATE | os.O_WRONLY - file, err := os.OpenFile(path, mod, 0644) - defer func() { - if file != nil { - file.Close() - } - }() - if err != nil { - log.Error().Err(err).Msgf("CSV create %s", path) - return nil - } - - w := csv.NewWriter(file) - w.Write(v.data.Header) - for _, r := range v.data.Rows { - w.Write(r.Fields) - } - w.Flush() - if err := w.Error(); err != nil { - log.Error().Err(err).Msgf("Screen dump %s", v.baseTitle) - } - - v.app.flash().infof("File %s saved successfully!", path) return nil } diff --git a/internal/views/table_helper.go b/internal/views/table_helper.go index e0d83ce9..927d14ad 100644 --- a/internal/views/table_helper.go +++ b/internal/views/table_helper.go @@ -1,22 +1,78 @@ package views import ( + "encoding/csv" "fmt" + "os" + "path/filepath" "regexp" "sort" "strings" + "time" "github.com/derailed/k9s/internal/config" "github.com/derailed/k9s/internal/resource" ) -var labelCmd = regexp.MustCompile(`\A\-l`) - const ( - descIndicator = "↓" - ascIndicator = "↑" + titleFmt = "[fg:bg:b] %s[fg:bg:-][[count:bg:b]%d[fg:bg:-]] " + searchFmt = "<[filter:bg:b]/%s[fg:bg:]> " + nsTitleFmt = "[fg:bg:b] %s([hilite:bg:b]%s[fg:bg:-])[fg:bg:-][[count:bg:b]%d[fg:bg:-]][fg:bg:-] " + labelSelIndicator = "-l" + descIndicator = "↓" + ascIndicator = "↑" + fullFmat = "%s-%s-%d.csv" + noNSFmat = "%s-%d.csv" ) +var ( + cpuRX = regexp.MustCompile(`\A.{0,1}CPU`) + memRX = regexp.MustCompile(`\A.{0,1}MEM`) + labelCmd = regexp.MustCompile(`\A\-l`) +) + +type cleanseFn func(string) string + +func saveTable(cluster, name string, data resource.TableData) (string, error) { + dir := filepath.Join(config.K9sDumpDir, cluster) + if err := ensureDir(dir); err != nil { + return "", err + } + + ns, now := data.Namespace, time.Now().UnixNano() + if ns == resource.AllNamespaces { + ns = resource.AllNamespace + } + fName := fmt.Sprintf(fullFmat, name, ns, now) + if ns == resource.NotNamespaced { + fName = fmt.Sprintf(noNSFmat, name, now) + } + + path := filepath.Join(dir, fName) + mod := os.O_CREATE | os.O_WRONLY + file, err := os.OpenFile(path, mod, 0644) + defer func() { + if file != nil { + file.Close() + } + }() + if err != nil { + return "", err + } + + w := csv.NewWriter(file) + w.Write(data.Header) + for _, r := range data.Rows { + w.Write(r.Fields) + } + w.Flush() + if err := w.Error(); err != nil { + return "", err + } + + return path, nil +} + func isLabelSelector(s string) bool { if s == "" { return false