diff options
Diffstat (limited to 'pkg/gui/controllers/tags_controller.go')
-rw-r--r-- | pkg/gui/controllers/tags_controller.go | 229 |
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 +} |