mirror of
https://github.com/jesseduffield/lazydocker.git
synced 2026-07-25 08:31:03 +00:00
Add compose profile support
This commit is contained in:
parent
bedde4a037
commit
c49f340d2d
9 changed files with 619 additions and 125 deletions
|
|
@ -40,6 +40,7 @@ type DockerCommand struct {
|
||||||
Config *config.AppConfig
|
Config *config.AppConfig
|
||||||
Client *client.Client
|
Client *client.Client
|
||||||
InDockerComposeProject bool
|
InDockerComposeProject bool
|
||||||
|
HasProfiles bool
|
||||||
ErrorChan chan error
|
ErrorChan chan error
|
||||||
ContainerMutex deadlock.Mutex
|
ContainerMutex deadlock.Mutex
|
||||||
ServiceMutex deadlock.Mutex
|
ServiceMutex deadlock.Mutex
|
||||||
|
|
@ -57,6 +58,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
|
// 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 {
|
type CommandObject struct {
|
||||||
DockerCompose string
|
DockerCompose string
|
||||||
|
Profile string
|
||||||
Service *Service
|
Service *Service
|
||||||
Container *Container
|
Container *Container
|
||||||
Image *Image
|
Image *Image
|
||||||
|
|
@ -109,7 +111,8 @@ func NewDockerCommand(log *logrus.Entry, osCommand *OSCommand, tr *i18n.Translat
|
||||||
Config: config,
|
Config: config,
|
||||||
Client: cli,
|
Client: cli,
|
||||||
ErrorChan: errorChan,
|
ErrorChan: errorChan,
|
||||||
InDockerComposeProject: true,
|
InDockerComposeProject: false,
|
||||||
|
HasProfiles: false,
|
||||||
Closers: []io.Closer{tunnelCloser},
|
Closers: []io.Closer{tunnelCloser},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -121,8 +124,20 @@ func NewDockerCommand(log *logrus.Entry, osCommand *OSCommand, tr *i18n.Translat
|
||||||
dockerCommand.NewCommandObject(CommandObject{}),
|
dockerCommand.NewCommandObject(CommandObject{}),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err == nil {
|
||||||
dockerCommand.InDockerComposeProject = false
|
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())
|
log.Warn(err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -217,6 +232,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
|
// GetContainers gets the docker containers
|
||||||
func (c *DockerCommand) GetContainers(existingContainers []*Container) ([]*Container, error) {
|
func (c *DockerCommand) GetContainers(existingContainers []*Container) ([]*Container, error) {
|
||||||
c.ContainerMutex.Lock()
|
c.ContainerMutex.Lock()
|
||||||
|
|
@ -279,7 +310,7 @@ func (c *DockerCommand) GetServices() ([]*Service, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
composeCommand := c.Config.UserConfig.CommandTemplates.DockerCompose
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -360,6 +391,19 @@ func (c *DockerCommand) DockerComposeConfig() string {
|
||||||
return output
|
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
|
// determineDockerHost tries to the determine the docker host that we should connect to
|
||||||
// in the following order of decreasing precedence:
|
// in the following order of decreasing precedence:
|
||||||
// - value of "DOCKER_HOST" environment variable
|
// - value of "DOCKER_HOST" environment variable
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,64 @@
|
||||||
package commands
|
package commands
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/jesseduffield/lazydocker/pkg/config"
|
||||||
|
"github.com/jesseduffield/lazydocker/pkg/utils"
|
||||||
|
)
|
||||||
|
|
||||||
type Project struct {
|
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)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -166,6 +166,9 @@ type CommandTemplatesConfig struct {
|
||||||
// downs and removes volumes
|
// downs and removes volumes
|
||||||
DownWithVolumes string `yaml:"downWithVolumes,omitempty"`
|
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
|
// 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
|
// few different docker-compose.yml files together, in which case you can set
|
||||||
// this to "docker compose -f foo/docker-compose.yml -f
|
// 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
|
// AllLogs is for showing what you get from doing `docker compose logs`. It
|
||||||
// combines all the logs together
|
// 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 is the command we use when you want to see all logs in a subprocess with no filtering
|
||||||
ViewAllLogs string `yaml:"viewAlLogs,omitempty"`
|
ViewAllLogs string `yaml:"viewAlLogs,omitempty"`
|
||||||
|
|
@ -210,7 +214,8 @@ type CommandTemplatesConfig struct {
|
||||||
// DockerComposeConfig is the command for viewing the config of your docker
|
// DockerComposeConfig is the command for viewing the config of your docker
|
||||||
// compose. It basically prints out the yaml from your docker-compose.yml
|
// compose. It basically prints out the yaml from your docker-compose.yml
|
||||||
// file(s)
|
// 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
|
// CheckDockerComposeConfig is what we use to check whether we are in a
|
||||||
// docker-compose context. If the command returns an error then we clearly
|
// docker-compose context. If the command returns an error then we clearly
|
||||||
|
|
@ -218,8 +223,22 @@ type CommandTemplatesConfig struct {
|
||||||
// and only show containers
|
// and only show containers
|
||||||
CheckDockerComposeConfig string `yaml:"checkDockerComposeConfig,omitempty"`
|
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 is the command for viewing the processes under a given service
|
||||||
ServiceTop string `yaml:"serviceTop,omitempty"`
|
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
|
// OSConfig contains config on the level of the os
|
||||||
|
|
@ -385,23 +404,31 @@ func GetDefaultConfig() UserConfig {
|
||||||
Tail: "",
|
Tail: "",
|
||||||
},
|
},
|
||||||
CommandTemplates: CommandTemplatesConfig{
|
CommandTemplates: CommandTemplatesConfig{
|
||||||
DockerCompose: "docker compose",
|
DockerCompose: "docker compose",
|
||||||
RestartService: "{{ .DockerCompose }} restart {{ .Service.Name }}",
|
RestartService: "{{ .DockerCompose }} restart {{ .Service.Name }}",
|
||||||
StartService: "{{ .DockerCompose }} start {{ .Service.Name }}",
|
StartService: "{{ .DockerCompose }} start {{ .Service.Name }}",
|
||||||
Up: "{{ .DockerCompose }} up -d",
|
Up: "{{ .DockerCompose }} up -d",
|
||||||
Down: "{{ .DockerCompose }} down",
|
Down: "{{ .DockerCompose }} down",
|
||||||
DownWithVolumes: "{{ .DockerCompose }} down --volumes",
|
DownWithVolumes: "{{ .DockerCompose }} down --volumes",
|
||||||
UpService: "{{ .DockerCompose }} up -d {{ .Service.Name }}",
|
UpService: "{{ .DockerCompose }} up -d {{ .Service.Name }}",
|
||||||
RebuildService: "{{ .DockerCompose }} up -d --build {{ .Service.Name }}",
|
UpProfile: "{{ .DockerCompose }} --profile {{ .Profile }} up -d",
|
||||||
RecreateService: "{{ .DockerCompose }} up -d --force-recreate {{ .Service.Name }}",
|
DownProfile: "{{ .DockerCompose }} --profile {{ .Profile }} down",
|
||||||
StopService: "{{ .DockerCompose }} stop {{ .Service.Name }}",
|
DownProfileWithVolumes: "{{ .DockerCompose }} --profile {{ .Profile }} down --volumes",
|
||||||
ServiceLogs: "{{ .DockerCompose }} logs --since=60m --follow {{ .Service.Name }}",
|
Restart: "{{ .DockerCompose }} restart",
|
||||||
ViewServiceLogs: "{{ .DockerCompose }} logs --follow {{ .Service.Name }}",
|
RestartProfile: "{{ .DockerCompose }} --profile {{ .Profile }} restart",
|
||||||
AllLogs: "{{ .DockerCompose }} logs --tail=300 --follow",
|
RebuildService: "{{ .DockerCompose }} up -d --build {{ .Service.Name }}",
|
||||||
ViewAllLogs: "{{ .DockerCompose }} logs",
|
RecreateService: "{{ .DockerCompose }} up -d --force-recreate {{ .Service.Name }}",
|
||||||
DockerComposeConfig: "{{ .DockerCompose }} config",
|
StopService: "{{ .DockerCompose }} stop {{ .Service.Name }}",
|
||||||
CheckDockerComposeConfig: "{{ .DockerCompose }} config --quiet",
|
ServiceLogs: "{{ .DockerCompose }} logs --since=60m --follow {{ .Service.Name }}",
|
||||||
ServiceTop: "{{ .DockerCompose }} top {{ .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{
|
CustomCommands: CustomCommands{
|
||||||
Containers: []CustomCommand{},
|
Containers: []CustomCommand{},
|
||||||
|
|
|
||||||
|
|
@ -149,6 +149,55 @@ func (gui *Gui) GetInitialKeybindings() []*Binding {
|
||||||
Handler: gui.handleViewAllLogs,
|
Handler: gui.handleViewAllLogs,
|
||||||
Description: gui.Tr.ViewLogs,
|
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",
|
ViewName: "menu",
|
||||||
Key: gocui.KeyEsc,
|
Key: gocui.KeyEsc,
|
||||||
|
|
@ -322,14 +371,14 @@ func (gui *Gui) GetInitialKeybindings() []*Binding {
|
||||||
ViewName: "services",
|
ViewName: "services",
|
||||||
Key: 'U',
|
Key: 'U',
|
||||||
Modifier: gocui.ModNone,
|
Modifier: gocui.ModNone,
|
||||||
Handler: gui.handleProjectUp,
|
Handler: gui.handleProjectUpMenu,
|
||||||
Description: gui.Tr.UpProject,
|
Description: gui.Tr.UpProject,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ViewName: "services",
|
ViewName: "services",
|
||||||
Key: 'D',
|
Key: 'D',
|
||||||
Modifier: gocui.ModNone,
|
Modifier: gocui.ModNone,
|
||||||
Handler: gui.handleProjectDown,
|
Handler: gui.handleProjectDownMenu,
|
||||||
Description: gui.Tr.DownProject,
|
Description: gui.Tr.DownProject,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,23 @@
|
||||||
package presentation
|
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 {
|
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,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package gui
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
|
"os/exec"
|
||||||
"path"
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
|
@ -11,9 +12,11 @@ import (
|
||||||
"github.com/jesseduffield/lazydocker/pkg/commands"
|
"github.com/jesseduffield/lazydocker/pkg/commands"
|
||||||
"github.com/jesseduffield/lazydocker/pkg/gui/panels"
|
"github.com/jesseduffield/lazydocker/pkg/gui/panels"
|
||||||
"github.com/jesseduffield/lazydocker/pkg/gui/presentation"
|
"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/tasks"
|
||||||
"github.com/jesseduffield/lazydocker/pkg/utils"
|
"github.com/jesseduffield/lazydocker/pkg/utils"
|
||||||
"github.com/jesseduffield/yaml"
|
"github.com/jesseduffield/yaml"
|
||||||
|
"github.com/samber/lo"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Although at the moment we'll only have one project, in future we could have
|
// 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]{
|
return &panels.SideListPanel[*commands.Project]{
|
||||||
ContextState: &panels.ContextState[*commands.Project]{
|
ContextState: &panels.ContextState[*commands.Project]{
|
||||||
GetMainTabs: func() []panels.MainTab[*commands.Project] {
|
GetMainTabs: func() []panels.MainTab[*commands.Project] {
|
||||||
if gui.DockerCommand.InDockerComposeProject {
|
tabsList := []panels.MainTab[*commands.Project]{
|
||||||
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]{
|
|
||||||
{
|
{
|
||||||
Key: "credits",
|
Key: "credits",
|
||||||
Title: gui.Tr.CreditsTitle,
|
Title: gui.Tr.CreditsTitle,
|
||||||
Render: gui.renderCredits,
|
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 {
|
GetItemContextCacheKey: func(project *commands.Project) string {
|
||||||
return "projects-" + project.Name
|
return "projects-" + project.Name
|
||||||
|
|
@ -67,13 +68,36 @@ func (gui *Gui) getProjectPanel() *panels.SideListPanel[*commands.Project] {
|
||||||
return false
|
return false
|
||||||
},
|
},
|
||||||
GetTableCells: presentation.GetProjectDisplayStrings,
|
GetTableCells: presentation.GetProjectDisplayStrings,
|
||||||
// It doesn't make sense to filter a list of only one item.
|
|
||||||
DisableFilter: true,
|
DisableFilter: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) refreshProject() error {
|
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()
|
return gui.Panels.Projects.RerenderList()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -112,19 +136,29 @@ func (gui *Gui) creditsStr() string {
|
||||||
}, "\n\n")
|
}, "\n\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) renderAllLogs(_project *commands.Project) tasks.TaskFunc {
|
func (gui *Gui) renderLogs(_project *commands.Project) tasks.TaskFunc {
|
||||||
return gui.NewTask(TaskOpts{
|
return gui.NewTask(TaskOpts{
|
||||||
Autoscroll: true,
|
Autoscroll: true,
|
||||||
Wrap: gui.Config.UserConfig.Gui.WrapMainPanel,
|
Wrap: gui.Config.UserConfig.Gui.WrapMainPanel,
|
||||||
Func: func(ctx context.Context) {
|
Func: func(ctx context.Context) {
|
||||||
gui.clearMainView()
|
gui.clearMainView()
|
||||||
|
|
||||||
cmd := gui.OSCommand.RunCustomCommand(
|
var cmd *exec.Cmd
|
||||||
utils.ApplyTemplate(
|
if _project.IsProfile {
|
||||||
gui.Config.UserConfig.CommandTemplates.AllLogs,
|
cmd = gui.OSCommand.RunCustomCommand(
|
||||||
gui.DockerCommand.NewCommandObject(commands.CommandObject{}),
|
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.Stdout = gui.Views.Main
|
||||||
cmd.Stderr = 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 {
|
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 gui.NewSimpleRenderStringTask(func() string {
|
||||||
return utils.ColoredYamlString(gui.DockerCommand.DockerComposeConfig())
|
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)
|
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
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -288,73 +288,6 @@ func (gui *Gui) handleServiceRenderLogsToMain(g *gocui.Gui, v *gocui.View) error
|
||||||
return gui.runSubprocess(c)
|
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 {
|
func (gui *Gui) handleServiceRestartMenu(g *gocui.Gui, v *gocui.View) error {
|
||||||
service, err := gui.Panels.Services.GetSelectedItem()
|
service, err := gui.Panels.Services.GetSelectedItem()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -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.
|
// 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.Main.IgnoreCarriageReturns = true
|
||||||
|
|
||||||
|
gui.Views.Project.Highlight = true
|
||||||
|
gui.Views.Project.SelBgColor = selectedLineBgColor
|
||||||
gui.Views.Project.Title = gui.Tr.ProjectTitle
|
gui.Views.Project.Title = gui.Tr.ProjectTitle
|
||||||
gui.Views.Project.TitlePrefix = "[1]"
|
gui.Views.Project.TitlePrefix = "[1]"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,14 @@ type TranslationSet struct {
|
||||||
ViewLogs string
|
ViewLogs string
|
||||||
UpProject string
|
UpProject string
|
||||||
DownProject string
|
DownProject string
|
||||||
|
RestartProject string
|
||||||
|
UpProfile string
|
||||||
|
DownProfile string
|
||||||
|
DownProfileWithVolumes string
|
||||||
|
RestartProfile string
|
||||||
|
UpAllProfiles string
|
||||||
|
DownAllProfiles string
|
||||||
|
DownAllProfilesWithVolumes string
|
||||||
ServicesTitle string
|
ServicesTitle string
|
||||||
ContainersTitle string
|
ContainersTitle string
|
||||||
StandaloneContainersTitle string
|
StandaloneContainersTitle string
|
||||||
|
|
@ -197,6 +205,14 @@ func englishSet() TranslationSet {
|
||||||
ViewLogs: "view logs",
|
ViewLogs: "view logs",
|
||||||
UpProject: "up project",
|
UpProject: "up project",
|
||||||
DownProject: "down 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",
|
RemoveImage: "remove image",
|
||||||
RemoveVolume: "remove volume",
|
RemoveVolume: "remove volume",
|
||||||
RemoveNetwork: "remove network",
|
RemoveNetwork: "remove network",
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue