remote_actions.go

  1package bug
  2
  3import (
  4	"fmt"
  5	"github.com/MichaelMure/git-bug/repository"
  6	"strings"
  7)
  8
  9const MsgNew = "new"
 10const MsgInvalid = "invalid data"
 11const MsgUpdated = "updated"
 12const MsgNothing = "nothing to do"
 13
 14func Fetch(repo repository.Repo, remote string) error {
 15	remoteRefSpec := fmt.Sprintf(bugsRemoteRefPattern, remote)
 16	fetchRefSpec := fmt.Sprintf("%s*:%s*", bugsRefPattern, remoteRefSpec)
 17
 18	return repo.FetchRefs(remote, fetchRefSpec)
 19}
 20
 21func Push(repo repository.Repo, remote string) error {
 22	return repo.PushRefs(remote, bugsRefPattern+"*")
 23}
 24
 25type MergeResult struct {
 26	Err error
 27
 28	Id      string
 29	HumanId string
 30	Status  string
 31}
 32
 33func newMergeError(id string, err error) MergeResult {
 34	return MergeResult{
 35		Id:      id,
 36		HumanId: formatHumanId(id),
 37		Status:  err.Error(),
 38	}
 39}
 40
 41func newMergeStatus(id string, status string) MergeResult {
 42	return MergeResult{
 43		Id:      id,
 44		HumanId: formatHumanId(id),
 45		Status:  status,
 46	}
 47}
 48
 49func MergeAll(repo repository.Repo, remote string) <-chan MergeResult {
 50	out := make(chan MergeResult)
 51
 52	go func() {
 53		defer close(out)
 54
 55		remoteRefSpec := fmt.Sprintf(bugsRemoteRefPattern, remote)
 56		remoteRefs, err := repo.ListRefs(remoteRefSpec)
 57
 58		if err != nil {
 59			out <- MergeResult{Err: err}
 60			return
 61		}
 62
 63		for _, remoteRef := range remoteRefs {
 64			refSplitted := strings.Split(remoteRef, "/")
 65			id := refSplitted[len(refSplitted)-1]
 66
 67			remoteBug, err := readBug(repo, remoteRef)
 68
 69			if err != nil {
 70				out <- newMergeError(id, err)
 71				continue
 72			}
 73
 74			// Check for error in remote data
 75			if !remoteBug.IsValid() {
 76				out <- newMergeStatus(id, MsgInvalid)
 77				continue
 78			}
 79
 80			localRef := bugsRefPattern + remoteBug.Id()
 81			localExist, err := repo.RefExist(localRef)
 82
 83			// the bug is not local yet, simply create the reference
 84			if !localExist {
 85				err := repo.CopyRef(remoteRef, localRef)
 86
 87				if err != nil {
 88					out <- newMergeError(id, err)
 89					return
 90				}
 91
 92				out <- newMergeStatus(id, MsgNew)
 93				continue
 94			}
 95
 96			localBug, err := readBug(repo, localRef)
 97
 98			if err != nil {
 99				out <- newMergeError(id, err)
100				return
101			}
102
103			updated, err := localBug.Merge(repo, remoteBug)
104
105			if err != nil {
106				out <- newMergeError(id, err)
107				return
108			}
109
110			if updated {
111				out <- newMergeStatus(id, MsgUpdated)
112			} else {
113				out <- newMergeStatus(id, MsgNothing)
114			}
115		}
116	}()
117
118	return out
119}