diff options
| author | Ibrahim Serdar Acikgoz <serdaracikgoz86@gmail.com> | 2018-11-19 18:26:48 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-11-19 18:26:48 +0300 |
| commit | 1d2578217b0a20417b15a55ae5c9b42176598c85 (patch) | |
| tree | 395c08f6b3ce08df6b98427c311afd604435b4d9 | |
| parent | Merge pull request #3 from isacikgoz/develop (diff) | |
| parent | various gui improvements (diff) | |
| download | gitbatch-1d2578217b0a20417b15a55ae5c9b42176598c85.tar.gz | |
Merge pull request #4 from isacikgoz/develop
various gui improvements
| -rw-r--r-- | pkg/git/git.go | 48 | ||||
| -rw-r--r-- | pkg/gui/gui.go | 378 |
2 files changed, 275 insertions, 151 deletions
diff --git a/pkg/git/git.go b/pkg/git/git.go index 86cc02d..9aa3a39 100644 --- a/pkg/git/git.go +++ b/pkg/git/git.go @@ -2,7 +2,9 @@ package git import ( "gopkg.in/src-d/go-git.v4" + "gopkg.in/src-d/go-git.v4/plumbing/object" "os" + "regexp" ) type RepoEntity struct { @@ -35,5 +37,51 @@ func InitializeRepository(directory string) (RepoEntity, error) { return entity, nil } +func (entity *RepoEntity) GetCommits() (commits []string, err error) { + r := entity.Repository + //TODO: Handle Errors + ref, _ := r.Head() + + cIter, _ := r.Log(&git.LogOptions{ + From: ref.Hash(), + Order: git.LogOrderCommitterTime, + }) + +// ... just iterates over the commits + err = cIter.ForEach(func(c *object.Commit) error { + commitstring := string([]rune(c.Hash.String())[:7]) + " " + c.Message + re := regexp.MustCompile(`\r?\n`) + commitstring = re.ReplaceAllString(commitstring, " ") + commits = append(commits, commitstring) + + return nil + }) + if err != nil { + return commits, err + } + return commits, nil +} + +func (entity *RepoEntity) GetRemotes() (remotes []string, err error) { + r := entity.Repository + + if list, err := r.Remotes(); err != nil { + return remotes, err + } else { + for _, r := range list { + remoteString := r.Config().Name + " → " + r.Config().URLs[0] + remotes = append(remotes, remoteString) + } + } + return remotes, nil +} + +func (entity *RepoEntity) GetStatus() (status string) { + status = "↑ " + entity.Pushables + " ↓ " + entity.Pullables + " → " + entity.Branch + re := regexp.MustCompile(`\r?\n`) + status = re.ReplaceAllString(status, " ") + return status +} + diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go index fcbe9b6..50fd99d 100644 --- a/pkg/gui/gui.go +++ b/pkg/gui/gui.go @@ -1,208 +1,284 @@ package gui import ( - "github.com/isacikgoz/gitbatch/pkg/git" - "github.com/jroimartin/gocui" - "fmt" + "github.com/isacikgoz/gitbatch/pkg/git" + "github.com/jroimartin/gocui" + "fmt" ) // Gui wraps the gocui Gui object which handles rendering and events var ( - repositories []git.RepoEntity + repositories []git.RepoEntity ) func layout(g *gocui.Gui) error { - maxX, maxY := g.Size() + maxX, maxY := g.Size() - if v, err := g.SetView("main", 0, 0, maxX-1, int(0.65*float32(maxY))-3); err != nil { - if err != gocui.ErrUnknownView { - return err - } - v.Title = " Matched Repositories " - v.Highlight = true - v.SelBgColor = gocui.ColorGreen - v.SelFgColor = gocui.ColorBlack + if v, err := g.SetView("main", 0, 0, int(0.5*float32(maxX))-1, maxY-2); err != nil { + if err != gocui.ErrUnknownView { + return err + } + v.Title = " Matched Repositories " + v.Highlight = true + v.SelBgColor = gocui.ColorWhite + v.SelFgColor = gocui.ColorBlack - for _, r := range repositories { - fmt.Fprintln(v, r.Name) - } + for _, r := range repositories { + fmt.Fprintln(v, r.Name) + } - if _, err = setCurrentViewOnTop(g, "main"); err != nil { - return err - } - } + if _, err = setCurrentViewOnTop(g, "main"); err != nil { + return err + } + } - if v, err := g.SetView("detail", 0, int(0.65*float32(maxY))-2, maxX-1, maxY-2); err != nil { - if err != gocui.ErrUnknownView { - return err - } - v.Title = " Repository Detail " - v.Wrap = true - v.Autoscroll = true - } + if v, err := g.SetView("status", int(0.5*float32(maxX)), 0, maxX-1, 2); err != nil { + if err != gocui.ErrUnknownView { + return err + } + v.Title = " Status " + v.Wrap = false + v.Autoscroll = false + } - if v, err := g.SetView("keybindings", -1, maxY-2, maxX, maxY); err != nil { - if err != gocui.ErrUnknownView { - return err - } - v.BgColor = gocui.ColorBlue - v.FgColor = gocui.ColorYellow - v.Frame = false - fmt.Fprintln(v, "q: quit ↑ ↓: navigate space: select") - } - return nil + if v, err := g.SetView("remotes", int(0.5*float32(maxX)), 3, maxX-1, int(0.25*float32(maxY))); err != nil { + if err != gocui.ErrUnknownView { + return err + } + v.Title = " Remotes " + v.Wrap = true + v.Autoscroll = true + } + + if v, err := g.SetView("commits", int(0.5*float32(maxX)), int(0.25*float32(maxY))+1, maxX-1, int(0.75*float32(maxY))); err != nil { + if err != gocui.ErrUnknownView { + return err + } + v.Title = " Commits " + v.Wrap = false + v.Autoscroll = false + } + + if v, err := g.SetView("schedule", int(0.5*float32(maxX)), int(0.75*float32(maxY))+1, maxX-1, maxY-2); err != nil { + if err != gocui.ErrUnknownView { + return err + } + v.Title = " Schedule " + v.Wrap = true + v.Autoscroll = true + } + + if v, err := g.SetView("keybindings", -1, maxY-2, maxX, maxY); err != nil { + if err != gocui.ErrUnknownView { + return err + } + v.BgColor = gocui.ColorWhite + v.FgColor = gocui.ColorBlack + v.Frame = false + fmt.Fprintln(v, "q: quit ↑ ↓: navigate space: select") + } + return nil } func keybindings(g *gocui.Gui) error { - if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil { - return err - } - if err := g.SetKeybinding("", 'q', gocui.ModNone, quit); err != nil { - return err - } - if err := g.SetKeybinding("main", gocui.KeyArrowDown, gocui.ModNone, cursorDown); err != nil { - return err - } - if err := g.SetKeybinding("main", gocui.KeyArrowUp, gocui.ModNone, cursorUp); err != nil { - return err - } - if err := g.SetKeybinding("main", gocui.KeySpace, gocui.ModNone, markRepository); err != nil { - return err - } - return nil + if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil { + return err + } + if err := g.SetKeybinding("", 'q', gocui.ModNone, quit); err != nil { + return err + } + if err := g.SetKeybinding("main", gocui.KeyArrowDown, gocui.ModNone, cursorDown); err != nil { + return err + } + if err := g.SetKeybinding("main", gocui.KeyArrowUp, gocui.ModNone, cursorUp); err != nil { + return err + } + if err := g.SetKeybinding("main", gocui.KeySpace, gocui.ModNone, markRepository); err != nil { + return err + } + return nil } func cursorDown(g *gocui.Gui, v *gocui.View) error { - if v != nil { - cx, cy := v.Cursor() - ox, oy := v.Origin() + if v != nil { + cx, cy := v.Cursor() + ox, oy := v.Origin() + + ly := len(repositories) -1 + + // if we are at the end we just return + if cy+oy == ly { + return nil + } + if err := v.SetCursor(cx, cy+1); err != nil { + + if err := v.SetOrigin(ox, oy+1); err != nil { + return err + } + } + if entity, err := getSelectedRepository(g, v); err != nil { + return err + } else { + if err := updateRemotes(g, entity); err != nil { + return err + } - ly := len(repositories) -1 + if err := updateStatus(g, entity); err != nil { + return err + } - // if we are at the end we just return - if cy+oy == ly { - return nil - } - if err := v.SetCursor(cx, cy+1); err != nil { - - if err := v.SetOrigin(ox, oy+1); err != nil { - return err - } - } - if err := updateDetail(g, v); err != nil { - return err - } - } - return nil + if err := updateCommits(g, entity); err != nil { + return err + } + } + } + return nil } func cursorUp(g *gocui.Gui, v *gocui.View) error { - if v != nil { - ox, oy := v.Origin() - cx, cy := v.Cursor() - if err := v.SetCursor(cx, cy-1); err != nil && oy > 0 { - if err := v.SetOrigin(ox, oy-1); err != nil { - return err - } - } - if err := updateDetail(g, v); err != nil { - return err - } - } - return nil + if v != nil { + ox, oy := v.Origin() + cx, cy := v.Cursor() + if err := v.SetCursor(cx, cy-1); err != nil && oy > 0 { + if err := v.SetOrigin(ox, oy-1); err != nil { + return err + } + } + if entity, err := getSelectedRepository(g, v); err != nil { + return err + } else { + if err := updateRemotes(g, entity); err != nil { + return err + } + + if err := updateStatus(g, entity); err != nil { + return err + } + + if err := updateCommits(g, entity); err != nil { + return err + } + } + } + return nil } func quit(g *gocui.Gui, v *gocui.View) error { - return gocui.ErrQuit + return gocui.ErrQuit } func setCurrentViewOnTop(g *gocui.Gui, name string) (*gocui.View, error) { - if _, err := g.SetCurrentView(name); err != nil { - return nil, err - } - return g.SetViewOnTop(name) + if _, err := g.SetCurrentView(name); err != nil { + return nil, err + } + return g.SetViewOnTop(name) } func getSelectedRepository(g *gocui.Gui, v *gocui.View) (git.RepoEntity, error) { - var l string - var err error - var r git.RepoEntity + var l string + var err error + var r git.RepoEntity + + _, cy := v.Cursor() + if l, err = v.Line(cy); err != nil { + return r, err + } + + for _, sr := range repositories { + if l == sr.Name { + return sr, nil + } + } + return r, err +} + +func updateRemotes(g *gocui.Gui, entity git.RepoEntity) error { + var err error + + out, err := g.View("remotes") + if err != nil { + return err + } + out.Clear() + + if list, err := entity.GetRemotes(); err != nil { + return err + } else { + for _, r := range list { + fmt.Fprintln(out, r) + } + } + + return nil +} + +func updateStatus(g *gocui.Gui, entity git.RepoEntity) error { + var err error + + out, err := g.View("status") + if err != nil { + return err + } + out.Clear() - _, cy := v.Cursor() - if l, err = v.Line(cy); err != nil { - return r, err - } + fmt.Fprintln(out, entity.GetStatus()) - for _, sr := range repositories { - if l == sr.Name { - return sr, nil - } - } - return r, err + return nil } -func updateDetail(g *gocui.Gui, v *gocui.View) error { - var err error - _, cy := v.Cursor() - if _, err = v.Line(cy); err != nil { - return err - } +func updateCommits(g *gocui.Gui, entity git.RepoEntity) error { + var err error - out, err := g.View("detail") - if err != nil { - return err - } + out, err := g.View("commits") + if err != nil { + return err + } + out.Clear() - out.Clear() + if list, err := entity.GetCommits(); err != nil { + return err + } else { + for _, c := range list { + fmt.Fprintln(out, c) + } + } - if repo, err := getSelectedRepository(g, v); err != nil { - out.Clear() - } else { - if list, err := repo.Repository.Remotes(); err != nil { - return err - } else { - fmt.Fprintln(out, "↑" + repo.Pushables + " ↓" + repo.Pullables + " → " + repo.Branch) - for _, r := range list { - fmt.Fprintln(out, r) - } - } - } - return nil + return nil } func markRepository(g *gocui.Gui, v *gocui.View) error { - var l string - var err error + var l string + var err error - _, cy := v.Cursor() - if l, err = v.Line(cy); err != nil { - return err - } else { - l = l + " X" - } + _, cy := v.Cursor() + if l, err = v.Line(cy); err != nil { + return err + } else { + l = l + " X" + } - return nil + return nil } // Run setup the gui with keybindings and start the mainloop func Run(repos []git.RepoEntity) error { - repositories = repos - g, err := gocui.NewGui(gocui.OutputNormal) - if err != nil { - return err - } - defer g.Close() + repositories = repos + g, err := gocui.NewGui(gocui.OutputNormal) + if err != nil { + return err + } + defer g.Close() - g.SetManagerFunc(layout) + g.SetManagerFunc(layout) - if err := keybindings(g); err != nil { - return err - } + if err := keybindings(g); err != nil { + return err + } - if err := g.MainLoop(); err != nil && err != gocui.ErrQuit { - return err - } - return nil + if err := g.MainLoop(); err != nil && err != gocui.ErrQuit { + return err + } + return nil } |
