From 34dc3e584dca3ddd809f7361e4b7cce801d671dd Mon Sep 17 00:00:00 2001 From: Jacob Lorenzen Date: Sun, 23 Jun 2024 14:06:35 +0200 Subject: [PATCH] feat: add tag command Signed-off-by: Jacob Lorenzen --- pkg/commands/image.go | 6 ++++++ pkg/gui/confirmation_panel.go | 6 ++++-- pkg/gui/gui.go | 2 +- pkg/gui/images_panel.go | 26 ++++++++++++++++++++++++++ pkg/gui/keybindings.go | 7 +++++++ pkg/i18n/english.go | 4 ++++ 6 files changed, 48 insertions(+), 3 deletions(-) diff --git a/pkg/commands/image.go b/pkg/commands/image.go index 5e29f1981..e753dc63d 100644 --- a/pkg/commands/image.go +++ b/pkg/commands/image.go @@ -2,6 +2,7 @@ package commands import ( "context" + "fmt" "strings" "github.com/docker/docker/api/types/image" @@ -143,3 +144,8 @@ func (c *DockerCommand) PruneImages() error { _, err := c.Client.ImagesPrune(context.Background(), filters.Args{}) return err } + +func (i *Image) String() string { + return fmt.Sprintf("%s:%s", i.Name, i.Tag) +} + diff --git a/pkg/gui/confirmation_panel.go b/pkg/gui/confirmation_panel.go index 6ed535531..28fadaed7 100644 --- a/pkg/gui/confirmation_panel.go +++ b/pkg/gui/confirmation_panel.go @@ -62,13 +62,15 @@ func (gui *Gui) getConfirmationPanelDimensions(wrap bool, prompt string) (int, i height/2 + panelHeight/2 } -func (gui *Gui) createPromptPanel(title string, handleConfirm func(*gocui.Gui, *gocui.View) error) error { +func (gui *Gui) createPromptPanel(title string, prompt string, handleConfirm func(*gocui.Gui, *gocui.View) error) error { gui.onNewPopupPanel() - err := gui.prepareConfirmationPanel(title, "") + err := gui.prepareConfirmationPanel(title, prompt) if err != nil { return err } gui.Views.Confirmation.Editable = true + gui.Views.Confirmation.SetContent(prompt) + gui.Views.Confirmation.SetCursor(len(prompt), 0) return gui.setKeyBindings(gui.g, handleConfirm, nil) } diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go index 254360105..bbeb39c29 100644 --- a/pkg/gui/gui.go +++ b/pkg/gui/gui.go @@ -443,7 +443,7 @@ func (gui *Gui) openFile(filename string) error { } func (gui *Gui) handleCustomCommand(g *gocui.Gui, v *gocui.View) error { - return gui.createPromptPanel(gui.Tr.CustomCommandTitle, func(g *gocui.Gui, v *gocui.View) error { + return gui.createPromptPanel(gui.Tr.CustomCommandTitle, "", func(g *gocui.Gui, v *gocui.View) error { command := gui.trimmedContent(v) return gui.runSubprocess(gui.OSCommand.RunCustomCommand(command)) }) diff --git a/pkg/gui/images_panel.go b/pkg/gui/images_panel.go index 6ef50fa9d..4b38a4226 100644 --- a/pkg/gui/images_panel.go +++ b/pkg/gui/images_panel.go @@ -219,3 +219,29 @@ func (gui *Gui) handleImagesBulkCommand(g *gocui.Gui, v *gocui.View) error { return gui.createBulkCommandMenu(bulkCommands, commandObject) } + +func (gui *Gui) handleImagesTagCommand(g *gocui.Gui, v *gocui.View) error { + image, err := gui.Panels.Images.GetSelectedItem() + if err != nil { + return nil + } + + return gui.createPromptPanel(gui.Tr.NewTagCommand, image.String(), func(g *gocui.Gui, v *gocui.View) error { + newTag := gui.trimmedContent(v) + + var cmd string + // if the user has provided a tag with a colon, we assume they've provided a full tag + if strings.Contains(newTag, ":") { + cmd = "docker tag " + image.String() + " " + newTag + } else { + cmd = "docker tag " + image.String() + " " + image.Name + ":" + newTag + } + + err := gui.runSubprocess(gui.OSCommand.RunCustomCommand(cmd)) + if err != nil { + return gui.createErrorPanel(err.Error()) + } + + return gui.reloadImages() + }) +} diff --git a/pkg/gui/keybindings.go b/pkg/gui/keybindings.go index 424f47c56..cce36df63 100644 --- a/pkg/gui/keybindings.go +++ b/pkg/gui/keybindings.go @@ -388,6 +388,13 @@ func (gui *Gui) GetInitialKeybindings() []*Binding { Handler: gui.handleImagesBulkCommand, Description: gui.Tr.ViewBulkCommands, }, + { + ViewName: "images", + Key: 't', + Modifier: gocui.ModNone, + Handler: gui.handleImagesTagCommand, + Description: gui.Tr.ViewTagCommands, + }, { ViewName: "volumes", Key: 'c', diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go index 0d4f82222..a5eb28740 100644 --- a/pkg/i18n/english.go +++ b/pkg/i18n/english.go @@ -106,6 +106,8 @@ type TranslationSet struct { ExecShell string RunCustomCommand string ViewBulkCommands string + ViewTagCommands string + NewTagCommand string FilterList string OpenInBrowser string SortContainersByState string @@ -206,6 +208,8 @@ func englishSet() TranslationSet { ExecShell: "exec shell", RunCustomCommand: "run predefined custom command", ViewBulkCommands: "view bulk commands", + ViewTagCommands: "view tag commands", + NewTagCommand: "new tag", FilterList: "filter list", OpenInBrowser: "open in browser (first port is http)", SortContainersByState: "sort containers by state",