1package resolvers
2
3import (
4 "context"
5 "errors"
6 "time"
7
8 "github.com/MichaelMure/git-bug/bug"
9 "github.com/MichaelMure/git-bug/cache"
10 "github.com/MichaelMure/git-bug/graphql/graph"
11 "github.com/MichaelMure/git-bug/graphql/models"
12 "github.com/MichaelMure/git-bug/identity"
13)
14
15var ErrNotAuthenticated = errors.New("not authenticated or read-only")
16
17var _ graph.MutationResolver = &mutationResolver{}
18
19type mutationResolver struct {
20 cache *cache.MultiRepoCache
21}
22
23func (r mutationResolver) getRepo(ref *string) (*cache.RepoCache, error) {
24 if ref != nil {
25 return r.cache.ResolveRepo(*ref)
26 }
27
28 return r.cache.DefaultRepo()
29}
30
31func (r mutationResolver) getBug(repoRef *string, bugPrefix string) (*cache.RepoCache, *cache.BugCache, error) {
32 repo, err := r.getRepo(repoRef)
33 if err != nil {
34 return nil, nil, err
35 }
36
37 bug, err := repo.ResolveBugPrefix(bugPrefix)
38 if err != nil {
39 return nil, nil, err
40 }
41 return repo, bug, nil
42}
43
44func (r mutationResolver) NewBug(ctx context.Context, input models.NewBugInput) (*models.NewBugPayload, error) {
45 repo, err := r.getRepo(input.RepoRef)
46 if err != nil {
47 return nil, err
48 }
49
50 id := identity.ForContext(ctx, repo)
51 if id == nil {
52 return nil, ErrNotAuthenticated
53 }
54 author := cache.NewIdentityCache(repo, id)
55
56 b, op, err := repo.NewBugRaw(author, time.Now().Unix(), input.Title, input.Message, input.Files, nil)
57 if err != nil {
58 return nil, err
59 }
60
61 return &models.NewBugPayload{
62 ClientMutationID: input.ClientMutationID,
63 Bug: models.NewLoadedBug(b.Snapshot()),
64 Operation: op,
65 }, nil
66}
67
68func (r mutationResolver) AddComment(ctx context.Context, input models.AddCommentInput) (*models.AddCommentPayload, error) {
69 repo, b, err := r.getBug(input.RepoRef, input.Prefix)
70 if err != nil {
71 return nil, err
72 }
73
74 id := identity.ForContext(ctx, repo)
75 if id == nil {
76 return nil, ErrNotAuthenticated
77 }
78 author := cache.NewIdentityCache(repo, id)
79
80 op, err := b.AddCommentRaw(author, time.Now().Unix(), input.Message, input.Files, nil)
81 if err != nil {
82 return nil, err
83 }
84
85 err = b.Commit()
86 if err != nil {
87 return nil, err
88 }
89
90 return &models.AddCommentPayload{
91 ClientMutationID: input.ClientMutationID,
92 Bug: models.NewLoadedBug(b.Snapshot()),
93 Operation: op,
94 }, nil
95}
96
97func (r mutationResolver) ChangeLabels(ctx context.Context, input *models.ChangeLabelInput) (*models.ChangeLabelPayload, error) {
98 repo, b, err := r.getBug(input.RepoRef, input.Prefix)
99 if err != nil {
100 return nil, err
101 }
102
103 id := identity.ForContext(ctx, repo)
104 if id == nil {
105 return nil, ErrNotAuthenticated
106 }
107 author := cache.NewIdentityCache(repo, id)
108
109 results, op, err := b.ChangeLabelsRaw(author, time.Now().Unix(), input.Added, input.Removed, nil)
110 if err != nil {
111 return nil, err
112 }
113
114 err = b.Commit()
115 if err != nil {
116 return nil, err
117 }
118
119 resultsPtr := make([]*bug.LabelChangeResult, len(results))
120 for i, result := range results {
121 resultsPtr[i] = &result
122 }
123
124 return &models.ChangeLabelPayload{
125 ClientMutationID: input.ClientMutationID,
126 Bug: models.NewLoadedBug(b.Snapshot()),
127 Operation: op,
128 Results: resultsPtr,
129 }, nil
130}
131
132func (r mutationResolver) OpenBug(ctx context.Context, input models.OpenBugInput) (*models.OpenBugPayload, error) {
133 repo, b, err := r.getBug(input.RepoRef, input.Prefix)
134 if err != nil {
135 return nil, err
136 }
137
138 id := identity.ForContext(ctx, repo)
139 if id == nil {
140 return nil, ErrNotAuthenticated
141 }
142 author := cache.NewIdentityCache(repo, id)
143
144 op, err := b.OpenRaw(author, time.Now().Unix(), nil)
145 if err != nil {
146 return nil, err
147 }
148
149 err = b.Commit()
150 if err != nil {
151 return nil, err
152 }
153
154 return &models.OpenBugPayload{
155 ClientMutationID: input.ClientMutationID,
156 Bug: models.NewLoadedBug(b.Snapshot()),
157 Operation: op,
158 }, nil
159}
160
161func (r mutationResolver) CloseBug(ctx context.Context, input models.CloseBugInput) (*models.CloseBugPayload, error) {
162 repo, b, err := r.getBug(input.RepoRef, input.Prefix)
163 if err != nil {
164 return nil, err
165 }
166
167 id := identity.ForContext(ctx, repo)
168 if id == nil {
169 return nil, ErrNotAuthenticated
170 }
171 author := cache.NewIdentityCache(repo, id)
172
173 op, err := b.CloseRaw(author, time.Now().Unix(), nil)
174 if err != nil {
175 return nil, err
176 }
177
178 err = b.Commit()
179 if err != nil {
180 return nil, err
181 }
182
183 return &models.CloseBugPayload{
184 ClientMutationID: input.ClientMutationID,
185 Bug: models.NewLoadedBug(b.Snapshot()),
186 Operation: op,
187 }, nil
188}
189
190func (r mutationResolver) SetTitle(ctx context.Context, input models.SetTitleInput) (*models.SetTitlePayload, error) {
191 repo, b, err := r.getBug(input.RepoRef, input.Prefix)
192 if err != nil {
193 return nil, err
194 }
195
196 id := identity.ForContext(ctx, repo)
197 if id == nil {
198 return nil, ErrNotAuthenticated
199 }
200 author := cache.NewIdentityCache(repo, id)
201
202 op, err := b.SetTitleRaw(author, time.Now().Unix(), input.Title, nil)
203 if err != nil {
204 return nil, err
205 }
206
207 err = b.Commit()
208 if err != nil {
209 return nil, err
210 }
211
212 return &models.SetTitlePayload{
213 ClientMutationID: input.ClientMutationID,
214 Bug: models.NewLoadedBug(b.Snapshot()),
215 Operation: op,
216 }, nil
217}