fix: address Copilot PR review comments

- Add nil checks to ContainerListItem methods to prevent panics
- Add nil checks in presentation/containers.go for pod and container
- Sort pods by name for deterministic ordering in the UI
- Make pod operation error messages consistent ("X not yet supported for pods")
- Remove --color flag from pod logs for consistency with container logs

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
christophe-duc 2026-01-07 18:26:39 -04:00
parent 0e0a67aef9
commit 1518ae2d36
5 changed files with 58 additions and 23 deletions

View file

@ -11,31 +11,40 @@ type ContainerListItem struct {
// ID returns the unique ID for the item.
func (c *ContainerListItem) ID() string {
if c.IsPod {
if c.IsPod && c.Pod != nil {
return c.Pod.ID
}
if c.Container != nil {
return c.Container.ID
}
return ""
}
// Name returns the display name for the item.
func (c *ContainerListItem) Name() string {
if c.IsPod {
if c.IsPod && c.Pod != nil {
return c.Pod.Name
}
if c.Container != nil {
return c.Container.Name
}
return ""
}
// State returns the state for the item.
func (c *ContainerListItem) State() string {
if c.IsPod {
if c.IsPod && c.Pod != nil {
return c.Pod.State()
}
if c.Container != nil {
return c.Container.Summary.State
}
return ""
}
// GetContainers returns the containers if this is a pod, nil otherwise.
func (c *ContainerListItem) GetContainers() []*Container {
if c.IsPod {
if c.IsPod && c.Pod != nil {
return c.Pod.Containers
}
return nil
@ -46,21 +55,30 @@ func (c *ContainerListItem) IsInPod() bool {
if c.IsPod {
return false
}
if c.Container != nil {
return c.Container.Summary.Pod != ""
}
return false
}
// PodID returns the pod ID if this container is in a pod, empty string otherwise.
func (c *ContainerListItem) PodID() string {
if c.IsPod {
if c.IsPod && c.Pod != nil {
return c.Pod.ID
}
if c.Container != nil {
return c.Container.Summary.Pod
}
return ""
}
// PodName returns the pod name if this container is in a pod, empty string otherwise.
func (c *ContainerListItem) PodName() string {
if c.IsPod {
if c.IsPod && c.Pod != nil {
return c.Pod.Name
}
if c.Container != nil {
return c.Container.Summary.PodName
}
return ""
}

View file

@ -7,6 +7,7 @@ import (
ogLog "log"
"os"
"os/exec"
"sort"
"strings"
"sync"
"time"
@ -426,8 +427,18 @@ func (c *PodmanCommand) buildContainerListItems(containers []*Container, podSumm
}
}
// Sort pod IDs for deterministic ordering
podIDs := make([]string, 0, len(podMap))
for podID := range podMap {
podIDs = append(podIDs, podID)
}
sort.Slice(podIDs, func(i, j int) bool {
return podMap[podIDs[i]].Name < podMap[podIDs[j]].Name
})
// Add pods and their containers
for podID, ps := range podMap {
for _, podID := range podIDs {
ps := podMap[podID]
// Create pod object
pod := &Pod{
ID: ps.ID,

View file

@ -175,7 +175,8 @@ func (gui *Gui) renderPodLogsToMainAux(pod *commands.Pod, ctx context.Context, n
func (gui *Gui) writePodLogs(pod *commands.Pod, ctx context.Context, writer io.Writer) error {
// Build podman pod logs command
args := []string{"pod", "logs", "--follow", "--color"}
// Note: --color is used to distinguish output from different containers in the pod
args := []string{"pod", "logs", "--follow"}
if gui.Config.UserConfig.Logs.Timestamps {
args = append(args, "--timestamps")

View file

@ -441,7 +441,7 @@ func (gui *Gui) handleContainersRemoveMenu(g *gocui.Gui, v *gocui.View) error {
}
if item.IsPod {
return gui.createErrorPanel("Pod operations not yet supported")
return gui.createErrorPanel("Remove not yet supported for pods")
}
ctr := item.Container
@ -501,7 +501,7 @@ func (gui *Gui) handleContainerPause(g *gocui.Gui, v *gocui.View) error {
}
if item.IsPod {
return gui.createErrorPanel("Pod operations not yet supported")
return gui.createErrorPanel("Pause not yet supported for pods")
}
return gui.PauseContainer(item.Container)
@ -514,7 +514,7 @@ func (gui *Gui) handleContainerStop(g *gocui.Gui, v *gocui.View) error {
}
if item.IsPod {
return gui.createErrorPanel("Pod operations not yet supported")
return gui.createErrorPanel("Stop not yet supported for pods")
}
ctr := item.Container
@ -536,7 +536,7 @@ func (gui *Gui) handleContainerRestart(g *gocui.Gui, v *gocui.View) error {
}
if item.IsPod {
return gui.createErrorPanel("Pod operations not yet supported")
return gui.createErrorPanel("Restart not yet supported for pods")
}
ctr := item.Container
@ -556,7 +556,7 @@ func (gui *Gui) handleContainerAttach(g *gocui.Gui, v *gocui.View) error {
}
if item.IsPod {
return gui.createErrorPanel("Pod operations not yet supported")
return gui.createErrorPanel("Attach not yet supported for pods")
}
ctr := item.Container
@ -588,7 +588,7 @@ func (gui *Gui) handleContainerViewLogs(g *gocui.Gui, v *gocui.View) error {
if item.IsPod {
// TODO: implement pod logs to stdout
return gui.createErrorPanel("Pod logs to stdout not yet supported")
return gui.createErrorPanel("View logs (stdout) not yet supported for pods")
}
gui.renderLogsToStdout(item.Container)
@ -603,7 +603,7 @@ func (gui *Gui) handleContainersExecShell(g *gocui.Gui, v *gocui.View) error {
}
if item.IsPod {
return gui.createErrorPanel("Cannot exec into a pod. Select a container instead.")
return gui.createErrorPanel("Exec shell not yet supported for pods. Select a container instead.")
}
return gui.containerExecShell(item.Container)
@ -628,7 +628,7 @@ func (gui *Gui) handleContainersCustomCommand(g *gocui.Gui, v *gocui.View) error
}
if item.IsPod {
return gui.createErrorPanel("Custom commands not yet supported for pods")
return gui.createErrorPanel("Custom commands not yet supported for pods. Select a container instead.")
}
commandObject := gui.PodmanCommand.NewCommandObject(commands.CommandObject{

View file

@ -26,10 +26,15 @@ func GetContainerDisplayStrings(guiConfig *config.GuiConfig, container *commands
// GetContainerListItemDisplayStrings returns display strings for a ContainerListItem (pod or container)
func GetContainerListItemDisplayStrings(guiConfig *config.GuiConfig, item *commands.ContainerListItem) []string {
if item.IsPod {
if item.IsPod && item.Pod != nil {
return GetPodDisplayStrings(guiConfig, item.Pod)
}
if item.Container == nil {
// Return an empty row with the expected number of columns when container data is missing.
return []string{"", "", "", "", "", ""}
}
// Add indentation for containers in pods
strings := GetContainerDisplayStrings(guiConfig, item.Container)
if item.Indent > 0 {