Files
server/poll/poll.go
T
2022-12-20 16:24:27 -07:00

109 lines
3.4 KiB
Go

package poll
import (
"time"
"github.com/op/go-logging"
"git.ohea.xyz/cursorius/server/config"
"git.ohea.xyz/cursorius/server/jobscheduler"
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing"
"github.com/go-git/go-git/v5/storage/memory"
)
var log = logging.MustGetLogger("cursorius-server")
type branch struct {
ref string
commitHash string
}
type tag struct {
ref string
commitHash string
}
func pollJob(repoName string, jobConfig config.Job, runCh chan jobscheduler.Run) {
prevCommits := make(map[string]string)
for {
time.Sleep(time.Duration(jobConfig.PollInterval) * time.Second)
log.Infof("Polling repo %v", repoName)
repo, err := git.Clone(memory.NewStorage(), nil, &git.CloneOptions{
URL: jobConfig.URL,
})
if err != nil {
log.Errorf("Could not clone repo %v from url %v: %v", repoName, jobConfig.URL, err)
continue
}
refsToRunFor := []string{}
// get branches
branches, err := repo.Branches()
if err != nil {
log.Errorf("Could not enumerate branches in repo %v: %v", repoName, err)
continue
}
branches.ForEach(func(branch *plumbing.Reference) error {
log.Debugf("Processing branch %v from repo %v", branch.Name().String(), repoName)
prevRef, ok := prevCommits[branch.Name().String()]
if ok {
if branch.Hash().String() != prevRef {
log.Debugf("Queuing job for branch %v in repo %v with hash %v", branch.Name().String(), repoName, branch.Hash().String())
prevCommits[branch.Name().String()] = branch.Hash().String()
refsToRunFor = append(refsToRunFor, branch.Name().String())
} else {
log.Debugf("Branch %v in repo %v has hash %v, which matches the previously seen hash of %v", branch.Name().String(), repoName, branch.Hash().String(), prevRef)
}
} else {
log.Debugf("Queuing job for newly discovered branch %v in repo %v with hash %v", branch.Name().String(), repoName, branch.Hash().String())
prevCommits[branch.Name().String()] = branch.Hash().String()
}
return nil
})
tags, err := repo.Tags()
if err != nil {
log.Errorf("Could not enumerate tags in repo %v: %v", repoName, err)
continue
}
tags.ForEach(func(tag *plumbing.Reference) error {
log.Debugf("Processing tag %v from repo %v", tag.Name().String(), repoName)
prevRef, ok := prevCommits[tag.Name().String()]
if ok {
if tag.Hash().String() != prevRef {
log.Debugf("Queuing job for tag %v in repo %v with hash %v", tag.Name().String(), repoName, tag.Hash().String())
prevCommits[tag.Name().String()] = tag.Hash().String()
refsToRunFor = append(refsToRunFor, tag.Name().String())
} else {
log.Debugf("Tag %v in repo %v has hash %v, which matches the previously seen hash of %v", tag.Name().String(), repoName, tag.Hash().String(), prevRef)
}
} else {
log.Debugf("Queuing job for newly discovered tag %v in repo %v with hash %v", tag.Name().String(), repoName, tag.Hash().String())
prevCommits[tag.Name().String()] = tag.Hash().String()
}
return nil
})
for _, ref := range refsToRunFor {
log.Debugf("Dispatching job for ref %v in repo %v", ref, repoName)
runCh <- jobscheduler.Run{
Name: repoName,
Ref: ref,
}
}
}
}
func StartPolling(jobs map[string]config.Job, runCh chan jobscheduler.Run) {
for jobName, job := range jobs {
if job.PollInterval == 0 {
continue
} else {
go pollJob(jobName, job, runCh)
}
}
}