diff options
| author | Ibrahim Serdar Acikgoz <serdaracikgoz86@gmail.com> | 2018-12-18 23:54:54 +0300 |
|---|---|---|
| committer | Ibrahim Serdar Acikgoz <serdaracikgoz86@gmail.com> | 2018-12-18 23:54:54 +0300 |
| commit | 44b3f9cf27cb4e4c5a0ab07f82685afa6d28a0c8 (patch) | |
| tree | 3747cb46200821616a89b77a1fc142aaaff7606f | |
| parent | go style refactoring on variable names and minor improvements (diff) | |
| download | gitbatch-44b3f9cf27cb4e4c5a0ab07f82685afa6d28a0c8.tar.gz | |
minor code style imrovements and code reduction
| -rw-r--r-- | pkg/git/cmd-commit.go | 2 | ||||
| -rw-r--r-- | pkg/git/remote.go | 6 | ||||
| -rw-r--r-- | pkg/git/remotebranch.go | 15 | ||||
| -rw-r--r-- | pkg/git/repository.go | 31 | ||||
| -rw-r--r-- | pkg/gui/commitview.go | 29 | ||||
| -rw-r--r-- | pkg/gui/diffview.go | 18 | ||||
| -rw-r--r-- | pkg/gui/mainview.go | 59 | ||||
| -rw-r--r-- | pkg/gui/sideviews.go | 170 | ||||
| -rw-r--r-- | pkg/gui/stagedview.go | 19 | ||||
| -rw-r--r-- | pkg/gui/stashview.go | 24 | ||||
| -rw-r--r-- | pkg/gui/statusview.go | 33 | ||||
| -rw-r--r-- | pkg/gui/unstagedview.go | 12 | ||||
| -rw-r--r-- | pkg/gui/util-queuehandler.go | 36 | ||||
| -rw-r--r-- | pkg/gui/util-textstyle.go | 62 |
14 files changed, 232 insertions, 284 deletions
diff --git a/pkg/git/cmd-commit.go b/pkg/git/cmd-commit.go index b06b6fb..6e836ab 100644 --- a/pkg/git/cmd-commit.go +++ b/pkg/git/cmd-commit.go @@ -55,6 +55,7 @@ func commitWithGit(e *RepoEntity, options CommitOptions) (err error) { } if err := GenericGitCommand(e.AbsPath, args); err != nil { log.Warn("Error at git command (commit)") + e.Refresh() return err } // till this step everything should be ok @@ -84,6 +85,7 @@ func commitWithGoGit(e *RepoEntity, options CommitOptions) (err error) { _, err = w.Commit(options.CommitMsg, opt) if err != nil { + e.Refresh() return err } // till this step everything should be ok diff --git a/pkg/git/remote.go b/pkg/git/remote.go index c8442af..72c8ddd 100644 --- a/pkg/git/remote.go +++ b/pkg/git/remote.go @@ -18,13 +18,15 @@ type Remote struct { // NextRemote iterates over next branch of a remote func (e *RepoEntity) NextRemote() error { e.Remote = e.Remotes[(e.currentRemoteIndex()+1)%len(e.Remotes)] - return e.Remote.SyncBranches(e.Branch.Name) + e.Remote.SyncBranches(e.Branch.Name) + return e.Publish(RepositoryUpdated, nil) } // PreviousRemote iterates over previous branch of a remote func (e *RepoEntity) PreviousRemote() error { e.Remote = e.Remotes[(len(e.Remotes)+e.currentRemoteIndex()-1)%len(e.Remotes)] - return e.Remote.SyncBranches(e.Branch.Name) + e.Remote.SyncBranches(e.Branch.Name) + return e.Publish(RepositoryUpdated, nil) } // returns the active remote index diff --git a/pkg/git/remotebranch.go b/pkg/git/remotebranch.go index 5fa1335..207f5a9 100644 --- a/pkg/git/remotebranch.go +++ b/pkg/git/remotebranch.go @@ -14,19 +14,18 @@ import ( type RemoteBranch struct { Name string Reference *plumbing.Reference - Deleted bool } // NextRemoteBranch iterates to the next remote branch -func (r *Remote) NextRemoteBranch() error { +func (r *Remote) NextRemoteBranch(e *RepoEntity) error { r.Branch = r.Branches[(r.currentRemoteBranchIndex()+1)%len(r.Branches)] - return nil + return e.Publish(RepositoryUpdated, nil) } // PreviousRemoteBranch iterates to the previous remote branch -func (r *Remote) PreviousRemoteBranch() error { +func (r *Remote) PreviousRemoteBranch(e *RepoEntity) error { r.Branch = r.Branches[(len(r.Branches)+r.currentRemoteBranchIndex()-1)%len(r.Branches)] - return nil + return e.Publish(RepositoryUpdated, nil) } // returns the active remote branch index @@ -42,21 +41,19 @@ func (r *Remote) currentRemoteBranchIndex() int { // search for the remote branches of the remote. It takes the go-git's repo // pointer in order to get storer struct -func (r *Remote) loadRemoteBranches(entity *RepoEntity) error { +func (r *Remote) loadRemoteBranches(e *RepoEntity) error { r.Branches = make([]*RemoteBranch, 0) - bs, err := remoteBranchesIter(entity.Repository.Storer) + bs, err := remoteBranchesIter(e.Repository.Storer) if err != nil { log.Warn("Cannot initiate iterator " + err.Error()) return err } defer bs.Close() err = bs.ForEach(func(b *plumbing.Reference) error { - deleted := false if strings.Split(b.Name().Short(), "/")[0] == r.Name { r.Branches = append(r.Branches, &RemoteBranch{ Name: b.Name().Short(), Reference: b, - Deleted: deleted, }) } return nil diff --git a/pkg/git/repository.go b/pkg/git/repository.go index 6d9226f..28c95cd 100644 --- a/pkg/git/repository.go +++ b/pkg/git/repository.go @@ -44,22 +44,27 @@ type RepositoryEvent struct { } // RepoState is the state of the repository for an operation -type RepoState uint8 +type RepoState struct { + State uint8 + Ready bool +} -const ( +var ( // Available implies repo is ready for the operation - Available RepoState = 0 + Available = RepoState{State: 0, Ready: true} // Queued means repo is queued for a operation - Queued RepoState = 1 + Queued = RepoState{State: 1, Ready: false} // Working means an operation is just started for this repository - Working RepoState = 2 + Working = RepoState{State: 2, Ready: false} // Paused is expected when a user interaction is required - Paused RepoState = 3 + Paused = RepoState{State: 3, Ready: true} // Success is the expected outcome of the operation - Success RepoState = 4 + Success = RepoState{State: 4, Ready: true} // Fail is the unexpected outcome of the operation - Fail RepoState = 5 + Fail = RepoState{State: 5, Ready: false} +) +const ( // This is the repository updated topic RepositoryUpdated = "repository.updated" ) @@ -90,8 +95,8 @@ func FastInitializeRepo(dir string) (e *RepoEntity, err error) { } // InitializeRepo initializes a RepoEntity struct with its belongings. -func InitializeRepo(directory string) (e *RepoEntity, err error) { - e, err = FastInitializeRepo(directory) +func InitializeRepo(dir string) (e *RepoEntity, err error) { + e, err = FastInitializeRepo(dir) if err != nil { return nil, err } @@ -100,8 +105,8 @@ func InitializeRepo(directory string) (e *RepoEntity, err error) { } // loadComponents initializes the fields of a repository such as branches, -// remotes, commits etc. -func (e *RepoEntity) loadComponents(hard bool) error { +// remotes, commits etc. If reset, reload commit, remote pointers too +func (e *RepoEntity) loadComponents(reset bool) error { if err := e.loadLocalBranches(); err != nil { return err } @@ -114,7 +119,7 @@ func (e *RepoEntity) loadComponents(hard bool) error { if err := e.loadStashedItems(); err != nil { log.Warn("Cannot load stashes") } - if hard { + if reset { // handle if there is no commit, maybe? // set commit pointer for repository if len(e.Commits) > 0 { diff --git a/pkg/gui/commitview.go b/pkg/gui/commitview.go index 0f22091..0810621 100644 --- a/pkg/gui/commitview.go +++ b/pkg/gui/commitview.go @@ -52,16 +52,12 @@ func (gui *Gui) openCommitMessageView(g *gocui.Gui, v *gocui.View) error { if err := gui.openCommitUserEmailView(g); err != nil { return err } - gui.updateKeyBindingsView(g, commitMessageViewFeature.Name) - if _, err := g.SetCurrentView(commitMessageViewFeature.Name); err != nil { - return err - } - return nil + return gui.focusToView(commitMessageViewFeature.Name) } // open an error view to inform user with a message and a useful note func (gui *Gui) openCommitUserNameView(g *gocui.Gui) error { - entity := gui.getSelectedRepository() + e := gui.getSelectedRepository() maxX, maxY := g.Size() // first, create the label for user vlabel, err := g.SetView(commitUserNameLabelFeature.Name, maxX/2-30, maxY/2, maxX/2-19, maxY/2+2) @@ -78,7 +74,7 @@ func (gui *Gui) openCommitUserNameView(g *gocui.Gui) error { if err != gocui.ErrUnknownView { return err } - name, err := git.Config(entity, git.ConfigOptions{ + name, err := git.Config(e, git.ConfigOptions{ Section: "user", Option: "name", }) @@ -94,7 +90,7 @@ func (gui *Gui) openCommitUserNameView(g *gocui.Gui) error { // open an error view to inform user with a message and a useful note func (gui *Gui) openCommitUserEmailView(g *gocui.Gui) error { - entity := gui.getSelectedRepository() + e := gui.getSelectedRepository() maxX, maxY := g.Size() // first, create the label for password vlabel, err := g.SetView(commitUserEmailLabelViewFeature.Name, maxX/2-30, maxY/2+1, maxX/2-19, maxY/2+3) @@ -111,7 +107,7 @@ func (gui *Gui) openCommitUserEmailView(g *gocui.Gui) error { if err != gocui.ErrUnknownView { return err } - email, err := git.Config(entity, git.ConfigOptions{ + email, err := git.Config(e, git.ConfigOptions{ Section: "user", Option: "email", }) @@ -127,7 +123,7 @@ func (gui *Gui) openCommitUserEmailView(g *gocui.Gui) error { // close the opened commite mesage view func (gui *Gui) submitCommitMessageView(g *gocui.Gui, v *gocui.View) error { - entity := gui.getSelectedRepository() + e := gui.getSelectedRepository() // in order to read buffer of the views, first we need to find'em v_msg, err := g.View(commitMessageViewFeature.Name) v_name, err := g.View(commitUserUserViewFeature.Name) @@ -141,7 +137,7 @@ func (gui *Gui) submitCommitMessageView(g *gocui.Gui, v *gocui.View) error { if len(email) <= 0 { return errors.New("User email needs to be provided") } - err = git.CommitCommand(entity, git.CommitOptions{ + err = git.CommitCommand(e, git.CommitOptions{ CommitMsg: msg, User: name, Email: email, @@ -149,20 +145,17 @@ func (gui *Gui) submitCommitMessageView(g *gocui.Gui, v *gocui.View) error { if err != nil { return err } - entity.Refresh() - err = gui.closeCommitMessageView(g, v) - return err + return gui.closeCommitMessageView(g, v) } // focus to next view func (gui *Gui) nextCommitView(g *gocui.Gui, v *gocui.View) error { - err := gui.nextViewOfGroup(g, v, commitViews) - return err + return gui.nextViewOfGroup(g, v, commitViews) } // close the opened commite mesage view func (gui *Gui) closeCommitMessageView(g *gocui.Gui, v *gocui.View) error { - entity := gui.getSelectedRepository() + e := gui.getSelectedRepository() g.Cursor = false for _, view := range commitViews { if err := g.DeleteView(view.Name); err != nil { @@ -174,7 +167,7 @@ func (gui *Gui) closeCommitMessageView(g *gocui.Gui, v *gocui.View) error { return err } } - if err := refreshAllStatusView(g, entity, true); err != nil { + if err := refreshAllStatusView(g, e, true); err != nil { return err } return gui.closeViewCleanup(commitMesageReturnView) diff --git a/pkg/gui/diffview.go b/pkg/gui/diffview.go index caf42fc..9a47f95 100644 --- a/pkg/gui/diffview.go +++ b/pkg/gui/diffview.go @@ -34,11 +34,11 @@ func (gui *Gui) prepareDiffView(g *gocui.Gui, v *gocui.View, display []string) ( // open diff view for the selcted commit // called from commitview, so initial view is commitview func (gui *Gui) openCommitDiffView(g *gocui.Gui, v *gocui.View) (err error) { - entity := gui.getSelectedRepository() - commit := entity.Commit + e := gui.getSelectedRepository() + commit := e.Commit commitDetail := []string{("Hash: " + cyan.Sprint(commit.Hash) + "\n" + "Author: " + commit.Author + "\n" + commit.Time + "\n" + "\n" + "\t\t" + commit.Message + "\n")} - diff, err := git.Diff(entity, entity.Commit.Hash) + diff, err := git.Diff(e, e.Commit.Hash) if err != nil { return err } @@ -56,15 +56,15 @@ func (gui *Gui) openCommitDiffView(g *gocui.Gui, v *gocui.View) (err error) { // called from status, so initial view may be stagedview or unstaged view func (gui *Gui) openFileDiffView(g *gocui.Gui, v *gocui.View) (err error) { - entity := gui.getSelectedRepository() + e := gui.getSelectedRepository() _, cy := v.Cursor() _, oy := v.Origin() var files []*git.File switch v.Name() { case unstageViewFeature.Name: - _, files, err = populateFileLists(entity) + _, files, err = populateFileLists(e) case stageViewFeature.Name: - files, _, err = populateFileLists(entity) + files, _, err = populateFileLists(e) } if err != nil { return err @@ -95,13 +95,13 @@ func (gui *Gui) openFileDiffView(g *gocui.Gui, v *gocui.View) (err error) { // called from stashview, so initial view is stashview func (gui *Gui) showStash(g *gocui.Gui, v *gocui.View) (err error) { - entity := gui.getSelectedRepository() + e := gui.getSelectedRepository() _, oy := v.Origin() _, cy := v.Cursor() - if len(entity.Stasheds) <= 0 { + if len(e.Stasheds) <= 0 { return nil } - stashedItem := entity.Stasheds[oy+cy] + stashedItem := e.Stasheds[oy+cy] output, err := stashedItem.Show() if err != nil { if err = gui.openErrorView(g, output, diff --git a/pkg/gui/mainview.go b/pkg/gui/mainview.go index 6bd55d9..e4c0159 100644 --- a/pkg/gui/mainview.go +++ b/pkg/gui/mainview.go @@ -6,6 +6,7 @@ import ( "github.com/isacikgoz/gitbatch/pkg/git" "github.com/jroimartin/gocui" + log "github.com/sirupsen/logrus" ) // this is the initial function for filling the values for the main view. the @@ -24,8 +25,8 @@ func (gui *Gui) fillMain(g *gocui.Gui) error { if _, err = gui.setCurrentViewOnTop(g, mainViewFeature.Name); err != nil { return err } - // Sort by name is default behavior as expected, so it handles redrwaing - // the main view + // Sort by name is default behavior as expected, so it handles initial + // rendering of the main view if err = gui.sortByName(g, v); err != nil { return err } @@ -35,7 +36,7 @@ func (gui *Gui) fillMain(g *gocui.Gui) error { } // refresh the main view and re-render the repository representations -func (gui *Gui) refreshMain() error { +func (gui *Gui) renderMain() error { gui.mutex.Lock() defer gui.mutex.Unlock() @@ -45,17 +46,17 @@ func (gui *Gui) refreshMain() error { } mainView.Clear() for _, r := range gui.State.Repositories { - fmt.Fprintln(mainView, gui.displayString(r)) + fmt.Fprintln(mainView, gui.repositoryLabel(r)) } // while refreshing, refresh sideViews for selected entity, something may // be changed? - return gui.refreshSideViews(gui.getSelectedRepository()) + return gui.renderSideViews(gui.getSelectedRepository()) } // listens the event -> "repository.updated" func (gui *Gui) repositoryUpdated(event *git.RepositoryEvent) error { gui.g.Update(func(g *gocui.Gui) error { - return gui.refreshMain() + return gui.renderMain() }) return nil } @@ -78,7 +79,7 @@ func (gui *Gui) cursorDown(g *gocui.Gui, v *gocui.View) error { } } } - return gui.refreshMain() + return gui.renderMain() } // moves the cursor upwards for the main view @@ -92,7 +93,7 @@ func (gui *Gui) cursorUp(g *gocui.Gui, v *gocui.View) error { } } } - return gui.refreshMain() + return gui.renderMain() } // returns the entity at cursors position by taking its position in the gui's @@ -103,9 +104,6 @@ func (gui *Gui) getSelectedRepository() *git.RepoEntity { v, _ := gui.g.View(mainViewFeature.Name) _, oy := v.Origin() _, cy := v.Cursor() - // if _, err := v.Line(cy); err != nil { - // return r, err - // } return gui.State.Repositories[cy+oy] } @@ -143,12 +141,41 @@ func (gui *Gui) removeFromQueue(entity *git.RepoEntity) error { return nil } +// this function starts the queue and updates the gui with the result of an +// operation +func (gui *Gui) startQueue(g *gocui.Gui, v *gocui.View) error { + go func(gui_go *Gui, g_go *gocui.Gui) { + for { + job, finished, err := gui_go.State.Queue.StartNext() + + if err != nil { + if err == git.ErrAuthenticationRequired { + // pause the job, so it will be indicated to being blocking + job.Entity.SetState(git.Paused) + err := gui_go.openAuthenticationView(g, gui_go.State.Queue, job, v.Name()) + if err != nil { + log.Warn(err.Error()) + return + } + } + return + // with not returning here, we simply ignore and continue + } + // if queue is finished simply return from this goroutine + if finished { + return + } + } + }(gui, g) + return nil +} + // marking repository is simply adding the repostirory into the queue. the // function does take its current state into account before adding it func (gui *Gui) markRepository(g *gocui.Gui, v *gocui.View) error { r := gui.getSelectedRepository() // maybe, failed entities may be added to queue again - if r.State() == git.Available || r.State() == git.Success || r.State() == git.Paused { + if r.State().Ready { if err := gui.addToQueue(r); err != nil { return err } @@ -156,8 +183,6 @@ func (gui *Gui) markRepository(g *gocui.Gui, v *gocui.View) error { if err := gui.removeFromQueue(r); err != nil { return err } - } else { - return nil } return nil } @@ -166,7 +191,7 @@ func (gui *Gui) markRepository(g *gocui.Gui, v *gocui.View) error { // current state into account before adding it func (gui *Gui) markAllRepositories(g *gocui.Gui, v *gocui.View) error { for _, r := range gui.State.Repositories { - if r.State() == git.Available || r.State() == git.Success { + if r.State().Ready { if err := gui.addToQueue(r); err != nil { return err } @@ -195,7 +220,7 @@ func (gui *Gui) unmarkAllRepositories(g *gocui.Gui, v *gocui.View) error { // sortByName sorts the repositories by A to Z order func (gui *Gui) sortByName(g *gocui.Gui, v *gocui.View) error { sort.Sort(git.Alphabetical(gui.State.Repositories)) - gui.refreshMain() + gui.renderMain() return nil } @@ -203,6 +228,6 @@ func (gui *Gui) sortByName(g *gocui.Gui, v *gocui.View) error { // the top element will be the last modified func (gui *Gui) sortByMod(g *gocui.Gui, v *gocui.View) error { sort.Sort(git.LastModified(gui.State.Repositories)) - gui.refreshMain() + gui.renderMain() return nil } diff --git a/pkg/gui/sideviews.go b/pkg/gui/sideviews.go index 21ce55e..6316255 100644 --- a/pkg/gui/sideviews.go +++ b/pkg/gui/sideviews.go @@ -13,45 +13,42 @@ var ( ) // refreshes the side views of the application for given git.RepoEntity struct -func (gui *Gui) refreshSideViews(entity *git.RepoEntity) error { +func (gui *Gui) renderSideViews(e *git.RepoEntity) error { var err error - if err = gui.updateRemotes(entity); err != nil { + if err = gui.renderRemotes(e); err != nil { return err } - if err = gui.updateBranch(entity); err != nil { + if err = gui.renderBranch(e); err != nil { return err } - if err = gui.updateRemoteBranches(entity); err != nil { + if err = gui.renderRemoteBranches(e); err != nil { return err } - if err = gui.updateCommits(entity); err != nil { + if err = gui.renderCommits(e); err != nil { return err } return err } // updates the remotesview for given entity -func (gui *Gui) updateRemotes(entity *git.RepoEntity) error { +func (gui *Gui) renderRemotes(e *git.RepoEntity) error { var err error out, err := gui.g.View(remoteViewFeature.Name) if err != nil { return err } out.Clear() - currentindex := 0 - totalRemotes := len(entity.Remotes) + totalRemotes := len(e.Remotes) if totalRemotes > 0 { - for i, r := range entity.Remotes { - // TODO: maybe the text styling can be moved to textstyle.go file + for i, r := range e.Remotes { _, shortURL := trimRemoteURL(r.URL[0]) - suffix := shortURL - if r.Name == entity.Remote.Name { + if r.Name == e.Remote.Name { currentindex = i - fmt.Fprintln(out, selectionIndicator+r.Name+": "+suffix) + fmt.Fprintln(out, selectionIndicator+r.Name+": "+shortURL) continue } - fmt.Fprintln(out, tab+r.Name+": "+suffix) + fmt.Fprintln(out, tab+r.Name+": "+shortURL) } if err = gui.smartAnchorRelativeToLine(out, currentindex, totalRemotes); err != nil { return err @@ -61,7 +58,7 @@ func (gui *Gui) updateRemotes(entity *git.RepoEntity) error { } // updates the remotebranchview for given entity -func (gui *Gui) updateRemoteBranches(entity *git.RepoEntity) error { +func (gui *Gui) renderRemoteBranches(e *git.RepoEntity) error { var err error out, err := gui.g.View(remoteBranchViewFeature.Name) if err != nil { @@ -69,19 +66,15 @@ func (gui *Gui) updateRemoteBranches(entity *git.RepoEntity) error { } out.Clear() currentindex := 0 - trb := len(entity.Remote.Branches) + trb := len(e.Remote.Branches) if trb > 0 { - for i, r := range entity.Remote.Branches { - rName := r.Name - if r.Deleted { - rName = rName + ws + dirty - } - if r.Name == entity.Remote.Branch.Name { + for i, r := range e.Remote.Branches { + if r.Name == e.Remote.Branch.Name { currentindex = i - fmt.Fprintln(out, selectionIndicator+rName) + fmt.Fprintln(out, selectionIndicator+r.Name) continue } - fmt.Fprintln(out, tab+rName) + fmt.Fprintln(out, tab+r.Name) } if err = gui.smartAnchorRelativeToLine(out, currentindex, trb); err != nil { return err @@ -91,18 +84,17 @@ func (gui *Gui) updateRemoteBranches(entity *git.RepoEntity) error { } // updates the branchview for given entity -func (gui *Gui) updateBranch(entity *git.RepoEntity) error { +func (gui *Gui) renderBranch(e *git.RepoEntity) error { var err error out, err := gui.g.View(branchViewFeature.Name) 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 { + totalbranches := len(e.Branches) + for i, b := range e.Branches { + if b.Name == e.Branch.Name { currentindex = i fmt.Fprintln(out, selectionIndicator+b.Name) continue @@ -114,31 +106,22 @@ func (gui *Gui) updateBranch(entity *git.RepoEntity) error { } // updates the commitsview for given entity -func (gui *Gui) updateCommits(entity *git.RepoEntity) error { +func (gui *Gui) renderCommits(e *git.RepoEntity) error { var err error out, err := gui.g.View(commitViewFeature.Name) if err != nil { return err } out.Clear() - currentindex := 0 - totalcommits := len(entity.Commits) - for i, c := range entity.Commits { - var body string - if c.CommitType == git.EvenCommit { - body = cyan.Sprint(c.Hash[:hashLength]) + " " + c.Message - } else if c.CommitType == git.LocalCommit { - body = blue.Sprint(c.Hash[:hashLength]) + " " + c.Message - } else { - body = yellow.Sprint(c.Hash[:hashLength]) + " " + c.Message - } - if c.Hash == entity.Commit.Hash { + totalcommits := len(e.Commits) + for i, c := range e.Commits { + if c.Hash == e.Commit.Hash { currentindex = i - fmt.Fprintln(out, selectionIndicator+body) + fmt.Fprintln(out, selectionIndicator+commitLabel(c)) continue } - fmt.Fprintln(out, tab+body) + fmt.Fprintln(out, tab+commitLabel(c)) } if err = gui.smartAnchorRelativeToLine(out, currentindex, totalcommits); err != nil { return err @@ -146,138 +129,103 @@ func (gui *Gui) updateCommits(entity *git.RepoEntity) error { return err } +// cursor down variant for sideviews func (gui *Gui) sideViewsNextItem(g *gocui.Gui, v *gocui.View) error { var err error - entity := gui.getSelectedRepository() + e := gui.getSelectedRepository() switch viewName := v.Name(); viewName { case remoteBranchViewFeature.Name: - if err = entity.Remote.NextRemoteBranch(); err != nil { - return err - } - err = gui.updateRemoteBranches(entity) + return e.Remote.NextRemoteBranch(e) case remoteViewFeature.Name: - if err = entity.NextRemote(); err != nil { - return err - } - err = gui.remoteChangeFollowUp(entity) + return e.NextRemote() case branchViewFeature.Name: - if err = entity.Checkout(entity.NextBranch()); err != nil { + if err = e.Checkout(e.NextBranch()); err != nil { err = gui.openErrorView(g, err.Error(), "You should manually resolve this issue", branchViewFeature.Name) return err } - // err = gui.checkoutFollowUp(entity) case commitViewFeature.Name: - entity.NextCommit() - - err = gui.updateCommits(entity) + e.NextCommit() + return gui.renderCommits(e) } return err } +// cursor up variant for sideviews func (gui *Gui) sideViewsPreviousItem(g *gocui.Gui, v *gocui.View) error { var err error - entity := gui.getSelectedRepository() + e := gui.getSelectedRepository() switch viewName := v.Name(); viewName { case remoteBranchViewFeature.Name: - if err = entity.Remote.PreviousRemoteBranch(); err != nil { - return err - } - err = gui.updateRemoteBranches(entity) + return e.Remote.PreviousRemoteBranch(e) case remoteViewFeature.Name: - if err = entity.PreviousRemote(); err != nil { - return err - } - err = gui.remoteChangeFollowUp(entity) + return e.PreviousRemote() case branchViewFeature.Name: - if err = entity.Checkout(entity.PreviousBranch()); err != nil { + if err = e.Checkout(e.PreviousBranch()); err != nil { err = gui.openErrorView(g, err.Error(), "You should manually resolve this issue", branchViewFeature.Name) return err } - // err = gui.checkoutFollowUp(entity) case commitViewFeature.Name: - entity.PreviousCommit() - - err = gui.updateCommits(entity) + e.PreviousCommit() + return gui.renderCommits(e) } return err } // basically does fetch --prune func (gui *Gui) syncRemoteBranch(g *gocui.Gui, v *gocui.View) error { - var err error - entity := gui.getSelectedRepository() - if err = git.Fetch(entity, git.FetchOptions{ - RemoteName: entity.Remote.Name, + e := gui.getSelectedRepository() + return git.Fetch(e, git.FetchOptions{ + RemoteName: e.Remote.Name, Prune: true, - }); err != nil { - return err - } - vr, err := g.View(remoteViewFeature.Name) - if err != nil { - return err - } - // have no idea why this works.. - // some time need to fix, movement aint bad huh? - gui.sideViewsNextItem(g, vr) - gui.sideViewsPreviousItem(g, vr) - err = gui.updateRemoteBranches(entity) - return err + }) } -// basically does fetch --prune +// opens a confirmation view for setting default merge branch func (gui *Gui) setUpstreamToBranch(g *gocui.Gui, v *gocui.View) error { maxX, maxY := g.Size() - entity := gui.getSelectedRepository() + e := gui.getSelectedRepository() v, err := g.SetView(confirmationViewFeature.Name, maxX/2-30, maxY/2-2, maxX/2+30, maxY/2+2) if err != nil { if err != gocui.ErrUnknownView { return err } - fmt.Fprintln(v, "branch."+entity.Branch.Name+"."+"remote"+"="+entity.Remote.Name) - fmt.Fprintln(v, "branch."+entity.Branch.Name+"."+"merge"+"="+entity.Branch.Reference.Name().String()) + fmt.Fprintln(v, "branch."+e.Branch.Name+"."+"remote"+"="+e.Remote.Name) + fmt.Fprintln(v, "branch."+e.Branch.Name+"."+"merge"+"="+e.Branch.Reference.Name().String()) } return gui.focusToView(confirmationViewFeature.Name) } -// basically does fetch --prune +// add config for upstream merge func (gui *Gui) confirmSetUpstreamToBranch(g *gocui.Gui, v *gocui.View) error { var err error - entity := gui.getSelectedRepository() - if err = git.AddConfig(entity, git.ConfigOptions{ - Section: "branch." + entity.Branch.Name, + e := gui.getSelectedRepository() + if err = git.AddConfig(e, git.ConfigOptions{ + Section: "branch." + e.Branch.Name, Option: "remote", Site: git.ConfigSiteLocal, - }, entity.Remote.Name); err != nil { + }, e.Remote.Name); err != nil { return err } - if err = git.AddConfig(entity, git.ConfigOptions{ - Section: "branch." + entity.Branch.Name, + if err = git.AddConfig(e, git.ConfigOptions{ + Section: "branch." + e.Branch.Name, Option: "merge", Site: git.ConfigSiteLocal, - }, entity.Branch.Reference.Name().String()); err != nil { + }, e.Branch.Reference.Name().String()); err != nil { return err } - entity.Refresh() + e.Refresh() return gui.closeConfirmationView(g, v) } +// close confirmation view func (gui *Gui) closeConfirmationView(g *gocui.Gui, v *gocui.View) error { if err := g.DeleteView(v.Name()); err != nil { return err } return gui.closeViewCleanup(branchViewFeature.Name) } - -// after checkout a remote some refreshments needed -func (gui *Gui) remoteChangeFollowUp(entity *git.RepoEntity) (err error) { - if err = gui.updateRemotes(entity); err != nil { - return err - } - err = gui.updateRemoteBranches(entity) - return err -} diff --git a/pkg/gui/stagedview.go b/pkg/gui/stagedview.go index 4a6beb9..a1c9737 100644 --- a/pkg/gui/stagedview.go +++ b/pkg/gui/stagedview.go @@ -18,44 +18,43 @@ func (gui *Gui) openStageView(g *gocui.Gui) error { } v.Title = stageViewFeature.Title } - entity := gui.getSelectedRepository() - if err := refreshStagedView(g, entity); err != nil { + if err := refreshStagedView(g); err != nil { return err } return gui.focusToView(stageViewFeature.Name) } func (gui *Gui) resetChanges(g *gocui.Gui, v *gocui.View) error { - entity := gui.getSelectedRepository() + e := gui.getSelectedRepository() _, cy := v.Cursor() _, oy := v.Origin() if len(stagedFiles) <= 0 || len(stagedFiles) <= cy+oy { return nil } - if err := git.Reset(entity, stagedFiles[cy+oy], git.ResetOptions{}); err != nil { + if err := git.Reset(e, stagedFiles[cy+oy], git.ResetOptions{}); err != nil { return err } - return refreshAllStatusView(g, entity, true) + return refreshAllStatusView(g, e, true) } func (gui *Gui) resetAllChanges(g *gocui.Gui, v *gocui.View) error { - entity := gui.getSelectedRepository() - ref, err := entity.Repository.Head() + e := gui.getSelectedRepository() + ref, err := e.Repository.Head() if err != nil { return err } - if err := git.ResetAll(entity, git.ResetOptions{ + if err := git.ResetAll(e, git.ResetOptions{ Hash: ref.Hash().String(), Rtype: git.ResetMixed, }); err != nil { return err } - return refreshAllStatusView(g, entity, true) + return refreshAllStatusView(g, e, true) } // refresh the main view and re-render the repository representations -func refreshStagedView(g *gocui.Gui, entity *git.RepoEntity) error { +func refreshStagedView(g *gocui.Gui) error { stageView, err := g.View(stageViewFeature.Name) if err != nil { return err diff --git a/pkg/gui/stashview.go b/pkg/gui/stashview.go index 6011df9..81de8f0 100644 --- a/pkg/gui/stashview.go +++ b/pkg/gui/stashview.go @@ -18,15 +18,15 @@ func (gui *Gui) openStashView(g *gocui.Gui) error { } v.Title = stashViewFeature.Title } - entity := gui.getSelectedRepository() - err = refreshStashView(g, entity) + e := gui.getSelectedRepository() + err = refreshStashView(g, e) return err } // func (gui *Gui) stashChanges(g *gocui.Gui, v *gocui.View) error { - entity := gui.getSelectedRepository() - output, err := entity.Stash() + e := gui.getSelectedRepository() + output, err := e.Stash() if err != nil { if err = gui.openErrorView(g, output, "You should manually resolve this issue", @@ -34,19 +34,19 @@ func (gui *Gui) stashChanges(g *gocui.Gui, v *gocui.View) error { return err } } - err = refreshAllStatusView(g, entity, true) + err = refreshAllStatusView(g, e, true) return err } // func (gui *Gui) popStash(g *gocui.Gui, v *gocui.View) error { - entity := gui.getSelectedRepository() + e := gui.getSelectedRepository() _, oy := v.Origin() _, cy := v.Cursor() - if len(entity.Stasheds) <= 0 { + if len(e.Stasheds) <= 0 { return nil } - stashedItem := entity.Stasheds[oy+cy] + stashedItem := e.Stasheds[oy+cy] output, err := stashedItem.Pop() if err != nil { if err = gui.openErrorView(g, output, @@ -56,14 +56,14 @@ func (gui *Gui) popStash(g *gocui.Gui, v *gocui.View) error { } } // since the pop is a func of stashed item, we need to refresh entity here - entity.Refresh() + e.Refresh() - err = refreshAllStatusView(g, entity, true) + err = refreshAllStatusView(g, e, true) return err } // refresh the main view and re-render the repository representations -func refreshStashView(g *gocui.Gui, entity *git.RepoEntity) error { +func refreshStashView(g *gocui.Gui, e *git.RepoEntity) error { stashView, err := g.View(stashViewFeature.Name) if err != nil { return err @@ -71,7 +71,7 @@ func refreshStashView(g *gocui.Gui, entity *git.RepoEntity) error { stashView.Clear() _, cy := stashView.Cursor() _, oy := stashView.Origin() - stashedItems := entity.Stasheds + stashedItems := e.Stasheds for i, stashedItem := range stashedItems { var prefix string if i == cy+oy { diff --git a/pkg/gui/statusview.go b/pkg/gui/statusview.go index 798b760..cc6ef51 100644 --- a/pkg/gui/statusview.go +++ b/pkg/gui/statusview.go @@ -32,8 +32,8 @@ func (gui *Gui) openStatusView(g *gocui.Gui, v *gocui.View) error { return nil } -func reloadFiles(entity *git.RepoEntity) (err error) { - stagedFiles, unstagedFiles, err = populateFileLists(entity) +func reloadFiles(e *git.RepoEntity) (err error) { + stagedFiles, unstagedFiles, err = populateFileLists(e) return err } @@ -67,8 +67,8 @@ func (gui *Gui) statusCursorDown(g *gocui.Gui, v *gocui.View) error { return err } } - entity := gui.getSelectedRepository() - if err := refreshStatusView(v.Name(), g, entity, false); err != nil { + e := gui.getSelectedRepository() + if err := refreshStatusView(v.Name(), g, e, false); err != nil { return err } } @@ -85,8 +85,8 @@ func (gui *Gui) statusCursorUp(g *gocui.Gui, v *gocui.View) error { return err } } - entity := gui.getSelectedRepository() - if err := refreshStatusView(v.Name(), g, entity, false); err != nil { + e := gui.getSelectedRepository() + if err := refreshStatusView(v.Name(), g, e, false); err != nil { return err } } @@ -96,13 +96,13 @@ func (gui *Gui) statusCursorUp(g *gocui.Gui, v *gocui.View) error { // header og the status layout func (gui *Gui) openStatusHeaderView(g *gocui.Gui) error { maxX, _ := g.Size() - entity := gui.getSelectedRepository() + e := gui.getSelectedRepository() v, err := g.SetView(statusHeaderViewFeature.Name, 6, 2, maxX-6, 4) if err != nil { if err != gocui.ErrUnknownView { return err } - fmt.Fprintln(v, entity.AbsPath) + fmt.Fprintln(v, e.AbsPath) // v.Frame = false v.Wrap = true } @@ -125,8 +125,9 @@ func (gui *Gui) closeStatusView(g *gocui.Gui, v *gocui.View) error { return gui.closeViewCleanup(mainViewFeature.Name) } -func populateFileLists(entity *git.RepoEntity) (staged, unstaged []*git.File, err error) { - files, err := git.Status(entity) +// generate file lists by git status command +func populateFileLists(e *git.RepoEntity) (staged, unstaged []*git.File, err error) { + files, err := git.Status(e) if err != nil { return nil, nil, err } @@ -141,13 +142,13 @@ func populateFileLists(entity *git.RepoEntity) (staged, unstaged []*git.File, er return staged, unstaged, err } -func refreshStatusView(viewName string, g *gocui.Gui, entity *git.RepoEntity, reload bool) error { +func refreshStatusView(viewName string, g *gocui.Gui, e *git.RepoEntity, reload bool) error { if reload { - reloadFiles(entity) + reloadFiles(e) } switch viewName { case stageViewFeature.Name: - if err := refreshStagedView(g, entity); err != nil { + if err := refreshStagedView(g); err != nil { return err } case unstageViewFeature.Name: @@ -155,16 +156,16 @@ func refreshStatusView(viewName string, g *gocui.Gui, entity *git.RepoEntity, re return err } case stashViewFeature.Name: - if err := refreshStashView(g, entity); err != nil { + if err := refreshStashView(g, e); err != nil { return err } } return nil } -func refreshAllStatusView(g *gocui.Gui, entity *git.RepoEntity, reload bool) error { +func refreshAllStatusView(g *gocui.Gui, e *git.RepoEntity, reload bool) error { for _, v := range statusViews { - if err := refreshStatusView(v.Name, g, entity, reload); err != nil { + if err := refreshStatusView(v.Name, g, e, reload); err != nil { return err } } diff --git a/pkg/gui/unstagedview.go b/pkg/gui/unstagedview.go index 1a33c12..dd2fe6d 100644 --- a/pkg/gui/unstagedview.go +++ b/pkg/gui/unstagedview.go @@ -23,26 +23,26 @@ func (gui *Gui) openUnStagedView(g *gocui.Gui) error { } func (gui *Gui) addChanges(g *gocui.Gui, v *gocui.View) error { - entity := gui.getSelectedRepository() + e := gui.getSelectedRepository() _, cy := v.Cursor() _, oy := v.Origin() if len(unstagedFiles) <= 0 || len(unstagedFiles) < cy+oy { return nil } - if err := git.Add(entity, unstagedFiles[cy+oy], git.AddOptions{}); err != nil { + if err := git.Add(e, unstagedFiles[cy+oy], git.AddOptions{}); err != nil { return err } - err := refreshAllStatusView(g, entity, true) + err := refreshAllStatusView(g, e, true) return err } func (gui *Gui) addAllChanges(g *gocui.Gui, v *gocui.View) error { - entity := gui.getSelectedRepository() - if err := git.AddAll(entity, git.AddOptions{}); err != nil { + e := gui.getSelectedRepository() + if err := git.AddAll(e, git.AddOptions{}); err != nil { return err } - err := refreshAllStatusView(g, entity, true) + err := refreshAllStatusView(g, e, true) return err } diff --git a/pkg/gui/util-queuehandler.go b/pkg/gui/util-queuehandler.go deleted file mode 100644 index e303825..0000000 --- a/pkg/gui/util-queuehandler.go +++ /dev/null @@ -1,36 +0,0 @@ -package gui - -import ( - "github.com/isacikgoz/gitbatch/pkg/git" - "github.com/jroimartin/gocui" - log "github.com/sirupsen/logrus" -) - -// this function starts the queue and updates the gui with the result of an -// operation -func (gui *Gui) startQueue(g *gocui.Gui, v *gocui.View) error { - go func(gui_go *Gui, g_go *gocui.Gui) { - for { - job, finished, err := gui_go.State.Queue.StartNext() - - if err != nil { - if err == git.ErrAuthenticationRequired { - // pause the job, so it will be indicated to being blocking - job.Entity.SetState(git.Paused) - err := gui_go.openAuthenticationView(g, gui_go.State.Queue, job, v.Name()) - if err != nil { - log.Warn(err.Error()) - return - } - } - return - // with not returning here, we simply ignore and continue - } - // if queue is finished simply return from this goroutine - if finished { - return - } - } - }(gui, g) - return nil -} diff --git a/pkg/gui/util-textstyle.go b/pkg/gui/util-textstyle.go index d303d9c..fbe2b64 100644 --- a/pkg/gui/util-textstyle.go +++ b/pkg/gui/util-textstyle.go @@ -24,13 +24,10 @@ var ( maxRepositoryLength = 20 hashLength = 7 - ws = " " - pushable = string(blue.Sprint("↖")) - pullable = string(blue.Sprint("↘")) - confidentArrow = string(magenta.Sprint("")) - unconfidentArrow = string(yellow.Sprint("")) - dirty = string(yellow.Sprint("✗")) - unknown = magenta.Sprint("?") + ws = " " + pushable = string(blue.Sprint("↖")) + pullable = string(blue.Sprint("↘")) + dirty = string(yellow.Sprint("✗")) queuedSymbol = "•" workingSymbol = "•" @@ -53,41 +50,41 @@ var ( // this function handles the render and representation of the repository // TODO: cleanup is required, right now it looks too complicated -func (gui *Gui) displayString(entity *git.RepoEntity) string { +func (gui *Gui) repositoryLabel(e *git.RepoEntity) string { suffix := "" prefix := "" repoName := "" - if entity.Branch.Pushables != "?" { - prefix = prefix + pushable + ws + entity.Branch.Pushables + - ws + pullable + ws + entity.Branch.Pullables + if e.Branch.Pushables != "?" { + prefix = prefix + pushable + ws + e.Branch.Pushables + + ws + pullable + ws + e.Branch.Pullables } else { - prefix = prefix + pushable + ws + yellow.Sprint(entity.Branch.Pushables) + - ws + pullable + ws + yellow.Sprint(entity.Branch.Pullables) + prefix = prefix + pushable + ws + yellow.Sprint(e.Branch.Pushables) + + ws + pullable + ws + yellow.Sprint(e.Branch.Pullables) } - selectedEntity := gui.getSelectedRepository() - if selectedEntity == entity { + se := gui.getSelectedRepository() + if se == e { prefix = prefix + selectionIndicator - repoName = green.Sprint(entity.Name) + repoName = green.Sprint(e.Name) } else { prefix = prefix + ws - repoName = entity.Name + repoName = e.Name } // some branch names can be really long, in that times I hope the first // characters are important and meaningful - branch := adjustTextLength(entity.Branch.Name, maxBranchLength) + branch := adjustTextLength(e.Branch.Name, maxBranchLength) prefix = prefix + string(cyan.Sprint(branch)) - if !entity.Branch.Clean { + if !e.Branch.Clean { prefix = prefix + ws + dirty + ws } else { prefix = prefix + ws } // rendering the satus according to repository's state - if entity.State() == git.Queued { - if inQueue, ty := gui.State.Queue.IsInTheQueue(entity); inQueue { + if e.State() == git.Queued { + if inQueue, ty := gui.State.Queue.IsInTheQueue(e); inQueue { switch mode := ty; mode { case git.FetchJob: suffix = blue.Sprint(queuedSymbol) @@ -100,20 +97,35 @@ func (gui *Gui) displayString(entity *git.RepoEntity) string { } } return prefix + repoName + ws + suffix - } else if entity.State() == git.Working { + } else if e.State() == git.Working { // TODO: maybe the type of the job can be written while its working? return prefix + repoName + ws + green.Sprint(workingSymbol) - } else if entity.State() == git.Success { + } else if e.State() == git.Success { return prefix + repoName + ws + green.Sprint(successSymbol) - } else if entity.State() == git.Paused { + } else if e.State() == git.Paused { return prefix + repoName + ws + yellow.Sprint(pauseSymbol) - } else if entity.State() == git.Fail { + } else if e.State() == git.Fail { return prefix + repoName + ws + red.Sprint(failSymbol) } else { return prefix + repoName } } +func commitLabel(c *git.Commit) string { + var body string + switch c.CommitType { + case git.EvenCommit: + body = cyan.Sprint(c.Hash[:hashLength]) + " " + c.Message + case git.LocalCommit: + body = blue.Sprint(c.Hash[:hashLength]) + " " + c.Message + case git.RemoteCommit: + body = yellow.Sprint(c.Hash[:hashLength]) + " " + c.Message + default: + body = c.Hash[:hashLength] + " " + c.Message + } + return body +} + // limit the text length for visual concerns func adjustTextLength(text string, maxLength int) (adjusted string) { if len(text) > maxLength { |
