mirror of
https://github.com/jesseduffield/lazydocker.git
synced 2026-07-25 08:31:03 +00:00
Use IsProjectScoped at remaining call sites + add test
Addresses Copilot review comments on PR #797: - Containers panel title, initial focus selection, and the local-project inclusion in getDiscoveredProjects all switched from InDockerComposeProject to IsProjectScoped, so they stay consistent when -p is given outside a compose dir. - Adds TestIsProjectScoped table test covering all four combinations. InDockerComposeProject is still used at the call sites that genuinely require a compose dir (renderDockerComposeConfig, GetServices). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
3974f6fec1
commit
f5ff116af9
5 changed files with 40 additions and 11 deletions
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/docker/client"
|
"github.com/docker/docker/client"
|
||||||
|
"github.com/jesseduffield/lazydocker/pkg/config"
|
||||||
"github.com/stretchr/testify/assert"
|
"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")
|
"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())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -91,10 +91,10 @@ func (gui *Gui) getContainersPanel() *panels.SideListPanel[*commands.Container]
|
||||||
// Otherwise all containers are shown in a flat list regardless
|
// Otherwise all containers are shown in a flat list regardless
|
||||||
// of which compose project they belong to.
|
// of which compose project they belong to.
|
||||||
if gui.DockerCommand.IsProjectScoped() {
|
if gui.DockerCommand.IsProjectScoped() {
|
||||||
// This check must be inside the InDockerComposeProject guard:
|
// This check must be inside the IsProjectScoped guard: when
|
||||||
// outside a compose project, services are still derived from
|
// not project-scoped, services are still derived from container
|
||||||
// container labels, so compose-managed containers from other
|
// labels, so compose-managed containers from other projects
|
||||||
// projects would be incorrectly hidden.
|
// would be incorrectly hidden.
|
||||||
//
|
//
|
||||||
// Note that this is O(N*M) time complexity where N is the number of services
|
// 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,
|
// and M is the number of containers. We expect N to be small but M may be large,
|
||||||
|
|
|
||||||
|
|
@ -459,7 +459,7 @@ func (gui *Gui) ShouldRefresh(key string) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) initiallyFocusedViewName() string {
|
func (gui *Gui) initiallyFocusedViewName() string {
|
||||||
if gui.DockerCommand.InDockerComposeProject {
|
if gui.DockerCommand.IsProjectScoped() {
|
||||||
return "services"
|
return "services"
|
||||||
}
|
}
|
||||||
return "containers"
|
return "containers"
|
||||||
|
|
|
||||||
|
|
@ -94,18 +94,19 @@ func (gui *Gui) refreshProject() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// getDiscoveredProjects returns all docker compose projects by examining container labels.
|
// getDiscoveredProjects returns all docker compose projects by examining container labels.
|
||||||
// The local project (from docker-compose.yml in the current directory) is included if
|
// The local project (from docker-compose.yml in the current directory, or from -p) is
|
||||||
// it has running containers or if InDockerComposeProject is true.
|
// 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 {
|
func (gui *Gui) getDiscoveredProjects() []*commands.Project {
|
||||||
containers := gui.Panels.Containers.List.GetAllItems()
|
containers := gui.Panels.Containers.List.GetAllItems()
|
||||||
projectNames := gui.DockerCommand.GetProjectNames(containers)
|
projectNames := gui.DockerCommand.GetProjectNames(containers)
|
||||||
|
|
||||||
// If we're in a docker compose project but it has no running containers,
|
// If we're scoped to a project but it has no running containers, still
|
||||||
// still include it. We don't fall back to the directory name here to avoid
|
// include it. We don't fall back to the directory name here to avoid
|
||||||
// briefly flashing the wrong project name on startup.
|
// briefly flashing the wrong project name on startup.
|
||||||
localName := gui.DockerCommand.LocalProjectName
|
localName := gui.DockerCommand.LocalProjectName
|
||||||
|
|
||||||
if gui.DockerCommand.InDockerComposeProject && localName != "" {
|
if gui.DockerCommand.IsProjectScoped() && localName != "" {
|
||||||
found := false
|
found := false
|
||||||
for _, name := range projectNames {
|
for _, name := range projectNames {
|
||||||
if name == localName {
|
if name == localName {
|
||||||
|
|
|
||||||
|
|
@ -130,7 +130,7 @@ func (gui *Gui) createAllViews() error {
|
||||||
|
|
||||||
gui.Views.Containers.Highlight = true
|
gui.Views.Containers.Highlight = true
|
||||||
gui.Views.Containers.SelBgColor = selectedLineBgColor
|
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
|
gui.Views.Containers.Title = gui.Tr.ContainersTitle
|
||||||
} else {
|
} else {
|
||||||
gui.Views.Containers.Title = gui.Tr.StandaloneContainersTitle
|
gui.Views.Containers.Title = gui.Tr.StandaloneContainersTitle
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue