diff options
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | main.go | 17 | ||||
| -rw-r--r-- | pkg/app/app.go | 7 | ||||
| -rw-r--r-- | pkg/command/command.go | 40 | ||||
| -rw-r--r-- | pkg/git/branch.go | 18 | ||||
| -rw-r--r-- | pkg/git/commit.go | 71 | ||||
| -rw-r--r-- | pkg/git/git-commands.go | 4 | ||||
| -rw-r--r-- | pkg/git/load.go | 2 | ||||
| -rw-r--r-- | pkg/git/remote.go | 35 | ||||
| -rw-r--r-- | pkg/git/remotebranch.go | 11 | ||||
| -rw-r--r-- | pkg/git/repository.go | 19 | ||||
| -rw-r--r-- | pkg/gui/branchview.go | 97 | ||||
| -rw-r--r-- | pkg/gui/cheatsheet.go | 63 | ||||
| -rw-r--r-- | pkg/gui/commitsview.go | 241 | ||||
| -rw-r--r-- | pkg/gui/errorview.go | 57 | ||||
| -rw-r--r-- | pkg/gui/execview.go | 197 | ||||
| -rw-r--r-- | pkg/gui/gui-util.go | 177 | ||||
| -rw-r--r-- | pkg/gui/gui.go | 257 | ||||
| -rw-r--r-- | pkg/gui/keybindings.go | 439 | ||||
| -rw-r--r-- | pkg/gui/mainview.go | 343 | ||||
| -rw-r--r-- | pkg/gui/remotebranchview.go | 77 | ||||
| -rw-r--r-- | pkg/gui/remotesview.go | 89 | ||||
| -rw-r--r-- | pkg/job/job.go | 18 | ||||
| -rw-r--r-- | pkg/utils/utils.go | 10 |
24 files changed, 1154 insertions, 1136 deletions
@@ -1,2 +1,3 @@ exec.go.test test.go +.vscode
\ No newline at end of file @@ -1,26 +1,27 @@ package main import ( - "github.com/isacikgoz/gitbatch/pkg/app" - "gopkg.in/alecthomas/kingpin.v2" "io/ioutil" "log" "os" - "path/filepath" + "path/filepath" "strings" + + "github.com/isacikgoz/gitbatch/pkg/app" + "gopkg.in/alecthomas/kingpin.v2" ) var ( - currentDir, err = os.Getwd() - dir = kingpin.Flag("directory", "Directory to roam for git repositories.").Default(currentDir).Short('d').String() - repoPattern = kingpin.Flag("pattern", "Pattern to filter repositories").Short('p').String() + currentDir, err = os.Getwd() + dir = kingpin.Flag("directory", "Directory to roam for git repositories.").Default(currentDir).Short('d').String() + repoPattern = kingpin.Flag("pattern", "Pattern to filter repositories").Short('p').String() ) func main() { kingpin.Parse() repositories := FindRepos(*dir) - app, err := app.Setup(repositories) + app, err := app.Setup(repositories) if err != nil { log.Fatal(err) } @@ -67,5 +68,3 @@ func FilterRepos(files []os.FileInfo) []os.FileInfo { } return filteredRepos } - - diff --git a/pkg/app/app.go b/pkg/app/app.go index 74939b2..3728893 100644 --- a/pkg/app/app.go +++ b/pkg/app/app.go @@ -1,14 +1,15 @@ package app import ( - "github.com/isacikgoz/gitbatch/pkg/gui" "io" + + "github.com/isacikgoz/gitbatch/pkg/gui" ) // App struct type App struct { closers []io.Closer - Gui *gui.Gui + Gui *gui.Gui } // Setup bootstrap a new application @@ -34,4 +35,4 @@ func (app *App) Close() error { } } return nil -}
\ No newline at end of file +} diff --git a/pkg/command/command.go b/pkg/command/command.go index 2c5a0c3..357f368 100644 --- a/pkg/command/command.go +++ b/pkg/command/command.go @@ -1,9 +1,9 @@ package command import ( + "log" "os/exec" "syscall" - "log" ) func RunCommandWithOutput(dir string, command string, args []string) (string, error) { @@ -11,7 +11,7 @@ func RunCommandWithOutput(dir string, command string, args []string) (string, er if dir != "" { cmd.Dir = dir } - output, err := cmd.Output() + output, err := cmd.Output() return string(output), err } @@ -22,23 +22,23 @@ func GetCommandStatus(dir string, command string, args []string) (int, error) { } var err error if err := cmd.Start(); err != nil { - return -1, err - } - if err := cmd.Wait(); err != nil { - if exiterr, ok := err.(*exec.ExitError); ok { - // The program has exited with an exit code != 0 + return -1, err + } + if err := cmd.Wait(); err != nil { + if exiterr, ok := err.(*exec.ExitError); ok { + // The program has exited with an exit code != 0 - // This works on both Unix and Windows. Although package - // syscall is generally platform dependent, WaitStatus is - // defined for both Unix and Windows and in both cases has - // an ExitStatus() method with the same signature. - if status, ok := exiterr.Sys().(syscall.WaitStatus); ok { - statusCode := status.ExitStatus() - return statusCode, err - } - } else { - log.Fatalf("cmd.Wait: %v", err) - } - } - return -1, err + // This works on both Unix and Windows. Although package + // syscall is generally platform dependent, WaitStatus is + // defined for both Unix and Windows and in both cases has + // an ExitStatus() method with the same signature. + if status, ok := exiterr.Sys().(syscall.WaitStatus); ok { + statusCode := status.ExitStatus() + return statusCode, err + } + } else { + log.Fatalf("cmd.Wait: %v", err) + } + } + return -1, err } diff --git a/pkg/git/branch.go b/pkg/git/branch.go index 485de13..ed5f83a 100644 --- a/pkg/git/branch.go +++ b/pkg/git/branch.go @@ -6,11 +6,11 @@ import ( ) type Branch struct { - Name string - Reference *plumbing.Reference - Pushables string - Pullables string - Clean bool + Name string + Reference *plumbing.Reference + Pushables string + Pullables string + Clean bool } func (entity *RepoEntity) GetActiveBranch() (branch *Branch) { @@ -35,9 +35,9 @@ func (entity *RepoEntity) loadLocalBranches() error { push, pull := UpstreamDifferenceCount(entity.AbsPath) clean := entity.isClean() branch := &Branch{Name: b.Name().Short(), Reference: b, Pushables: push, Pullables: pull, Clean: clean} - lbs = append(lbs, branch) - } - return nil + lbs = append(lbs, branch) + } + return nil }) entity.Branches = lbs return err @@ -87,4 +87,4 @@ func (entity *RepoEntity) isClean() bool { return false } return status.IsClean() -}
\ No newline at end of file +} diff --git a/pkg/git/commit.go b/pkg/git/commit.go index 5aa24d1..9027958 100644 --- a/pkg/git/commit.go +++ b/pkg/git/commit.go @@ -1,11 +1,12 @@ package git import ( + "regexp" + "time" + "gopkg.in/src-d/go-git.v4" "gopkg.in/src-d/go-git.v4/plumbing" "gopkg.in/src-d/go-git.v4/plumbing/object" - "regexp" - "time" ) var ( @@ -13,10 +14,10 @@ var ( ) type Commit struct { - Hash string - Author string + Hash string + Author string Message string - Time time.Time + Time time.Time } func newCommit(hash, author, message string, time time.Time) (commit *Commit) { @@ -25,7 +26,7 @@ func newCommit(hash, author, message string, time time.Time) (commit *Commit) { } func (entity *RepoEntity) NextCommit() error { - currentCommitIndex := 0 + currentCommitIndex := 0 for i, cs := range entity.Commits { if cs.Hash == entity.Commit.Hash { currentCommitIndex = i @@ -43,32 +44,32 @@ func (entity *RepoEntity) loadCommits() error { r := entity.Repository entity.Commits = make([]*Commit, 0) ref, err := r.Head() - if err != nil { - return err - } + if err != nil { + return err + } - cIter, err := r.Log(&git.LogOptions{ - From: ref.Hash(), + cIter, err := r.Log(&git.LogOptions{ + From: ref.Hash(), Order: git.LogOrderCommitterTime, - }) + }) if err != nil { - return err - } + return err + } defer cIter.Close() - // ... just iterates over the commits - err = cIter.ForEach(func(c *object.Commit) error { - re := regexp.MustCompile(`\r?\n`) - commit := newCommit(re.ReplaceAllString(c.Hash.String(), " "), c.Author.Email, re.ReplaceAllString(c.Message, " "), c.Author.When) - entity.Commits = append(entity.Commits, commit) + // ... just iterates over the commits + err = cIter.ForEach(func(c *object.Commit) error { + re := regexp.MustCompile(`\r?\n`) + commit := newCommit(re.ReplaceAllString(c.Hash.String(), " "), c.Author.Email, re.ReplaceAllString(c.Message, " "), c.Author.When) + entity.Commits = append(entity.Commits, commit) - return nil + return nil }) if err != nil { return err } // entity.Commits = commits - return nil + return nil } func (entity *RepoEntity) Diff(hash string) (diff string, err error) { @@ -79,12 +80,12 @@ func (entity *RepoEntity) Diff(hash string) (diff string, err error) { currentCommitIndex = i } } - if len(entity.Commits) -currentCommitIndex <= 1 { + if len(entity.Commits)-currentCommitIndex <= 1 { return "there is no diff", nil } commits, err := entity.Repository.Log(&git.LogOptions{ - From: plumbing.NewHash(entity.Commit.Hash), //plumbing.NewHash(entity.Commits[currentCommitIndex].Hash), + From: plumbing.NewHash(entity.Commit.Hash), //plumbing.NewHash(entity.Commits[currentCommitIndex].Hash), Order: git.LogOrderCommitterTime, }) if err != nil { @@ -92,18 +93,18 @@ func (entity *RepoEntity) Diff(hash string) (diff string, err error) { } currentCommit, err := commits.Next() - if err != nil { - return "", err - } + if err != nil { + return "", err + } currentTree, err := currentCommit.Tree() if err != nil { return diff, err } prevCommit, err := commits.Next() - if err != nil { - return "", err - } + if err != nil { + return "", err + } prevTree, err := prevCommit.Tree() if err != nil { return diff, err @@ -115,11 +116,11 @@ func (entity *RepoEntity) Diff(hash string) (diff string, err error) { } for _, c := range changes { - patch, err := c.Patch() - if err != nil { - break - } - diff = diff + patch.String() + "\n" + patch, err := c.Patch() + if err != nil { + break + } + diff = diff + patch.String() + "\n" } return diff, nil -}
\ No newline at end of file +} diff --git a/pkg/git/git-commands.go b/pkg/git/git-commands.go index 386c2ca..a1514e7 100644 --- a/pkg/git/git-commands.go +++ b/pkg/git/git-commands.go @@ -2,10 +2,10 @@ package git import ( "strings" + "github.com/isacikgoz/gitbatch/pkg/command" ) - // UpstreamDifferenceCount checks how many pushables/pullables there are for the // current branch // TODO: get pull pushes to remote branch vs local branch @@ -57,4 +57,4 @@ func (entity *RepoEntity) CheckoutWithGit(branch string) error { return err } return nil -}
\ No newline at end of file +} diff --git a/pkg/git/load.go b/pkg/git/load.go index 70a2475..f8032e8 100644 --- a/pkg/git/load.go +++ b/pkg/git/load.go @@ -33,4 +33,4 @@ func LoadRepositoryEntities(directories []string) (entities []*RepoEntity, err e // finished wg.Wait() return entities, nil -}
\ No newline at end of file +} diff --git a/pkg/git/remote.go b/pkg/git/remote.go index ec61fd7..ba05e1a 100644 --- a/pkg/git/remote.go +++ b/pkg/git/remote.go @@ -1,13 +1,10 @@ package git -import ( -) - type Remote struct { - Name string - URL []string - Branch *RemoteBranch - Branches []*RemoteBranch + Name string + URL []string + Branch *RemoteBranch + Branches []*RemoteBranch } func (entity *RepoEntity) NextRemote() error { @@ -23,7 +20,7 @@ func (entity *RepoEntity) NextRemote() error { } else { entity.Remote = entity.Remotes[currentRemoteIndex+1] } - + return nil } @@ -34,19 +31,19 @@ func (entity *RepoEntity) loadRemotes() error { remotes, err := r.Remotes() for _, rm := range remotes { - remote := &Remote{ - Name: rm.Config().Name, - URL: rm.Config().URLs, - } - remote.loadRemoteBranches(&r) - if len(remote.Branches) > 0 { - remote.Branch = remote.Branches[0] - } - entity.Remotes = append(entity.Remotes, remote) - + remote := &Remote{ + Name: rm.Config().Name, + URL: rm.Config().URLs, + } + remote.loadRemoteBranches(&r) + if len(remote.Branches) > 0 { + remote.Branch = remote.Branches[0] + } + entity.Remotes = append(entity.Remotes, remote) + } if err != nil { return err } return err -}
\ No newline at end of file +} diff --git a/pkg/git/remotebranch.go b/pkg/git/remotebranch.go index 8ccca53..435a259 100644 --- a/pkg/git/remotebranch.go +++ b/pkg/git/remotebranch.go @@ -1,10 +1,11 @@ package git import ( + "strings" + "gopkg.in/src-d/go-git.v4" "gopkg.in/src-d/go-git.v4/plumbing" "gopkg.in/src-d/go-git.v4/plumbing/storer" - "strings" ) type RemoteBranch struct { @@ -25,7 +26,7 @@ func (remote *Remote) NextRemoteBranch() error { } else { remote.Branch = remote.Branches[currentRemoteIndex+1] } - + return nil } @@ -39,9 +40,9 @@ func (remote *Remote) loadRemoteBranches(r *git.Repository) error { err = bs.ForEach(func(b *plumbing.Reference) error { if strings.Split(b.Name().Short(), "/")[0] == remote.Name { remote.Branches = append(remote.Branches, &RemoteBranch{ - Name: b.Name().Short(), + Name: b.Name().Short(), Reference: b, - }) + }) } return nil }) @@ -63,4 +64,4 @@ func remoteBranchesIter(s storer.ReferenceStorer) (storer.ReferenceIter, error) } return false }, refs), nil -}
\ No newline at end of file +} diff --git a/pkg/git/repository.go b/pkg/git/repository.go index 630f4cb..2c3770c 100644 --- a/pkg/git/repository.go +++ b/pkg/git/repository.go @@ -1,11 +1,12 @@ package git import ( - "gopkg.in/src-d/go-git.v4" - "github.com/isacikgoz/gitbatch/pkg/utils" + "errors" "os" "time" - "errors" + + "github.com/isacikgoz/gitbatch/pkg/utils" + "gopkg.in/src-d/go-git.v4" ) type RepoEntity struct { @@ -36,11 +37,11 @@ func InitializeRepository(directory string) (entity *RepoEntity, err error) { return nil, err } entity = &RepoEntity{RepoID: utils.NewHash(), - Name: fileInfo.Name(), - AbsPath: directory, - Repository: *r, - Marked: false, - } + Name: fileInfo.Name(), + AbsPath: directory, + Repository: *r, + Marked: false, + } entity.loadLocalBranches() entity.loadCommits() if len(entity.Commits) > 0 { @@ -120,4 +121,4 @@ func (entity *RepoEntity) Refresh() error { return err } return nil -}
\ No newline at end of file +} diff --git a/pkg/gui/branchview.go b/pkg/gui/branchview.go index 45d8527..5e61bff 100644 --- a/pkg/gui/branchview.go +++ b/pkg/gui/branchview.go @@ -1,55 +1,62 @@ package gui import ( - "github.com/isacikgoz/gitbatch/pkg/git" - "github.com/jroimartin/gocui" - "fmt" + "fmt" + + "github.com/isacikgoz/gitbatch/pkg/git" + "github.com/jroimartin/gocui" ) func (gui *Gui) updateBranch(g *gocui.Gui, entity *git.RepoEntity) error { - var err error - out, err := g.View("branch") - if err != nil { - return err - } - out.Clear() + var err error + out, err := g.View("branch") + if err != nil { + return err + } + out.Clear() - currentindex := 0 - totalbranches := len(entity.Branches) - for i, b := range entity.Branches { - if b.Name == entity.Branch.Name { - currentindex = i - fmt.Fprintln(out, selectionIndicator() + b.Name) - continue - } - fmt.Fprintln(out, tab() + b.Name) - } - if err = gui.smartAnchorRelativeToLine(out, currentindex, totalbranches); err != nil { - return err - } - return nil + currentindex := 0 + totalbranches := len(entity.Branches) + for i, b := range entity.Branches { + var suffix string + if !b.Clean { + suffix = " " + yellow.Sprint("✗") + } else { + suffix = " " + green.Sprint("✔") + } + if b.Name == entity.Branch.Name { + currentindex = i + fmt.Fprintln(out, selectionIndicator()+b.Name+suffix) + continue + } + fmt.Fprintln(out, tab()+b.Name+suffix) + } + if err = gui.smartAnchorRelativeToLine(out, currentindex, totalbranches); err != nil { + return err + } + return nil } func (gui *Gui) nextBranch(g *gocui.Gui, v *gocui.View) error { - var err error - entity, err := gui.getSelectedRepository(g, v) - if err != nil { - return err - } - if err = entity.Checkout(entity.NextBranch()); err != nil { - if err = gui.openErrorView(g, "Stage your changes before checkout", "You should manually manage this issue"); err != nil { - return err - } - return nil - } - if err = gui.updateBranch(g, entity); err != nil { - return err - } - if err = gui.updateCommits(g, entity); err != nil { - return err - } - if err = gui.refreshMain(g); err != nil { - return err - } - return nil -}
\ No newline at end of file + var err error + entity, err := gui.getSelectedRepository(g, v) + if err != nil { + return err + } + if err = entity.Checkout(entity.NextBranch()); err != nil { + if err = gui.openErrorView(g, "Stage your changes before checkout", "You should manually manage this issue"); err != nil { + return err + } + return nil + } + if err = gui.updateBranch(g, entity); err != nil { + return err + } + if err = gui.updateCommits(g, entity); err != nil { + return err + } + if err = gui.refreshMain(g); err != nil { + return err + } + return nil +} diff --git a/pkg/gui/cheatsheet.go b/pkg/gui/cheatsheet.go index bf26e7f..fcdf85f 100644 --- a/pkg/gui/cheatsheet.go +++ b/pkg/gui/cheatsheet.go @@ -1,40 +1,41 @@ package gui import ( - "github.com/jroimartin/gocui" - "fmt" + "fmt" + + "github.com/jroimartin/gocui" ) func (gui *Gui) openCheatSheetView(g *gocui.Gui, v *gocui.View) error { - maxX, maxY := g.Size() - v, err := g.SetView(cheatSheetViewFeature.Name, maxX/2-25, maxY/2-10, maxX/2+25, maxY/2+10) - if err != nil { - if err != gocui.ErrUnknownView { - return err - } - v.Title = cheatSheetViewFeature.Title - fmt.Fprintln(v, " ") - for _, k := range gui.KeyBindings { - if k.View == mainViewFeature.Name || k.View == "" { - binding := " " + k.Display + ": " + k.Description - fmt.Fprintln(v, binding) - } - } - } - gui.updateKeyBindingsView(g, cheatSheetViewFeature.Name) - if _, err := g.SetCurrentView(cheatSheetViewFeature.Name); err != nil { - return err - } - return nil + maxX, maxY := g.Size() + v, err := g.SetView(cheatSheetViewFeature.Name, maxX/2-25, maxY/2-10, maxX/2+25, maxY/2+10) + if err != nil { + if err != gocui.ErrUnknownView { + return err + } + v.Title = cheatSheetViewFeature.Title + fmt.Fprintln(v, " ") + for _, k := range gui.KeyBindings { + if k.View == mainViewFeature.Name || k.View == "" { + binding := " " + k.Display + ": " + k.Description + fmt.Fprintln(v, binding) + } + } + } + gui.updateKeyBindingsView(g, cheatSheetViewFeature.Name) + if _, err := g.SetCurrentView(cheatSheetViewFeature.Name); err != nil { + return err + } + return nil } func (gui *Gui) closeCheatSheetView(g *gocui.Gui, v *gocui.View) error { - if err := g.DeleteView(v.Name()); err != nil { - return nil - } - if _, err := g.SetCurrentView(mainViewFeature.Name); err != nil { - return err - } - gui.updateKeyBindingsView(g, mainViewFeature.Name) - return nil -}
\ No newline at end of file + if err := g.DeleteView(v.Name()); err != nil { + return nil + } + if _, err := g.SetCurrentView(mainViewFeature.Name); err != nil { + return err + } + gui.updateKeyBindingsView(g, mainViewFeature.Name) + return nil +} diff --git a/pkg/gui/commitsview.go b/pkg/gui/commitsview.go index 7cd2844..200b962 100644 --- a/pkg/gui/commitsview.go +++ b/pkg/gui/commitsview.go @@ -1,149 +1,150 @@ package gui import ( - "github.com/isacikgoz/gitbatch/pkg/git" - "github.com/jroimartin/gocui" - "fmt" - "strings" - "regexp" + "fmt" + "regexp" + "strings" + + "github.com/isacikgoz/gitbatch/pkg/git" + "github.com/jroimartin/gocui" ) func (gui *Gui) updateCommits(g *gocui.Gui, entity *git.RepoEntity) error { - var err error - out, err := g.View(commitViewFeature.Name) - if err != nil { - return err - } - out.Clear() + var err error + out, err := g.View(commitViewFeature.Name) + if err != nil { + return err + } + out.Clear() - currentindex := 0 - totalcommits := len(entity.Commits) - for i, c := range entity.Commits { - if c.Hash == entity.Commit.Hash { - currentindex = i - fmt.Fprintln(out, selectionIndicator() + green.Sprint(c.Hash[:git.Hashlimit]) + " " + c.Message) - continue - } - fmt.Fprintln(out, tab() + cyan.Sprint(c.Hash[:git.Hashlimit]) + " " + c.Message) - } - if err = gui.smartAnchorRelativeToLine(out, currentindex, totalcommits); err != nil { - return err - } - return nil + currentindex := 0 + totalcommits := len(entity.Commits) + for i, c := range entity.Commits { + if c.Hash == entity.Commit.Hash { + currentindex = i + fmt.Fprintln(out, selectionIndicator()+green.Sprint(c.Hash[:git.Hashlimit])+" "+c.Message) + continue + } + fmt.Fprintln(out, tab()+cyan.Sprint(c.Hash[:git.Hashlimit])+" "+c.Message) + } + if err = gui.smartAnchorRelativeToLine(out, currentindex, totalcommits); err != nil { + return err + } + return nil } func (gui *Gui) nextCommit(g *gocui.Gui, v *gocui.View) error { - var err error - entity, err := gui.getSelectedRepository(g, v) - if err != nil { - return err - } - if err = entity.NextCommit(); err != nil { - return err - } - if err = gui.updateCommits(g, entity); err != nil { - return err - } - return nil + var err error + entity, err := gui.getSelectedRepository(g, v) + if err != nil { + return err + } + if err = entity.NextCommit(); err != nil { + return err + } + if err = gui.updateCommits(g, entity); err != nil { + return err + } + return nil } func (gui *Gui) showCommitDetail(g *gocui.Gui, v *gocui.View) error { - maxX, maxY := g.Size() - v, err := g.SetView(commitdetailViewFeature.Name, 5, 3, maxX-5, maxY-3) - if err != nil { - if err != gocui.ErrUnknownView { - return err - } - v.Title = commitdetailViewFeature.Title - v.Overwrite = true - v.Wrap = true + maxX, maxY := g.Size() + v, err := g.SetView(commitdetailViewFeature.Name, 5, 3, maxX-5, maxY-3) + if err != nil { + if err != gocui.ErrUnknownView { + return err + } + v.Title = commitdetailViewFeature.Title + v.Overwrite = true + v.Wrap = true + + main, _ := g.View(mainViewFeature.Name) - main, _ := g.View(mainViewFeature.Name) + entity, err := gui.getSelectedRepository(g, main) + if err != nil { + return err + } + commit := entity.Commit + commitDetail := "Hash: " + cyan.Sprint(commit.Hash) + "\n" + "Author: " + commit.Author + "\n" + commit.Time.String() + "\n" + "\n" + "\t\t" + commit.Message + "\n" + fmt.Fprintln(v, commitDetail) + diff, err := entity.Diff(entity.Commit.Hash) + if err != nil { + return err + } + colorized := colorizeDiff(diff) + for _, line := range colorized { + fmt.Fprintln(v, line) + } + } - entity, err := gui.getSelectedRepository(g, main) - if err != nil { - return err - } - commit := entity.Commit - commitDetail := "Hash: " + cyan.Sprint(commit.Hash) + "\n" + "Author: " + commit.Author + "\n" + commit.Time.String() + "\n" + "\n" + "\t\t" + commit.Message + "\n" - fmt.Fprintln(v, commitDetail) - diff, err := entity.Diff(entity.Commit.Hash) - if err != nil { - return err - } - colorized := colorizeDiff(diff) - for _, line := range colorized{ - fmt.Fprintln(v, line) - } - } - - gui.updateKeyBindingsView(g, commitdetailViewFeature.Name) - if _, err := g.SetCurrentView(commitdetailViewFeature.Name); err != nil { - return err - } - return nil + gui.updateKeyBindingsView(g, commitdetailViewFeature.Name) + if _, err := g.SetCurrentView(commitdetailViewFeature.Name); err != nil { + return err + } + return nil } func (gui *Gui) closeCommitDetailView(g *gocui.Gui, v *gocui.View) error { - if err := g.DeleteView(v.Name()); err != nil { - return nil - } - if _, err := g.SetCurrentView(mainViewFeature.Name); err != nil { - return err - } - gui.updateKeyBindingsView(g, mainViewFeature.Name) - return nil + if err := g.DeleteView(v.Name()); err != nil { + return nil + } + if _, err := g.SetCurrentView(mainViewFeature.Name); err != nil { + return err + } + gui.updateKeyBindingsView(g, mainViewFeature.Name) + return nil } func (gui *Gui) commitCursorDown(g *gocui.Gui, v *gocui.View) error { - if v != nil { - ox, oy := v.Origin() - _, vy := v.Size() + if v != nil { + ox, oy := v.Origin() + _, vy := v.Size() - // TODO: do something when it hits bottom - if err := v.SetOrigin(ox, oy+vy/2); err != nil { - return err - } - } - return nil + // TODO: do something when it hits bottom + if err := v.SetOrigin(ox, oy+vy/2); err != nil { + return err + } + } + return nil } func (gui *Gui) commitCursorUp(g *gocui.Gui, v *gocui.View) error { - if v != nil { - ox, oy := v.Origin() - _, vy := v.Size() + if v != nil { + ox, oy := v.Origin() + _, vy := v.Size() - if oy-vy/2 > 0 { - if err := v.SetOrigin(ox, oy-vy/2); err != nil { - return err - } - } else if oy-vy/2 <= 0{ - if err := v.SetOrigin(0, 0); err != nil { - return err - } - } - } - return nil + if oy-vy/2 > 0 { + if err := v.SetOrigin(ox, oy-vy/2); err != nil { + return err + } + } else if oy-vy/2 <= 0 { + if err := v.SetOrigin(0, 0); err != nil { + return err + } + } + } + return nil } func colorizeDiff(original string) (colorized []string) { - colorized = strings.Split(original, "\n") - re := regexp.MustCompile(`@@ .+ @@`) - for i, line := range colorized { - if len(line) > 0 { - if line[0] == '-' { - colorized[i] = red.Sprint(line) - } else if line [0] == '+' { - colorized[i] = green.Sprint(line) - } else if re.MatchString(line) { - s := re.FindString(line) - colorized[i] = cyan.Sprint(s) + line[len(s):] - } else { - continue - } - } else { - continue - } - } - return colorized -}
\ No newline at end of file + colorized = strings.Split(original, "\n") + re := regexp.MustCompile(`@@ .+ @@`) + for i, line := range colorized { + if len(line) > 0 { + if line[0] == '-' { + colorized[i] = red.Sprint(line) + } else if line[0] == '+' { + colorized[i] = green.Sprint(line) + } else if re.MatchString(line) { + s := re.FindString(line) + colorized[i] = cyan.Sprint(s) + line[len(s):] + } else { + continue + } + } else { + continue + } + } + return colorized +} diff --git a/pkg/gui/errorview.go b/pkg/gui/errorview.go index bf3eaf9..cf44108 100644 --- a/pkg/gui/errorview.go +++ b/pkg/gui/errorview.go @@ -1,39 +1,40 @@ package gui import ( - "github.com/jroimartin/gocui" - "fmt" + "fmt" + + "github.com/jroimartin/gocui" ) func (gui *Gui) openErrorView(g *gocui.Gui, message string, note string) error { - maxX, maxY := g.Size() + maxX, maxY := g.Size() - v, err := g.SetView(errorViewFeature.Name, maxX/2-30, maxY/2-3, maxX/2+30, maxY/2+3) - if err != nil { - if err != gocui.ErrUnknownView { - return err - } - v.Title = errorViewFeature.Title - v.Wrap = true - ps := red.Sprint("Note:") + " " + note - fmt.Fprintln(v, message) - fmt.Fprintln(v, "\n" + ps) - } - gui.updateKeyBindingsView(g, errorViewFeature.Name) - if _, err := g.SetCurrentView(errorViewFeature.Name); err != nil { - return err - } - return nil + v, err := g.SetView(errorViewFeature.Name, maxX/2-30, maxY/2-3, maxX/2+30, maxY/2+3) + if err != nil { + if err != gocui.ErrUnknownView { + return err + } + v.Title = errorViewFeature.Title + v.Wrap = true + ps := red.Sprint("Note:") + " " + note + fmt.Fprintln(v, message) + fmt.Fprintln(v, "\n"+ps) + } + gui.updateKeyBindingsView(g, errorViewFeature.Name) + if _, err := g.SetCurrentView(errorViewFeature.Name); err != nil { + return err + } + return nil } func (gui *Gui) closeErrorView(g *gocui.Gui, v *gocui.View) error { - if err := g.DeleteView(v.Name()); err != nil { - return nil - } - if _, err := g.SetCurrentView(mainViewFeature.Name); err != nil { - return err - } - gui.updateKeyBindingsView(g, mainViewFeature.Name) - return nil -}
\ No newline at end of file + if err := g.DeleteView(v.Name()); err != nil { + return nil + } + if _, err := g.SetCurrentView(mainViewFeature.Name); err != nil { + return err + } + gui.updateKeyBindingsView(g, mainViewFeature.Name) + return nil +} diff --git a/pkg/gui/execview.go b/pkg/gui/execview.go index 6371e0e..e258f43 100644 --- a/pkg/gui/execview.go +++ b/pkg/gui/execview.go @@ -1,114 +1,115 @@ package gui import ( - "github.com/jroimartin/gocui" - "fmt" - "strconv" - "errors" + "errors" + "fmt" + "strconv" + + "github.com/jroimartin/gocui" ) func (gui *Gui) openExecConfirmationView(g *gocui.Gui, v *gocui.View) error { - maxX, maxY := g.Size() - err := gui.State.Queue.StartNext() - if err != nil { - return err - } - if mrs,_ := gui.getMarkedEntities(); len(mrs) < 1 { - return nil - } + maxX, maxY := g.Size() + err := gui.State.Queue.StartNext() + if err != nil { + return err + } + if mrs, _ := gui.getMarkedEntities(); len(mrs) < 1 { + return nil + } - v, err = g.SetView(execViewFeature.Name, maxX/2-35, maxY/2-5, maxX/2+35, maxY/2+5) - if err != nil { - if err != gocui.ErrUnknownView { - return err - } - v.Title = gui.State.Mode.DisplayString + " Confirmation" - v.Wrap = true - mrs, _ := gui.getMarkedEntities() - jobs := strconv.Itoa(len(mrs)) + " " + gui.State.Mode.ExecString + ":" - fmt.Fprintln(v, jobs) - for _, r := range mrs { - line := " - " + green.Sprint(r.Name) + ": " + r.Remote.Name + green.Sprint(" → ") + r.Branch.Name - fmt.Fprintln(v, line) - } - ps := red.Sprint("Note:") + " When " + gui.State.Mode.CommandString + " operation is completed, you will be notified." - fmt.Fprintln(v, "\n" + ps) - } - gui.updateKeyBindingsView(g, execViewFeature.Name) - if _, err := g.SetCurrentView(execViewFeature.Name); err != nil { - return err - } - return nil + v, err = g.SetView(execViewFeature.Name, maxX/2-35, maxY/2-5, maxX/2+35, maxY/2+5) + if err != nil { + if err != gocui.ErrUnknownView { + return err + } + v.Title = gui.State.Mode.DisplayString + " Confirmation" + v.Wrap = true + mrs, _ := gui.getMarkedEntities() + jobs := strconv.Itoa(len(mrs)) + " " + gui.State.Mode.ExecString + ":" + fmt.Fprintln(v, jobs) + for _, r := range mrs { + line := " - " + green.Sprint(r.Name) + ": " + r.Remote.Name + green.Sprint(" → ") + r.Branch.Name + fmt.Fprintln(v, line) + } + ps := red.Sprint("Note:") + " When " + gui.State.Mode.CommandString + " operation is completed, you will be notified." + fmt.Fprintln(v, "\n"+ps) + } + gui.updateKeyBindingsView(g, execViewFeature.Name) + if _, err := g.SetCurrentView(execViewFeature.Name); err != nil { + return err + } + return nil } func (gui *Gui) closeExecView(g *gocui.Gui, v *gocui.View) error { - go g.Update(func(g *gocui.Gui) error { - mainView,_ := g.View(mainViewFeature.Name) - entity, err := gui.getSelectedRepository(g, mainView) - if err != nil { - return err - } - gui.updateCommits(g, entity) - return nil - }) - if err := g.DeleteView(v.Name()); err != nil { - return nil - } - if _, err := g.SetCurrentView(mainViewFeature.Name); err != nil { - return err - } - gui.updateKeyBindingsView(g, mainViewFeature.Name) - return nil + go g.Update(func(g *gocui.Gui) error { + mainView, _ := g.View(mainViewFeature.Name) + entity, err := gui.getSelectedRepository(g, mainView) + if err != nil { + return err + } + gui.updateCommits(g, entity) + return nil + }) + if err := g.DeleteView(v.Name()); err != nil { + return nil + } + if _, err := g.SetCurrentView(mainViewFeature.Name); err != nil { + return err + } + gui.updateKeyBindingsView(g, mainViewFeature.Name) + return nil } func (gui *Gui) execute(g *gocui.Gui, v *gocui.View) error { - // somehow this fucntion called after this method returns, strange? - go g.Update(func(g *gocui.Gui) error { - err := updateKeyBindingsViewForExecution(g) - if err != nil { - return err - } - return nil - }) - - mrs, _ := gui.getMarkedEntities() - for _, mr := range mrs { - // here we will be waiting - switch mode := gui.State.Mode.ModeID; mode { - case FetchMode: - err := mr.Fetch() - if err != nil { - cv, _ := g.View(execViewFeature.Name) - gui.closeExecView(g, cv) - gui.openErrorView(g, err.Error(), "An error occured, manual resolving reuqired") - return nil - } - case PullMode: - err := mr.Pull() - if err != nil { - cv, _ := g.View(execViewFeature.Name) - gui.closeExecView(g, cv) - gui.openErrorView(g, err.Error(), "It maybe a conflict, manual resolving reuqired") - return nil - } - default: - return errors.New("No mode is selected") - } - mr.Unmark() - gui.refreshMain(g) - } - return nil + // somehow this fucntion called after this method returns, strange? + go g.Update(func(g *gocui.Gui) error { + err := updateKeyBindingsViewForExecution(g) + if err != nil { + return err + } + return nil + }) + + mrs, _ := gui.getMarkedEntities() + for _, mr := range mrs { + // here we will be waiting + switch mode := gui.State.Mode.ModeID; mode { + case FetchMode: + err := mr.Fetch() + if err != nil { + cv, _ := g.View(execViewFeature.Name) + gui.closeExecView(g, cv) + gui.openErrorView(g, err.Error(), "An error occured, manual resolving reuqired") + return nil + } + case PullMode: + err := mr.Pull() + if err != nil { + cv, _ := g.View(execViewFeature.Name) + gui.closeExecView(g, cv) + gui.openErrorView(g, err.Error(), "It maybe a conflict, manual resolving reuqired") + return nil + } + default: + return errors.New("No mode is selected") + } + mr.Unmark() + gui.refreshMain(g) + } + return nil } func updateKeyBindingsViewForExecution(g *gocui.Gui) error { - v, err := g.View(keybindingsViewFeature.Name) - if err != nil { - return err - } - v.Clear() - v.BgColor = gocui.ColorGreen - v.FgColor = gocui.ColorBlack - v.Frame = false - fmt.Fprintln(v, " Operation Completed; c: close/cancel") - return nil -}
\ No newline at end of file + v, err := g.View(keybindingsViewFeature.Name) + if err != nil { + return err + } + v.Clear() + v.BgColor = gocui.ColorGreen + v.FgColor = gocui.ColorBlack + v.Frame = false + fmt.Fprintln(v, " Operation Completed; c: close/cancel") + return nil +} diff --git a/pkg/gui/gui-util.go b/pkg/gui/gui-util.go index 2b65e97..73e9c85 100644 --- a/pkg/gui/gui-util.go +++ b/pkg/gui/gui-util.go @@ -1,119 +1,120 @@ package gui import ( - "github.com/fatih/color" - "github.com/isacikgoz/gitbatch/pkg/utils" - "github.com/isacikgoz/gitbatch/pkg/git" - "github.com/jroimartin/gocui" + "github.com/fatih/color" + "github.com/isacikgoz/gitbatch/pkg/git" + "github.com/isacikgoz/gitbatch/pkg/utils" + "github.com/jroimartin/gocui" ) + var ( - blue = color.New(color.FgBlue) - green = color.New(color.FgGreen) - red = color.New(color.FgRed) - cyan = color.New(color.FgCyan) - yellow = color.New(color.FgYellow) - white = color.New(color.FgWhite) - magenta = color.New(color.FgMagenta) + blue = color.New(color.FgBlue) + green = color.New(color.FgGreen) + red = color.New(color.FgRed) + cyan = color.New(color.FgCyan) + yellow = color.New(color.FgYellow) + white = color.New(color.FgWhite) + magenta = color.New(color.FgMagenta) ) func (gui *Gui) refreshViews(g *gocui.Gui, entity *git.RepoEntity) error { - if err := gui.updateRemotes(g, entity); err != nil { - return err - } - if err := gui.updateBranch(g, entity); err != nil { - return err - } - if err := gui.updateRemoteBranches(g, entity); err != nil { - return err - } - if err := gui.updateCommits(g, entity); err != nil { - return err - } - return nil + if err := gui.updateRemotes(g, entity); err != nil { + return err + } + if err := gui.updateBranch(g, entity); err != nil { + return err + } + if err := gui.updateRemoteBranches(g, entity); err != nil { + return err + } + if err := gui.updateCommits(g, entity); err != nil { + return err + } + return nil } func (gui *Gui) switchMode(g *gocui.Gui, v *gocui.View) error { - switch mode := gui.State.Mode.ModeID; mode { - case FetchMode: - gui.State.Mode = pullMode - case PullMode: - gui.State.Mode = fetchMode - default: - gui.State.Mode = fetchMode - } - gui.updateKeyBindingsView(g, mainViewFeature.Name) - gui.unMarkAllRepositories(g, v) - return nil + switch mode := gui.State.Mode.ModeID; mode { + case FetchMode: + gui.State.Mode = pullMode + case PullMode: + gui.State.Mode = fetchMode + default: + gui.State.Mode = fetchMode + } + gui.updateKeyBindingsView(g, mainViewFeature.Name) + gui.unMarkAllRepositories(g, v) + return nil } func (gui *Gui) 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) } // if the cursor down past the last item, move it to the last line func (gui *Gui) correctCursor(v *gocui.View) error { - cx, cy := v.Cursor() - ox, oy := v.Origin() - width, height := v.Size() - maxY := height - 1 - ly := width - 1 - if oy+cy <= ly { - return nil - } - newCy := utils.Min(ly, maxY) - if err := v.SetCursor(cx, newCy); err != nil { - return err - } - if err := v.SetOrigin(ox, ly-newCy); err != nil { - return err - } - return nil + cx, cy := v.Cursor() + ox, oy := v.Origin() + width, height := v.Size() + maxY := height - 1 + ly := width - 1 + if oy+cy <= ly { + return nil + } + newCy := utils.Min(ly, maxY) + if err := v.SetCursor(cx, newCy); err != nil { + return err + } + if err := v.SetOrigin(ox, ly-newCy); err != nil { + return err + } + return nil } -func (gui *Gui) smartAnchorRelativeToLine(v *gocui.View, currentindex, totallines int) error { +func (gui *Gui) smartAnchorRelativeToLine(v *gocui.View, currentindex, totallines int) error { - _, y := v.Size() - if currentindex >= int(0.5*float32(y)) && totallines - currentindex + int(0.5*float32(y)) >= y{ - if err := v.SetOrigin(0, currentindex - int(0.5*float32(y))); err != nil { - return err - } - } else if totallines - currentindex < y && totallines > y { - if err := v.SetOrigin(0, totallines -y ); err != nil { - return err - } - } else if totallines - currentindex <= int(0.5*float32(y)) && totallines > y -1 && currentindex > y { - if err := v.SetOrigin(0, currentindex - int(0.5*float32(y))); err != nil { - return err - } - } else { - if err := v.SetOrigin(0, 0); err != nil { - return err - } - } - return nil + _, y := v.Size() + if currentindex >= int(0.5*float32(y)) && totallines-currentindex+int(0.5*float32(y)) >= y { + if err := v.SetOrigin(0, currentindex-int(0.5*float32(y))); err != nil { + return err + } + } else if totallines-currentindex < y && totallines > y { + if err := v.SetOrigin(0, totallines-y); err != nil { + return err + } + } else if totallines-currentindex <= int(0.5*float32(y)) && totallines > y-1 && currentindex > y { + if err := v.SetOrigin(0, currentindex-int(0.5*float32(y))); err != nil { + return err + } + } else { + if err := v.SetOrigin(0, 0); err != nil { + return err + } + } + return nil } func selectionIndicator() string { - return green.Sprint("→ ") + return green.Sprint("→ ") } func tab() string { - return green.Sprint(" ") + return green.Sprint(" ") } func writeRightHandSide(v *gocui.View, text string, cx, cy int) error { - runes := []rune(text) - tl := len(runes) - lx, _ := v.Size() - v.MoveCursor(lx-tl, cy-1, true) - for i := tl-1; i >= 0; i-- { - v.EditDelete(true) - v.EditWrite(runes[i]) - } - v.SetCursor(cx, cy) - return nil -}
\ No newline at end of file + runes := []rune(text) + tl := len(runes) + lx, _ := v.Size() + v.MoveCursor(lx-tl, cy-1, true) + for i := tl - 1; i >= 0; i-- { + v.EditDelete(true) + v.EditWrite(runes[i]) + } + v.SetCursor(cx, cy) + return nil +} diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go index c171397..674a4b8 100644 --- a/pkg/gui/gui.go +++ b/pkg/gui/gui.go @@ -1,68 +1,69 @@ package gui import ( - "github.com/isacikgoz/gitbatch/pkg/git" - "github.com/isacikgoz/gitbatch/pkg/job" - "github.com/jroimartin/gocui" - "fmt" + "fmt" + + "github.com/isacikgoz/gitbatch/pkg/git" + "github.com/isacikgoz/gitbatch/pkg/job" + "github.com/jroimartin/gocui" ) type Gui struct { g *gocui.Gui - KeyBindings []*KeyBinding - State guiState + KeyBindings []*KeyBinding + State guiState } type guiState struct { - Repositories []*git.RepoEntity - Directories []string - Mode mode - Queue *job.JobQueue + Repositories []*git.RepoEntity + Directories []string + Mode mode + Queue *job.JobQueue } type viewFeature struct { - Name string - Title string + Name string + Title string } type mode struct { - ModeID ModeID - DisplayString string - CommandString string - ExecString string + ModeID ModeID + DisplayString string + CommandString string + ExecString string } type ModeID int8 const ( - FetchMode ModeID = 0 - PullMode ModeID = 1 + FetchMode ModeID = 0 + PullMode ModeID = 1 ) var ( - mainViewFeature = viewFeature{Name: "main", Title: " Matched Repositories "} - loadingViewFeature = viewFeature{Name: "loading", Title: " Loading in Progress "} - branchViewFeature = viewFeature{Name: "branch", Title: " Local Branches "} - remoteViewFeature = viewFeature{Name: "remotes", Title: " Remotes "} - remoteBranchViewFeature = viewFeature{Name: "remotebranches", Title: " Remote Branches "} - commitViewFeature = viewFeature{Name: "commits", Title: " Commits "} - scheduleViewFeature = viewFeature{Name: "schedule", Title: " Schedule "} - keybindingsViewFeature = viewFeature{Name: "keybindings", Title: " Keybindings "} - execViewFeature = viewFeature{Name: "execution", Title: " Execution Parameters "} - commitdetailViewFeature = viewFeature{Name: "commitdetail", Title: " Commit Detail "} - cheatSheetViewFeature = viewFeature{Name: "cheatsheet", Title: " Application Controls "} - errorViewFeature = viewFeature{Name: "error", Title: " Error "} + mainViewFeature = viewFeature{Name: "main", Title: " Matched Repositories "} + loadingViewFeature = viewFeature{Name: "loading", Title: " Loading in Progress "} + branchViewFeature = viewFeature{Name: "branch", Title: " Local Branches "} + remoteViewFeature = viewFeature{Name: "remotes", Title: " Remotes "} + remoteBranchViewFeature = viewFeature{Name: "remotebranches", Title: " Remote Branches "} + commitViewFeature = viewFeature{Name: "commits", Title: " Commits "} + scheduleViewFeature = viewFeature{Name: "schedule", Title: " Schedule "} + keybindingsViewFeature = viewFeature{Name: "keybindings", Title: " Keybindings "} + execViewFeature = viewFeature{Name: "execution", Title: " Execution Parameters "} + commitdetailViewFeature = viewFeature{Name: "commitdetail", Title: " Commit Detail "} + cheatSheetViewFeature = viewFeature{Name: "cheatsheet", Title: " Application Controls "} + errorViewFeature = viewFeature{Name: "error", Title: " Error "} - fetchMode = mode{ModeID: FetchMode, DisplayString: "Fetch", CommandString: "fetch", ExecString : "repositories will be fetched"} - pullMode = mode{ModeID: PullMode, DisplayString: "Pull", CommandString: "pull", ExecString : "repositories will be pulled"} + fetchMode = mode{ModeID: FetchMode, DisplayString: "Fetch", CommandString: "fetch", ExecString: "repositories will be fetched"} + pullMode = mode{ModeID: PullMode, DisplayString: "Pull", CommandString: "pull", ExecString: "repositories will be pulled"} ) func NewGui(directoies []string) (*Gui, error) { - initialState := guiState{ - Directories: directoies, - Mode: fetchMode, - Queue: job.CreateJobQueue(), - } + initialState := guiState{ + Directories: directoies, + Mode: fetchMode, + Queue: job.CreateJobQueue(), + } gui := &Gui{ State: initialState, } @@ -70,102 +71,102 @@ func NewGui(directoies []string) (*Gui, error) { } func (gui *Gui) Run() error { - g, err := gocui.NewGui(gocui.OutputNormal) - if err != nil { - return err - } - go func(g_ui *Gui) { - maxX, maxY := g.Size() - v, err := g.SetView(loadingViewFeature.Name, maxX/2-10, maxY/2-1, maxX/2+10, maxY/2+1) - if err != nil { - if err != gocui.ErrUnknownView { - return - } - fmt.Fprintln(v, "Loading...") - } - if _, err := g.SetCurrentView(loadingViewFeature.Name); err != nil { - return - } - rs, err := git.LoadRepositoryEntities(g_ui.State.Directories) - if err != nil { - return - } - g_ui.State.Repositories = rs - gui.fillMain(g) - }(gui) + g, err := gocui.NewGui(gocui.OutputNormal) + if err != nil { + return err + } + go func(g_ui *Gui) { + maxX, maxY := g.Size() + v, err := g.SetView(loadingViewFeature.Name, maxX/2-10, maxY/2-1, maxX/2+10, maxY/2+1) + if err != nil { + if err != gocui.ErrUnknownView { + return + } + fmt.Fprintln(v, "Loading...") + } + if _, err := g.SetCurrentView(loadingViewFeature.Name); err != nil { + return + } + rs, err := git.LoadRepositoryEntities(g_ui.State.Directories) + if err != nil { + return + } + g_ui.State.Repositories = rs + gui.fillMain(g) + }(gui) - defer g.Close() - gui.g = g - g.SetManagerFunc(gui.layout) + defer g.Close() + gui.g = g + g.SetManagerFunc(gui.layout) - if err := gui.generateKeybindings(); err != nil { - return err - } - if err := gui.keybindings(g); err != nil { - return err - } - if err := g.MainLoop(); err != nil && err != gocui.ErrQuit { - return err - } - return nil + if err := gui.generateKeybindings(); err != nil { + return err + } + if err := gui.keybindings(g); err != nil { + return err + } + if err := g.MainLoop(); err != nil && err != gocui.ErrQuit { + return err + } + return nil } func (gui *Gui) layout(g *gocui.Gui) error { - maxX, maxY := g.Size() - if v, err := g.SetView(mainViewFeature.Name, 0, 0, int(0.55*float32(maxX))-1, maxY-2); err != nil { - if err != gocui.ErrUnknownView { - return err - } - v.Title = mainViewFeature.Title - v.Highlight = true - v.SelBgColor = gocui.ColorWhite - v.SelFgColor = gocui.ColorBlack - v.Overwrite = true - } - if v, err := g.SetView(remoteViewFeature.Name, int(0.55*float32(maxX)), 0, maxX-1, int(0.10*float32(maxY))); err != nil { - if err != gocui.ErrUnknownView { - return err - } - v.Title = remoteViewFeature.Title - v.Wrap = false - v.Autoscroll = false - } - if v, err := g.SetView(remoteBranchViewFeature.Name, int(0.55*float32(maxX)), int(0.10*float32(maxY))+1, maxX-1, int(0.35*float32(maxY))); err != nil { - if err != gocui.ErrUnknownView { - return err - } - v.Title = remoteBranchViewFeature.Title - v.Wrap = false - v.Overwrite = false - } - if v, err := g.SetView(branchViewFeature.Name, int(0.55*float32(maxX)), int(0.35*float32(maxY))+1, maxX-1, int(0.60*float32(maxY))); err != nil { - if err != gocui.ErrUnknownView { - return err - } - v.Title = branchViewFeature.Title - v.Wrap = false - v.Autoscroll = false - } - if v, err := g.SetView(commitViewFeature.Name, int(0.55*float32(maxX)), int(0.60*float32(maxY))+1, maxX-1, maxY-2); err != nil { - if err != gocui.ErrUnknownView { - return err - } - v.Title = commitViewFeature.Title - v.Wrap = false - v.Autoscroll = false - } - if v, err := g.SetView(keybindingsViewFeature.Name, -1, maxY-2, maxX, maxY); err != nil { - if err != gocui.ErrUnknownView { - return err - } - v.BgColor = gocui.ColorWhite - v.FgColor = gocui.ColorBlack - v.Frame = false - gui.updateKeyBindingsView(g, mainViewFeature.Name) - } - return nil + maxX, maxY := g.Size() + if v, err := g.SetView(mainViewFeature.Name, 0, 0, int(0.55*float32(maxX))-1, maxY-2); err != nil { + if err != gocui.ErrUnknownView { + return err + } + v.Title = mainViewFeature.Title + v.Highlight = true + v.SelBgColor = gocui.ColorWhite + v.SelFgColor = gocui.ColorBlack + v.Overwrite = true + } + if v, err := g.SetView(remoteViewFeature.Name, int(0.55*float32(maxX)), 0, maxX-1, int(0.10*float32(maxY))); err != nil { + if err != gocui.ErrUnknownView { + return err + } + v.Title = remoteViewFeature.Title + v.Wrap = false + v.Autoscroll = false + } + if v, err := g.SetView(remoteBranchViewFeature.Name, int(0.55*float32(maxX)), int(0.10*float32(maxY))+1, maxX-1, int(0.35*float32(maxY))); err != nil { + if err != gocui.ErrUnknownView { + return err + } + v.Title = remoteBranchViewFeature.Title + v.Wrap = false + v.Overwrite = false + } + if v, err := g.SetView(branchViewFeature.Name, int(0.55*float32(maxX)), int(0.35*float32(maxY))+1, maxX-1, int(0.60*float32(maxY))); err != nil { + if err != gocui.ErrUnknownView { + return err + } + v.Title = branchViewFeature.Title + v.Wrap = false + v.Autoscroll = false + } + if v, err := g.SetView(commitViewFeature.Name, int(0.55*float32(maxX)), int(0.60*float32(maxY))+1, maxX-1, maxY-2); err != nil { + if err != gocui.ErrUnknownView { + return err + } + v.Title = commitViewFeature.Title + v.Wrap = false + v.Autoscroll = false + } + if v, err := g.SetView(keybindingsViewFeature.Name, -1, maxY-2, maxX, maxY); err != nil { + if err != gocui.ErrUnknownView { + return err + } + v.BgColor = gocui.ColorWhite + v.FgColor = gocui.ColorBlack + v.Frame = false + gui.updateKeyBindingsView(g, mainViewFeature.Name) + } + return nil } func (gui *Gui) quit(g *gocui.Gui, v *gocui.View) error { - return gocui.ErrQuit -}
\ No newline at end of file + return gocui.ErrQuit +} diff --git a/pkg/gui/keybindings.go b/pkg/gui/keybindings.go index 73f2629..51ce61c 100644 --- a/pkg/gui/keybindings.go +++ b/pkg/gui/keybindings.go @@ -1,234 +1,235 @@ package gui import ( - "github.com/jroimartin/gocui" - "fmt" + "fmt" + + "github.com/jroimartin/gocui" ) type KeyBinding struct { - View string - Handler func(*gocui.Gui, *gocui.View) error - Key interface{} - Modifier gocui.Modifier - Display string - Description string - Vital bool + View string + Handler func(*gocui.Gui, *gocui.View) error + Key interface{} + Modifier gocui.Modifier + Display string + Description string + Vital bool } func (gui *Gui) generateKeybindings() error { - gui.KeyBindings = []*KeyBinding{ - { - View: "", - Key: gocui.KeyCtrlC, - Modifier: gocui.ModNone, - Handler: gui.quit, - Display: "ctrl + c", - Description: "Force application to quit", - Vital: false, - },{ - View: mainViewFeature.Name, - Key: 'q', - Modifier: gocui.ModNone, - Handler: gui.quit, - Display: "q", - Description: "Quit", - Vital: true, - },{ - View: mainViewFeature.Name, - Key: gocui.KeyTab, - Modifier: gocui.ModNone, - Handler: gui.switchMode, - Display: "tab", - Description: "Switch mode", - Vital: true, - },{ - View: mainViewFeature.Name, - Key: gocui.KeyArrowUp, - Modifier: gocui.ModNone, - Handler: gui.cursorUp, - Display: "↑", - Description: "Up", - Vital: true, - },{ - View: mainViewFeature.Name, - Key: gocui.KeyArrowDown, - Modifier: gocui.ModNone, - Handler: gui.cursorDown, - Display: "↓", - Description: "Down", - Vital: true, - },{ - View: mainViewFeature.Name, - Key: 'b', - Modifier: gocui.ModNone, - Handler: gui.nextBranch, - Display: "b", - Description: "Iterate over branches", - Vital: false, - },{ - View: mainViewFeature.Name, - Key: 'r', - Modifier: gocui.ModNone, - Handler: gui.nextRemote, - Display: "r", - Description: "Iterate over remotes", - Vital: false, - },{ - View: mainViewFeature.Name, - Key: 'z', - Modifier: gocui.ModNone, - Handler: gui.nextRemoteBranch, - Display: "z", - Description: "Iterate over remote branches", - Vital: false, - },{ - View: mainViewFeature.Name, - Key: 's', - Modifier: gocui.ModNone, - Handler: gui.nextCommit, - Display: "s", - Description: "Iterate over commits", - Vital: false, - },{ - View: mainViewFeature.Name, - Key: 'x', - Modifier: gocui.ModNone, - Handler: gui.showCommitDetail, - Display: "x", - Description: "Show commit diff", - Vital: false, - },{ - View: mainViewFeature.Name, - Key: 'c', - Modifier: gocui.ModNone, - Handler: gui.openCheatSheetView, - Display: "c", - Description: "Open cheatsheet window", - Vital: false, - },{ - View: mainViewFeature.Name, - Key: gocui.KeyEnter, - Modifier: gocui.ModNone, - Handler: gui.openExecConfirmationView, - Display: "enter", - Description: "Execute jobs", - Vital: true, - },{ - View: mainViewFeature.Name, - Key: gocui.KeySpace, - Modifier: gocui.ModNone, - Handler: gui.markRepository, - Display: "space", - Description: "Select", - Vital: true, - },{ - View: mainViewFeature.Name, - Key: 'a', - Modifier: gocui.ModNone, - Handler: gui.markAllRepositories, - Display: "a", - Description: "Select all", - Vital: false, - },{ - View: mainViewFeature.Name, - Key: 'd', - Modifier: gocui.ModNone, - Handler: gui.unMarkAllRepositories, - Display: "d", - Description: "Deselect all", - Vital: false, - },{ - View: commitdetailViewFeature.Name, - Key: 'c', - Modifier: gocui.ModNone, - Handler: gui.closeCommitDetailView, - Display: "c", - Description: "close/cancel", - Vital: true, - },{ - View: commitdetailViewFeature.Name, - Key: gocui.KeyArrowUp, - Modifier: gocui.ModNone, - Handler: gui.commitCursorUp, - Display: "↑", - Description: "Page up", - Vital: true, - },{ - View: commitdetailViewFeature.Name, - Key: gocui.KeyArrowDown, - Modifier: gocui.ModNone, - Handler: gui.commitCursorDown, - Display: "↓", - Description: "Page down", - Vital: true, - },{ - View: cheatSheetViewFeature.Name, - Key: 'c', - Modifier: gocui.ModNone, - Handler: gui.closeCheatSheetView, - Display: "c", - Description: "close/cancel", - Vital: true, - },{ - View: execViewFeature.Name, - Key: 'c', - Modifier: gocui.ModNone, - Handler: gui.closeExecView, - Display: "c", - Description: "close/cancel", - Vital: true, - },{ - View: execViewFeature.Name, - Key: gocui.KeyEnter, - Modifier: gocui.ModNone, - Handler: gui.execute, - Display: "enter", - Description: "Execute", - Vital: true, - },{ - View: errorViewFeature.Name, - Key: 'c', - Modifier: gocui.ModNone, - Handler: gui.closeErrorView, - Display: "c", - Description: "close/cancel", - Vital: true, - }, - } - return nil + gui.KeyBindings = []*KeyBinding{ + { + View: "", + Key: gocui.KeyCtrlC, + Modifier: gocui.ModNone, + Handler: gui.quit, + Display: "ctrl + c", + Description: "Force application to quit", + Vital: false, + }, { + View: mainViewFeature.Name, + Key: 'q', + Modifier: gocui.ModNone, + Handler: gui.quit, + Display: "q", + Description: "Quit", + Vital: true, + }, { + View: mainViewFeature.Name, + Key: gocui.KeyTab, + Modifier: gocui.ModNone, + Handler: gui.switchMode, + Display: "tab", + Description: "Switch mode", + Vital: true, + }, { + View: mainViewFeature.Name, + Key: gocui.KeyArrowUp, + Modifier: gocui.ModNone, + Handler: gui.cursorUp, + Display: "↑", + Description: "Up", + Vital: true, + }, { + View: mainViewFeature.Name, + Key: gocui.KeyArrowDown, + Modifier: gocui.ModNone, + Handler: gui.cursorDown, + Display: "↓", + Description: "Down", + Vital: true, + }, { + View: mainViewFeature.Name, + Key: 'b', + Modifier: gocui.ModNone, + Handler: gui.nextBranch, + Display: "b", + Description: "Iterate over branches", + Vital: false, + }, { + View: mainViewFeature.Name, + Key: 'r', + Modifier: gocui.ModNone, + Handler: gui.nextRemote, + Display: "r", + Description: "Iterate over remotes", + Vital: false, + }, { + View: mainViewFeature.Name, + Key: 'z', + Modifier: gocui.ModNone, + Handler: gui.nextRemoteBranch, + Display: "z", + Description: "Iterate over remote branches", + Vital: false, + }, { + View: mainViewFeature.Name, + Key: 's', + Modifier: gocui.ModNone, + Handler: gui.nextCommit, + Display: "s", + Description: "Iterate over commits", + Vital: false, + }, { + View: mainViewFeature.Name, + Key: 'x', + Modifier: gocui.ModNone, + Handler: gui.showCommitDetail, + Display: "x", + Description: "Show commit diff", + Vital: false, + }, { + View: mainViewFeature.Name, + Key: 'c', + Modifier: gocui.ModNone, + Handler: gui.openCheatSheetView, + Display: "c", + Description: "Open cheatsheet window", + Vital: false, + }, { + View: mainViewFeature.Name, + Key: gocui.KeyEnter, + Modifier: gocui.ModNone, + Handler: gui.openExecConfirmationView, + Display: "enter", + Description: "Execute jobs", + Vital: true, + }, { + View: mainViewFeature.Name, + Key: gocui.KeySpace, + Modifier: gocui.ModNone, + Handler: gui.markRepository, + Display: "space", + Description: "Select", + Vital: true, + }, { + View: mainViewFeature.Name, + Key: 'a', + Modifier: gocui.ModNone, + Handler: gui.markAllRepositories, + Display: "a", + Description: "Select all", + Vital: false, + }, { + View: mainViewFeature.Name, + Key: 'd', + Modifier: gocui.ModNone, + Handler: gui.unMarkAllRepositories, + Display: "d", + Description: "Deselect all", + Vital: false, + }, { + View: commitdetailViewFeature.Name, + Key: 'c', + Modifier: gocui.ModNone, + Handler: gui.closeCommitDetailView, + Display: "c", + Description: "close/cancel", + Vital: true, + }, { + View: commitdetailViewFeature.Name, + Key: gocui.KeyArrowUp, + Modifier: gocui.ModNone, + Handler: gui.commitCursorUp, + Display: "↑", + Description: "Page up", + Vital: true, + }, { + View: commitdetailViewFeature.Name, + Key: gocui.KeyArrowDown, + Modifier: gocui.ModNone, + Handler: gui.commitCursorDown, + Display: "↓", + Description: "Page down", + Vital: true, + }, { + View: cheatSheetViewFeature.Name, + Key: 'c', + Modifier: gocui.ModNone, + Handler: gui.closeCheatSheetView, + Display: "c", + Description: "close/cancel", + Vital: true, + }, { + View: execViewFeature.Name, + Key: 'c', + Modifier: gocui.ModNone, + Handler: gui.closeExecView, + Display: "c", + Description: "close/cancel", + Vital: true, + }, { + View: execViewFeature.Name, + Key: gocui.KeyEnter, + Modifier: gocui.ModNone, + Handler: gui.execute, + Display: "enter", + Description: "Execute", + Vital: true, + }, { + View: errorViewFeature.Name, + Key: 'c', + Modifier: gocui.ModNone, + Handler: gui.closeErrorView, + Display: "c", + Description: "close/cancel", + Vital: true, + }, + } + return nil } func (gui *Gui) keybindings(g *gocui.Gui) error { - for _, k := range gui.KeyBindings { - if err := g.SetKeybinding(k.View, k.Key, k.Modifier, k.Handler); err != nil { - return err - } - } - return nil + for _, k := range gui.KeyBindings { + if err := g.SetKeybinding(k.View, k.Key, k.Modifier, k.Handler); err != nil { + return err + } + } + return nil } func (gui *Gui) updateKeyBindingsView(g *gocui.Gui, viewName string) error { - v, err := g.View(keybindingsViewFeature.Name) - if err != nil { - return err - } - v.Clear() - v.BgColor = gocui.ColorWhite - v.FgColor = gocui.ColorBlack - v.Frame = false - for _, k := range gui.KeyBindings { - if k.View == viewName && k.Vital { - binding := " " + k.Display + ": " + k.Description + " |" - fmt.Fprint(v, binding) - } - } - switch mode := gui.State.Mode.ModeID; mode { - case FetchMode: - writeRightHandSide(v, "Fetch", 0, 0) - case PullMode: - writeRightHandSide(v, "Pull", 0, 0) - default: - writeRightHandSide(v, "No-Mode", 0, 0) - } - return nil -}
\ No newline at end of file + v, err := g.View(keybindingsViewFeature.Name) + if err != nil { + return err + } + v.Clear() + v.BgColor = gocui.ColorWhite + v.FgColor = gocui.ColorBlack + v.Frame = false + for _, k := range gui.KeyBindings { + if k.View == viewName && k.Vital { + binding := " " + k.Display + ": " + k.Description + " |" + fmt.Fprint(v, binding) + } + } + switch mode := gui.State.Mode.ModeID; mode { + case FetchMode: + writeRightHandSide(v, "Fetch", 0, 0) + case PullMode: + writeRightHandSide(v, "Pull", 0, 0) + default: + writeRightHandSide(v, "No-Mode", 0, 0) + } + return nil +} diff --git a/pkg/gui/mainview.go b/pkg/gui/mainview.go index 9c69f65..346bdc4 100644 --- a/pkg/gui/mainview.go +++ b/pkg/gui/mainview.go @@ -1,205 +1,206 @@ package gui import ( - "fmt" - "sync" - "github.com/isacikgoz/gitbatch/pkg/git" - "github.com/isacikgoz/gitbatch/pkg/job" - "github.com/jroimartin/gocui" - "regexp" + "fmt" + "regexp" + "sync" + + "github.com/isacikgoz/gitbatch/pkg/git" + "github.com/isacikgoz/gitbatch/pkg/job" + "github.com/jroimartin/gocui" ) func (gui *Gui) fillMain(g *gocui.Gui) error { - g.Update(func(g *gocui.Gui) error { - v, err := g.View(mainViewFeature.Name) - if err != nil { - return err - } - for _, r := range gui.State.Repositories { - fmt.Fprintln(v, displayString(r)) - } - err = g.DeleteView(loadingViewFeature.Name) - if err != nil { - return err - } - if _, err = gui.setCurrentViewOnTop(g, mainViewFeature.Name); err != nil { - return err - } - if entity, err := gui.getSelectedRepository(g, v); err != nil { - return err - } else { - gui.refreshViews(g, entity) - } - return nil - }) - return nil + g.Update(func(g *gocui.Gui) error { + v, err := g.View(mainViewFeature.Name) + if err != nil { + return err + } + for _, r := range gui.State.Repositories { + fmt.Fprintln(v, displayString(r)) + } + err = g.DeleteView(loadingViewFeature.Name) + if err != nil { + return err + } + if _, err = gui.setCurrentViewOnTop(g, mainViewFeature.Name); err != nil { + return err + } + if entity, err := gui.getSelectedRepository(g, v); err != nil { + return err + } else { + gui.refreshViews(g, entity) + } + return nil + }) + return nil } func (gui *Gui) cursorDown(g *gocui.Gui, v *gocui.View) error { - if v != nil { - cx, cy := v.Cursor() - ox, oy := v.Origin() - ly := len(gui.State.Repositories) -1 + if v != nil { + cx, cy := v.Cursor() + ox, oy := v.Origin() + ly := len(gui.State.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 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 := gui.getSelectedRepository(g, v); err != nil { - return err - } else { - gui.refreshViews(g, entity) - } - } - return nil + if err := v.SetOrigin(ox, oy+1); err != nil { + return err + } + } + if entity, err := gui.getSelectedRepository(g, v); err != nil { + return err + } else { + gui.refreshViews(g, entity) + } + } + return nil } func (gui *Gui) 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 entity, err := gui.getSelectedRepository(g, v); err != nil { - return err - } else { - gui.refreshViews(g, entity) - } - } - 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 := gui.getSelectedRepository(g, v); err != nil { + return err + } else { + gui.refreshViews(g, entity) + } + } + return nil } func (gui *Gui) 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 - } - rg := regexp.MustCompile(` → .+ `) - ss := rg.Split(l, 5) - for _, sr := range gui.State.Repositories { - if ss[len(ss)-1] == sr.Name { - return sr, nil - } - } - return r, err + _, cy := v.Cursor() + if l, err = v.Line(cy); err != nil { + return r, err + } + rg := regexp.MustCompile(` → .+ `) + ss := rg.Split(l, 5) + for _, sr := range gui.State.Repositories { + if ss[len(ss)-1] == sr.Name { + return sr, nil + } + } + return r, err } func (gui *Gui) markRepository(g *gocui.Gui, v *gocui.View) error { - if r, err := gui.getSelectedRepository(g, v); err != nil { - return err - } else { - if err != nil { - return err - } - if !r.Branch.Clean { - if err = gui.openErrorView(g, "Stage your changes before pull", "You should manually resolve this issue"); err != nil { - return err - } - return nil - } - if !r.Marked { - r.Mark() - err := gui.State.Queue.AddJob(&job.Job{ - JobType: job.Fetch, - RepoID: r.RepoID, - Name: r.Name, - Args: make([]string, 0), - }) - if err != nil { - return err - } - } else { - err := gui.State.Queue.RemoveFromQueue(r.RepoID) - if err != nil { - return err - } - r.Unmark() - } - gui.refreshMain(g) - } - return nil + if r, err := gui.getSelectedRepository(g, v); err != nil { + return err + } else { + if err != nil { + return err + } + if !r.Branch.Clean { + if err = gui.openErrorView(g, "Stage your changes before pull", "You should manually resolve this issue"); err != nil { + return err + } + return nil + } + if !r.Marked { + r.Mark() + err := gui.State.Queue.AddJob(&job.Job{ + JobType: job.Fetch, + RepoID: r.RepoID, + Name: r.Name, + Args: make([]string, 0), + }) + if err != nil { + return err + } + } else { + err := gui.State.Queue.RemoveFromQueue(r.RepoID) + if err != nil { + return err + } + r.Unmark() + } + gui.refreshMain(g) + } + return nil } func (gui *Gui) markAllRepositories(g *gocui.Gui, v *gocui.View) error { - for _, r := range gui.State.Repositories { - if r.Branch.Clean { - r.Mark() - } - } - if err := gui.refreshMain(g); err !=nil { - return err - } - return nil + for _, r := range gui.State.Repositories { + if r.Branch.Clean { + r.Mark() + } + } + if err := gui.refreshMain(g); err != nil { + return err + } + return nil } func (gui *Gui) unMarkAllRepositories(g *gocui.Gui, v *gocui.View) error { - for _, r := range gui.State.Repositories { - r.Unmark() - } - if err := gui.refreshMain(g); err !=nil { - return err - } - return nil + for _, r := range gui.State.Repositories { + r.Unmark() + } + if err := gui.refreshMain(g); err != nil { + return err + } + return nil } func (gui *Gui) refreshMain(g *gocui.Gui) error { - - mainView, err := g.View(mainViewFeature.Name) - if err != nil { - return err - } - mainView.Clear() - for _, r := range gui.State.Repositories { - fmt.Fprintln(mainView, displayString(r)) - } - return nil + + mainView, err := g.View(mainViewFeature.Name) + if err != nil { + return err + } + mainView.Clear() + for _, r := range gui.State.Repositories { + fmt.Fprintln(mainView, displayString(r)) + } + return nil } func (gui *Gui) getMarkedEntities() (rs []*git.RepoEntity, err error) { - var wg sync.WaitGroup - var mu sync.Mutex - for _, r := range gui.State.Repositories { - wg.Add(1) - go func(repo *git.RepoEntity){ - defer wg.Done() - if repo.Marked { - mu.Lock() - rs = append(rs, repo) - mu.Unlock() - } - }(r) - } - wg.Wait() - return rs, nil + var wg sync.WaitGroup + var mu sync.Mutex + for _, r := range gui.State.Repositories { + wg.Add(1) + go func(repo *git.RepoEntity) { + defer wg.Done() + if repo.Marked { + mu.Lock() + rs = append(rs, repo) + mu.Unlock() + } + }(r) + } + wg.Wait() + return rs, nil } -func displayString(entity *git.RepoEntity) string{ - prefix := "" - if entity.Branch.Pushables != "?" { - prefix = prefix + string(blue.Sprint("↑")) + "" + entity.Branch.Pushables + " " + - string(blue.Sprint("↓")) + "" + entity.Branch.Pullables + string(magenta.Sprint(" → ")) - } else { - prefix = prefix + magenta.Sprint("?") + string(yellow.Sprint(" → ")) - } - prefix = prefix + string(cyan.Sprint(entity.Branch.Name)) + " " - if entity.Marked { - return prefix + string(green.Sprint(entity.Name)) - } else if !entity.Branch.Clean { - return prefix + string(yellow.Sprint(entity.Name)) - } else { - return prefix + string(white.Sprint(entity.Name)) - } -}
\ No newline at end of file +func displayString(entity *git.RepoEntity) string { + prefix := "" + if entity.Branch.Pushables != "?" { + prefix = prefix + string(blue.Sprint("↑")) + "" + entity.Branch.Pushables + " " + + string(blue.Sprint("↓")) + "" + entity.Branch.Pullables + string(magenta.Sprint(" → ")) + } else { + prefix = prefix + magenta.Sprint("?") + string(yellow.Sprint(" → ")) + } + prefix = prefix + string(cyan.Sprint(entity.Branch.Name)) + " " + if entity.Marked { + return prefix + string(green.Sprint(entity.Name)) + } else if !entity.Branch.Clean { + return prefix + string(yellow.Sprint(entity.Name)) + } else { + return prefix + string(white.Sprint(entity.Name)) + } +} diff --git a/pkg/gui/remotebranchview.go b/pkg/gui/remotebranchview.go index 7238f91..adc5dcb 100644 --- a/pkg/gui/remotebranchview.go +++ b/pkg/gui/remotebranchview.go @@ -1,50 +1,51 @@ package gui import ( - "github.com/isacikgoz/gitbatch/pkg/git" - "github.com/jroimartin/gocui" - "fmt" + "fmt" + + "github.com/isacikgoz/gitbatch/pkg/git" + "github.com/jroimartin/gocui" ) func (gui *Gui) updateRemoteBranches(g *gocui.Gui, entity *git.RepoEntity) error { - var err error + var err error - out, err := g.View(remoteBranchViewFeature.Name) - if err != nil { - return err - } - out.Clear() - currentindex := 0 - trb := len(entity.Remote.Branches) - if trb > 0 { - for i, r := range entity.Remote.Branches { - if r.Name == entity.Remote.Branch.Name { - currentindex = i - fmt.Fprintln(out, selectionIndicator() + r.Name) - continue - } - fmt.Fprintln(out, tab() + r.Name) - } - if err = gui.smartAnchorRelativeToLine(out, currentindex, trb); err != nil { - return err - } - } - return nil + out, err := g.View(remoteBranchViewFeature.Name) + if err != nil { + return err + } + out.Clear() + currentindex := 0 + trb := len(entity.Remote.Branches) + if trb > 0 { + for i, r := range entity.Remote.Branches { + if r.Name == entity.Remote.Branch.Name { + currentindex = i + fmt.Fprintln(out, selectionIndicator()+r.Name) + continue + } + fmt.Fprintln(out, tab()+r.Name) + } + if err = gui.smartAnchorRelativeToLine(out, currentindex, trb); err != nil { + return err + } + } + return nil } func (gui *Gui) nextRemoteBranch(g *gocui.Gui, v *gocui.View) error { - var err error - entity, err := gui.getSelectedRepository(g, v) - if err != nil { - return err - } + var err error + entity, err := gui.getSelectedRepository(g, v) + if err != nil { + return err + } - if err = entity.Remote.NextRemoteBranch(); err != nil { - return err - } + if err = entity.Remote.NextRemoteBranch(); err != nil { + return err + } - if err = gui.updateRemoteBranches(g, entity); err != nil { - return err - } - return nil -}
\ No newline at end of file + if err = gui.updateRemoteBranches(g, entity); err != nil { + return err + } + return nil +} diff --git a/pkg/gui/remotesview.go b/pkg/gui/remotesview.go index 5d3b924..bbc6ce4 100644 --- a/pkg/gui/remotesview.go +++ b/pkg/gui/remotesview.go @@ -1,55 +1,56 @@ package gui import ( - "github.com/isacikgoz/gitbatch/pkg/git" - "github.com/isacikgoz/gitbatch/pkg/utils" - "github.com/jroimartin/gocui" - "fmt" + "fmt" + + "github.com/isacikgoz/gitbatch/pkg/git" + "github.com/isacikgoz/gitbatch/pkg/utils" + "github.com/jroimartin/gocui" ) func (gui *Gui) updateRemotes(g *gocui.Gui, entity *git.RepoEntity) error { - var err error + var err error - out, err := g.View(remoteViewFeature.Name) - if err != nil { - return err - } - out.Clear() + out, err := g.View(remoteViewFeature.Name) + if err != nil { + return err + } + out.Clear() - currentindex := 0 - totalRemotes := len(entity.Remotes) - if totalRemotes > 0 { - for i, r := range entity.Remotes { - URLtype, shortURL := utils.TrimRemoteURL(r.URL[0]) - suffix := "(" + URLtype + ")" + " " + shortURL - if r.Name == entity.Remote.Name { - currentindex = i - fmt.Fprintln(out, selectionIndicator() + r.Name + ": " + suffix) - continue - } - fmt.Fprintln(out, tab() + r.Name + ": " + suffix) - } - if err = gui.smartAnchorRelativeToLine(out, currentindex, totalRemotes); err != nil { - return err - } - } - return nil + currentindex := 0 + totalRemotes := len(entity.Remotes) + if totalRemotes > 0 { + for i, r := range entity.Remotes { + URLtype, shortURL := utils.TrimRemoteURL(r.URL[0]) + suffix := "(" + URLtype + ")" + " " + shortURL + if r.Name == entity.Remote.Name { + currentindex = i + fmt.Fprintln(out, selectionIndicator()+r.Name+": "+suffix) + continue + } + fmt.Fprintln(out, tab()+r.Name+": "+suffix) + } + if err = gui.smartAnchorRelativeToLine(out, currentindex, totalRemotes); err != nil { + return err + } + } + return nil } func (gui *Gui) nextRemote(g *gocui.Gui, v *gocui.View) error { - var err error - entity, err := gui.getSelectedRepository(g, v) - if err != nil { - return err - } - if err = entity.NextRemote(); err != nil { - return err - } - if err = gui.updateRemotes(g, entity); err != nil { - return err - } - if err = gui.updateRemoteBranches(g, entity); err != nil { - return err - } - return nil -}
\ No newline at end of file + var err error + entity, err := gui.getSelectedRepository(g, v) + if err != nil { + return err + } + if err = entity.NextRemote(); err != nil { + return err + } + if err = gui.updateRemotes(g, entity); err != nil { + return err + } + if err = gui.updateRemoteBranches(g, entity); err != nil { + return err + } + return nil +} diff --git a/pkg/job/job.go b/pkg/job/job.go index 6bd5f4d..0e756d8 100644 --- a/pkg/job/job.go +++ b/pkg/job/job.go @@ -1,15 +1,15 @@ package job import ( - "fmt" "errors" + "fmt" ) type Job struct { - JobType JobType - RepoID string - Name string - Args []string + JobType JobType + RepoID string + Name string + Args []string } type JobQueue struct { @@ -19,8 +19,8 @@ type JobQueue struct { type JobType string const ( - Fetch JobType = "FETCH" - Pull JobType = "PULL" + Fetch JobType = "FETCH" + Pull JobType = "PULL" ) func CreateJob() (j *Job, err error) { @@ -68,7 +68,7 @@ func (jobQueue *JobQueue) StartNext() error { func (jobQueue *JobQueue) RemoveFromQueue(repoID string) error { removed := false for i, job := range jobQueue.series { - if job.RepoID == repoID{ + if job.RepoID == repoID { jobQueue.series = append(jobQueue.series[:i], jobQueue.series[i+1:]...) removed = true } @@ -77,4 +77,4 @@ func (jobQueue *JobQueue) RemoveFromQueue(repoID string) error { return errors.New("There is no job with given repoID") } return nil -}
\ No newline at end of file +} diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index 4855cbd..05fcc8e 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -1,12 +1,12 @@ package utils import ( - "strings" - "regexp" + "crypto/sha1" + "fmt" "math/rand" + "regexp" + "strings" "time" - "fmt" - "crypto/sha1" ) var characterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789") @@ -69,4 +69,4 @@ func NewHash(n ...int) string { bs := hash.Sum(nil) return fmt.Sprintf("%x", bs) -}
\ No newline at end of file +} |
