1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
|
package queue
import (
"errors"
"fmt"
"time"
"github.com/isacikgoz/gitbatch/pkg/git"
)
// Job relates the type of the operation and the entity
type Job struct {
JobType JobType
Entity *git.RepoEntity
}
// JobQueue holds the slice of Jobs
type JobQueue struct {
series []*Job
}
// JobType is the a git operation supported
type JobType string
const (
// Fetch is wrapper of git fetch command
Fetch JobType = "fetch"
// Pull is wrapper of git pull command
Pull JobType = "pull"
// Merge is wrapper of git merge command
Merge JobType = "merge"
)
// CreateJob es its name implies creates a job struct and return its pointer
func CreateJob() (j *Job, err error) {
fmt.Println("Job created.")
return j, nil
}
// starts the job
func (job *Job) start() error {
job.Entity.State = git.Working
// added for testing, TODO: remove
time.Sleep(time.Second)
// TODO: Handle errors?
switch mode := job.JobType; mode {
case Fetch:
if err := job.Entity.Fetch(); err != nil {
job.Entity.State = git.Fail
return nil
}
job.Entity.RefreshPushPull()
job.Entity.State = git.Success
case Pull:
if err := job.Entity.Pull(); err != nil {
job.Entity.State = git.Fail
return nil
}
job.Entity.RefreshPushPull()
job.Entity.State = git.Success
case Merge:
if err := job.Entity.Merge(); err != nil {
job.Entity.State = git.Fail
return nil
}
job.Entity.RefreshPushPull()
job.Entity.State = git.Success
default:
job.Entity.State = git.Available
return nil
}
return nil
}
// CreateJobQueue creates a jobqueue struct and initialize its slice then return
// its pointer
func CreateJobQueue() (jobQueue *JobQueue) {
s := make([]*Job, 0)
return &JobQueue{
series: s,
}
}
// AddJob adds a job to the queue
func (jobQueue *JobQueue) AddJob(j *Job) error {
for _, job := range jobQueue.series {
if job.Entity.RepoID == j.Entity.RepoID && job.JobType == j.JobType {
return errors.New("Same job already is in the queue")
}
}
jobQueue.series = append(jobQueue.series, nil)
copy(jobQueue.series[1:], jobQueue.series[0:])
jobQueue.series[0] = j
return nil
}
// StartNext starts the next job in the queue
func (jobQueue *JobQueue) StartNext() (j *Job, finished bool, err error) {
finished = false
if len(jobQueue.series) < 1 {
finished = true
return nil, finished, nil
}
i := len(jobQueue.series) - 1
lastJob := jobQueue.series[i]
jobQueue.series = jobQueue.series[:i]
if err = lastJob.start(); err != nil {
return lastJob, finished, err
}
return lastJob, finished, nil
}
// RemoveFromQueue deletes the given entity and its job from the queue
// TODO: it is not safe if the job has been started
func (jobQueue *JobQueue) RemoveFromQueue(entity *git.RepoEntity) error {
removed := false
for i, job := range jobQueue.series {
if job.Entity.RepoID == entity.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
}
// IsInTheQueue function; since the job and entity is not tied with its own
// struct, this function returns true if that entity is in the queue along with
// the jobs type
func (jobQueue *JobQueue) IsInTheQueue(entity *git.RepoEntity) (inTheQueue bool, jt JobType) {
inTheQueue = false
for _, job := range jobQueue.series {
if job.Entity.RepoID == entity.RepoID {
inTheQueue = true
jt = job.JobType
}
}
return inTheQueue, jt
}
|