summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIbrahim Serdar Acikgoz <serdaracikgoz86@gmail.com>2018-11-22 01:16:41 +0300
committerGitHub <noreply@github.com>2018-11-22 01:16:41 +0300
commitedf7fab3c3f64085b6781b2368c84565e31121d8 (patch)
tree5767e1d5ffa997284ca764c9f9cc5e4f531dfd09
parentsycnhronize with dev branch (diff)
parentrefactoring and added initial implementation of fetc & pull mechanisms (diff)
downloadgitbatch-edf7fab3c3f64085b6781b2368c84565e31121d8.tar.gz
Merge pull request #6 from isacikgoz/develop
Develop
-rw-r--r--.gitignore1
-rw-r--r--main.go1
-rw-r--r--pkg/app/app.go26
-rw-r--r--pkg/git/git-commands.go14
-rw-r--r--pkg/git/load.go41
-rw-r--r--pkg/git/model.go (renamed from pkg/git/git.go)81
-rw-r--r--pkg/git/repository.go112
-rw-r--r--pkg/gui/gui-util.go95
-rw-r--r--pkg/gui/gui.go142
-rw-r--r--pkg/gui/keybindings.go17
-rw-r--r--pkg/gui/pullview.go105
-rw-r--r--pkg/gui/scheduleview.go2
12 files changed, 494 insertions, 143 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..8c11484
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+exec.go.test
diff --git a/main.go b/main.go
index 81ee897..4a716d3 100644
--- a/main.go
+++ b/main.go
@@ -24,6 +24,7 @@ func main() {
if err != nil {
log.Fatal(err)
}
+
app.Gui.Run()
defer app.Close()
diff --git a/pkg/app/app.go b/pkg/app/app.go
index 83231a5..c3575a4 100644
--- a/pkg/app/app.go
+++ b/pkg/app/app.go
@@ -2,7 +2,6 @@ package app
import (
"github.com/isacikgoz/gitbatch/pkg/gui"
- "github.com/isacikgoz/gitbatch/pkg/git"
"io"
)
@@ -18,12 +17,13 @@ func Setup(directories []string) (*App, error) {
closers: []io.Closer{},
}
- entities, err := createRepositoryEntities(directories)
- if err != nil {
- return app, err
- }
+ var err error
+ // entities, err := createRepositoryEntities(directories)
+ // if err != nil {
+ // return app, err
+ // }
- app.Gui, err = gui.NewGui(entities)
+ app.Gui, err = gui.NewGui(directories)
if err != nil {
return app, err
}
@@ -39,16 +39,4 @@ func (app *App) Close() error {
}
}
return nil
-}
-
-func createRepositoryEntities(directories []string) (entities []*git.RepoEntity, err error) {
- entities = make([]*git.RepoEntity, 0)
- for _, dir := range directories {
- entity, err := git.InitializeRepository(dir)
- if err != nil {
- continue
- }
- entities = append(entities, entity)
- }
- return entities, nil
-}
+} \ No newline at end of file
diff --git a/pkg/git/git-commands.go b/pkg/git/git-commands.go
index 1cf6fb7..a871356 100644
--- a/pkg/git/git-commands.go
+++ b/pkg/git/git-commands.go
@@ -6,6 +6,7 @@ import (
"github.com/isacikgoz/gitbatch/pkg/utils"
)
+
// UpstreamDifferenceCount checks how many pushables/pullables there are for the
// current branch
func UpstreamDifferenceCount(repoPath string) (string, string) {
@@ -35,5 +36,14 @@ func CurrentBranchName(repoPath string) (string, error) {
return utils.TrimTrailingNewline(branchName), nil
}
-
-
+func (entity *RepoEntity) IsClean() (bool, error) {
+ worktree, err := entity.Repository.Worktree()
+ if err != nil {
+ return true, nil
+ }
+ status, err := worktree.Status()
+ if err != nil {
+ return status.IsClean(), nil
+ }
+ return false, nil
+} \ No newline at end of file
diff --git a/pkg/git/load.go b/pkg/git/load.go
new file mode 100644
index 0000000..5d62dcf
--- /dev/null
+++ b/pkg/git/load.go
@@ -0,0 +1,41 @@
+package git
+
+import (
+ "sync"
+)
+
+func LoadRepositoryEntities(directories []string) (entities []*RepoEntity, err error) {
+ entities = make([]*RepoEntity, 0)
+
+ var wg sync.WaitGroup
+ var mu sync.Mutex
+
+ for _, dir := range directories {
+ // increment wait counter by one because we run a single goroutine
+ // below
+ wg.Add(1)
+
+ go func(d string) {
+
+ // decrement the wait counter by one, we call it in a defer so it's
+ // called at the end of this goroutine
+ defer wg.Done()
+ entity, err := InitializeRepository(d)
+ if err != nil {
+ return
+ }
+
+ // lock so we don't get a race if multiple go routines try to add
+ // to the same entities
+ mu.Lock()
+ entities = append(entities, entity)
+ mu.Unlock()
+ }(dir)
+ }
+
+ // wait until the wait counter is zero, this happens if all goroutines have
+ // finished
+ wg.Wait()
+
+ return entities, nil
+} \ No newline at end of file
diff --git a/pkg/git/git.go b/pkg/git/model.go
index db7af8f..2c02eda 100644
--- a/pkg/git/git.go
+++ b/pkg/git/model.go
@@ -5,38 +5,30 @@ import (
"github.com/isacikgoz/gitbatch/pkg/utils"
"gopkg.in/src-d/go-git.v4"
"gopkg.in/src-d/go-git.v4/plumbing/object"
- "os"
"regexp"
)
-type RepoEntity struct {
- Name string
- AbsPath string
- Repository git.Repository
- Pushables string
- Pullables string
- Branch string
- Marked bool
+func (entity *RepoEntity) GetRemotes() (remotes []string, err error) {
+ r := entity.Repository
+
+ remotes, err = getRemotes(&r)
+ if err !=nil {
+ return nil ,err
+ }
+ return remotes, nil
}
-func InitializeRepository(directory string) (entity *RepoEntity, err error) {
- file, err := os.Open(directory)
- if err != nil {
- return entity, err
- }
- fileInfo, err := file.Stat()
- if err != nil {
- return entity, err
- }
- r, err := git.PlainOpen(directory)
- if err != nil {
- return entity, err
- }
- pushable, pullable := UpstreamDifferenceCount(directory)
- branch, err := CurrentBranchName(directory)
- entity = &RepoEntity{fileInfo.Name(), directory, *r, pushable, pullable, branch, false}
-
- return entity, nil
+func getRemotes(r *git.Repository) (remotes []string, err error) {
+
+ if list, err := r.Remotes(); err != nil {
+ return remotes, err
+ } else {
+ for _, r := range list {
+ remoteString := r.Config().Name + " → " + r.Config().URLs[0]
+ remotes = append(remotes, remoteString)
+ }
+ }
+ return remotes, nil
}
func (entity *RepoEntity) GetCommits() (commits []string, err error) {
@@ -64,20 +56,6 @@ func (entity *RepoEntity) GetCommits() (commits []string, err error) {
return commits, nil
}
-func (entity *RepoEntity) GetRemotes() (remotes []string, err error) {
- r := entity.Repository
-
- if list, err := r.Remotes(); err != nil {
- return remotes, err
- } else {
- for _, r := range list {
- remoteString := r.Config().Name + " → " + r.Config().URLs[0]
- remotes = append(remotes, remoteString)
- }
- }
- return remotes, nil
-}
-
func (entity *RepoEntity) GetStatus() (status string) {
status = "↑ " + entity.Pushables + " ↓ " + entity.Pullables + " → " + entity.Branch
re := regexp.MustCompile(`\r?\n`)
@@ -85,12 +63,15 @@ func (entity *RepoEntity) GetStatus() (status string) {
return status
}
-func (entity *RepoEntity) Mark() {
- entity.Marked = true
-}
-
-func (entity *RepoEntity) UnMark() {
- entity.Marked = false
-}
-
-
+func (entity *RepoEntity) GetDisplayString() string{
+ if entity.Marked {
+ green := color.New(color.FgGreen)
+ return string(green.Sprint(entity.Name))
+ } else if !entity.Clean {
+ orange := color.New(color.FgYellow)
+ return string(orange.Sprint(entity.Name))
+ } else {
+ white := color.New(color.FgWhite)
+ return string(white.Sprint(entity.Name))
+ }
+} \ No newline at end of file
diff --git a/pkg/git/repository.go b/pkg/git/repository.go
new file mode 100644
index 0000000..93cdbc9
--- /dev/null
+++ b/pkg/git/repository.go
@@ -0,0 +1,112 @@
+package git
+
+import (
+ "gopkg.in/src-d/go-git.v4"
+ "gopkg.in/src-d/go-git.v4/plumbing"
+ "os"
+ "time"
+)
+
+type RepoEntity struct {
+ Name string
+ AbsPath string
+ Repository git.Repository
+ Pushables string
+ Pullables string
+ Branch string
+ Remote string
+ Marked bool
+ Clean bool
+}
+
+func InitializeRepository(directory string) (entity *RepoEntity, err error) {
+ file, err := os.Open(directory)
+ if err != nil {
+ return nil, err
+ }
+ fileInfo, err := file.Stat()
+ if err != nil {
+ return nil, err
+ }
+ r, err := git.PlainOpen(directory)
+ if err != nil {
+ return nil, err
+ }
+ pushable, pullable := UpstreamDifferenceCount(directory)
+ branch, err := CurrentBranchName(directory)
+ remotes, err := getRemotes(r)
+ entity = &RepoEntity{fileInfo.Name(), directory, *r, pushable, pullable, branch, remotes[0], false, isClean(r, fileInfo.Name())}
+
+ return entity, nil
+}
+
+func isClean(r *git.Repository, name string) bool {
+ w, err := r.Worktree()
+ if err != nil {
+ return false
+ }
+ // TODO: This function is incredibly slow
+ s, err := w.Status()
+ if err != nil {
+ return false
+ }
+ return s.IsClean()
+}
+
+func (entity *RepoEntity) Mark() {
+ entity.Marked = true
+}
+
+func (entity *RepoEntity) Unmark() {
+ entity.Marked = false
+}
+
+func (entity *RepoEntity) Pull() error {
+ w, err := entity.Repository.Worktree()
+ if err != nil {
+ return err
+ }
+ ref := plumbing.NewBranchReferenceName(entity.Branch)
+ err = w.Pull(&git.PullOptions{
+ RemoteName: entity.Remote,
+ ReferenceName: ref,
+ })
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func (entity *RepoEntity) PullTest() error {
+ time.Sleep(5 * time.Second)
+
+ return nil
+}
+
+func (entity *RepoEntity) Fetch() error {
+ err := entity.Repository.Fetch(&git.FetchOptions{
+ RemoteName: entity.Remote,
+ })
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func (entity *RepoEntity) GetActiveBranch() string{
+ headRef, _ := entity.Repository.Head()
+ return headRef.Name().String()
+}
+
+func (entity *RepoEntity) GetActiveRemote() string {
+ if list, err := entity.Repository.Remotes(); err != nil {
+ return ""
+ } else {
+ for _, r := range list {
+ return r.Config().Name
+ }
+ }
+ return ""
+} \ No newline at end of file
diff --git a/pkg/gui/gui-util.go b/pkg/gui/gui-util.go
index 21ba9ae..d842eb8 100644
--- a/pkg/gui/gui-util.go
+++ b/pkg/gui/gui-util.go
@@ -1,8 +1,10 @@
package gui
import (
- "github.com/isacikgoz/gitbatch/pkg/git"
+ "fmt"
+ "sync"
"github.com/isacikgoz/gitbatch/pkg/utils"
+ "github.com/isacikgoz/gitbatch/pkg/git"
"github.com/jroimartin/gocui"
)
@@ -32,7 +34,7 @@ func (gui *Gui) cursorDown(g *gocui.Gui, v *gocui.View) error {
cx, cy := v.Cursor()
ox, oy := v.Origin()
- ly := len(gui.Repositories) -1
+ ly := len(gui.State.Repositories) -1
// if we are at the end we just return
if cy+oy == ly {
@@ -81,7 +83,7 @@ func (gui *Gui) getSelectedRepository(g *gocui.Gui, v *gocui.View) (*git.RepoEnt
return r, err
}
- for _, sr := range gui.Repositories {
+ for _, sr := range gui.State.Repositories {
if l == sr.Name {
return sr, nil
}
@@ -89,6 +91,61 @@ func (gui *Gui) getSelectedRepository(g *gocui.Gui, v *gocui.View) (*git.RepoEnt
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.Marked != true {
+ r.Mark()
+ } else {
+ r.Unmark()
+ }
+ gui.refreshMain(g)
+ gui.updateSchedule(g)
+ }
+
+ return nil
+}
+
+func (gui *Gui) markAllRepositories(g *gocui.Gui, v *gocui.View) error {
+ for _, r := range gui.State.Repositories {
+ r.Mark()
+ }
+ if err := gui.refreshMain(g); err !=nil {
+ return err
+ }
+ gui.updateSchedule(g)
+ 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
+ }
+ gui.updateSchedule(g)
+ return nil
+}
+
+func (gui *Gui) refreshMain(g *gocui.Gui) error {
+
+ mainView, err := g.View("main")
+ if err != nil {
+ return err
+ }
+ mainView.Clear()
+ for _, r := range gui.State.Repositories {
+ fmt.Fprintln(mainView, r.GetDisplayString())
+ }
+ return nil
+}
+
// 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()
@@ -109,22 +166,22 @@ func (gui *Gui) correctCursor(v *gocui.View) error {
return nil
}
-func (gui *Gui) getCommitsView(g *gocui.Gui) *gocui.View {
- v, _ := g.View("commits")
- return v
-}
+func (gui *Gui) getMarkedEntities() (rs []*git.RepoEntity, err error) {
+ var wg sync.WaitGroup
+ var mu sync.Mutex
-func (gui *Gui) getRemotesView(g *gocui.Gui) *gocui.View {
- v, _ := g.View("remotes")
- return v
-}
-
-func (gui *Gui) getScheduleView(g *gocui.Gui) *gocui.View {
- v, _ := g.View("schedule")
- return v
-}
+ 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()
-func (gui *Gui) getStatusView(g *gocui.Gui) *gocui.View {
- v, _ := g.View("status")
- return v
+ return rs, nil
} \ No newline at end of file
diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go
index 96e2c0a..55c6c18 100644
--- a/pkg/gui/gui.go
+++ b/pkg/gui/gui.go
@@ -2,28 +2,103 @@ package gui
import (
"github.com/isacikgoz/gitbatch/pkg/git"
- "github.com/isacikgoz/gitbatch/pkg/utils"
- "github.com/fatih/color"
"github.com/jroimartin/gocui"
"fmt"
+ "time"
+ "os"
+ "os/exec"
+ "io/ioutil"
+ "log"
)
+// SentinelErrors are the errors that have special meaning and need to be checked
+// by calling functions. The less of these, the better
+type SentinelErrors struct {
+ ErrSubProcess error
+}
+
// Gui wraps the gocui Gui object which handles rendering and events
type Gui struct {
g *gocui.Gui
- Repositories []*git.RepoEntity
+ SubProcess *exec.Cmd
+ State guiState
+ Errors SentinelErrors
+}
+
+type guiState struct {
+ Repositories []*git.RepoEntity
+ Directories []string
}
// NewGui builds a new gui handler
-func NewGui(entities []*git.RepoEntity) (*Gui, error) {
+func NewGui(directoies []string) (*Gui, error) {
+ rs, err := git.LoadRepositoryEntities(directoies)
+ if err != nil {
+ return nil, err
+ }
+ initialState := guiState{
+ Repositories: rs,
+ }
gui := &Gui{
- Repositories: entities,
+ State: initialState,
}
return gui, nil
}
+// Run setup the gui with keybindings and start the mainloop
+func (gui *Gui) Run() error {
+
+ g, err := gocui.NewGui(gocui.OutputNormal)
+ if err != nil {
+ return err
+ }
+ defer g.Close()
+
+ g.SetManagerFunc(gui.layout)
+
+ if err := gui.keybindings(g); err != nil {
+ return err
+ }
+
+ if err := g.MainLoop(); err != nil && err != gocui.ErrQuit {
+ return err
+ }
+ return nil
+}
+
+// RunWithSubprocesses loops, instantiating a new gocui.Gui with each iteration
+// if the error returned from a run is a ErrSubProcess, it runs the subprocess
+// otherwise it handles the error, possibly by quitting the application
+func (gui *Gui) RunWithSubprocesses() {
+ for {
+ if err := gui.Run(); err != nil {
+ if err == gocui.ErrQuit {
+ break
+ } else if err == gui.Errors.ErrSubProcess {
+ gui.SubProcess.Stdin = os.Stdin
+ gui.SubProcess.Stdout = os.Stdout
+ gui.SubProcess.Stderr = os.Stderr
+ gui.SubProcess.Run()
+ gui.SubProcess.Stdout = ioutil.Discard
+ gui.SubProcess.Stderr = ioutil.Discard
+ gui.SubProcess.Stdin = nil
+ gui.SubProcess = nil
+ } else {
+ log.Fatal(err)
+ }
+ }
+ }
+}
+
+func (gui *Gui) goEvery(g *gocui.Gui, interval time.Duration, function func(*gocui.Gui) error) {
+ go func() {
+ for range time.Tick(interval) {
+ function(g)
+ }
+ }()
+}
func (gui *Gui) layout(g *gocui.Gui) error {
maxX, maxY := g.Size()
@@ -37,8 +112,8 @@ func (gui *Gui) layout(g *gocui.Gui) error {
v.SelBgColor = gocui.ColorWhite
v.SelFgColor = gocui.ColorBlack
v.Overwrite = true
- for _, r := range gui.Repositories {
- fmt.Fprintln(v, r.Name)
+ for _, r := range gui.State.Repositories {
+ fmt.Fprintln(v, r.GetDisplayString())
}
if _, err = gui.setCurrentViewOnTop(g, "main"); err != nil {
@@ -89,39 +164,11 @@ func (gui *Gui) layout(g *gocui.Gui) error {
v.BgColor = gocui.ColorWhite
v.FgColor = gocui.ColorBlack
v.Frame = false
- fmt.Fprintln(v, "q: quit ↑ ↓: navigate space: select")
+ fmt.Fprintln(v, "q: quit | ↑ ↓: navigate | space: select/deselect | a: select all | r: clear selection | enter: execute")
}
return nil
}
-func (gui *Gui) markRepository(g *gocui.Gui, v *gocui.View) error {
-
- if e, err := gui.getSelectedRepository(g, v); err != nil {
- return err
- } else {
- mainView, err := g.View("main")
- if err != nil {
- return err
- }
- if e.Marked != true {
- e.Mark()
- } else {
- e.UnMark()
- }
- mainView.Clear()
- for _, r := range gui.Repositories {
- if r.Marked {
- fmt.Fprintln(mainView, utils.ColoredString(r.Name, color.FgGreen))
- } else {
- fmt.Fprintln(mainView, r.Name)
- }
- }
- gui.updateSchedule(g)
- }
-
- return nil
-}
-
func (gui *Gui) quit(g *gocui.Gui, v *gocui.View) error {
return gocui.ErrQuit
}
@@ -133,24 +180,17 @@ func (gui *Gui) setCurrentViewOnTop(g *gocui.Gui, name string) (*gocui.View, err
return g.SetViewOnTop(name)
}
-// Run setup the gui with keybindings and start the mainloop
-func (gui *Gui) Run() error {
+func (gui *Gui) updateKeyBindingsViewForMainView(g *gocui.Gui) error {
- g, err := gocui.NewGui(gocui.OutputNormal)
+ v, err := g.View("keybindings")
if err != nil {
return err
}
- defer g.Close()
-
- g.SetManagerFunc(gui.layout)
-
- if err := gui.keybindings(g); err != nil {
- return err
- }
- if err := g.MainLoop(); err != nil && err != gocui.ErrQuit {
- return err
- }
+ v.Clear()
+ v.BgColor = gocui.ColorWhite
+ v.FgColor = gocui.ColorBlack
+ v.Frame = false
+ fmt.Fprintln(v, "q: quit | ↑ ↓: navigate | space: select/deselect | a: select all | r: clear selection | enter: execute")
return nil
-}
-
+} \ No newline at end of file
diff --git a/pkg/gui/keybindings.go b/pkg/gui/keybindings.go
index fcaf40a..5f2164e 100644
--- a/pkg/gui/keybindings.go
+++ b/pkg/gui/keybindings.go
@@ -8,7 +8,16 @@ func (gui *Gui) keybindings(g *gocui.Gui) error {
if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, gui.quit); err != nil {
return err
}
- if err := g.SetKeybinding("", 'q', gocui.ModNone, gui.quit); err != nil {
+ if err := g.SetKeybinding("main", 'q', gocui.ModNone, gui.quit); err != nil {
+ return err
+ }
+ if err := g.SetKeybinding("main", gocui.KeyEnter, gocui.ModNone, gui.openPullView); err != nil {
+ return err
+ }
+ if err := g.SetKeybinding("pull", 'c', gocui.ModNone, gui.closePullView); err != nil {
+ return err
+ }
+ if err := g.SetKeybinding("pull", gocui.KeyEnter, gocui.ModNone, gui.executePull); err != nil {
return err
}
if err := g.SetKeybinding("main", gocui.KeyArrowDown, gocui.ModNone, gui.cursorDown); err != nil {
@@ -20,5 +29,11 @@ func (gui *Gui) keybindings(g *gocui.Gui) error {
if err := g.SetKeybinding("main", gocui.KeySpace, gocui.ModNone, gui.markRepository); err != nil {
return err
}
+ if err := g.SetKeybinding("main", 'a', gocui.ModNone, gui.markAllRepositories); err != nil {
+ return err
+ }
+ if err := g.SetKeybinding("main", 'r', gocui.ModNone, gui.unMarkAllRepositories); err != nil {
+ return err
+ }
return nil
} \ No newline at end of file
diff --git a/pkg/gui/pullview.go b/pkg/gui/pullview.go
new file mode 100644
index 0000000..90e3797
--- /dev/null
+++ b/pkg/gui/pullview.go
@@ -0,0 +1,105 @@
+package gui
+
+import (
+ "github.com/jroimartin/gocui"
+ "fmt"
+)
+
+func (gui *Gui) openPullView(g *gocui.Gui, v *gocui.View) error {
+ maxX, maxY := g.Size()
+
+ v, err := g.SetView("pull", maxX/2-35, maxY/2-5, maxX/2+35, maxY/2+5)
+ if err != nil {
+ if err != gocui.ErrUnknownView {
+ return err
+ }
+ v.Title = " " + "Execution Parameters" + " "
+ v.Wrap = false
+ mrs, _ := gui.getMarkedEntities()
+ for _, r := range mrs {
+ line := r.Name + " : " + r.GetActiveRemote() + "/" + r.Branch + " → " + r.GetActiveBranch()
+ fmt.Fprintln(v, line)
+ }
+ }
+ gui.updateKeyBindingsViewForPullView(g)
+ if _, err := g.SetCurrentView("pull"); err != nil {
+ return err
+ }
+ return nil
+}
+
+func (gui *Gui) closePullView(g *gocui.Gui, v *gocui.View) error {
+
+ if err := g.DeleteView(v.Name()); err != nil {
+ return nil
+ }
+ if _, err := g.SetCurrentView("main"); err != nil {
+ return err
+ }
+ gui.updateKeyBindingsViewForMainView(g)
+
+ return nil
+}
+
+func (gui *Gui) executePull(g *gocui.Gui, v *gocui.View) error {
+ gui.updateKeyBindingsViewForExecution(g)
+ mrs, _ := gui.getMarkedEntities()
+
+ gui.updateKeyBindingsViewForExecution(g)
+ for _, mr := range mrs {
+
+ go gui.counter(g)
+
+ // here we will be waiting
+ mr.Pull()
+ mr.Unmark()
+ }
+
+ gui.refreshMain(g)
+ gui.updateSchedule(g)
+ gui.closePullView(g, v)
+ return nil
+}
+
+func (gui *Gui) updateKeyBindingsViewForPullView(g *gocui.Gui) error {
+
+ v, err := g.View("keybindings")
+ if err != nil {
+ return err
+ }
+ v.Clear()
+ v.BgColor = gocui.ColorGreen
+ v.FgColor = gocui.ColorBlack
+ v.Frame = false
+ fmt.Fprintln(v, "c: cancel | ↑ ↓: navigate | enter: execute")
+ return nil
+}
+
+
+func (gui *Gui) updateKeyBindingsViewForExecution(g *gocui.Gui) error {
+
+ v, err := g.View("keybindings")
+ if err != nil {
+ return err
+ }
+ v.Clear()
+ v.BgColor = gocui.ColorRed
+ v.FgColor = gocui.ColorWhite
+ v.Frame = false
+ fmt.Fprintln(v, " PULLING REPOSITORIES")
+ return nil
+}
+
+func (gui *Gui) counter(g *gocui.Gui) {
+
+ v, err := g.View("pull")
+ if err != nil {
+ return
+ }
+
+ g.Update(func(g *gocui.Gui) error {
+ v.Clear()
+ fmt.Fprintln(v, "Pulling...")
+ return nil
+ })
+}
diff --git a/pkg/gui/scheduleview.go b/pkg/gui/scheduleview.go
index 7c7a1f2..7a8a1d3 100644
--- a/pkg/gui/scheduleview.go
+++ b/pkg/gui/scheduleview.go
@@ -15,7 +15,7 @@ func (gui *Gui) updateSchedule(g *gocui.Gui) error {
}
out.Clear()
pullJobs := 0
- for _, r := range gui.Repositories {
+ for _, r := range gui.State.Repositories {
if r.Marked {
pullJobs++
}