diff --git a/pkg/commands/docker_test.go b/pkg/commands/docker_test.go index 0d459686..db45a06f 100644 --- a/pkg/commands/docker_test.go +++ b/pkg/commands/docker_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/docker/docker/client" + "github.com/jesseduffield/lazydocker/pkg/config" "github.com/stretchr/testify/assert" ) @@ -61,3 +62,30 @@ func TestNewDockerClientVersionNegotiation(t *testing.T) { "client version should not be locked to DOCKER_API_VERSION env var") }) } + +// TestIsProjectScoped covers the predicate that drives whether the +// project/services panels appear and whether the containers panel filters by +// project. The "outside compose dir + -p" case is the regression we fixed +// after PR #776 silently disabled it. +func TestIsProjectScoped(t *testing.T) { + cases := []struct { + name string + inDockerComposeProject bool + projectName string + want bool + }{ + {"inside compose dir, no -p", true, "", true}, + {"inside compose dir, with -p", true, "myproject", true}, + {"outside compose dir, no -p", false, "", false}, + {"outside compose dir, with -p", false, "myproject", true}, + } + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + c := &DockerCommand{ + InDockerComposeProject: tc.inDockerComposeProject, + Config: &config.AppConfig{ProjectName: tc.projectName}, + } + assert.Equal(t, tc.want, c.IsProjectScoped()) + }) + } +} diff --git a/pkg/gui/containers_panel.go b/pkg/gui/containers_panel.go index f9254b94..a638ee29 100644 --- a/pkg/gui/containers_panel.go +++ b/pkg/gui/containers_panel.go @@ -91,10 +91,10 @@ func (gui *Gui) getContainersPanel() *panels.SideListPanel[*commands.Container] // Otherwise all containers are shown in a flat list regardless // of which compose project they belong to. if gui.DockerCommand.IsProjectScoped() { - // This check must be inside the InDockerComposeProject guard: - // outside a compose project, services are still derived from - // container labels, so compose-managed containers from other - // projects would be incorrectly hidden. + // This check must be inside the IsProjectScoped guard: when + // not project-scoped, services are still derived from container + // labels, so compose-managed containers from other projects + // would be incorrectly hidden. // // Note that this is O(N*M) time complexity where N is the number of services // and M is the number of containers. We expect N to be small but M may be large, diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go index e7b55463..6ea2ee6c 100644 --- a/pkg/gui/gui.go +++ b/pkg/gui/gui.go @@ -459,7 +459,7 @@ func (gui *Gui) ShouldRefresh(key string) bool { } func (gui *Gui) initiallyFocusedViewName() string { - if gui.DockerCommand.InDockerComposeProject { + if gui.DockerCommand.IsProjectScoped() { return "services" } return "containers" diff --git a/pkg/gui/project_panel.go b/pkg/gui/project_panel.go index 13e281ca..e41f7b8f 100644 --- a/pkg/gui/project_panel.go +++ b/pkg/gui/project_panel.go @@ -94,18 +94,19 @@ func (gui *Gui) refreshProject() error { } // getDiscoveredProjects returns all docker compose projects by examining container labels. -// The local project (from docker-compose.yml in the current directory) is included if -// it has running containers or if InDockerComposeProject is true. +// The local project (from docker-compose.yml in the current directory, or from -p) is +// included even when it has no running containers, so the user always sees the project +// they explicitly scoped to. func (gui *Gui) getDiscoveredProjects() []*commands.Project { containers := gui.Panels.Containers.List.GetAllItems() projectNames := gui.DockerCommand.GetProjectNames(containers) - // If we're in a docker compose project but it has no running containers, - // still include it. We don't fall back to the directory name here to avoid + // If we're scoped to a project but it has no running containers, still + // include it. We don't fall back to the directory name here to avoid // briefly flashing the wrong project name on startup. localName := gui.DockerCommand.LocalProjectName - if gui.DockerCommand.InDockerComposeProject && localName != "" { + if gui.DockerCommand.IsProjectScoped() && localName != "" { found := false for _, name := range projectNames { if name == localName { diff --git a/pkg/gui/views.go b/pkg/gui/views.go index 95553f5a..f231c3c6 100644 --- a/pkg/gui/views.go +++ b/pkg/gui/views.go @@ -130,7 +130,7 @@ func (gui *Gui) createAllViews() error { gui.Views.Containers.Highlight = true gui.Views.Containers.SelBgColor = selectedLineBgColor - if gui.Config.UserConfig.Gui.ShowAllContainers || !gui.DockerCommand.InDockerComposeProject { + if gui.Config.UserConfig.Gui.ShowAllContainers || !gui.DockerCommand.IsProjectScoped() { gui.Views.Containers.Title = gui.Tr.ContainersTitle } else { gui.Views.Containers.Title = gui.Tr.StandaloneContainersTitle