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}