Skip to content

Commit

Permalink
cacheable and provide test cases
Browse files Browse the repository at this point in the history
  • Loading branch information
wjiec committed Nov 25, 2023
1 parent 54a5d96 commit 4a4e0d2
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 40 deletions.
101 changes: 64 additions & 37 deletions internal/view/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,16 @@ func (a *App) initSignals() {
}

func (a *App) suggestCommand() model.SuggestionFunc {
namespaceNames, err := a.namespaceNames()
if err != nil {
log.Error().Err(err).Msg("failed to list namespaces")
}

contextNames, err := a.contextNames()
if err != nil {
log.Error().Err(err).Msg("failed to list contexts")
}

return func(s string) (entries sort.StringSlice) {
if s == "" {
if a.cmdHistory.Empty() {
Expand All @@ -166,7 +176,7 @@ func (a *App) suggestCommand() model.SuggestionFunc {
}
}

entries = append(entries, a.suggestSubCommand(s)...)
entries = append(entries, suggestSubCommand(s, namespaceNames, contextNames)...)
if len(entries) == 0 {
return nil
}
Expand All @@ -175,47 +185,30 @@ func (a *App) suggestCommand() model.SuggestionFunc {
}
}

func (a *App) suggestSubCommand(command string) []string {
cmds := strings.Fields(command)
if len(cmds[0]) == 0 || len(cmds) != 2 {
return nil
func (a *App) namespaceNames() ([]string, error) {
namespaces, err := a.factory.Client().ValidNamespaces()
if err != nil {
return nil, err
}

var suggests []string
switch strings.ToLower(cmds[0]) {
case "cow", "q", "q!", "qa", "Q", "quit", "?", "h", "help", "a", "alias", "x", "xray", "dir":
return nil // ignore special commands
case "ctx", "context", "contexts":
ctxs, err := a.factory.Client().Config().Contexts()
if err != nil {
log.Error().Err(err).Msg("failed to list contexts")
return nil
}

for contextName := range ctxs {
if suggest, ok := shouldAddSuggest(cmds[1], contextName); ok {
suggests = append(suggests, suggest)
}
}
default:
nss, err := a.factory.Client().ValidNamespaces()
if err != nil {
log.Error().Err(err).Msg("failed to list nss")
return nil
}

if suggest, ok := shouldAddSuggest(cmds[1], client.NamespaceAll); ok {
suggests = append(suggests, suggest)
}
namespaceNames := make([]string, 0, len(namespaces))
for _, namespace := range namespaces {
namespaceNames = append(namespaceNames, namespace.Name)
}
return namespaceNames, nil
}

for _, ns := range nss {
if suggest, ok := shouldAddSuggest(cmds[1], ns.Name); ok {
suggests = append(suggests, suggest)
}
}
func (a *App) contextNames() ([]string, error) {
contexts, err := a.factory.Client().Config().Contexts()
if err != nil {
return nil, err
}

return suggests
contextNames := make([]string, 0, len(contexts))
for ctxName := range contexts {
contextNames = append(contextNames, ctxName)
}
return contextNames, nil
}

func (a *App) keyboard(evt *tcell.EventKey) *tcell.EventKey {
Expand Down Expand Up @@ -714,6 +707,40 @@ func (a *App) statusIndicator() *ui.StatusIndicator {
return a.Views()["statusIndicator"].(*ui.StatusIndicator)
}

// ----------------------------------------------------------------------------
// Helpers

func suggestSubCommand(command string, namespaces, contexts []string) []string {
cmds := strings.Fields(command)
if len(cmds[0]) == 0 || len(cmds) != 2 {
return nil
}

var suggests []string
switch strings.ToLower(cmds[0]) {
case "cow", "q", "q!", "qa", "Q", "quit", "?", "h", "help", "a", "alias", "x", "xray", "dir":
return nil // ignore special commands
case "ctx", "context", "contexts":
for _, ctxName := range contexts {
if suggest, ok := shouldAddSuggest(cmds[1], ctxName); ok {
suggests = append(suggests, suggest)
}
}
default:
if suggest, ok := shouldAddSuggest(cmds[1], client.NamespaceAll); ok {
suggests = append(suggests, suggest)
}

for _, ns := range namespaces {
if suggest, ok := shouldAddSuggest(cmds[1], ns); ok {
suggests = append(suggests, suggest)
}
}
}

return suggests
}

func shouldAddSuggest(command, suggest string) (string, bool) {
if command != suggest && strings.HasPrefix(suggest, command) {
return strings.TrimPrefix(suggest, command), true
Expand Down
33 changes: 30 additions & 3 deletions internal/view/app_test.go
Original file line number Diff line number Diff line change
@@ -1,19 +1,46 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright Authors of K9s

package view_test
package view

import (
"testing"

"github.com/derailed/k9s/internal/config"
"github.com/derailed/k9s/internal/view"
"github.com/stretchr/testify/assert"
)

func TestAppNew(t *testing.T) {
a := view.NewApp(config.NewConfig(ks{}))
a := NewApp(config.NewConfig(ks{}))
_ = a.Init("blee", 10)

assert.Equal(t, 11, len(a.GetActions()))
}

func Test_suggestSubCommand(t *testing.T) {
namespaceNames := []string{"kube-system", "kube-public", "default", "nginx-ingress"}
contextNames := []string{"develop", "test", "pre", "prod"}

tests := []struct {
Command string
Suggestions []string
}{
{Command: "q", Suggestions: nil},
{Command: "xray dp", Suggestions: nil},
{Command: "help k", Suggestions: nil},
{Command: "ctx p", Suggestions: []string{"re", "rod"}},
{Command: "ctx p", Suggestions: []string{"re", "rod"}},
{Command: "ctx pr", Suggestions: []string{"e", "od"}},
{Command: "context d", Suggestions: []string{"evelop"}},
{Command: "contexts t", Suggestions: []string{"est"}},
{Command: "po ", Suggestions: nil},
{Command: "po x", Suggestions: nil},
{Command: "po k", Suggestions: []string{"ube-system", "ube-public"}},
{Command: "po kube-", Suggestions: []string{"system", "public"}},
}

for _, tt := range tests {
got := suggestSubCommand(tt.Command, namespaceNames, contextNames)
assert.Equal(t, tt.Suggestions, got)
}
}

0 comments on commit 4a4e0d2

Please sign in to comment.