feat: add support for renaming contexts. (#2006)

* feat: add support for renaming contexts.

* chore: try to reduce ABC

* test: account for the `rename` hint
mine
Jacob Lorenzen 2023-03-17 16:11:09 +01:00 committed by GitHub
parent 2955e2251f
commit c851277e33
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 84 additions and 1 deletions

View File

@ -133,6 +133,26 @@ func (c *Config) DelContext(n string) error {
return clientcmd.ModifyConfig(acc, cfg, true)
}
// RenameContext renames a context.
func (c *Config) RenameContext(old string, new string) error {
cfg, err := c.RawConfig()
if err != nil {
return err
}
if _, ok := cfg.Contexts[new]; ok {
return fmt.Errorf("context with name %s already exists", new)
}
cfg.Contexts[new] = cfg.Contexts[old]
delete(cfg.Contexts, old)
acc, err := c.ConfigAccess()
if err != nil {
return err
}
return clientcmd.ModifyConfig(acc, cfg, true)
}
// ContextNames fetch all available contexts.
func (c *Config) ContextNames() ([]string, error) {
cfg, err := c.RawConfig()

View File

@ -7,9 +7,15 @@ import (
"github.com/derailed/k9s/internal/dao"
"github.com/derailed/k9s/internal/ui"
"github.com/derailed/tcell/v2"
"github.com/derailed/tview"
"github.com/rs/zerolog/log"
)
const (
renamePage = "rename"
inputField = "New name:"
)
// Context presents a context viewer.
type Context struct {
ResourceViewer
@ -28,6 +34,63 @@ func NewContext(gvr client.GVR) ResourceViewer {
func (c *Context) bindKeys(aa ui.KeyActions) {
aa.Delete(ui.KeyShiftA, tcell.KeyCtrlSpace, ui.KeySpace)
aa.Add(ui.KeyActions{
ui.KeyR: ui.NewKeyAction("Rename", c.renameCmd, true),
})
}
func (c *Context) renameCmd(evt *tcell.EventKey) *tcell.EventKey {
contextName := c.GetTable().GetSelectedItem()
if contextName == "" {
return evt
}
app := c.App()
c.showRenameModal(app, contextName, c.renameDialogCallback)
return nil
}
func (c *Context) renameDialogCallback(form *tview.Form, contextName string) error {
app := c.App()
input := form.GetFormItemByLabel(inputField).(*tview.InputField)
if err := app.factory.Client().Config().RenameContext(contextName, input.GetText()); err != nil {
c.App().Flash().Err(err)
return nil
}
c.Refresh()
return nil
}
func (c *Context) showRenameModal(a *App, name string, ok func(form *tview.Form, contextName string)(error)) {
p := a.Content.Pages
f := c.makeStyledForm()
f.AddInputField(inputField, name, 0, nil, nil).
AddButton("OK", func() {
if err := ok(f, name); err != nil {
c.App().Flash().Err(err)
return
}
p.RemovePage(renamePage)
}).
AddButton("Cancel", func() {
p.RemovePage(renamePage)
})
m := tview.NewModalForm("<Rename>", f)
p.AddPage(renamePage, m, false, false)
p.ShowPage(renamePage)
}
func (c *Context) makeStyledForm() *tview.Form {
f := tview.NewForm()
f.SetItemPadding(0)
f.SetButtonsAlign(tview.AlignCenter).
SetButtonBackgroundColor(tview.Styles.PrimitiveBackgroundColor).
SetButtonTextColor(tview.Styles.PrimaryTextColor).
SetLabelColor(tcell.ColorAqua).
SetFieldTextColor(tcell.ColorOrange)
return f
}
func (c *Context) useCtx(app *App, model ui.Tabular, gvr, path string) {

View File

@ -13,5 +13,5 @@ func TestContext(t *testing.T) {
assert.Nil(t, ctx.Init(makeCtx()))
assert.Equal(t, "Contexts", ctx.Name())
assert.Equal(t, 4, len(ctx.Hints()))
assert.Equal(t, 5, len(ctx.Hints()))
}