diff options
author | Michael Muré <batolettre@gmail.com> | 2018-08-12 21:09:30 +0200 |
---|---|---|
committer | Michael Muré <batolettre@gmail.com> | 2018-08-12 21:09:30 +0200 |
commit | e2f4b027c946831c3f4f119d87a80513c7cf8fdc (patch) | |
tree | b2ec57c89c49062ab2e8adeacb2646d2f152db80 /termui | |
parent | 721ed3248e8bf167a89df14d9fc2bf5b0fe45753 (diff) | |
download | git-bug-e2f4b027c946831c3f4f119d87a80513c7cf8fdc.tar.gz |
termui: implement push/pull
Diffstat (limited to 'termui')
-rw-r--r-- | termui/bug_table.go | 100 | ||||
-rw-r--r-- | termui/error_popup.go | 72 | ||||
-rw-r--r-- | termui/msg_popup.go | 89 | ||||
-rw-r--r-- | termui/show_bug.go | 6 | ||||
-rw-r--r-- | termui/termui.go | 14 |
5 files changed, 198 insertions, 83 deletions
diff --git a/termui/bug_table.go b/termui/bug_table.go index 1432d943..cd5ee1f6 100644 --- a/termui/bug_table.go +++ b/termui/bug_table.go @@ -1,7 +1,9 @@ package termui import ( + "bytes" "fmt" + "github.com/MichaelMure/git-bug/bug" "github.com/MichaelMure/git-bug/cache" "github.com/MichaelMure/git-bug/util" @@ -14,6 +16,8 @@ const bugTableHeaderView = "bugTableHeaderView" const bugTableFooterView = "bugTableFooterView" const bugTableInstructionView = "bugTableInstructionView" +const remote = "origin" + type bugTable struct { repo cache.RepoCacher allIds []string @@ -105,7 +109,7 @@ func (bt *bugTable) layout(g *gocui.Gui) error { v.Frame = false v.BgColor = gocui.ColorBlue - fmt.Fprintf(v, "[q] Quit [←,h] Previous page [↓,j] Down [↑,k] Up [→,l] Next page [enter] Open bug [n] New bug") + fmt.Fprintf(v, "[q] Quit [←↓↑→,hjkl] Navigation [enter] Open bug [n] New bug [i] Pull [o] Push") } _, err = g.SetCurrentView(bugTableView) @@ -176,6 +180,18 @@ func (bt *bugTable) keybindings(g *gocui.Gui) error { return err } + // Pull + if err := g.SetKeybinding(bugTableView, 'i', gocui.ModNone, + bt.pull); err != nil { + return err + } + + // Push + if err := g.SetKeybinding(bugTableView, 'o', gocui.ModNone, + bt.push); err != nil { + return err + } + return nil } @@ -383,3 +399,85 @@ func (bt *bugTable) openBug(g *gocui.Gui, v *gocui.View) error { ui.showBug.SetBug(bt.bugs[bt.pageCursor+y]) return ui.activateWindow(ui.showBug) } + +func (bt *bugTable) pull(g *gocui.Gui, v *gocui.View) error { + // Note: this is very hacky + + ui.msgPopup.Activate("Pull from remote "+remote, "...") + + go func() { + stdout, err := bt.repo.Fetch(remote) + + if err != nil { + g.Update(func(gui *gocui.Gui) error { + ui.msgPopup.Activate(msgPopupErrorTitle, err.Error()) + return nil + }) + } else { + g.Update(func(gui *gocui.Gui) error { + ui.msgPopup.UpdateMessage(stdout) + return nil + }) + } + + var buffer bytes.Buffer + beginLine := "" + + for merge := range bt.repo.MergeAll(remote) { + if merge.Status == bug.MsgMergeNothing { + continue + } + + if merge.Err != nil { + g.Update(func(gui *gocui.Gui) error { + ui.msgPopup.Activate(msgPopupErrorTitle, err.Error()) + return nil + }) + } else { + fmt.Fprintf(&buffer, "%s%s: %s", + beginLine, util.Cyan(merge.HumanId), merge.Status, + ) + + beginLine = "\n" + + g.Update(func(gui *gocui.Gui) error { + ui.msgPopup.UpdateMessage(buffer.String()) + return nil + }) + } + } + + fmt.Fprintf(&buffer, "%sdone", beginLine) + + g.Update(func(gui *gocui.Gui) error { + ui.msgPopup.UpdateMessage(buffer.String()) + return nil + }) + + }() + + return nil +} + +func (bt *bugTable) push(g *gocui.Gui, v *gocui.View) error { + ui.msgPopup.Activate("Push to remote "+remote, "...") + + go func() { + // TODO: make the remote configurable + stdout, err := bt.repo.Push(remote) + + if err != nil { + g.Update(func(gui *gocui.Gui) error { + ui.msgPopup.Activate(msgPopupErrorTitle, err.Error()) + return nil + }) + } else { + g.Update(func(gui *gocui.Gui) error { + ui.msgPopup.UpdateMessage(stdout) + return nil + }) + } + }() + + return nil +} diff --git a/termui/error_popup.go b/termui/error_popup.go deleted file mode 100644 index f8f53feb..00000000 --- a/termui/error_popup.go +++ /dev/null @@ -1,72 +0,0 @@ -package termui - -import ( - "fmt" - - "github.com/MichaelMure/git-bug/util" - "github.com/jroimartin/gocui" -) - -const errorPopupView = "errorPopupView" - -type errorPopup struct { - message string -} - -func newErrorPopup() *errorPopup { - return &errorPopup{ - message: "", - } -} - -func (ep *errorPopup) keybindings(g *gocui.Gui) error { - if err := g.SetKeybinding(errorPopupView, gocui.KeySpace, gocui.ModNone, ep.close); err != nil { - return err - } - if err := g.SetKeybinding(errorPopupView, gocui.KeyEnter, gocui.ModNone, ep.close); err != nil { - return err - } - - return nil -} - -func (ep *errorPopup) layout(g *gocui.Gui) error { - if ep.message == "" { - return nil - } - - maxX, maxY := g.Size() - - width := minInt(30, maxX) - wrapped, nblines := util.WordWrap(ep.message, width-2) - height := minInt(nblines+1, maxY) - x0 := (maxX - width) / 2 - y0 := (maxY - height) / 2 - - v, err := g.SetView(errorPopupView, x0, y0, x0+width, y0+height) - if err != nil { - if err != gocui.ErrUnknownView { - return err - } - - v.Frame = true - v.Title = "Error" - - fmt.Fprintf(v, wrapped) - } - - if _, err := g.SetCurrentView(errorPopupView); err != nil { - return err - } - - return nil -} - -func (ep *errorPopup) close(g *gocui.Gui, v *gocui.View) error { - ep.message = "" - return g.DeleteView(errorPopupView) -} - -func (ep *errorPopup) Activate(message string) { - ep.message = message -} diff --git a/termui/msg_popup.go b/termui/msg_popup.go new file mode 100644 index 00000000..dea24fb4 --- /dev/null +++ b/termui/msg_popup.go @@ -0,0 +1,89 @@ +package termui + +import ( + "fmt" + + "github.com/MichaelMure/git-bug/util" + "github.com/jroimartin/gocui" +) + +const msgPopupView = "msgPopupView" + +const msgPopupErrorTitle = "Error" + +type msgPopup struct { + active bool + title string + message string +} + +func newMsgPopup() *msgPopup { + return &msgPopup{ + message: "", + } +} + +func (ep *msgPopup) keybindings(g *gocui.Gui) error { + if err := g.SetKeybinding(msgPopupView, gocui.KeySpace, gocui.ModNone, ep.close); err != nil { + return err + } + if err := g.SetKeybinding(msgPopupView, gocui.KeyEnter, gocui.ModNone, ep.close); err != nil { + return err + } + if err := g.SetKeybinding(msgPopupView, 'q', gocui.ModNone, ep.close); err != nil { + return err + } + + return nil +} + +func (ep *msgPopup) layout(g *gocui.Gui) error { + if !ep.active { + return nil + } + + maxX, maxY := g.Size() + + width := minInt(60, maxX) + wrapped, lines := util.TextWrap(ep.message, width-2) + height := minInt(lines+1, maxY-3) + x0 := (maxX - width) / 2 + y0 := (maxY - height) / 2 + + v, err := g.SetView(msgPopupView, x0, y0, x0+width, y0+height) + if err != nil { + if err != gocui.ErrUnknownView { + return err + } + + v.Frame = true + v.Autoscroll = true + } + + v.Title = ep.title + + v.Clear() + fmt.Fprintf(v, wrapped) + + if _, err := g.SetCurrentView(msgPopupView); err != nil { + return err + } + + return nil +} + +func (ep *msgPopup) close(g *gocui.Gui, v *gocui.View) error { + ep.active = false + ep.message = "" + return g.DeleteView(msgPopupView) +} + +func (ep *msgPopup) Activate(title string, message string) { + ep.active = true + ep.title = title + ep.message = message +} + +func (ep *msgPopup) UpdateMessage(message string) { + ep.message = message +} diff --git a/termui/show_bug.go b/termui/show_bug.go index c0896e08..799af9c7 100644 --- a/termui/show_bug.go +++ b/termui/show_bug.go @@ -93,7 +93,7 @@ func (sb *showBug) layout(g *gocui.Gui) error { } v.Clear() - fmt.Fprintf(v, "[q] Save and return [←,h] Left [↓,j] Down [↑,k] Up [→,l] Right ") + fmt.Fprintf(v, "[q] Save and return [←↓↑→,hjkl] Navigation ") if sb.isOnSide { fmt.Fprint(v, "[a] Add label [r] Remove label") @@ -591,7 +591,7 @@ func (sb *showBug) addLabel(g *gocui.Gui, v *gocui.View) error { err := sb.bug.ChangeLabels(trimLabels(labels), nil) if err != nil { - ui.errorPopup.Activate(err.Error()) + ui.msgPopup.Activate(msgPopupErrorTitle, err.Error()) } g.Update(func(gui *gocui.Gui) error { @@ -614,7 +614,7 @@ func (sb *showBug) removeLabel(g *gocui.Gui, v *gocui.View) error { err := sb.bug.ChangeLabels(nil, trimLabels(labels)) if err != nil { - ui.errorPopup.Activate(err.Error()) + ui.msgPopup.Activate(msgPopupErrorTitle, err.Error()) } g.Update(func(gui *gocui.Gui) error { diff --git a/termui/termui.go b/termui/termui.go index 535842e4..b45bbc2e 100644 --- a/termui/termui.go +++ b/termui/termui.go @@ -19,7 +19,7 @@ type termUI struct { bugTable *bugTable showBug *showBug - errorPopup *errorPopup + msgPopup *msgPopup inputPopup *inputPopup } @@ -49,7 +49,7 @@ func Run(repo repository.Repo) error { cache: c, bugTable: newBugTable(c), showBug: newShowBug(c), - errorPopup: newErrorPopup(), + msgPopup: newMsgPopup(), inputPopup: newInputPopup(), } @@ -106,7 +106,7 @@ func layout(g *gocui.Gui) error { return err } - if err := ui.errorPopup.layout(g); err != nil { + if err := ui.msgPopup.layout(g); err != nil { return err } @@ -131,7 +131,7 @@ func keybindings(g *gocui.Gui) error { return err } - if err := ui.errorPopup.keybindings(g); err != nil { + if err := ui.msgPopup.keybindings(g); err != nil { return err } @@ -166,7 +166,7 @@ func newBugWithEditor(repo cache.RepoCacher) error { } if err == input.ErrEmptyTitle { - ui.errorPopup.Activate("Empty title, aborting.") + ui.msgPopup.Activate(msgPopupErrorTitle, "Empty title, aborting.") } else { _, err := repo.NewBug(title, message) if err != nil { @@ -199,7 +199,7 @@ func addCommentWithEditor(bug cache.BugCacher) error { } if err == input.ErrEmptyMessage { - ui.errorPopup.Activate("Empty message, aborting.") + ui.msgPopup.Activate(msgPopupErrorTitle, "Empty message, aborting.") } else { err := bug.AddComment(message) if err != nil { @@ -232,7 +232,7 @@ func setTitleWithEditor(bug cache.BugCacher) error { } if err == input.ErrEmptyTitle { - ui.errorPopup.Activate("Empty title, aborting.") + ui.msgPopup.Activate(msgPopupErrorTitle, "Empty title, aborting.") } else { err := bug.SetTitle(title) if err != nil { |