summaryrefslogtreecommitdiffstats
path: root/pkg/gui/controllers/tags_controller.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/gui/controllers/tags_controller.go')
-rw-r--r--pkg/gui/controllers/tags_controller.go229
1 files changed, 229 insertions, 0 deletions
diff --git a/pkg/gui/controllers/tags_controller.go b/pkg/gui/controllers/tags_controller.go
new file mode 100644
index 000000000..723a1074b
--- /dev/null
+++ b/pkg/gui/controllers/tags_controller.go
@@ -0,0 +1,229 @@
+package controllers
+
+import (
+ "github.com/jesseduffield/lazygit/pkg/commands"
+ "github.com/jesseduffield/lazygit/pkg/commands/models"
+ "github.com/jesseduffield/lazygit/pkg/config"
+ "github.com/jesseduffield/lazygit/pkg/gui/context"
+ "github.com/jesseduffield/lazygit/pkg/gui/popup"
+ "github.com/jesseduffield/lazygit/pkg/gui/types"
+ "github.com/jesseduffield/lazygit/pkg/utils"
+)
+
+type TagsController struct {
+ c *ControllerCommon
+ context types.IListContext
+ git *commands.GitCommand
+ allContexts context.ContextTree
+
+ refHelper IRefHelper
+ suggestionsHelper ISuggestionsHelper
+
+ getSelectedTag func() *models.Tag
+ switchToSubCommitsContext func(string) error
+}
+
+var _ types.IController = &TagsController{}
+
+func NewTagsController(
+ c *ControllerCommon,
+ context types.IListContext,
+ git *commands.GitCommand,
+ allContexts context.ContextTree,
+ refHelper IRefHelper,
+ suggestionsHelper ISuggestionsHelper,
+
+ getSelectedTag func() *models.Tag,
+ switchToSubCommitsContext func(string) error,
+) *TagsController {
+ return &TagsController{
+ c: c,
+ context: context,
+ git: git,
+ allContexts: allContexts,
+ refHelper: refHelper,
+ suggestionsHelper: suggestionsHelper,
+
+ getSelectedTag: getSelectedTag,
+ switchToSubCommitsContext: switchToSubCommitsContext,
+ }
+}
+
+func (self *TagsController) Keybindings(getKey func(key string) interface{}, config config.KeybindingConfig, guards types.KeybindingGuards) []*types.Binding {
+ bindings := []*types.Binding{
+ {
+ Key: getKey(config.Universal.Select),
+ Handler: self.withSelectedTag(self.checkout),
+ Description: self.c.Tr.LcCheckout,
+ },
+ {
+ Key: getKey(config.Universal.Remove),
+ Handler: self.withSelectedTag(self.delete),
+ Description: self.c.Tr.LcDeleteTag,
+ },
+ {
+ Key: getKey(config.Branches.PushTag),
+ Handler: self.withSelectedTag(self.push),
+ Description: self.c.Tr.LcPushTag,
+ },
+ {
+ Key: getKey(config.Universal.New),
+ Handler: self.create,
+ Description: self.c.Tr.LcCreateTag,
+ },
+ {
+ Key: getKey(config.Commits.ViewResetOptions),
+ Handler: self.withSelectedTag(self.createResetMenu),
+ Description: self.c.Tr.LcViewResetOptions,
+ OpensMenu: true,
+ },
+ {
+ Key: getKey(config.Universal.GoInto),
+ Handler: self.withSelectedTag(self.enter),
+ Description: self.c.Tr.LcViewCommits,
+ },
+ }
+
+ return append(bindings, self.context.Keybindings(getKey, config, guards)...)
+}
+
+func (self *TagsController) checkout(tag *models.Tag) error {
+ self.c.LogAction(self.c.Tr.Actions.CheckoutTag)
+ if err := self.refHelper.CheckoutRef(tag.Name, types.CheckoutRefOptions{}); err != nil {
+ return err
+ }
+ return self.c.PushContext(self.allContexts.Branches)
+}
+
+func (self *TagsController) enter(tag *models.Tag) error {
+ return self.switchToSubCommitsContext(tag.Name)
+}
+
+func (self *TagsController) delete(tag *models.Tag) error {
+ prompt := utils.ResolvePlaceholderString(
+ self.c.Tr.DeleteTagPrompt,
+ map[string]string{
+ "tagName": tag.Name,
+ },
+ )
+
+ return self.c.Ask(popup.AskOpts{
+ Title: self.c.Tr.DeleteTagTitle,
+ Prompt: prompt,
+ HandleConfirm: func() error {
+ self.c.LogAction(self.c.Tr.Actions.DeleteTag)
+ if err := self.git.Tag.Delete(tag.Name); err != nil {
+ return self.c.Error(err)
+ }
+ return self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC, Scope: []types.RefreshableView{types.COMMITS, types.TAGS}})
+ },
+ })
+}
+
+func (self *TagsController) push(tag *models.Tag) error {
+ title := utils.ResolvePlaceholderString(
+ self.c.Tr.PushTagTitle,
+ map[string]string{
+ "tagName": tag.Name,
+ },
+ )
+
+ return self.c.Prompt(popup.PromptOpts{
+ Title: title,
+ InitialContent: "origin",
+ FindSuggestionsFunc: self.suggestionsHelper.GetRemoteSuggestionsFunc(),
+ HandleConfirm: func(response string) error {
+ return self.c.WithWaitingStatus(self.c.Tr.PushingTagStatus, func() error {
+ self.c.LogAction(self.c.Tr.Actions.PushTag)
+ err := self.git.Tag.Push(response, tag.Name)
+ if err != nil {
+ _ = self.c.Error(err)
+ }
+
+ return nil
+ })
+ },
+ })
+}
+
+func (self *TagsController) createResetMenu(tag *models.Tag) error {
+ return self.refHelper.CreateGitResetMenu(tag.Name)
+}
+
+func (self *TagsController) CreateTagMenu(commitSha string) error {
+ return self.c.Menu(popup.CreateMenuOptions{
+ Title: self.c.Tr.TagMenuTitle,
+ Items: []*popup.MenuItem{
+ {
+ DisplayString: self.c.Tr.LcLightweightTag,
+ OnPress: func() error {
+ return self.handleCreateLightweightTag(commitSha)
+ },
+ },
+ {
+ DisplayString: self.c.Tr.LcAnnotatedTag,
+ OnPress: func() error {
+ return self.handleCreateAnnotatedTag(commitSha)
+ },
+ },
+ },
+ })
+}
+
+func (self *TagsController) afterTagCreate() error {
+ self.context.GetPanelState().SetSelectedLineIdx(0)
+ return self.c.Refresh(types.RefreshOptions{
+ Mode: types.ASYNC, Scope: []types.RefreshableView{types.COMMITS, types.TAGS},
+ })
+}
+
+func (self *TagsController) handleCreateAnnotatedTag(commitSha string) error {
+ return self.c.Prompt(popup.PromptOpts{
+ Title: self.c.Tr.TagNameTitle,
+ HandleConfirm: func(tagName string) error {
+ return self.c.Prompt(popup.PromptOpts{
+ Title: self.c.Tr.TagMessageTitle,
+ HandleConfirm: func(msg string) error {
+ self.c.LogAction(self.c.Tr.Actions.CreateAnnotatedTag)
+ if err := self.git.Tag.CreateAnnotated(tagName, commitSha, msg); err != nil {
+ return self.c.Error(err)
+ }
+ return self.afterTagCreate()
+ },
+ })
+ },
+ })
+}
+
+func (self *TagsController) handleCreateLightweightTag(commitSha string) error {
+ return self.c.Prompt(popup.PromptOpts{
+ Title: self.c.Tr.TagNameTitle,
+ HandleConfirm: func(tagName string) error {
+ self.c.LogAction(self.c.Tr.Actions.CreateLightweightTag)
+ if err := self.git.Tag.CreateLightweight(tagName, commitSha); err != nil {
+ return self.c.Error(err)
+ }
+ return self.afterTagCreate()
+ },
+ })
+}
+
+func (self *TagsController) create() error {
+ // leaving commit SHA blank so that we're just creating the tag for the current commit
+ return self.CreateTagMenu("")
+}
+
+func (self *TagsController) withSelectedTag(f func(tag *models.Tag) error) func() error {
+ return func() error {
+ tag := self.getSelectedTag()
+ if tag == nil {
+ return nil
+ }
+
+ return f(tag)
+ }
+}
+
+func (self *TagsController) Context() types.Context {
+ return self.context
+}