fix: respect explicit docker compose override

This commit is contained in:
lawrence3699 2026-04-19 12:15:02 +10:00
parent 9134abeefd
commit 51a3ed50dc
No known key found for this signature in database
4 changed files with 125 additions and 0 deletions

View file

@ -158,6 +158,10 @@ func NewDockerCommand(log *logrus.Entry, osCommand *OSCommand, tr *i18n.Translat
}
func (c *DockerCommand) setDockerComposeCommand(config *config.AppConfig) {
if config.UserConfig.CommandTemplates.DockerComposeSetByUser {
return
}
if config.UserConfig.CommandTemplates.DockerCompose != "docker compose" {
return
}

View file

@ -1,10 +1,14 @@
package commands
import (
"fmt"
"os"
"os/exec"
"path/filepath"
"testing"
"github.com/docker/docker/client"
"github.com/jesseduffield/lazydocker/pkg/config"
"github.com/stretchr/testify/assert"
)
@ -61,3 +65,78 @@ func TestNewDockerClientVersionNegotiation(t *testing.T) {
"client version should not be locked to DOCKER_API_VERSION env var")
})
}
func TestSetDockerComposeCommandRespectsExplicitUserOverride(t *testing.T) {
configDir := t.TempDir()
configPath := filepath.Join(configDir, "config.yml")
content := []byte("commandTemplates:\n dockerCompose: docker compose\n")
if err := os.WriteFile(configPath, content, 0o600); err != nil {
t.Fatalf("Unexpected error: %s", err)
}
originalConfigDir := os.Getenv("CONFIG_DIR")
defer func() {
if originalConfigDir == "" {
os.Unsetenv("CONFIG_DIR")
} else {
os.Setenv("CONFIG_DIR", originalConfigDir)
}
}()
os.Setenv("CONFIG_DIR", configDir)
appConfig, err := config.NewAppConfig("lazydocker", "version", "commit", "date", "buildSource", false, nil, "projectDir", "")
if err != nil {
t.Fatalf("Unexpected error: %s", err)
}
osCommand := NewOSCommand(NewDummyLog(), appConfig)
osCommand.SetCommand(newHelperCommand(true))
dockerCommand := &DockerCommand{
OSCommand: osCommand,
Config: appConfig,
}
dockerCommand.setDockerComposeCommand(appConfig)
assert.Equal(t, "docker compose", appConfig.UserConfig.CommandTemplates.DockerCompose)
}
func TestSetDockerComposeCommandFallsBackWhenUnconfigured(t *testing.T) {
userConfig := config.GetDefaultConfig()
appConfig := &config.AppConfig{UserConfig: &userConfig}
osCommand := NewOSCommand(NewDummyLog(), appConfig)
osCommand.SetCommand(newHelperCommand(true))
dockerCommand := &DockerCommand{
OSCommand: osCommand,
Config: appConfig,
}
dockerCommand.setDockerComposeCommand(appConfig)
assert.Equal(t, "docker-compose", appConfig.UserConfig.CommandTemplates.DockerCompose)
}
func TestDockerCommandHelperProcess(t *testing.T) {
if len(os.Args) < 4 || os.Args[2] != "--" || os.Args[3] != "docker-helper" {
return
}
if len(os.Args) > 4 && os.Args[4] == "fail" {
fmt.Fprint(os.Stderr, "simulated failure")
os.Exit(1)
}
os.Exit(0)
}
func newHelperCommand(shouldFail bool) func(string, ...string) *exec.Cmd {
return func(name string, arg ...string) *exec.Cmd {
args := []string{"-test.run=TestDockerCommandHelperProcess", "--", "docker-helper"}
if shouldFail {
args = append(args, "fail")
}
return exec.Command(os.Args[0], args...)
}
}

View file

@ -174,6 +174,9 @@ type CommandTemplatesConfig struct {
// of whatever you've set in this value rather than you having to copy and
// paste it to all the other commands
DockerCompose string `yaml:"dockerCompose,omitempty"`
// DockerComposeSetByUser tracks whether dockerCompose was explicitly present
// in the user's config file so command auto-detection does not overwrite it.
DockerComposeSetByUser bool `yaml:"-"`
// StopService is the command for stopping a service
StopService string `yaml:"stopService,omitempty"`
@ -579,10 +582,25 @@ func loadUserConfig(configDir string, base *UserConfig) (*UserConfig, error) {
return nil, err
}
type commandTemplatePresence struct {
DockerCompose *string `yaml:"dockerCompose,omitempty"`
}
type userConfigPresence struct {
CommandTemplates commandTemplatePresence `yaml:"commandTemplates,omitempty"`
}
presence := userConfigPresence{}
if err := yaml.Unmarshal(content, &presence); err != nil {
return nil, err
}
if err := yaml.Unmarshal(content, base); err != nil {
return nil, err
}
base.CommandTemplates.DockerComposeSetByUser = presence.CommandTemplates.DockerCompose != nil
return base, nil
}

View file

@ -2,6 +2,7 @@ package config
import (
"os"
"path/filepath"
"testing"
"github.com/jesseduffield/yaml"
@ -96,3 +97,26 @@ func TestWritingToConfigFile(t *testing.T) {
// modifying an existing file that already has 'ConfirmOnQuit'
testFn(t, conf, false)
}
func TestLoadUserConfigMarksExplicitDockerComposeOverride(t *testing.T) {
configDir := t.TempDir()
configPath := filepath.Join(configDir, "config.yml")
content := []byte("commandTemplates:\n dockerCompose: docker compose\n")
if err := os.WriteFile(configPath, content, 0o600); err != nil {
t.Fatalf("Unexpected error: %s", err)
}
conf, err := loadUserConfigWithDefaults(configDir)
if err != nil {
t.Fatalf("Unexpected error: %s", err)
}
if conf.CommandTemplates.DockerCompose != "docker compose" {
t.Fatalf("Expected docker compose but got %s", conf.CommandTemplates.DockerCompose)
}
if !conf.CommandTemplates.DockerComposeSetByUser {
t.Fatal("Expected dockerCompose override to be marked as user-set")
}
}