mirror of
https://github.com/skoelle/kctl-tui.git
synced 2026-09-17 20:10:24 +00:00
fix: config error handling, stderr separation, single-env pane, namespace sort
This commit is contained in:
+2
-2
@@ -1,8 +1,8 @@
|
|||||||
# Binaries
|
# Binaries
|
||||||
/bin/
|
/bin/
|
||||||
/dist/
|
/dist/
|
||||||
kctl-tui
|
/kctl-tui
|
||||||
kctl-tui.exe
|
/kctl-tui.exe
|
||||||
|
|
||||||
# Go
|
# Go
|
||||||
*.test
|
*.test
|
||||||
|
|||||||
+16
-9
@@ -3,6 +3,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"sort"
|
||||||
|
|
||||||
tea "github.com/charmbracelet/bubbletea"
|
tea "github.com/charmbracelet/bubbletea"
|
||||||
"github.com/charmbracelet/bubbles/list"
|
"github.com/charmbracelet/bubbles/list"
|
||||||
@@ -235,6 +236,7 @@ func (m *fullModel) loadNamespacesFor(teamValue string) tea.Cmd {
|
|||||||
for ns := range m.namespaces {
|
for ns := range m.namespaces {
|
||||||
names = append(names, ns)
|
names = append(names, ns)
|
||||||
}
|
}
|
||||||
|
sort.Strings(names)
|
||||||
} else {
|
} else {
|
||||||
names = namespacesForLabelValue(m.namespaces, m.cfg.TeamLabelKey, teamValue)
|
names = namespacesForLabelValue(m.namespaces, m.cfg.TeamLabelKey, teamValue)
|
||||||
}
|
}
|
||||||
@@ -257,26 +259,31 @@ func (m *fullModel) startTmuxSession() tea.Cmd {
|
|||||||
selfPath, m.selectedContext, m.selectedNamespace, m.selectedTeam)
|
selfPath, m.selectedContext, m.selectedNamespace, m.selectedTeam)
|
||||||
|
|
||||||
envA := m.cfg.Envs[0]
|
envA := m.cfg.Envs[0]
|
||||||
envB := m.cfg.Envs[0]
|
|
||||||
if len(m.cfg.Envs) > 1 {
|
|
||||||
envB = m.cfg.Envs[1]
|
|
||||||
}
|
|
||||||
ctxA := m.cfg.ResolveContext(envA, m.selectedContext)
|
ctxA := m.cfg.ResolveContext(envA, m.selectedContext)
|
||||||
ctxB := m.cfg.ResolveContext(envB, m.selectedContext)
|
|
||||||
|
|
||||||
k9sCmdA := fmt.Sprintf("k9s --context %s -n %s", ctxA, m.selectedNamespace)
|
k9sCmdA := fmt.Sprintf("k9s --context %s -n %s", ctxA, m.selectedNamespace)
|
||||||
k9sCmdB := fmt.Sprintf("k9s --context %s -n %s", ctxB, m.selectedNamespace)
|
|
||||||
|
|
||||||
c := exec.Command("tmux", "new-session", "-d", "-s", "kctl",
|
args := []string{
|
||||||
|
"new-session", "-d", "-s", "kctl",
|
||||||
panelCmd, ";",
|
panelCmd, ";",
|
||||||
"set-option", "-t", "kctl", "remain-on-exit", "on", ";",
|
"set-option", "-t", "kctl", "remain-on-exit", "on", ";",
|
||||||
"split-window", "-v", "-t", "kctl:0.0", k9sCmdA, ";",
|
"split-window", "-v", "-t", "kctl:0.0", k9sCmdA, ";",
|
||||||
"split-window", "-v", "-t", "kctl:0.1", k9sCmdB, ";",
|
}
|
||||||
|
if len(m.cfg.Envs) > 1 {
|
||||||
|
envB := m.cfg.Envs[1]
|
||||||
|
ctxB := m.cfg.ResolveContext(envB, m.selectedContext)
|
||||||
|
k9sCmdB := fmt.Sprintf("k9s --context %s -n %s", ctxB, m.selectedNamespace)
|
||||||
|
args = append(args,
|
||||||
|
"split-window", "-v", "-t", "kctl:0.1", k9sCmdB, ";",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
args = append(args,
|
||||||
"select-layout", "-t", "kctl", "even-vertical", ";",
|
"select-layout", "-t", "kctl", "even-vertical", ";",
|
||||||
"select-pane", "-t", "kctl:0.0", ";",
|
"select-pane", "-t", "kctl:0.0", ";",
|
||||||
"attach", "-t", "kctl",
|
"attach", "-t", "kctl",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
c := exec.Command("tmux", args...)
|
||||||
|
|
||||||
return tea.ExecProcess(c, func(err error) tea.Msg {
|
return tea.ExecProcess(c, func(err error) tea.Msg {
|
||||||
return tmuxDoneMsg{err: err}
|
return tmuxDoneMsg{err: err}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -76,13 +76,18 @@ func newPanelModel(context, ns, team string) *panelModel {
|
|||||||
ti.Focus()
|
ti.Focus()
|
||||||
|
|
||||||
cfgPath, _ := config.DefaultPath()
|
cfgPath, _ := config.DefaultPath()
|
||||||
cfg, _ := config.Load(cfgPath)
|
cfg, loadErr := config.Load(cfgPath)
|
||||||
|
|
||||||
l := list.New(nil, list.NewDefaultDelegate(), 0, 0)
|
l := list.New(nil, list.NewDefaultDelegate(), 0, 0)
|
||||||
l.SetShowStatusBar(false)
|
l.SetShowStatusBar(false)
|
||||||
|
|
||||||
m := &panelModel{context: context, ns: ns, team: team, cfg: cfg, step: stepEnvMenu, list: l, input: ti}
|
m := &panelModel{context: context, ns: ns, team: team, cfg: cfg, step: stepEnvMenu, list: l, input: ti}
|
||||||
m.showEnvMenu()
|
if loadErr != nil {
|
||||||
|
m.err = fmt.Errorf("config load failed: %w", loadErr)
|
||||||
|
m.step = stepError
|
||||||
|
} else {
|
||||||
|
m.showEnvMenu()
|
||||||
|
}
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,11 +20,21 @@ import (
|
|||||||
|
|
||||||
func runOutput(name string, args ...string) (string, error) {
|
func runOutput(name string, args ...string) (string, error) {
|
||||||
cmd := exec.Command(name, args...)
|
cmd := exec.Command(name, args...)
|
||||||
out, err := cmd.CombinedOutput()
|
var stdout, stderr strings.Builder
|
||||||
|
cmd.Stdout = &stdout
|
||||||
|
cmd.Stderr = &stderr
|
||||||
|
err := cmd.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("%s %s failed: %w\n%s", name, strings.Join(args, " "), err, string(out))
|
msg := fmt.Sprintf("%s %s failed: %v", name, strings.Join(args, " "), err)
|
||||||
|
if s := strings.TrimSpace(stderr.String()); s != "" {
|
||||||
|
msg += "\n" + s
|
||||||
|
}
|
||||||
|
if s := strings.TrimSpace(stdout.String()); s != "" {
|
||||||
|
msg += "\n" + s
|
||||||
|
}
|
||||||
|
return "", fmt.Errorf("%s", msg)
|
||||||
}
|
}
|
||||||
return strings.TrimSpace(string(out)), nil
|
return strings.TrimSpace(stdout.String()), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// kubectlArgs prepends a --context flag when context is non-empty.
|
// kubectlArgs prepends a --context flag when context is non-empty.
|
||||||
|
|||||||
Reference in New Issue
Block a user