This commit is contained in:
Saravanabalagi Ramachandran 2026-01-26 13:56:11 -08:00 committed by GitHub
commit 167e754544
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
18 changed files with 1045 additions and 187 deletions

View file

@ -39,6 +39,7 @@ type DockerCommand struct {
Config *config.AppConfig
Client *client.Client
InDockerComposeProject bool
HasProfiles bool
ErrorChan chan error
ContainerMutex deadlock.Mutex
ServiceMutex deadlock.Mutex
@ -56,6 +57,7 @@ type LimitedDockerCommand interface {
// CommandObject is what we pass to our template resolvers when we are running a custom command. We do not guarantee that all fields will be populated: just the ones that make sense for the current context
type CommandObject struct {
DockerCompose string
Profile string
Service *Service
Container *Container
Image *Image
@ -123,7 +125,8 @@ func NewDockerCommand(log *logrus.Entry, osCommand *OSCommand, tr *i18n.Translat
Config: config,
Client: cli,
ErrorChan: errorChan,
InDockerComposeProject: true,
InDockerComposeProject: false,
HasProfiles: false,
Closers: []io.Closer{tunnelCloser},
}
@ -135,8 +138,20 @@ func NewDockerCommand(log *logrus.Entry, osCommand *OSCommand, tr *i18n.Translat
dockerCommand.NewCommandObject(CommandObject{}),
),
)
if err != nil {
dockerCommand.InDockerComposeProject = false
if err == nil {
dockerCommand.InDockerComposeProject = true
err = osCommand.RunCommand(
utils.ApplyTemplate(
config.UserConfig.CommandTemplates.CheckDockerComposeProfiles,
dockerCommand.NewCommandObject(CommandObject{}),
),
)
if err == nil {
dockerCommand.HasProfiles = true
} else {
log.Warn("No profiles found in docker-compose project")
}
} else {
log.Warn(err.Error())
}
@ -231,6 +246,22 @@ L:
}
}
// GetProfiles gets the profiles defined in the compose file
func (c *DockerCommand) GetProfiles() ([]string, error) {
if !c.InDockerComposeProject {
return nil, nil
}
composeCommand := c.Config.UserConfig.CommandTemplates.DockerCompose
output, err := c.OSCommand.RunCommandWithOutput(fmt.Sprintf("%s config --profiles", composeCommand))
if err != nil {
return nil, err
}
profiles := utils.SplitLines(output)
return profiles, nil
}
// GetContainers gets the docker containers
func (c *DockerCommand) GetContainers(existingContainers []*Container) ([]*Container, error) {
c.ContainerMutex.Lock()
@ -297,7 +328,7 @@ func (c *DockerCommand) GetServices() ([]*Service, error) {
}
composeCommand := c.Config.UserConfig.CommandTemplates.DockerCompose
output, err := c.OSCommand.RunCommandWithOutput(fmt.Sprintf("%s config --services", composeCommand))
output, err := c.OSCommand.RunCommandWithOutput(fmt.Sprintf("%s --profile=* config --services", composeCommand))
if err != nil {
return nil, err
}
@ -378,6 +409,19 @@ func (c *DockerCommand) DockerComposeConfig() string {
return output
}
func (c *DockerCommand) DockerComposeProfileConfig(profile string) string {
output, err := c.OSCommand.RunCommandWithOutput(
utils.ApplyTemplate(
c.OSCommand.Config.UserConfig.CommandTemplates.DockerComposeProfileConfig,
c.NewCommandObject(CommandObject{Profile: profile}),
),
)
if err != nil {
output = err.Error()
}
return output
}
// determineDockerHost tries to the determine the docker host that we should connect to
// in the following order of decreasing precedence:
// - value of "DOCKER_HOST" environment variable

View file

@ -1,5 +1,64 @@
package commands
import (
"github.com/jesseduffield/lazydocker/pkg/config"
"github.com/jesseduffield/lazydocker/pkg/utils"
)
type Project struct {
Name string
Name string
IsProfile bool
OSCommand *OSCommand
Config *config.AppConfig
DockerCommand LimitedDockerCommand
}
// Up ups the project
func (p *Project) Up() error {
commandTemplates := p.Config.UserConfig.CommandTemplates
templateCmdStr := commandTemplates.Up
if p.IsProfile {
templateCmdStr = commandTemplates.UpProfile
}
return p.runCommand(templateCmdStr)
}
// Down downs the project
func (p *Project) Down() error {
defer func() {
if r := recover(); r != nil {
p.OSCommand.Log.Error(r)
}
}()
commandTemplates := p.Config.UserConfig.CommandTemplates
templateCmdStr := commandTemplates.Down
if p.IsProfile {
templateCmdStr = commandTemplates.DownProfile
}
return p.runCommand(templateCmdStr)
}
// Restart restarts the project
func (p *Project) Restart() error {
commandTemplates := p.Config.UserConfig.CommandTemplates
templateCmdStr := commandTemplates.Restart
if p.IsProfile {
templateCmdStr = commandTemplates.RestartProfile
}
return p.runCommand(templateCmdStr)
}
// Run custom command on the project
func (p *Project) runCommand(templateCmdStr string) error {
cmdObj := CommandObject{}
if p.IsProfile {
cmdObj.Profile = p.Name
}
command := utils.ApplyTemplate(
templateCmdStr,
p.DockerCommand.NewCommandObject(cmdObj),
)
// log command
return p.OSCommand.RunCommand(command)
}

View file

@ -166,6 +166,9 @@ type CommandTemplatesConfig struct {
// downs and removes volumes
DownWithVolumes string `yaml:"downWithVolumes,omitempty"`
// Restarts everything
Restart string `yaml:"restart,omitempty"`
// DockerCompose is for your docker-compose command. You may want to combine a
// few different docker-compose.yml files together, in which case you can set
// this to "docker compose -f foo/docker-compose.yml -f
@ -202,7 +205,8 @@ type CommandTemplatesConfig struct {
// AllLogs is for showing what you get from doing `docker compose logs`. It
// combines all the logs together
AllLogs string `yaml:"allLogs,omitempty"`
AllLogs string `yaml:"allLogs,omitempty"`
AllLogsProfile string `yaml:"allLogsProfile,omitempty"`
// ViewAllLogs is the command we use when you want to see all logs in a subprocess with no filtering
ViewAllLogs string `yaml:"viewAlLogs,omitempty"`
@ -210,7 +214,8 @@ type CommandTemplatesConfig struct {
// DockerComposeConfig is the command for viewing the config of your docker
// compose. It basically prints out the yaml from your docker-compose.yml
// file(s)
DockerComposeConfig string `yaml:"dockerComposeConfig,omitempty"`
DockerComposeConfig string `yaml:"dockerComposeConfig,omitempty"`
DockerComposeProfileConfig string `yaml:"dockerComposeProfileConfig,omitempty"`
// CheckDockerComposeConfig is what we use to check whether we are in a
// docker-compose context. If the command returns an error then we clearly
@ -218,8 +223,22 @@ type CommandTemplatesConfig struct {
// and only show containers
CheckDockerComposeConfig string `yaml:"checkDockerComposeConfig,omitempty"`
// CheckDockerComposeProfiles is what we use to check whether we are in a
// docker-compose context with profiles.
CheckDockerComposeProfiles string `yaml:"checkDockerComposeProfiles,omitempty"`
// ServiceTop is the command for viewing the processes under a given service
ServiceTop string `yaml:"serviceTop,omitempty"`
// UpProfile is the command for starting a project
UpProfile string `yaml:"upProfile,omitempty"`
// DownProfile is the command for stopping a project with a given profile
DownProfile string `yaml:"downProfile,omitempty"`
DownProfileWithVolumes string `yaml:"downProfileWithVolumes,omitempty"`
// RestartProfile is the command for restarting a project with a given profile
RestartProfile string `yaml:"restartProfile,omitempty"`
}
// OSConfig contains config on the level of the os
@ -385,23 +404,31 @@ func GetDefaultConfig() UserConfig {
Tail: "",
},
CommandTemplates: CommandTemplatesConfig{
DockerCompose: "docker compose",
RestartService: "{{ .DockerCompose }} restart {{ .Service.Name }}",
StartService: "{{ .DockerCompose }} start {{ .Service.Name }}",
Up: "{{ .DockerCompose }} up -d",
Down: "{{ .DockerCompose }} down",
DownWithVolumes: "{{ .DockerCompose }} down --volumes",
UpService: "{{ .DockerCompose }} up -d {{ .Service.Name }}",
RebuildService: "{{ .DockerCompose }} up -d --build {{ .Service.Name }}",
RecreateService: "{{ .DockerCompose }} up -d --force-recreate {{ .Service.Name }}",
StopService: "{{ .DockerCompose }} stop {{ .Service.Name }}",
ServiceLogs: "{{ .DockerCompose }} logs --since=60m --follow {{ .Service.Name }}",
ViewServiceLogs: "{{ .DockerCompose }} logs --follow {{ .Service.Name }}",
AllLogs: "{{ .DockerCompose }} logs --tail=300 --follow",
ViewAllLogs: "{{ .DockerCompose }} logs",
DockerComposeConfig: "{{ .DockerCompose }} config",
CheckDockerComposeConfig: "{{ .DockerCompose }} config --quiet",
ServiceTop: "{{ .DockerCompose }} top {{ .Service.Name }}",
DockerCompose: "docker compose",
RestartService: "{{ .DockerCompose }} restart {{ .Service.Name }}",
StartService: "{{ .DockerCompose }} start {{ .Service.Name }}",
Up: "{{ .DockerCompose }} up -d",
Down: "{{ .DockerCompose }} down",
DownWithVolumes: "{{ .DockerCompose }} down --volumes",
UpService: "{{ .DockerCompose }} up -d {{ .Service.Name }}",
UpProfile: "{{ .DockerCompose }} --profile {{ .Profile }} up -d",
DownProfile: "{{ .DockerCompose }} --profile {{ .Profile }} down",
DownProfileWithVolumes: "{{ .DockerCompose }} --profile {{ .Profile }} down --volumes",
Restart: "{{ .DockerCompose }} restart",
RestartProfile: "{{ .DockerCompose }} --profile {{ .Profile }} restart",
RebuildService: "{{ .DockerCompose }} up -d --build {{ .Service.Name }}",
RecreateService: "{{ .DockerCompose }} up -d --force-recreate {{ .Service.Name }}",
StopService: "{{ .DockerCompose }} stop {{ .Service.Name }}",
ServiceLogs: "{{ .DockerCompose }} logs --since=60m --follow {{ .Service.Name }}",
ViewServiceLogs: "{{ .DockerCompose }} logs --follow {{ .Service.Name }}",
AllLogs: "{{ .DockerCompose }} logs --tail=300 --follow",
AllLogsProfile: "{{ .DockerCompose }} --profile {{ .Profile }} logs --tail=300 --follow",
ViewAllLogs: "{{ .DockerCompose }} logs",
DockerComposeConfig: "{{ .DockerCompose }} config",
DockerComposeProfileConfig: "{{ .DockerCompose }} --profile {{ .Profile }} config",
CheckDockerComposeConfig: "{{ .DockerCompose }} config --quiet",
CheckDockerComposeProfiles: "{{ .DockerCompose }} config --profiles --quiet | grep -q '[^[:space:]]'; echo $?",
ServiceTop: "{{ .DockerCompose }} top {{ .Service.Name }}",
},
CustomCommands: CustomCommands{
Containers: []CustomCommand{},

View file

@ -149,6 +149,55 @@ func (gui *Gui) GetInitialKeybindings() []*Binding {
Handler: gui.handleViewAllLogs,
Description: gui.Tr.ViewLogs,
},
{
ViewName: "project",
Key: 'U',
Modifier: gocui.ModNone,
Handler: gui.handleProjectUpMenu,
Description: gui.Tr.UpProject,
},
{
ViewName: "project",
Key: 'D',
Modifier: gocui.ModNone,
Handler: gui.handleProjectDownMenu,
Description: gui.Tr.DownProject,
},
{
ViewName: "project",
Key: 'R',
Modifier: gocui.ModNone,
Handler: gui.handleProjectRestartMenu,
Description: gui.Tr.RestartProject,
},
{
ViewName: "project",
Key: 'u',
Modifier: gocui.ModNone,
Handler: gui.handleProjectUp,
Description: gui.Tr.UpProfile,
},
{
ViewName: "project",
Key: 'd',
Modifier: gocui.ModNone,
Handler: gui.handleProjectDown,
Description: gui.Tr.DownProfile,
},
{
ViewName: "project",
Key: 'r',
Modifier: gocui.ModNone,
Handler: gui.handleProjectRestart,
Description: gui.Tr.RestartProfile,
},
// {
// ViewName: "project",
// Key: 'b',
// Modifier: gocui.ModNone,
// Handler: gui.handleServicesBulkCommand,
// Description: gui.Tr.ViewBulkCommands,
// },
{
ViewName: "menu",
Key: gocui.KeyEsc,
@ -322,14 +371,14 @@ func (gui *Gui) GetInitialKeybindings() []*Binding {
ViewName: "services",
Key: 'U',
Modifier: gocui.ModNone,
Handler: gui.handleProjectUp,
Handler: gui.handleProjectUpMenu,
Description: gui.Tr.UpProject,
},
{
ViewName: "services",
Key: 'D',
Modifier: gocui.ModNone,
Handler: gui.handleProjectDown,
Handler: gui.handleProjectDownMenu,
Description: gui.Tr.DownProject,
},
{

View file

@ -1,7 +1,23 @@
package presentation
import "github.com/jesseduffield/lazydocker/pkg/commands"
import (
"github.com/fatih/color"
"github.com/jesseduffield/lazydocker/pkg/commands"
"github.com/jesseduffield/lazydocker/pkg/utils"
)
func GetProjectDisplayStrings(project *commands.Project) []string {
return []string{project.Name}
if project.IsProfile {
// show "profile" word in aqua
return []string{
utils.ColoredString("profile", color.FgCyan),
"",
project.Name,
}
}
return []string{
"project",
"",
project.Name,
}
}

View file

@ -3,6 +3,7 @@ package gui
import (
"bytes"
"context"
"os/exec"
"path"
"strings"
@ -11,9 +12,11 @@ import (
"github.com/jesseduffield/lazydocker/pkg/commands"
"github.com/jesseduffield/lazydocker/pkg/gui/panels"
"github.com/jesseduffield/lazydocker/pkg/gui/presentation"
"github.com/jesseduffield/lazydocker/pkg/gui/types"
"github.com/jesseduffield/lazydocker/pkg/tasks"
"github.com/jesseduffield/lazydocker/pkg/utils"
"github.com/jesseduffield/yaml"
"github.com/samber/lo"
)
// Although at the moment we'll only have one project, in future we could have
@ -23,33 +26,31 @@ func (gui *Gui) getProjectPanel() *panels.SideListPanel[*commands.Project] {
return &panels.SideListPanel[*commands.Project]{
ContextState: &panels.ContextState[*commands.Project]{
GetMainTabs: func() []panels.MainTab[*commands.Project] {
if gui.DockerCommand.InDockerComposeProject {
return []panels.MainTab[*commands.Project]{
{
Key: "logs",
Title: gui.Tr.LogsTitle,
Render: gui.renderAllLogs,
},
{
Key: "config",
Title: gui.Tr.DockerComposeConfigTitle,
Render: gui.renderDockerComposeConfig,
},
{
Key: "credits",
Title: gui.Tr.CreditsTitle,
Render: gui.renderCredits,
},
}
}
return []panels.MainTab[*commands.Project]{
tabsList := []panels.MainTab[*commands.Project]{
{
Key: "credits",
Title: gui.Tr.CreditsTitle,
Render: gui.renderCredits,
},
}
if gui.DockerCommand.InDockerComposeProject {
tabsListCompose := []panels.MainTab[*commands.Project]{
{
Key: "logs",
Title: gui.Tr.LogsTitle,
Render: gui.renderLogs,
},
{
Key: "config",
Title: gui.Tr.DockerComposeConfigTitle,
Render: gui.renderDockerComposeConfig,
},
}
tabsList = append(tabsListCompose, tabsList...)
}
return tabsList
},
GetItemContextCacheKey: func(project *commands.Project) string {
return "projects-" + project.Name
@ -67,13 +68,36 @@ func (gui *Gui) getProjectPanel() *panels.SideListPanel[*commands.Project] {
return false
},
GetTableCells: presentation.GetProjectDisplayStrings,
// It doesn't make sense to filter a list of only one item.
DisableFilter: true,
}
}
func (gui *Gui) refreshProject() error {
gui.Panels.Projects.SetItems([]*commands.Project{{Name: gui.getProjectName()}})
projectName := gui.getProjectName()
profiles, err := gui.DockerCommand.GetProfiles()
if err != nil {
return err
}
gui.DockerCommand.HasProfiles = len(profiles) > 0
items := []*commands.Project{{
Name: projectName,
IsProfile: false,
Config: gui.Config,
OSCommand: gui.OSCommand,
DockerCommand: gui.DockerCommand,
}}
for _, profile := range profiles {
items = append(items, &commands.Project{
Name: profile,
IsProfile: true,
Config: gui.Config,
OSCommand: gui.OSCommand,
DockerCommand: gui.DockerCommand,
})
}
gui.Panels.Projects.SetItems(items)
return gui.Panels.Projects.RerenderList()
}
@ -112,19 +136,29 @@ func (gui *Gui) creditsStr() string {
}, "\n\n")
}
func (gui *Gui) renderAllLogs(_project *commands.Project) tasks.TaskFunc {
func (gui *Gui) renderLogs(_project *commands.Project) tasks.TaskFunc {
return gui.NewTask(TaskOpts{
Autoscroll: true,
Wrap: gui.Config.UserConfig.Gui.WrapMainPanel,
Func: func(ctx context.Context) {
gui.clearMainView()
cmd := gui.OSCommand.RunCustomCommand(
utils.ApplyTemplate(
gui.Config.UserConfig.CommandTemplates.AllLogs,
gui.DockerCommand.NewCommandObject(commands.CommandObject{}),
),
)
var cmd *exec.Cmd
if _project.IsProfile {
cmd = gui.OSCommand.RunCustomCommand(
utils.ApplyTemplate(
gui.Config.UserConfig.CommandTemplates.AllLogsProfile,
gui.DockerCommand.NewCommandObject(commands.CommandObject{Profile: _project.Name}),
),
)
} else {
cmd = gui.OSCommand.RunCustomCommand(
utils.ApplyTemplate(
gui.Config.UserConfig.CommandTemplates.AllLogs,
gui.DockerCommand.NewCommandObject(commands.CommandObject{}),
),
)
}
cmd.Stdout = gui.Views.Main
cmd.Stderr = gui.Views.Main
@ -145,6 +179,11 @@ func (gui *Gui) renderAllLogs(_project *commands.Project) tasks.TaskFunc {
}
func (gui *Gui) renderDockerComposeConfig(_project *commands.Project) tasks.TaskFunc {
if _project.IsProfile {
return gui.NewSimpleRenderStringTask(func() string {
return utils.ColoredYamlString(gui.DockerCommand.DockerComposeProfileConfig(_project.Name))
})
}
return gui.NewSimpleRenderStringTask(func() string {
return utils.ColoredYamlString(gui.DockerCommand.DockerComposeConfig())
})
@ -180,3 +219,312 @@ func (gui *Gui) handleViewAllLogs(g *gocui.Gui, v *gocui.View) error {
return gui.runSubprocess(c)
}
func (gui *Gui) handleProjectUpMenu(g *gocui.Gui, v *gocui.View) error {
upCommand := utils.ApplyTemplate(
gui.Config.UserConfig.CommandTemplates.Up,
gui.DockerCommand.NewCommandObject(commands.CommandObject{}),
)
options := []*commandOption{
{
description: gui.Tr.UpProject,
command: upCommand,
onPress: func() error {
return gui.WithWaitingStatus(gui.Tr.UppingProjectStatus, func() error {
if err := gui.OSCommand.RunCommand(upCommand); err != nil {
return gui.createErrorPanel(err.Error())
}
return nil
})
},
},
}
if gui.DockerCommand.HasProfiles {
upAllProfilesCommand := utils.ApplyTemplate(
gui.Config.UserConfig.CommandTemplates.UpProfile,
gui.DockerCommand.NewCommandObject(commands.CommandObject{Profile: "*"}),
)
options = append(options, &commandOption{
description: gui.Tr.UpAllProfiles,
command: upAllProfilesCommand,
onPress: func() error {
return gui.WithWaitingStatus(gui.Tr.UppingProjectStatus, func() error {
if err := gui.OSCommand.RunCommand(upAllProfilesCommand); err != nil {
return gui.createErrorPanel(err.Error())
}
return nil
})
},
})
profile, err := gui.Panels.Projects.GetSelectedItem()
if err == nil && profile.IsProfile {
upProfileCommand := utils.ApplyTemplate(
gui.Config.UserConfig.CommandTemplates.UpProfile,
gui.DockerCommand.NewCommandObject(commands.CommandObject{Profile: profile.Name}),
)
options = append(options, &commandOption{
description: gui.Tr.UpProfile,
command: upProfileCommand,
onPress: func() error {
return gui.WithWaitingStatus(gui.Tr.UppingProjectStatus, func() error {
if err := gui.OSCommand.RunCommand(upProfileCommand); err != nil {
return gui.createErrorPanel(err.Error())
}
return nil
})
},
})
}
}
menuItems := lo.Map(options, func(option *commandOption, _ int) *types.MenuItem {
return &types.MenuItem{
LabelColumns: option.getDisplayStrings(),
OnPress: option.onPress,
}
})
return gui.Menu(CreateMenuOptions{
Title: "",
Items: menuItems,
})
}
func (gui *Gui) handleProjectDownMenu(g *gocui.Gui, v *gocui.View) error {
downCommand := utils.ApplyTemplate(
gui.Config.UserConfig.CommandTemplates.Down,
gui.DockerCommand.NewCommandObject(commands.CommandObject{}),
)
downWithVolumesCommand := utils.ApplyTemplate(
gui.Config.UserConfig.CommandTemplates.DownWithVolumes,
gui.DockerCommand.NewCommandObject(commands.CommandObject{}),
)
options := []*commandOption{
{
description: gui.Tr.Down,
command: downCommand,
onPress: func() error {
return gui.WithWaitingStatus(gui.Tr.DowningStatus, func() error {
if err := gui.OSCommand.RunCommand(downCommand); err != nil {
return gui.createErrorPanel(err.Error())
}
return nil
})
},
},
{
description: gui.Tr.DownWithVolumes,
command: downWithVolumesCommand,
onPress: func() error {
return gui.WithWaitingStatus(gui.Tr.DowningStatus, func() error {
if err := gui.OSCommand.RunCommand(downWithVolumesCommand); err != nil {
return gui.createErrorPanel(err.Error())
}
return nil
})
},
},
}
if gui.DockerCommand.HasProfiles {
downProfileCommand := utils.ApplyTemplate(
gui.Config.UserConfig.CommandTemplates.DownProfile,
gui.DockerCommand.NewCommandObject(commands.CommandObject{Profile: "*"}),
)
downProfileWithVolumesCommand := utils.ApplyTemplate(
gui.Config.UserConfig.CommandTemplates.DownProfileWithVolumes,
gui.DockerCommand.NewCommandObject(commands.CommandObject{Profile: "*"}),
)
options = append(options, &commandOption{
description: gui.Tr.DownAllProfiles,
command: downProfileCommand,
onPress: func() error {
return gui.WithWaitingStatus(gui.Tr.DowningStatus, func() error {
if err := gui.OSCommand.RunCommand(downProfileCommand); err != nil {
return gui.createErrorPanel(err.Error())
}
return nil
})
},
}, &commandOption{
description: gui.Tr.DownAllProfilesWithVolumes,
command: downProfileWithVolumesCommand,
onPress: func() error {
return gui.WithWaitingStatus(gui.Tr.DowningStatus, func() error {
if err := gui.OSCommand.RunCommand(downProfileWithVolumesCommand); err != nil {
return gui.createErrorPanel(err.Error())
}
return nil
})
},
})
profile, err := gui.Panels.Projects.GetSelectedItem()
if err == nil && profile.IsProfile {
downProfileCommand := utils.ApplyTemplate(
gui.Config.UserConfig.CommandTemplates.DownProfile,
gui.DockerCommand.NewCommandObject(commands.CommandObject{Profile: profile.Name}),
)
downProfileWithVolumesCommand := utils.ApplyTemplate(
gui.Config.UserConfig.CommandTemplates.DownProfileWithVolumes,
gui.DockerCommand.NewCommandObject(commands.CommandObject{Profile: profile.Name}),
)
options = append(options, &commandOption{
description: gui.Tr.DownProfile,
command: downProfileCommand,
onPress: func() error {
return gui.WithWaitingStatus(gui.Tr.DowningStatus, func() error {
if err := gui.OSCommand.RunCommand(downProfileCommand); err != nil {
return gui.createErrorPanel(err.Error())
}
return nil
})
},
}, &commandOption{
description: gui.Tr.DownProfileWithVolumes,
command: downProfileWithVolumesCommand,
onPress: func() error {
return gui.WithWaitingStatus(gui.Tr.DowningStatus, func() error {
if err := gui.OSCommand.RunCommand(downProfileWithVolumesCommand); err != nil {
return gui.createErrorPanel(err.Error())
}
return nil
})
},
})
}
}
menuItems := lo.Map(options, func(option *commandOption, _ int) *types.MenuItem {
return &types.MenuItem{
LabelColumns: option.getDisplayStrings(),
OnPress: option.onPress,
}
})
return gui.Menu(CreateMenuOptions{
Title: "",
Items: menuItems,
})
}
func (gui *Gui) handleProjectRestartMenu(g *gocui.Gui, v *gocui.View) error {
restartCommand := utils.ApplyTemplate(
gui.Config.UserConfig.CommandTemplates.Restart,
gui.DockerCommand.NewCommandObject(commands.CommandObject{}),
)
options := []*commandOption{
{
description: gui.Tr.Restart,
command: restartCommand,
onPress: func() error {
return gui.WithWaitingStatus(gui.Tr.RestartingStatus, func() error {
if err := gui.OSCommand.RunCommand(restartCommand); err != nil {
return gui.createErrorPanel(err.Error())
}
return nil
})
},
},
}
if gui.DockerCommand.HasProfiles {
restartProfileCommand := utils.ApplyTemplate(
gui.Config.UserConfig.CommandTemplates.RestartProfile,
gui.DockerCommand.NewCommandObject(commands.CommandObject{Profile: "*"}),
)
options = append(options, &commandOption{
description: gui.Tr.Restart,
command: restartProfileCommand,
onPress: func() error {
return gui.WithWaitingStatus(gui.Tr.RestartingStatus, func() error {
if err := gui.OSCommand.RunCommand(restartProfileCommand); err != nil {
return gui.createErrorPanel(err.Error())
}
return nil
})
},
})
profile, err := gui.Panels.Projects.GetSelectedItem()
if err == nil && profile.IsProfile {
restartProfileCommand := utils.ApplyTemplate(
gui.Config.UserConfig.CommandTemplates.RestartProfile,
gui.DockerCommand.NewCommandObject(commands.CommandObject{Profile: profile.Name}),
)
options = append(options, &commandOption{
description: gui.Tr.Restart,
command: restartProfileCommand,
onPress: func() error {
return gui.WithWaitingStatus(gui.Tr.RestartingStatus, func() error {
if err := gui.OSCommand.RunCommand(restartProfileCommand); err != nil {
return gui.createErrorPanel(err.Error())
}
return nil
})
},
})
}
}
menuItems := lo.Map(options, func(option *commandOption, _ int) *types.MenuItem {
return &types.MenuItem{
LabelColumns: option.getDisplayStrings(),
OnPress: option.onPress,
}
})
return gui.Menu(CreateMenuOptions{
Title: "",
Items: menuItems,
})
}
func (gui *Gui) handleProjectUp(g *gocui.Gui, v *gocui.View) error {
project, err := gui.Panels.Projects.GetSelectedItem()
if err != nil {
return nil
}
return gui.WithWaitingStatus(gui.Tr.UppingProjectStatus, func() error {
if err := project.Up(); err != nil {
return gui.createErrorPanel(err.Error())
}
return nil
})
}
func (gui *Gui) handleProjectDown(g *gocui.Gui, v *gocui.View) error {
project, err := gui.Panels.Projects.GetSelectedItem()
if err != nil {
return nil
}
return gui.WithWaitingStatus(gui.Tr.DowningStatus, func() error {
if err := project.Down(); err != nil {
return gui.createErrorPanel(err.Error())
}
return nil
})
}
func (gui *Gui) handleProjectRestart(g *gocui.Gui, v *gocui.View) error {
project, err := gui.Panels.Projects.GetSelectedItem()
if err != nil {
return nil
}
return gui.WithWaitingStatus(gui.Tr.RestartingStatus, func() error {
if err := project.Restart(); err != nil {
return gui.createErrorPanel(err.Error())
}
return nil
})
}

View file

@ -288,73 +288,6 @@ func (gui *Gui) handleServiceRenderLogsToMain(g *gocui.Gui, v *gocui.View) error
return gui.runSubprocess(c)
}
func (gui *Gui) handleProjectUp(g *gocui.Gui, v *gocui.View) error {
return gui.createConfirmationPanel(gui.Tr.Confirm, gui.Tr.ConfirmUpProject, func(g *gocui.Gui, v *gocui.View) error {
cmdStr := utils.ApplyTemplate(
gui.Config.UserConfig.CommandTemplates.Up,
gui.DockerCommand.NewCommandObject(commands.CommandObject{}),
)
return gui.WithWaitingStatus(gui.Tr.UppingProjectStatus, func() error {
if err := gui.OSCommand.RunCommand(cmdStr); err != nil {
return gui.createErrorPanel(err.Error())
}
return nil
})
}, nil)
}
func (gui *Gui) handleProjectDown(g *gocui.Gui, v *gocui.View) error {
downCommand := utils.ApplyTemplate(
gui.Config.UserConfig.CommandTemplates.Down,
gui.DockerCommand.NewCommandObject(commands.CommandObject{}),
)
downWithVolumesCommand := utils.ApplyTemplate(
gui.Config.UserConfig.CommandTemplates.DownWithVolumes,
gui.DockerCommand.NewCommandObject(commands.CommandObject{}),
)
options := []*commandOption{
{
description: gui.Tr.Down,
command: downCommand,
onPress: func() error {
return gui.WithWaitingStatus(gui.Tr.DowningStatus, func() error {
if err := gui.OSCommand.RunCommand(downCommand); err != nil {
return gui.createErrorPanel(err.Error())
}
return nil
})
},
},
{
description: gui.Tr.DownWithVolumes,
command: downWithVolumesCommand,
onPress: func() error {
return gui.WithWaitingStatus(gui.Tr.DowningStatus, func() error {
if err := gui.OSCommand.RunCommand(downWithVolumesCommand); err != nil {
return gui.createErrorPanel(err.Error())
}
return nil
})
},
},
}
menuItems := lo.Map(options, func(option *commandOption, _ int) *types.MenuItem {
return &types.MenuItem{
LabelColumns: option.getDisplayStrings(),
OnPress: option.onPress,
}
})
return gui.Menu(CreateMenuOptions{
Title: "",
Items: menuItems,
})
}
func (gui *Gui) handleServiceRestartMenu(g *gocui.Gui, v *gocui.View) error {
service, err := gui.Panels.Services.GetSelectedItem()
if err != nil {

View file

@ -118,6 +118,8 @@ func (gui *Gui) createAllViews() error {
// when you run a docker container with the -it flags (interactive mode) it adds carriage returns for some reason. This is not docker's fault, it's an os-level default.
gui.Views.Main.IgnoreCarriageReturns = true
gui.Views.Project.Highlight = true
gui.Views.Project.SelBgColor = selectedLineBgColor
gui.Views.Project.Title = gui.Tr.ProjectTitle
gui.Views.Project.TitlePrefix = "[1]"

View file

@ -56,7 +56,6 @@ func chineseSet() TranslationSet {
Recreate: "重新创建",
PreviousContext: "上一个选项卡",
NextContext: "下一个选项卡",
// Attach: "连接/附加",
ViewLogs: "查看日志",
UpProject: "创建并启动容器",
DownProject: "停止并移除容器",
@ -80,6 +79,16 @@ func chineseSet() TranslationSet {
OpenInBrowser: "在浏览器中打开(第一个端口为http)",
SortContainersByState: "按状态排序容器",
Attach: "附加",
RestartProject: "重新启动项目",
UpProfile: "启动配置文件",
DownProfile: "关闭配置文件",
DownProfileWithVolumes: "关闭包括卷的配置文件",
RestartProfile: "重新启动配置文件",
UpAllProfiles: "启动所有配置文件",
DownAllProfiles: "关闭所有配置文件",
DownAllProfilesWithVolumes: "关闭包括卷的所有配置文件",
GlobalTitle: "全局",
MainTitle: "主要",
ProjectTitle: "项目",
@ -132,5 +141,14 @@ func chineseSet() TranslationSet {
LcNextScreenMode: "下一个屏幕模式(正常/半屏/全屏)",
LcPrevScreenMode: "上一个屏幕模式",
FilterPrompt: "筛选",
DetachFromContainerShortCut: "默认情况下,按 ctrl-p 然后 ctrl-q 从容器分离",
FocusProjects: "聚焦项目面板",
FocusServices: "聚焦服务面板",
FocusContainers: "聚焦容器面板",
FocusImages: "聚焦镜像面板",
FocusVolumes: "聚焦卷面板",
FocusNetworks: "聚焦网络面板",
}
}

View file

@ -94,5 +94,61 @@ func dutchSet() TranslationSet {
StopContainer: "Weet je zeker dat je deze container wil stoppen?",
PressEnterToReturn: "Druk op enter om terug te gaan naar lazydocker (Deze popup kan uit gezet worden door in de config dit neer te zetten `gui.returnImmediately: true`)",
DetachFromContainerShortCut: "Als u wilt loskoppelen van de container, drukt u standaard op ctrl-p en vervolgens op ctrl-q",
StartingStatus: "starten",
UppingServiceStatus: "service omhoog brengen",
UppingProjectStatus: "project omhoog brengen",
DowningStatus: "neerhalen",
PausingStatus: "pauzeren",
RunningBulkCommandStatus: "Bulkopdracht uitvoeren",
WaitingForContainerInfo: "Kan niet doorgaan totdat Docker meer informatie over de container geeft. Probeer het over een paar momenten opnieuw.",
CannotKillChildError: "Drie seconden gewacht tot het kinderproces stopt. Er kan een weesproces zijn dat blijft draaien op uw systeem.",
LcFilter: "filter lijst",
Quit: "stoppen",
Down: "project neerhalen",
DownWithVolumes: "project neerhalen met volumes",
Start: "start",
Pause: "pauzeer",
UpService: "service omhoog brengen",
UpProject: "project omhoog brengen",
DownProject: "project neerhalen",
RestartProject: "project herstarten",
UpProfile: "profiel omhoog brengen",
DownProfile: "profiel neerhalen",
DownProfileWithVolumes: "profiel neerhalen met volumes",
RestartProfile: "profiel herstarten",
UpAllProfiles: "alle profielen omhoog brengen",
DownAllProfiles: "alle profielen neerhalen",
DownAllProfilesWithVolumes: "alle profielen neerhalen met volumes",
RemoveWithoutPruneWithForce: "verwijderen (geforceerd) zonder ongelabelde ouders te verwijderen",
RemoveWithForce: "verwijderen (geforceerd)",
StopAllContainers: "alle containers stoppen",
RemoveAllContainers: "alle containers verwijderen (geforceerd)",
ExecShell: "shell uitvoeren",
ViewBulkCommands: "bekijk bulkopdrachten",
FilterList: "filter lijst",
OpenInBrowser: "openen in browser (eerste poort is http)",
SortContainersByState: "sorteer containers op status",
ConfirmUpProject: "Weet je zeker dat je je docker-compose project omhoog wilt brengen?",
ConfirmStopContainers: "Weet je zeker dat je alle containers wilt stoppen?",
ConfirmRemoveContainers: "Weet je zeker dat je alle containers wilt verwijderen?",
BulkCommandTitle: "Bulkopdracht:",
NoServices: "Geen services",
NoContainerForService: "Geen logs om te tonen; service is niet gekoppeld aan een container",
No: "nee",
Yes: "ja",
LcNextScreenMode: "volgende schermmodus (normaal/half/volledig scherm)",
LcPrevScreenMode: "vorige schermmodus",
FilterPrompt: "filter",
FocusProjects: "focus projectenpaneel",
FocusServices: "focus dienstenpaneel",
FocusContainers: "focus containerpaneel",
FocusImages: "focus imagepaneel",
FocusVolumes: "focus volumepaneel",
FocusNetworks: "focus netwerkpaneel",
}
}

View file

@ -67,6 +67,14 @@ type TranslationSet struct {
ViewLogs string
UpProject string
DownProject string
RestartProject string
UpProfile string
DownProfile string
DownProfileWithVolumes string
RestartProfile string
UpAllProfiles string
DownAllProfiles string
DownAllProfilesWithVolumes string
ServicesTitle string
ContainersTitle string
StandaloneContainersTitle string
@ -197,6 +205,14 @@ func englishSet() TranslationSet {
ViewLogs: "view logs",
UpProject: "up project",
DownProject: "down project",
RestartProject: "restart project",
UpProfile: "up profile",
DownProfile: "down profile",
DownProfileWithVolumes: "down profile with volumes",
RestartProfile: "restart profile",
UpAllProfiles: "up all profiles",
DownAllProfiles: "down all profiles",
DownAllProfilesWithVolumes: "down all profiles with volumes",
RemoveImage: "remove image",
RemoveVolume: "remove volume",
RemoveNetwork: "remove network",

View file

@ -69,6 +69,7 @@ func frenchSet() TranslationSet {
ViewBulkCommands: "voir les commandes groupées",
OpenInBrowser: "ouvrir dans le navigateur (le premier port est http)",
SortContainersByState: "ordonner les conteneurs par état",
FilterList: "filtrer la liste",
GlobalTitle: "Global",
MainTitle: "Principal",
@ -99,6 +100,8 @@ func frenchSet() TranslationSet {
NoImages: "Aucune image",
NoVolumes: "Aucun volume",
NoNetworks: "Aucun réseau",
NoServices: "Aucun service",
NoContainerForService: "Aucun journal à afficher ; le service n'est pas associé à un conteneur",
ConfirmQuit: "Êtes-vous certain de vouloir quitter ?",
MustForceToRemoveContainer: "Vous ne pouvez pas supprimer un conteneur qui tourne sans le forcer. Voulez-vous le forcer ?",
@ -116,5 +119,37 @@ func frenchSet() TranslationSet {
No: "non",
Yes: "oui",
LcNextScreenMode: "mode d'écran suivant (normal/demi/plein écran)",
LcPrevScreenMode: "mode d'écran précédent",
FilterPrompt: "filtrer",
FocusProjects: "focus sur le panneau des projets",
FocusServices: "focus sur le panneau des services",
FocusContainers: "focus sur le panneau des conteneurs",
FocusImages: "focus sur le panneau des images",
FocusVolumes: "focus sur le panneau des volumes",
FocusNetworks: "focus sur le panneau des réseaux",
UpProject: "monter le projet",
DownProject: "descendre le projet",
RestartProject: "redémarrer le projet",
UpProfile: "monter le profil",
DownProfile: "descendre le profil",
DownProfileWithVolumes: "descendre le profil avec les volumes",
RestartProfile: "redémarrer le profil",
UpAllProfiles: "monter tous les profils",
DownAllProfiles: "descendre tous les profils",
DownAllProfilesWithVolumes: "descendre tous les profils avec les volumes",
Quit: "quitter",
ConfirmUpProject: "Êtes-vous certain de vouloir monter votre projet docker-compose ?",
LcFilter: "filtrer la liste",
UppingProjectStatus: "montée du projet",
UppingServiceStatus: "montée du service",
DowningStatus: "descente",
UpService: "monter le service",
Down: "descendre le projet",
DownWithVolumes: "descendre le projet avec les volumes",
}
}

View file

@ -5,25 +5,35 @@ func germanSet() TranslationSet {
PruningStatus: "zerstören",
RemovingStatus: "entfernen",
RestartingStatus: "neustarten",
StartingStatus: "starten",
StoppingStatus: "anhalten",
RunningCustomCommandStatus: "führt benutzerdefinierten Befehl aus",
UppingServiceStatus: "Dienst hochfahren",
UppingProjectStatus: "Projekt hochfahren",
DowningStatus: "herunterfahren",
PausingStatus: "pausieren",
RunningCustomCommandStatus: "führt benutzerdefinierten Befehl aus",
RunningBulkCommandStatus: "führt Massenbefehl aus",
NoViewMachingNewLineFocusedSwitchStatement: "No view matching newLineFocused switch statement",
ErrorOccurred: "Es ist ein Fehler aufgetreten! Bitte erstelle ein Issue hier: https://github.com/jesseduffield/lazydocker/issues",
ConnectionFailed: "Verbindung zum Docker Client fehlgeschlagen. Du musst ggf. den Docker Client neustarten.",
UnattachableContainerError: "Der Container bietet keine Unterstützung für das Anbinden. Du musst den Dienst entweder mit der '-it' Flagge benutzen oder `stdin_open: true, tty: true` in der docker-compose.yml Datei setzen.",
WaitingForContainerInfo: "Kann nicht fortfahren, bis Docker uns mehr Informationen über den Container gibt. Bitte versuche es in ein paar Momenten erneut.",
CannotAttachStoppedContainerError: "Du kannst keinen angehaltenen Container anbinden. Du musst ihn erst starten (was du tun kannst, indem du 'r' drückst), (ja, ich bin zu faul um das zu automatisieren) (aber ist schon cool, dass ich so eine Konversation durch eine Fehlermeldung mit dir führen kann)",
CannotAccessDockerSocketError: "Kann nicht auf den Socket zugreifen: unix:///var/run/docker.sock\nFühre lazydocker als root aus oder lese https://docs.docker.com/install/linux/linux-postinstall/",
CannotKillChildError: "Wartete drei Sekunden, bis der Kindprozess gestoppt wurde. Es könnte ein verwaister Prozess auf deinem System weiterlaufen.",
Donate: "Spenden",
Confirm: "Bestätigen",
Return: "zurück",
FocusMain: "fokussieren aufs Hauptpanel",
LcFilter: "Liste filtern",
Navigate: "navigieren",
Execute: "ausführen",
Close: "schließen",
Quit: "beenden",
Menu: "menü",
MenuTitle: "Menü",
Scroll: "scrollen",
@ -31,27 +41,52 @@ func germanSet() TranslationSet {
EditConfig: "bearbeite lazydocker Konfiguration",
Cancel: "abbrechen",
Remove: "entfernen",
HideStopped: "angehaltene Container ausblenden/anzeigen",
ForceRemove: "Entfernen erzwingen",
RemoveWithVolumes: "entferne mit Volumes",
RemoveService: "entferne Container",
UpService: "Dienst hochfahren",
Stop: "anhalten",
Pause: "pausieren",
Restart: "neustarten",
Down: "Projekt herunterfahren",
DownWithVolumes: "Projekt mit Volumes herunterfahren",
Start: "starten",
Rebuild: "neubauen",
Recreate: "neuerstellen",
PreviousContext: "vorheriges Tab",
NextContext: "nächstes Tab",
Attach: "anbinden",
ViewLogs: "zeige Protokolle",
UpProject: "Projekt hochfahren",
DownProject: "Projekt herunterfahren",
RestartProject: "Projekt neu starten",
UpProfile: "Profil hochfahren",
DownProfile: "Profil herunterfahren",
DownProfileWithVolumes: "Profil mit Volumes herunterfahren",
RestartProfile: "Profil neu starten",
UpAllProfiles: "alle Profile hochfahren",
DownAllProfiles: "alle Profile herunterfahren",
DownAllProfilesWithVolumes: "alle Profile mit Volumes herunterfahren",
RemoveImage: "entferne Image",
RemoveVolume: "entferne Volume",
RemoveNetwork: "entferne Netzwerk",
RemoveWithoutPrune: "entfernen, ohne die unmarkierten Eltern zu entfernen",
PruneContainers: "entferne verlassene Container",
PruneVolumes: "entferne unbenutzte Volumes",
PruneNetworks: "entferne unbenutzte Netzwerk",
PruneImages: "entferne unbenutzte Images",
ViewRestartOptions: "zeige Neustartoptionen",
RunCustomCommand: "führe vordefinierten benutzerdefinierten Befehl aus",
RemoveWithoutPruneWithForce: "entfernen (erzwungen), ohne die unmarkierten Eltern zu entfernen",
RemoveWithForce: "entfernen (erzwungen)",
PruneContainers: "entferne verlassene Container",
PruneVolumes: "entferne unbenutzte Volumes",
PruneNetworks: "entferne unbenutzte Netzwerk",
PruneImages: "entferne unbenutzte Images",
StopAllContainers: "alle Container anhalten",
RemoveAllContainers: "alle Container entfernen (erzwungen)",
ViewRestartOptions: "zeige Neustartoptionen",
ExecShell: "Shell ausführen",
RunCustomCommand: "führe vordefinierten benutzerdefinierten Befehl aus",
ViewBulkCommands: "zeige Massenbefehle",
FilterList: "Liste filtern",
OpenInBrowser: "im Browser öffnen (erster Port ist HTTP)",
SortContainersByState: "Container nach Status sortieren",
GlobalTitle: "Global",
MainTitle: "Haupt",
@ -63,6 +98,7 @@ func germanSet() TranslationSet {
VolumesTitle: "Volumes",
NetworksTitle: "Netzwerk",
CustomCommandTitle: "Benutzerdefinierter Befehl",
BulkCommandTitle: "Massenbefehl",
ErrorTitle: "Fehler",
LogsTitle: "Protokoll",
ConfigTitle: "Konfiguration",
@ -74,6 +110,7 @@ func germanSet() TranslationSet {
ContainerConfigTitle: "Container Konfiguration",
ContainerEnvTitle: "Container Env",
NothingToDisplay: "Nothing to display",
NoContainerForService: "Keine Protokolle anzuzeigen; Dienst ist keinem Container zugeordnet",
CannotDisplayEnvVariables: "Something went wrong while displaying environment variables",
NoContainers: "Keine Container",
@ -81,17 +118,35 @@ func germanSet() TranslationSet {
NoImages: "Keine Images",
NoVolumes: "Keine Volumes",
NoNetworks: "Keine Netzwerk",
NoServices: "Keine Dienste",
ConfirmQuit: "Bist du dir sicher, dass du verlassen möchtest?",
ConfirmUpProject: "Bist du dir sicher, dass du dein Docker-Compose-Projekt hochfahren möchtest?",
MustForceToRemoveContainer: "Du kannst keinen Container entfernen, der noch ausgeführt wird außer du erzwingst es. Möchtest du es erzwingen?",
NotEnoughSpace: "Nicht genug Platz um die Panel darzustellen",
ConfirmPruneImages: "Bist du dir sicher, dass du alle unbenutzten Images entfernen möchtest?",
ConfirmPruneContainers: "Bist du dir sicher, dass du alle angehaltenen Container entfernen möchtes?",
ConfirmStopContainers: "Bist du dir sicher, dass du alle Container anhalten möchtest?",
ConfirmRemoveContainers: "Bist du dir sicher, dass du alle Container entfernen möchtest?",
ConfirmPruneVolumes: "Bist du dir sicher, dass du alle unbenutzen Volumes entfernen möchtest?",
ConfirmPruneNetworks: "Bist du dir sicher, dass du alle unbenutzen Netzwerk entfernen möchtest?",
StopService: "Bist du dir sicher, dass du den Dienst dieses Containers anhalten möchtest?",
StopContainer: "Bist du dir sicher, dass du den Container anhalten möchtest?",
PressEnterToReturn: "Drücke Eingabe um zu lazydocker zurückzukehren. (Diese Nachfrage kann in Deiner Konfiguration deaktiviert werden, indem du folgenden Wert setzt: `gui.returnImmediately: true`)",
DetachFromContainerShortCut: "Um sich vom Container zu trennen, drücken Sie standardmäßig ctrl-p und dann ctrl-q",
No: "nein",
Yes: "ja",
LcNextScreenMode: "nächster Bildschirmmodus (normal/halb/vollbild)",
LcPrevScreenMode: "vorheriger Bildschirmmodus",
FilterPrompt: "filtern",
FocusProjects: "fokussiere Projektpanel",
FocusServices: "fokussiere Dienstepanel",
FocusContainers: "fokussiere Containerpanel",
FocusImages: "fokussiere Imagepanel",
FocusVolumes: "fokussiere Volumepanel",
FocusNetworks: "fokussiere Netzwerkpanel",
}
}

View file

@ -5,53 +5,88 @@ func polishSet() TranslationSet {
PruningStatus: "czyszczenie",
RemovingStatus: "usuwanie",
RestartingStatus: "restartowanie",
StartingStatus: "uruchamianie",
StoppingStatus: "zatrzymywanie",
UppingServiceStatus: "uruchamianie serwisu",
UppingProjectStatus: "uruchamianie projektu",
DowningStatus: "zatrzymywanie projektu",
PausingStatus: "pauzowanie",
RunningCustomCommandStatus: "uruchamianie własnej komendty",
RunningBulkCommandStatus: "uruchamianie polecenia zbiorczego",
NoViewMachingNewLineFocusedSwitchStatement: "Żaden widok nie odpowiada instrukcji przełączenia newLineFocused",
ErrorOccurred: "Wystąpił błąd! Proszę go zgłosić na https://github.com/jesseduffield/lazydocker/issues",
ConnectionFailed: "Błąd połączenia z Dockerem. Być może należy go zrestartować.",
UnattachableContainerError: "Kontener nie obsługuje przyczepiania (attach). Musisz albo użyć flag '-it', albo `stdin_open: true, tty: true` w pliku docker-compose.yml.",
WaitingForContainerInfo: "Nie można kontynuować, dopóki Docker nie dostarczy więcej informacji o kontenerze. Spróbuj ponownie za kilka chwil.",
CannotAttachStoppedContainerError: "Nie można przyczepić się do zatrzymanego kontenera, należy go najpierw uruchomić (co można wykonać wciskając przycisk 'r')",
CannotAccessDockerSocketError: "Nie udało się uzyskać dostępu do unix:///var/run/docker.sock\nUruchom program jako root lub przeczytaj https://docs.docker.com/install/linux/linux-postinstall/",
CannotKillChildError: "Czekano trzy sekundy na zatrzymanie procesu potomnego. Może istnieć osierocony proces, który nadal działa na Twoim systemie.",
Donate: "Dotacja",
Confirm: "Potwierdź",
Return: "powrót",
FocusMain: "skup na głównym panelu",
Navigate: "nawigowanie",
Execute: "wykonaj",
Close: "zamknij",
Menu: "menu",
MenuTitle: "Menu",
Scroll: "przewiń",
OpenConfig: "otwórz konfigurację",
EditConfig: "edytuj konfigurację",
Cancel: "anuluj",
Remove: "usuń",
ForceRemove: "usuń siłą",
RemoveWithVolumes: "usuń z wolumenami",
RemoveService: "usuń kontenery",
Stop: "zatrzymaj",
Restart: "restartuj",
Rebuild: "przebuduj",
Recreate: "odtwórz",
PreviousContext: "poprzednia zakładka",
NextContext: "następna zakładka",
Attach: "przyczep",
ViewLogs: "pokaż logi",
RemoveImage: "usuń obraz",
RemoveVolume: "usuń wolumen",
RemoveNetwork: "usuń sieci",
RemoveWithoutPrune: "usuń bez kasowania nieoznaczonych rodziców",
PruneContainers: "wyczyść kontenery",
PruneVolumes: "wyczyść nieużywane wolumeny",
PruneNetworks: "wyczyść nieużywane sieci",
PruneImages: "wyczyść nieużywane obrazy",
ViewRestartOptions: "pokaż opcje restartu",
RunCustomCommand: "wykonaj predefiniowaną własną komende",
Return: "powrót",
FocusMain: "skup na głównym panelu",
LcFilter: "filtruj listę",
Navigate: "nawigowanie",
Execute: "wykonaj",
Close: "zamknij",
Quit: "wyjdź",
Menu: "menu",
MenuTitle: "Menu",
Scroll: "przewiń",
OpenConfig: "otwórz konfigurację",
EditConfig: "edytuj konfigurację",
Cancel: "anuluj",
Remove: "usuń",
HideStopped: "ukryj/pokaż zatrzymane kontenery",
ForceRemove: "usuń siłą",
RemoveWithVolumes: "usuń z wolumenami",
RemoveService: "usuń kontenery",
UpService: "uruchom serwis",
Stop: "zatrzymaj",
Pause: "pauzuj",
Restart: "restartuj",
Down: "zatrzymaj projekt",
DownWithVolumes: "zatrzymaj projekt z wolumenami",
Start: "uruchom",
Rebuild: "przebuduj",
Recreate: "odtwórz",
PreviousContext: "poprzednia zakładka",
NextContext: "następna zakładka",
Attach: "przyczep",
ViewLogs: "pokaż logi",
UpProject: "uruchom projekt",
DownProject: "zatrzymaj projekt",
RestartProject: "zrestartuj projekt",
UpProfile: "uruchom profil",
DownProfile: "zatrzymaj profil",
DownProfileWithVolumes: "zatrzymaj profil z wolumenami",
RestartProfile: "zrestartuj profil",
UpAllProfiles: "uruchom wszystkie profile",
DownAllProfiles: "zatrzymaj wszystkie profile",
DownAllProfilesWithVolumes: "zatrzymaj wszystkie profile z wolumenami",
RemoveImage: "usuń obraz",
RemoveVolume: "usuń wolumen",
RemoveNetwork: "usuń sieci",
RemoveWithoutPrune: "usuń bez kasowania nieoznaczonych rodziców",
RemoveWithoutPruneWithForce: "usuń (wymuszone) bez kasowania nieoznaczonych rodziców",
RemoveWithForce: "usuń (wymuszone)",
PruneContainers: "wyczyść kontenery",
PruneVolumes: "wyczyść nieużywane wolumeny",
PruneNetworks: "wyczyść nieużywane sieci",
PruneImages: "wyczyść nieużywane obrazy",
StopAllContainers: "zatrzymaj wszystkie kontenery",
RemoveAllContainers: "usuń wszystkie kontenery (wymuszone)",
ViewRestartOptions: "pokaż opcje restartu",
ExecShell: "uruchom powłokę",
RunCustomCommand: "wykonaj predefiniowaną własną komende",
ViewBulkCommands: "pokaż polecenia zbiorcze",
FilterList: "filtruj listę",
OpenInBrowser: "otwórz w przeglądarce (pierwszy port to http)",
SortContainersByState: "sortuj kontenery według stanu",
GlobalTitle: "Globalne",
MainTitle: "Główne",
@ -63,6 +98,7 @@ func polishSet() TranslationSet {
VolumesTitle: "Wolumeny",
NetworksTitle: "Sieci",
CustomCommandTitle: "Własna komenda:",
BulkCommandTitle: "Polecenie zbiorcze:",
ErrorTitle: "Błąd",
LogsTitle: "Logi",
ConfigTitle: "Konfiguracja",
@ -74,6 +110,7 @@ func polishSet() TranslationSet {
ContainerConfigTitle: "Konfiguracja kontenera",
ContainerEnvTitle: "Container Env",
NothingToDisplay: "Nothing to display",
NoContainerForService: "Brak logów do pokazania; serwis nie jest powiązany z kontenerem",
CannotDisplayEnvVariables: "Something went wrong while displaying environment variables",
NoContainers: "Brak kontenerów",
@ -81,17 +118,35 @@ func polishSet() TranslationSet {
NoImages: "Brak obrazów",
NoVolumes: "Brak wolumenów",
NoNetworks: "Brak sieci",
NoServices: "Brak serwisów",
ConfirmQuit: "Na pewno chcesz wyjść?",
ConfirmUpProject: "Na pewno uruchomić projekt docker-compose?",
MustForceToRemoveContainer: "Nie możesz usunąć uruchomionego kontenera dopóki nie zrobisz tego siłą. Chcesz wykonać to z siłą?",
NotEnoughSpace: "Niedostateczna ilość miejsca do wyświetlenia paneli",
ConfirmPruneImages: "Na pewno wyczyścić wszystkie nieużywane obrazy?",
ConfirmPruneContainers: "Na pewno wyczyścić wszystkie nieuruchomione kontenery?",
ConfirmStopContainers: "Na pewno zatrzymać wszystkie kontenery?",
ConfirmRemoveContainers: "Na pewno usunąć wszystkie kontenery?",
ConfirmPruneVolumes: "Na pewno wyczyścić wszystkie nieużywane wolumeny?",
ConfirmPruneNetworks: "Na pewno wyczyścić wszystkie nieużywane sieci?",
StopService: "Na pewno zatrzymać kontenery tego serwisu?",
StopContainer: "Na pewno zatrzymać ten kontener?",
PressEnterToReturn: "Wciśnij enter aby powrócić do lazydockera (ten komunikat może być wyłączony w konfiguracji poprzez ustawienie `gui.returnImmediately: true`)",
DetachFromContainerShortCut: "Domyślnie, aby odłączyć się od kontenera, naciśnij ctrl-p, a następnie ctrl-q",
No: "nie",
Yes: "tak",
LcNextScreenMode: "następny tryb ekranu (normalny/połowa/pełny ekran)",
LcPrevScreenMode: "poprzedni tryb ekranu",
FilterPrompt: "filtruj",
FocusProjects: "skup na panelu projektów",
FocusServices: "skup na panelu serwisów",
FocusContainers: "skup na panelu kontenerów",
FocusImages: "skup na panelu obrazów",
FocusVolumes: "skup na panelu wolumenów",
FocusNetworks: "skup na panelu sieci",
}
}

View file

@ -60,6 +60,14 @@ func portugueseSet() TranslationSet {
ViewLogs: "ver logs",
UpProject: "subir projeto",
DownProject: "derrubar projeto",
RestartProject: "reiniciar projeto",
UpProfile: "subir perfil",
DownProfile: "derrubar perfil",
DownProfileWithVolumes: "derrubar perfil com volumes",
RestartProfile: "reiniciar perfil",
UpAllProfiles: "subir todos os perfis",
DownAllProfiles: "derrubar todos os perfis",
DownAllProfilesWithVolumes: "derrubar todos os perfis com volumes",
RemoveImage: "remover imagem",
RemoveVolume: "remover volume",
RemoveNetwork: "remover rede",
@ -133,5 +141,12 @@ func portugueseSet() TranslationSet {
LcNextScreenMode: "modo de tela seguinte (normal/meia/tela cheia)",
LcPrevScreenMode: "modo de tela anterior",
FilterPrompt: "filtro",
FocusProjects: "focar no painel de projetos",
FocusServices: "focar no painel de serviços",
FocusContainers: "focar no painel de contêineres",
FocusImages: "focar no painel de imagens",
FocusVolumes: "focar no painel de volumes",
FocusNetworks: "focar no painel de redes",
}
}

View file

@ -14,12 +14,15 @@ func spanishSet() TranslationSet {
RunningCustomCommandStatus: "ejecutando comando personalizado",
RunningBulkCommandStatus: "ejecutando comando masivo",
ErrorOccurred: "¡Hubo un error! Por favor crea un issue en https://github.com/jesseduffield/lazydocker/issues",
ConnectionFailed: "Falló la conexión con el docker client. Quizá necesitas reiniciar tu docker client",
UnattachableContainerError: "Container does not support attaching. You must either run the service with the '-it' flag or use `stdin_open: true, tty: true` in the docker-compose.yml file",
WaitingForContainerInfo: "No podemos proceder hasta que docker nos de más información sobre el contenedor. Inténtalo otra vez en unos segundos.",
CannotAccessDockerSocketError: "No es posible acceder al docker socket en: unix:///var/run/docker.sock\nEjecuta lazydocker como root o lee https://docs.docker.com/install/linux/linux-postinstall/",
CannotKillChildError: "Esperamos tres segundos a que el proceso hijo se detenga. Debe de haber un proceso huérfano que continua activo en tu sistema.",
NoViewMachingNewLineFocusedSwitchStatement: "No hay vista que coincida con la declaración de cambio de línea nueva enfocada",
ErrorOccurred: "¡Hubo un error! Por favor crea un issue en https://github.com/jesseduffield/lazydocker/issues",
ConnectionFailed: "Falló la conexión con el docker client. Quizá necesitas reiniciar tu docker client",
UnattachableContainerError: "Container does not support attaching. You must either run the service with the '-it' flag or use `stdin_open: true, tty: true` in the docker-compose.yml file",
WaitingForContainerInfo: "No podemos proceder hasta que docker nos de más información sobre el contenedor. Inténtalo otra vez en unos segundos.",
CannotAttachStoppedContainerError: "No puedes adjuntarte a un contenedor detenido, necesitas iniciarlo primero (lo cual puedes hacer con la tecla 'r') (sí, soy demasiado perezoso para hacerlo automáticamente por ti) (bastante genial que pueda comunicarme contigo uno a uno en forma de mensaje de error)",
CannotAccessDockerSocketError: "No es posible acceder al docker socket en: unix:///var/run/docker.sock\nEjecuta lazydocker como root o lee https://docs.docker.com/install/linux/linux-postinstall/",
CannotKillChildError: "Esperamos tres segundos a que el proceso hijo se detenga. Debe de haber un proceso huérfano que continua activo en tu sistema.",
Donate: "Donar",
Confirm: "Confirmar",
@ -33,6 +36,7 @@ func spanishSet() TranslationSet {
Quit: "salir",
Menu: "menú",
MenuTitle: "Menú",
Scroll: "desplazar",
OpenConfig: "abrir configuración de lazydocker",
EditConfig: "editar configuración de lazydocker",
Cancel: "cancelar",
@ -52,9 +56,18 @@ func spanishSet() TranslationSet {
Recreate: "recrear",
PreviousContext: "anterior pestaña",
NextContext: "siguiente pestaña",
Attach: "adjuntar",
ViewLogs: "ver logs",
UpProject: "levantar proyecto",
DownProject: "dar de baja el proyecto",
RestartProject: "reiniciar proyecto",
UpProfile: "levantar perfil",
DownProfile: "bajar perfil",
DownProfileWithVolumes: "bajar perfil con volúmenes",
RestartProfile: "reiniciar perfil",
UpAllProfiles: "levantar todos los perfiles",
DownAllProfiles: "bajar todos los perfiles",
DownAllProfilesWithVolumes: "bajar todos los perfiles con volúmenes",
RemoveImage: "limpiar imagen",
RemoveVolume: "limpiar volúmen",
RemoveNetwork: "limpiar red",
@ -107,23 +120,33 @@ func spanishSet() TranslationSet {
NoNetworks: "Sin redes",
NoServices: "Sin servicios",
ConfirmQuit: "¿Realmente quieres salir?",
ConfirmUpProject: "¿Realmente quieres levantar tu proyecto docker compose?",
MustForceToRemoveContainer: "No puedes borrar un contenedor en ejecución a menos de que lo fuerces, ¿quieres hacerlo?",
NotEnoughSpace: "No hay suficiente espacio para renderizar los paneles",
ConfirmPruneImages: "¿Realmente quieres limpiar todas tus imágenes?",
ConfirmPruneContainers: "¿Realmente quieres limpiar todos los contenedores finalizados?",
ConfirmStopContainers: "¿Realmente quieres detener todos los contenedores?",
ConfirmRemoveContainers: "¿Realmente quieres borrar todos los contenedores?",
ConfirmPruneVolumes: "¿Realmente quieres limpiar todos los vólumenes sin usar?",
ConfirmPruneNetworks: "¿Realmente quieres limpiar todas las redes sin usar?",
StopService: "¿Realmente quieres detener los contenedores de este servicio?",
StopContainer: "¿Realmente quieres detener este contenedor?",
PressEnterToReturn: "Presionar [enter] para volver a lazydocker (este mensaje puede ser desactivado en tu configuración poniendo `gui.returnImmediately: true`)",
ConfirmQuit: "¿Realmente quieres salir?",
ConfirmUpProject: "¿Realmente quieres levantar tu proyecto docker compose?",
MustForceToRemoveContainer: "No puedes borrar un contenedor en ejecución a menos de que lo fuerces, ¿quieres hacerlo?",
NotEnoughSpace: "No hay suficiente espacio para renderizar los paneles",
ConfirmPruneImages: "¿Realmente quieres limpiar todas tus imágenes?",
ConfirmPruneContainers: "¿Realmente quieres limpiar todos los contenedores finalizados?",
ConfirmStopContainers: "¿Realmente quieres detener todos los contenedores?",
ConfirmRemoveContainers: "¿Realmente quieres borrar todos los contenedores?",
ConfirmPruneVolumes: "¿Realmente quieres limpiar todos los vólumenes sin usar?",
ConfirmPruneNetworks: "¿Realmente quieres limpiar todas las redes sin usar?",
StopService: "¿Realmente quieres detener los contenedores de este servicio?",
StopContainer: "¿Realmente quieres detener este contenedor?",
PressEnterToReturn: "Presionar [enter] para volver a lazydocker (este mensaje puede ser desactivado en tu configuración poniendo `gui.returnImmediately: true`)",
DetachFromContainerShortCut: "Por defecto, para desacoplarte del contenedor presiona ctrl-p y luego ctrl-q",
No: "no",
Yes: "sí",
FilterPrompt: "filtrar",
LcNextScreenMode: "siguiente modo de pantalla (normal/mitad/pantalla completa)",
LcPrevScreenMode: "modo de pantalla anterior",
FilterPrompt: "filtrar",
FocusProjects: "enfocar panel de proyectos",
FocusServices: "enfocar panel de servicios",
FocusContainers: "enfocar panel de contenedores",
FocusImages: "enfocar panel de imágenes",
FocusVolumes: "enfocar panel de volúmenes",
FocusNetworks: "enfocar panel de redes",
}
}

View file

@ -7,6 +7,12 @@ func turkishSet() TranslationSet {
RestartingStatus: "yeniden başlatılıyor",
StoppingStatus: "durduruluyor",
RunningCustomCommandStatus: "özel komut çalıştır",
StartingStatus: "başlatılıyor",
UppingServiceStatus: "servis yükseltiliyor",
UppingProjectStatus: "proje yükseltiliyor",
DowningStatus: "indiriliyor",
PausingStatus: "durduruluyor",
RunningBulkCommandStatus: "toplu komut çalıştırılıyor",
NoViewMachingNewLineFocusedSwitchStatement: "NewLineFocused anahtar deyimi ile eşleşen görünüm yok",
@ -15,6 +21,7 @@ func turkishSet() TranslationSet {
UnattachableContainerError: "Konteyner attaching modunda çalışmayı desteklemiyor. Hizmeti '-it' opsiyonu ile çalıştırmanız veya docker-compose.yml dosyasında `stdin_open: true, tty: true` kullanmanız gerekir.",
CannotAttachStoppedContainerError: "Durdurulan konteynera bağlanamazsınız, ilk önce başlatmanız gerekir (aslında başlatmayı r tuşu ile yapabilirsiniz) (evet, senin için bunu otomatik olarak yapabilirim fakat çok tembelim) (hata mesajı ile seninle birebir iletişim kurmam çok daha güzel)",
CannotAccessDockerSocketError: "Docker' a şu adresten erişilemiyor : unix:///var/run/docker.sock\n lazydocker' ı root(kök kullanıcı) olarak çalıştır veya şu adresteki adımları takip et : https://docs.docker.com/install/linux/linux-postinstall/",
CannotKillChildError: "Alt işlemin durması için üç saniye beklendi. Sisteminizde çalışmaya devam eden bir yetim işlem olabilir.",
Donate: "Bağış",
Confirm: "Onayla",
@ -52,6 +59,31 @@ func turkishSet() TranslationSet {
PruneImages: "kullanılmayan imajları temizle",
ViewRestartOptions: "yeniden başlatma seçeneklerini görüntüle",
RunCustomCommand: "önceden tanımlanmış özel komutu çalıştır",
Down: "projeyi indir",
DownWithVolumes: "projeyi alanlarla birlikte indir",
Start: "başlat",
Pause: "durdur",
UpService: "servisi yükselt",
UpProject: "projeyi yükselt",
DownProject: "projeyi indir",
RestartProject: "projeyi yeniden başlat",
UpProfile: "profili yükselt",
DownProfile: "profili indir",
DownProfileWithVolumes: "profili alanlarla birlikte indir",
RestartProfile: "profili yeniden başlat",
UpAllProfiles: "tüm profilleri yükselt",
DownAllProfiles: "tüm profilleri indir",
DownAllProfilesWithVolumes: "tüm profilleri alanlarla birlikte indir",
RemoveWithoutPruneWithForce: "etiketsiz ebeveynleri silmeden zorla kaldır",
RemoveWithForce: "zorla kaldır",
StopAllContainers: "tüm konteynerleri durdur",
RemoveAllContainers: "tüm konteynerleri kaldır (zorla)",
ExecShell: "kabuk çalıştır",
ViewBulkCommands: "toplu komutları görüntüle",
FilterList: "listeyi filtrele",
OpenInBrowser: "tarayıcıda aç (ilk port http)",
SortContainersByState: "konteynerleri duruma göre sırala",
HideStopped: "durdurulan konteynerleri gizle/göster",
GlobalTitle: "Global",
MainTitle: "Ana",
@ -81,6 +113,8 @@ func turkishSet() TranslationSet {
NoImages: "Imajlar yok",
NoVolumes: "Alanlar yok",
NoNetworks: "Ağları yok",
NoServices: "Servis yok",
NoContainerForService: "Gösterilecek günlük yok; servis bir konteyner ile ilişkilendirilmemiş",
ConfirmQuit: ıkmak istediğine emin misin?",
MustForceToRemoveContainer: "Zorlamadan çalışan bir konteyneri kaldıramazsınız. Zorlamak ister misin?",
@ -93,5 +127,28 @@ func turkishSet() TranslationSet {
StopContainer: "Bu konteyneri durdurmak istediğinize emin misiniz?",
PressEnterToReturn: "lazydocker' a geri dönmek için enter tuşuna basın ( Bu uyarı, `gui.return Immediately: true` ayarıyla devre dışı bırakılabilir)",
DetachFromContainerShortCut: "Varsayılan olarak, kaptan ayırmak için ctrl-p ve ardından ctrl-q tuşlarına basın",
ConfirmUpProject: "Docker Compose projenizi yükseltmek istediğinizden emin misiniz?",
ConfirmStopContainers: "Tüm konteynerleri durdurmak istediğinizden emin misiniz?",
ConfirmRemoveContainers: "Tüm konteynerleri kaldırmak istediğinizden emin misiniz?",
WaitingForContainerInfo: "Docker'dan konteyner hakkında daha fazla bilgi alınana kadar devam edilemiyor. Lütfen birkaç saniye sonra tekrar deneyin.",
LcFilter: "listeyi filtrele",
Quit: ıkış",
BulkCommandTitle: "Toplu Komut:",
No: "hayır",
Yes: "evet",
LcNextScreenMode: "sonraki ekran modu (normal/yarım/tam ekran)",
LcPrevScreenMode: "önceki ekran modu",
FilterPrompt: "filtrele",
FocusProjects: "projeler paneline odaklan",
FocusServices: "servisler paneline odaklan",
FocusContainers: "konteynerler paneline odaklan",
FocusImages: "görüntüler paneline odaklan",
FocusVolumes: "alanlar paneline odaklan",
FocusNetworks: "ağlar paneline odaklan",
}
}

View file

@ -1,4 +1,3 @@
version: "3.5"
services:
my-service:
build:
@ -23,3 +22,54 @@ services:
dockerfile: Dockerfile
context: .
command: /app/print-random-stuff.sh
my-service4-prof1:
build:
dockerfile: Dockerfile
context: .
command: /app/print-random-stuff.sh
profiles:
- prof1
my-service5-prof1:
build:
dockerfile: Dockerfile
context: .
command: /app/print-random-stuff.sh
profiles:
- prof1
my-service6-prof2:
build:
dockerfile: Dockerfile
context: .
command: /app/print-random-stuff.sh
profiles:
- prof2
my-service7-prof3:
build:
dockerfile: Dockerfile
context: .
command: /app/print-random-stuff.sh
profiles:
- prof3
my-service8-prof12:
build:
dockerfile: Dockerfile
context: .
command: /app/print-random-stuff.sh
profiles:
- prof1
- prof2
my-service9-prof123:
build:
dockerfile: Dockerfile
context: .
command: /app/print-random-stuff.sh
profiles:
- prof1
- prof2
- prof3