summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorİbrahim Serdar Açıkgöz <serdaracikgoz86@gmail.com>2018-11-27 18:31:26 +0300
committerİbrahim Serdar Açıkgöz <serdaracikgoz86@gmail.com>2018-11-27 18:31:26 +0300
commitc93bef2e140634d68b3bf37ed55cebb6fd16b2c8 (patch)
tree551977ba882bff9d4a6904330b6f4cbf68ab2b3b
parentperformance improvement and modal initiation (diff)
downloadgitbatch-c93bef2e140634d68b3bf37ed55cebb6fd16b2c8.tar.gz
change remote branch to hierarchical structure and intiate job mechanism.
-rw-r--r--pkg/git/remote.go49
-rw-r--r--pkg/git/remotebranch.go66
-rw-r--r--pkg/git/repository.go24
-rw-r--r--pkg/gui/execview.go37
-rw-r--r--pkg/gui/gui-util.go6
-rw-r--r--pkg/gui/gui.go28
-rw-r--r--pkg/gui/keybindings.go8
-rw-r--r--pkg/gui/mainview.go15
-rw-r--r--pkg/gui/remotebranchview.go50
-rw-r--r--pkg/gui/remotesview.go28
-rw-r--r--pkg/gui/scheduleview.go41
-rw-r--r--pkg/job/job.go80
-rw-r--r--pkg/utils/utils.go53
13 files changed, 370 insertions, 115 deletions
diff --git a/pkg/git/remote.go b/pkg/git/remote.go
index 1651cc2..ec61fd7 100644
--- a/pkg/git/remote.go
+++ b/pkg/git/remote.go
@@ -1,19 +1,19 @@
package git
import (
- "gopkg.in/src-d/go-git.v4/plumbing"
- "gopkg.in/src-d/go-git.v4/plumbing/storer"
)
type Remote struct {
Name string
- Reference *plumbing.Reference
+ URL []string
+ Branch *RemoteBranch
+ Branches []*RemoteBranch
}
func (entity *RepoEntity) NextRemote() error {
currentRemoteIndex := 0
for i, remote := range entity.Remotes {
- if remote.Reference.Hash() == entity.Remote.Reference.Hash() {
+ if remote.Name == entity.Remote.Name {
currentRemoteIndex = i
}
}
@@ -27,37 +27,26 @@ func (entity *RepoEntity) NextRemote() error {
return nil
}
-func (entity *RepoEntity) loadRemoteBranches() error {
+func (entity *RepoEntity) loadRemotes() error {
r := entity.Repository
entity.Remotes = make([]*Remote, 0)
- bs, err := remoteBranchesIter(r.Storer)
- if err != nil {
- return err
+
+ 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)
+
}
- defer bs.Close()
- err = bs.ForEach(func(b *plumbing.Reference) error {
- entity.Remotes = append(entity.Remotes, &Remote{
- Name: b.Name().Short(),
- Reference: b,
- })
- return nil
- })
if err != nil {
return err
}
return err
-}
-
-func remoteBranchesIter(s storer.ReferenceStorer) (storer.ReferenceIter, error) {
- refs, err := s.IterReferences()
- if err != nil {
- return nil, err
- }
-
- return storer.NewReferenceFilteredIter(func(ref *plumbing.Reference) bool {
- if ref.Type() == plumbing.HashReference {
- return ref.Name().IsRemote()
- }
- return false
- }, refs), nil
} \ No newline at end of file
diff --git a/pkg/git/remotebranch.go b/pkg/git/remotebranch.go
new file mode 100644
index 0000000..8ccca53
--- /dev/null
+++ b/pkg/git/remotebranch.go
@@ -0,0 +1,66 @@
+package git
+
+import (
+ "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 {
+ Name string
+ Reference *plumbing.Reference
+}
+
+func (remote *Remote) NextRemoteBranch() error {
+ currentRemoteIndex := 0
+ for i, rb := range remote.Branches {
+ if rb.Reference.Hash() == remote.Branch.Reference.Hash() {
+ currentRemoteIndex = i
+ }
+ }
+ // WARNING: DIDN'T CHECK THE LIFE CYCLE
+ if currentRemoteIndex == len(remote.Branches)-1 {
+ remote.Branch = remote.Branches[0]
+ } else {
+ remote.Branch = remote.Branches[currentRemoteIndex+1]
+ }
+
+ return nil
+}
+
+func (remote *Remote) loadRemoteBranches(r *git.Repository) error {
+ remote.Branches = make([]*RemoteBranch, 0)
+ bs, err := remoteBranchesIter(r.Storer)
+ if err != nil {
+ return err
+ }
+ defer bs.Close()
+ 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(),
+ Reference: b,
+ })
+ }
+ return nil
+ })
+ if err != nil {
+ return err
+ }
+ return err
+}
+
+func remoteBranchesIter(s storer.ReferenceStorer) (storer.ReferenceIter, error) {
+ refs, err := s.IterReferences()
+ if err != nil {
+ return nil, err
+ }
+
+ return storer.NewReferenceFilteredIter(func(ref *plumbing.Reference) bool {
+ if ref.Type() == plumbing.HashReference {
+ return ref.Name().IsRemote()
+ }
+ return false
+ }, refs), nil
+} \ No newline at end of file
diff --git a/pkg/git/repository.go b/pkg/git/repository.go
index 9ecb973..630f4cb 100644
--- a/pkg/git/repository.go
+++ b/pkg/git/repository.go
@@ -2,13 +2,14 @@ package git
import (
"gopkg.in/src-d/go-git.v4"
+ "github.com/isacikgoz/gitbatch/pkg/utils"
"os"
"time"
- "strings"
"errors"
)
type RepoEntity struct {
+ RepoID string
Name string
AbsPath string
Repository git.Repository
@@ -34,7 +35,8 @@ func InitializeRepository(directory string) (entity *RepoEntity, err error) {
if err != nil {
return nil, err
}
- entity = &RepoEntity{Name: fileInfo.Name(),
+ entity = &RepoEntity{RepoID: utils.NewHash(),
+ Name: fileInfo.Name(),
AbsPath: directory,
Repository: *r,
Marked: false,
@@ -46,7 +48,7 @@ func InitializeRepository(directory string) (entity *RepoEntity, err error) {
} else {
return entity, errors.New("There is no commit for this repository: " + directory)
}
- entity.loadRemoteBranches()
+ entity.loadRemotes()
entity.Branch = entity.GetActiveBranch()
if len(entity.Remotes) > 0 {
// TODO: tend to take origin/master as default
@@ -68,12 +70,13 @@ func (entity *RepoEntity) Unmark() {
func (entity *RepoEntity) Pull() error {
// TODO: Migrate this code to src-d/go-git
// 2018-11-25: tried but it fails, will investigate.
- rm := entity.Remote.Reference.Name().Short()
- remote := strings.Split(rm, "/")[0]
- if err := entity.FetchWithGit(remote); err != nil {
+ rm := entity.Remote.Name
+ if err := entity.FetchWithGit(rm); err != nil {
return err
}
- if err := entity.MergeWithGit(rm); err != nil {
+ entity.Checkout(entity.Branch)
+ if err := entity.MergeWithGit(entity.Remote.Branch.Name); err != nil {
+ entity.Refresh()
return err
}
entity.Refresh()
@@ -87,9 +90,8 @@ func (entity *RepoEntity) PullTest() error {
}
func (entity *RepoEntity) Fetch() error {
- rm := entity.Remote.Reference.Name().Short()
- remote := strings.Split(rm, "/")[0]
- if err := entity.FetchWithGit(remote); err != nil {
+ rm := entity.Remote.Name
+ if err := entity.FetchWithGit(rm); err != nil {
return err
}
entity.Refresh()
@@ -114,7 +116,7 @@ func (entity *RepoEntity) Refresh() error {
if err := entity.loadCommits(); err != nil {
return err
}
- if err := entity.loadRemoteBranches(); err != nil {
+ if err := entity.loadRemotes(); err != nil {
return err
}
return nil
diff --git a/pkg/gui/execview.go b/pkg/gui/execview.go
index 39a46cb..6371e0e 100644
--- a/pkg/gui/execview.go
+++ b/pkg/gui/execview.go
@@ -9,8 +9,15 @@ import (
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
+ }
- v, err := g.SetView(execViewFeature.Name, maxX/2-35, maxY/2-5, maxX/2+35, maxY/2+5)
+ 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
@@ -35,14 +42,21 @@ func (gui *Gui) openExecConfirmationView(g *gocui.Gui, v *gocui.View) error {
}
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.refreshMain(g)
gui.updateKeyBindingsView(g, mainViewFeature.Name)
return nil
}
@@ -62,13 +76,24 @@ func (gui *Gui) execute(g *gocui.Gui, v *gocui.View) error {
// here we will be waiting
switch mode := gui.State.Mode.ModeID; mode {
case FetchMode:
- mr.Fetch()
+ 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:
- mr.Pull()
+ 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")
}
- gui.refreshViews(g, mr)
mr.Unmark()
gui.refreshMain(g)
}
diff --git a/pkg/gui/gui-util.go b/pkg/gui/gui-util.go
index 5dd0c0c..2b65e97 100644
--- a/pkg/gui/gui-util.go
+++ b/pkg/gui/gui-util.go
@@ -24,10 +24,10 @@ func (gui *Gui) refreshViews(g *gocui.Gui, entity *git.RepoEntity) error {
if err := gui.updateBranch(g, entity); err != nil {
return err
}
- if err := gui.updateCommits(g, entity); err != nil {
- return err
+ if err := gui.updateRemoteBranches(g, entity); err != nil {
+ return err
}
- if err := gui.updateSchedule(g, entity); err != nil {
+ if err := gui.updateCommits(g, entity); err != nil {
return err
}
return nil
diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go
index 569e9ce..c171397 100644
--- a/pkg/gui/gui.go
+++ b/pkg/gui/gui.go
@@ -2,6 +2,7 @@ package gui
import (
"github.com/isacikgoz/gitbatch/pkg/git"
+ "github.com/isacikgoz/gitbatch/pkg/job"
"github.com/jroimartin/gocui"
"fmt"
)
@@ -16,6 +17,7 @@ type guiState struct {
Repositories []*git.RepoEntity
Directories []string
Mode mode
+ Queue *job.JobQueue
}
type viewFeature struct {
@@ -40,8 +42,9 @@ const (
var (
mainViewFeature = viewFeature{Name: "main", Title: " Matched Repositories "}
loadingViewFeature = viewFeature{Name: "loading", Title: " Loading in Progress "}
- branchViewFeature = viewFeature{Name: "branch", Title: " Branches "}
+ 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 "}
@@ -58,6 +61,7 @@ func NewGui(directoies []string) (*Gui, error) {
initialState := guiState{
Directories: directoies,
Mode: fetchMode,
+ Queue: job.CreateJobQueue(),
}
gui := &Gui{
State: initialState,
@@ -118,37 +122,37 @@ func (gui *Gui) layout(g *gocui.Gui) error {
v.SelFgColor = gocui.ColorBlack
v.Overwrite = true
}
- if v, err := g.SetView(branchViewFeature.Name, int(0.55*float32(maxX)), 0, maxX-1, int(0.20*float32(maxY))-1); err != nil {
+ 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 = branchViewFeature.Title
+ v.Title = remoteViewFeature.Title
v.Wrap = false
v.Autoscroll = false
}
- if v, err := g.SetView(remoteViewFeature.Name, int(0.55*float32(maxX)), int(0.20*float32(maxY)), maxX-1, int(0.40*float32(maxY))); err != nil {
+ 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 = remoteViewFeature.Title
+ v.Title = remoteBranchViewFeature.Title
v.Wrap = false
- v.Overwrite = true
+ v.Overwrite = false
}
- if v, err := g.SetView(commitViewFeature.Name, int(0.55*float32(maxX)), int(0.40*float32(maxY))+1, maxX-1, int(0.73*float32(maxY))); err != nil {
+ 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 = commitViewFeature.Title
+ v.Title = branchViewFeature.Title
v.Wrap = false
v.Autoscroll = false
}
- if v, err := g.SetView(scheduleViewFeature.Name, int(0.55*float32(maxX)), int(0.73*float32(maxY))+1, maxX-1, maxY-2); err != nil {
+ 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 = scheduleViewFeature.Title
- v.Wrap = true
- v.Autoscroll = true
+ 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 {
diff --git a/pkg/gui/keybindings.go b/pkg/gui/keybindings.go
index 6605a4d..73f2629 100644
--- a/pkg/gui/keybindings.go
+++ b/pkg/gui/keybindings.go
@@ -75,6 +75,14 @@ func (gui *Gui) generateKeybindings() error {
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,
diff --git a/pkg/gui/mainview.go b/pkg/gui/mainview.go
index 824fce1..9c69f65 100644
--- a/pkg/gui/mainview.go
+++ b/pkg/gui/mainview.go
@@ -4,6 +4,7 @@ import (
"fmt"
"sync"
"github.com/isacikgoz/gitbatch/pkg/git"
+ "github.com/isacikgoz/gitbatch/pkg/job"
"github.com/jroimartin/gocui"
"regexp"
)
@@ -111,11 +112,23 @@ func (gui *Gui) markRepository(g *gocui.Gui, v *gocui.View) error {
}
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)
- gui.updateSchedule(g, r)
}
return nil
}
diff --git a/pkg/gui/remotebranchview.go b/pkg/gui/remotebranchview.go
new file mode 100644
index 0000000..7238f91
--- /dev/null
+++ b/pkg/gui/remotebranchview.go
@@ -0,0 +1,50 @@
+package gui
+
+import (
+ "github.com/isacikgoz/gitbatch/pkg/git"
+ "github.com/jroimartin/gocui"
+ "fmt"
+)
+
+func (gui *Gui) updateRemoteBranches(g *gocui.Gui, entity *git.RepoEntity) 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
+}
+
+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
+ }
+
+ 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
diff --git a/pkg/gui/remotesview.go b/pkg/gui/remotesview.go
index e674f43..5d3b924 100644
--- a/pkg/gui/remotesview.go
+++ b/pkg/gui/remotesview.go
@@ -2,6 +2,7 @@ package gui
import (
"github.com/isacikgoz/gitbatch/pkg/git"
+ "github.com/isacikgoz/gitbatch/pkg/utils"
"github.com/jroimartin/gocui"
"fmt"
)
@@ -17,16 +18,20 @@ func (gui *Gui) updateRemotes(g *gocui.Gui, entity *git.RepoEntity) error {
currentindex := 0
totalRemotes := len(entity.Remotes)
- for i, r := range entity.Remotes {
- if r.Name == entity.Remote.Name {
- currentindex = i
- fmt.Fprintln(out, selectionIndicator() + r.Name)
- continue
+ 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)
}
- fmt.Fprintln(out, tab() + r.Name)
- }
- if err = gui.smartAnchorRelativeToLine(out, currentindex, totalRemotes); err != nil {
- return err
+ if err = gui.smartAnchorRelativeToLine(out, currentindex, totalRemotes); err != nil {
+ return err
+ }
}
return nil
}
@@ -37,13 +42,14 @@ func (gui *Gui) nextRemote(g *gocui.Gui, v *gocui.View) error {
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
diff --git a/pkg/gui/scheduleview.go b/pkg/gui/scheduleview.go
deleted file mode 100644
index 2b83605..0000000
--- a/pkg/gui/scheduleview.go
+++ /dev/null
@@ -1,41 +0,0 @@
-package gui
-
-import (
- "github.com/isacikgoz/gitbatch/pkg/git"
- "github.com/jroimartin/gocui"
- "fmt"
- "strings"
-)
-
-func (gui *Gui) updateSchedule(g *gocui.Gui, entity *git.RepoEntity) error {
- var err error
-
- out, err := g.View(scheduleViewFeature.Name)
- if err != nil {
- return err
- }
- out.Clear()
- if entity.Marked {
-
- rm := entity.Remote.Reference.Name().Short()
- switch mode := gui.State.Mode.ModeID; mode {
- case FetchMode:
- remote := strings.Split(rm, "/")[0]
- s := green.Sprint("$") + " git fetch " + remote
- fmt.Fprintln(out, s)
- case PullMode:
- s := green.Sprint("$") + " git checkout " + entity.Branch.Name + " " + green.Sprint("✓")
- fmt.Fprintln(out, s)
- remote := strings.Split(rm, "/")[0]
- s = green.Sprint("$") + " git fetch " + remote
- fmt.Fprintln(out, s)
- s = green.Sprint("$") + " git merge " + entity.Remote.Name
- fmt.Fprintln(out, s)
- default:
- fmt.Fprintln(out, "No mode selected")
- }
- } else {
- return nil
- }
- return nil
-} \ No newline at end of file
diff --git a/pkg/job/job.go b/pkg/job/job.go
new file mode 100644
index 0000000..6bd5f4d
--- /dev/null
+++ b/pkg/job/job.go
@@ -0,0 +1,80 @@
+package job
+
+import (
+ "fmt"
+ "errors"
+)
+
+type Job struct {
+ JobType JobType
+ RepoID string
+ Name string
+ Args []string
+}
+
+type JobQueue struct {
+ series []*Job
+}
+
+type JobType string
+
+const (
+ Fetch JobType = "FETCH"
+ Pull JobType = "PULL"
+)
+
+func CreateJob() (j *Job, err error) {
+ fmt.Println("Job created.")
+ return j, nil
+}
+
+func (job *Job) start() error {
+ switch mode := job.JobType; mode {
+ case Fetch:
+ fmt.Println("Fetch operation is started")
+ case Pull:
+ fmt.Println("Pull operation is started")
+ default:
+ return errors.New("Unknown job type")
+ }
+ return nil
+}
+
+func CreateJobQueue() (jobQueue *JobQueue) {
+ s := make([]*Job, 0)
+ return &JobQueue{
+ series: s,
+ }
+}
+
+func (jobQueue *JobQueue) AddJob(j *Job) error {
+ for _, job := range jobQueue.series {
+ if job.RepoID == j.RepoID && job.JobType == j.JobType {
+ return errors.New("Same job already is in the queue")
+ }
+ }
+ jobQueue.series = append(jobQueue.series, j)
+ return nil
+}
+
+func (jobQueue *JobQueue) StartNext() error {
+ lastJob := jobQueue.series[len(jobQueue.series)-1]
+ if err := lastJob.start(); err != nil {
+ return err
+ }
+ return nil
+}
+
+func (jobQueue *JobQueue) RemoveFromQueue(repoID string) error {
+ removed := false
+ for i, job := range jobQueue.series {
+ if job.RepoID == repoID{
+ jobQueue.series = append(jobQueue.series[:i], jobQueue.series[i+1:]...)
+ removed = true
+ }
+ }
+ if !removed {
+ 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 6a8b007..4855cbd 100644
--- a/pkg/utils/utils.go
+++ b/pkg/utils/utils.go
@@ -2,8 +2,16 @@ package utils
import (
"strings"
+ "regexp"
+ "math/rand"
+ "time"
+ "fmt"
+ "crypto/sha1"
)
+var characterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
+var src = rand.NewSource(time.Now().UnixNano())
+
func TrimTrailingNewline(str string) string {
if strings.HasSuffix(str, "\n") {
return str[:len(str)-1]
@@ -16,4 +24,49 @@ func Min(x, y int) int {
return x
}
return y
+}
+
+func TrimRemoteURL(url string) (urltype string, shorturl string) {
+ ressh := regexp.MustCompile(`git@`)
+ rehttp := regexp.MustCompile(`http://`)
+ rehttps := regexp.MustCompile(`https://`)
+
+ if ressh.MatchString(url) {
+ shorturl = ressh.Split(url, 5)[1]
+ urltype = "ssh"
+ } else if rehttp.MatchString(url) {
+ shorturl = rehttp.Split(url, 5)[1]
+ urltype = "http"
+ } else if rehttps.MatchString(url) {
+ shorturl = rehttps.Split(url, 5)[1]
+ urltype = "https"
+ }
+ return urltype, shorturl
+}
+
+// RandomString generates a random string of n length
+func RandomString(n int) string {
+ b := make([]rune, n)
+ for i := range b {
+ b[i] = characterRunes[rand.Intn(len(characterRunes))]
+ }
+ return string(b)
+}
+
+// NewSHA1Hash generates a new SHA1 hash based on
+// a random number of characters.
+func NewHash(n ...int) string {
+ noRandomCharacters := 32
+
+ if len(n) > 0 {
+ noRandomCharacters = n[0]
+ }
+
+ randString := RandomString(noRandomCharacters)
+
+ hash := sha1.New()
+ hash.Write([]byte(randString))
+ bs := hash.Sum(nil)
+
+ return fmt.Sprintf("%x", bs)
} \ No newline at end of file