Signed-off-by: nelind nel.n.lindberg@gmail.com
+202
-1
api/tangled/cbor_gen.go
+202
-1
api/tangled/cbor_gen.go
···
6741
6741
6742
6742
return nil
6743
6743
}
6744
+
func (t *RepoPull_StackInfo) MarshalCBOR(w io.Writer) error {
6745
+
if t == nil {
6746
+
_, err := w.Write(cbg.CborNull)
6747
+
return err
6748
+
}
6749
+
6750
+
cw := cbg.NewCborWriter(w)
6751
+
fieldCount := 2
6752
+
6753
+
if t.Parent == nil {
6754
+
fieldCount--
6755
+
}
6756
+
6757
+
if _, err := cw.Write(cbg.CborEncodeMajorType(cbg.MajMap, uint64(fieldCount))); err != nil {
6758
+
return err
6759
+
}
6760
+
6761
+
// t.Parent (string) (string)
6762
+
if t.Parent != nil {
6763
+
6764
+
if len("parent") > 1000000 {
6765
+
return xerrors.Errorf("Value in field \"parent\" was too long")
6766
+
}
6767
+
6768
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("parent"))); err != nil {
6769
+
return err
6770
+
}
6771
+
if _, err := cw.WriteString(string("parent")); err != nil {
6772
+
return err
6773
+
}
6774
+
6775
+
if t.Parent == nil {
6776
+
if _, err := cw.Write(cbg.CborNull); err != nil {
6777
+
return err
6778
+
}
6779
+
} else {
6780
+
if len(*t.Parent) > 1000000 {
6781
+
return xerrors.Errorf("Value in field t.Parent was too long")
6782
+
}
6783
+
6784
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(*t.Parent))); err != nil {
6785
+
return err
6786
+
}
6787
+
if _, err := cw.WriteString(string(*t.Parent)); err != nil {
6788
+
return err
6789
+
}
6790
+
}
6791
+
}
6792
+
6793
+
// t.ChangeId (string) (string)
6794
+
if len("changeId") > 1000000 {
6795
+
return xerrors.Errorf("Value in field \"changeId\" was too long")
6796
+
}
6797
+
6798
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("changeId"))); err != nil {
6799
+
return err
6800
+
}
6801
+
if _, err := cw.WriteString(string("changeId")); err != nil {
6802
+
return err
6803
+
}
6804
+
6805
+
if len(t.ChangeId) > 1000000 {
6806
+
return xerrors.Errorf("Value in field t.ChangeId was too long")
6807
+
}
6808
+
6809
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.ChangeId))); err != nil {
6810
+
return err
6811
+
}
6812
+
if _, err := cw.WriteString(string(t.ChangeId)); err != nil {
6813
+
return err
6814
+
}
6815
+
return nil
6816
+
}
6817
+
6818
+
func (t *RepoPull_StackInfo) UnmarshalCBOR(r io.Reader) (err error) {
6819
+
*t = RepoPull_StackInfo{}
6820
+
6821
+
cr := cbg.NewCborReader(r)
6822
+
6823
+
maj, extra, err := cr.ReadHeader()
6824
+
if err != nil {
6825
+
return err
6826
+
}
6827
+
defer func() {
6828
+
if err == io.EOF {
6829
+
err = io.ErrUnexpectedEOF
6830
+
}
6831
+
}()
6832
+
6833
+
if maj != cbg.MajMap {
6834
+
return fmt.Errorf("cbor input should be of type map")
6835
+
}
6836
+
6837
+
if extra > cbg.MaxLength {
6838
+
return fmt.Errorf("RepoPull_StackInfo: map struct too large (%d)", extra)
6839
+
}
6840
+
6841
+
n := extra
6842
+
6843
+
nameBuf := make([]byte, 8)
6844
+
for i := uint64(0); i < n; i++ {
6845
+
nameLen, ok, err := cbg.ReadFullStringIntoBuf(cr, nameBuf, 1000000)
6846
+
if err != nil {
6847
+
return err
6848
+
}
6849
+
6850
+
if !ok {
6851
+
// Field doesn't exist on this type, so ignore it
6852
+
if err := cbg.ScanForLinks(cr, func(cid.Cid) {}); err != nil {
6853
+
return err
6854
+
}
6855
+
continue
6856
+
}
6857
+
6858
+
switch string(nameBuf[:nameLen]) {
6859
+
// t.Parent (string) (string)
6860
+
case "parent":
6861
+
6862
+
{
6863
+
b, err := cr.ReadByte()
6864
+
if err != nil {
6865
+
return err
6866
+
}
6867
+
if b != cbg.CborNull[0] {
6868
+
if err := cr.UnreadByte(); err != nil {
6869
+
return err
6870
+
}
6871
+
6872
+
sval, err := cbg.ReadStringWithMax(cr, 1000000)
6873
+
if err != nil {
6874
+
return err
6875
+
}
6876
+
6877
+
t.Parent = (*string)(&sval)
6878
+
}
6879
+
}
6880
+
// t.ChangeId (string) (string)
6881
+
case "changeId":
6882
+
6883
+
{
6884
+
sval, err := cbg.ReadStringWithMax(cr, 1000000)
6885
+
if err != nil {
6886
+
return err
6887
+
}
6888
+
6889
+
t.ChangeId = string(sval)
6890
+
}
6891
+
6892
+
default:
6893
+
// Field doesn't exist on this type, so ignore it
6894
+
if err := cbg.ScanForLinks(r, func(cid.Cid) {}); err != nil {
6895
+
return err
6896
+
}
6897
+
}
6898
+
}
6899
+
6900
+
return nil
6901
+
}
6744
6902
func (t *RepoPull_Target) MarshalCBOR(w io.Writer) error {
6745
6903
if t == nil {
6746
6904
_, err := w.Write(cbg.CborNull)
···
6882
7040
}
6883
7041
6884
7042
cw := cbg.NewCborWriter(w)
6885
-
fieldCount := 7
7043
+
fieldCount := 8
6886
7044
6887
7045
if t.Body == nil {
6888
7046
fieldCount--
···
6892
7050
fieldCount--
6893
7051
}
6894
7052
7053
+
if t.StackInfo == nil {
7054
+
fieldCount--
7055
+
}
7056
+
6895
7057
if _, err := cw.Write(cbg.CborEncodeMajorType(cbg.MajMap, uint64(fieldCount))); err != nil {
6896
7058
return err
6897
7059
}
···
7050
7212
if _, err := cw.WriteString(string(t.CreatedAt)); err != nil {
7051
7213
return err
7052
7214
}
7215
+
7216
+
// t.StackInfo (tangled.RepoPull_StackInfo) (struct)
7217
+
if t.StackInfo != nil {
7218
+
7219
+
if len("stackInfo") > 1000000 {
7220
+
return xerrors.Errorf("Value in field \"stackInfo\" was too long")
7221
+
}
7222
+
7223
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("stackInfo"))); err != nil {
7224
+
return err
7225
+
}
7226
+
if _, err := cw.WriteString(string("stackInfo")); err != nil {
7227
+
return err
7228
+
}
7229
+
7230
+
if err := t.StackInfo.MarshalCBOR(cw); err != nil {
7231
+
return err
7232
+
}
7233
+
}
7053
7234
return nil
7054
7235
}
7055
7236
···
7199
7380
7200
7381
t.CreatedAt = string(sval)
7201
7382
}
7383
+
// t.StackInfo (tangled.RepoPull_StackInfo) (struct)
7384
+
case "stackInfo":
7385
+
7386
+
{
7387
+
7388
+
b, err := cr.ReadByte()
7389
+
if err != nil {
7390
+
return err
7391
+
}
7392
+
if b != cbg.CborNull[0] {
7393
+
if err := cr.UnreadByte(); err != nil {
7394
+
return err
7395
+
}
7396
+
t.StackInfo = new(RepoPull_StackInfo)
7397
+
if err := t.StackInfo.UnmarshalCBOR(cr); err != nil {
7398
+
return xerrors.Errorf("unmarshaling t.StackInfo pointer: %w", err)
7399
+
}
7400
+
}
7401
+
7402
+
}
7202
7403
7203
7404
default:
7204
7405
// Field doesn't exist on this type, so ignore it
+16
-7
api/tangled/repopull.go
+16
-7
api/tangled/repopull.go
···
17
17
} //
18
18
// RECORDTYPE: RepoPull
19
19
type RepoPull struct {
20
-
LexiconTypeID string `json:"$type,const=sh.tangled.repo.pull" cborgen:"$type,const=sh.tangled.repo.pull"`
21
-
Body *string `json:"body,omitempty" cborgen:"body,omitempty"`
22
-
CreatedAt string `json:"createdAt" cborgen:"createdAt"`
23
-
Patch string `json:"patch" cborgen:"patch"`
24
-
Source *RepoPull_Source `json:"source,omitempty" cborgen:"source,omitempty"`
25
-
Target *RepoPull_Target `json:"target" cborgen:"target"`
26
-
Title string `json:"title" cborgen:"title"`
20
+
LexiconTypeID string `json:"$type,const=sh.tangled.repo.pull" cborgen:"$type,const=sh.tangled.repo.pull"`
21
+
Body *string `json:"body,omitempty" cborgen:"body,omitempty"`
22
+
CreatedAt string `json:"createdAt" cborgen:"createdAt"`
23
+
Patch string `json:"patch" cborgen:"patch"`
24
+
Source *RepoPull_Source `json:"source,omitempty" cborgen:"source,omitempty"`
25
+
StackInfo *RepoPull_StackInfo `json:"stackInfo,omitempty" cborgen:"stackInfo,omitempty"`
26
+
Target *RepoPull_Target `json:"target" cborgen:"target"`
27
+
Title string `json:"title" cborgen:"title"`
27
28
}
28
29
29
30
// RepoPull_Source is a "source" in the sh.tangled.repo.pull schema.
···
33
34
Sha string `json:"sha" cborgen:"sha"`
34
35
}
35
36
37
+
// RepoPull_StackInfo is a "stackInfo" in the sh.tangled.repo.pull schema.
38
+
type RepoPull_StackInfo struct {
39
+
// changeId: Change ID of this commit/change. Principly also available in the patch itself as a line in the commit footer.
40
+
ChangeId string `json:"changeId" cborgen:"changeId"`
41
+
// parent: AT-URI of the PR for the parent commit/change in the change stack.
42
+
Parent *string `json:"parent,omitempty" cborgen:"parent,omitempty"`
43
+
}
44
+
36
45
// RepoPull_Target is a "target" in the sh.tangled.repo.pull schema.
37
46
type RepoPull_Target struct {
38
47
Branch string `json:"branch" cborgen:"branch"`
+7
appview/db/db.go
+7
appview/db/db.go
+38
-10
appview/db/pulls.go
+38
-10
appview/db/pulls.go
···
72
72
// stacking
73
73
StackId string // nullable string
74
74
ChangeId string // nullable string
75
+
ParentAt *syntax.ATURI
75
76
ParentChangeId string // nullable string
76
77
77
78
// meta
···
91
92
}
92
93
93
94
record := tangled.RepoPull{
94
-
Title: p.Title,
95
-
Body: &p.Body,
96
-
CreatedAt: p.Created.Format(time.RFC3339),
95
+
Title: p.Title,
96
+
Body: &p.Body,
97
+
CreatedAt: p.Created.Format(time.RFC3339),
97
98
Target: &tangled.RepoPull_Target{
98
99
Repo: p.RepoAt.String(),
99
100
Branch: p.TargetBranch,
100
101
},
101
-
Patch: p.LatestPatch(),
102
-
Source: source,
102
+
Patch: p.LatestPatch(),
103
+
Source: source,
104
+
StackInfo: &tangled.RepoPull_StackInfo{
105
+
ChangeId: p.ChangeId,
106
+
Parent: (*string)(p.ParentAt),
107
+
},
103
108
}
104
109
return record
105
110
}
···
255
260
}
256
261
}
257
262
258
-
var stackId, changeId, parentChangeId *string
263
+
var stackId, changeId, parentAt, parentChangeId *string
259
264
if pull.StackId != "" {
260
265
stackId = &pull.StackId
261
266
}
262
267
if pull.ChangeId != "" {
263
268
changeId = &pull.ChangeId
264
269
}
270
+
if pull.ParentAt != nil {
271
+
parentAt = (*string)(pull.ParentAt)
272
+
}
265
273
if pull.ParentChangeId != "" {
266
274
parentChangeId = &pull.ParentChangeId
267
275
}
···
269
277
_, err = tx.Exec(
270
278
`
271
279
insert into pulls (
272
-
repo_at, owner_did, pull_id, title, target_branch, body, rkey, state, source_branch, source_repo_at, stack_id, change_id, parent_change_id
280
+
repo_at, owner_did, pull_id, title, target_branch, body, rkey, state, source_branch, source_repo_at, stack_id, change_id, parent_at, parent_change_id
273
281
)
274
-
values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
282
+
values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
275
283
pull.RepoAt,
276
284
pull.OwnerDid,
277
285
pull.PullId,
···
284
292
sourceRepoAt,
285
293
stackId,
286
294
changeId,
295
+
parentAt,
287
296
parentChangeId,
288
297
)
289
298
if err != nil {
···
341
350
source_repo_at,
342
351
stack_id,
343
352
change_id,
353
+
parent_at,
344
354
parent_change_id
345
355
from
346
356
pulls
···
356
366
for rows.Next() {
357
367
var pull Pull
358
368
var createdAt string
359
-
var sourceBranch, sourceRepoAt, stackId, changeId, parentChangeId sql.NullString
369
+
var sourceBranch, sourceRepoAt, stackId, changeId, parentAt, parentChangeId sql.NullString
360
370
err := rows.Scan(
361
371
&pull.OwnerDid,
362
372
&pull.RepoAt,
···
371
381
&sourceRepoAt,
372
382
&stackId,
373
383
&changeId,
384
+
&parentAt,
374
385
&parentChangeId,
375
386
)
376
387
if err != nil {
···
402
413
if changeId.Valid {
403
414
pull.ChangeId = changeId.String
404
415
}
416
+
if parentAt.Valid {
417
+
parentAtParsed, err := syntax.ParseATURI(parentAt.String)
418
+
if err != nil {
419
+
return nil, err
420
+
}
421
+
pull.ParentAt = &parentAtParsed
422
+
}
405
423
if parentChangeId.Valid {
406
424
pull.ParentChangeId = parentChangeId.String
407
425
}
···
530
548
source_repo_at,
531
549
stack_id,
532
550
change_id,
551
+
parent_at,
533
552
parent_change_id
534
553
from
535
554
pulls
···
540
559
541
560
var pull Pull
542
561
var createdAt string
543
-
var sourceBranch, sourceRepoAt, stackId, changeId, parentChangeId sql.NullString
562
+
var sourceBranch, sourceRepoAt, stackId, changeId, parentAt, parentChangeId sql.NullString
544
563
err := row.Scan(
545
564
&pull.OwnerDid,
546
565
&pull.PullId,
···
555
574
&sourceRepoAt,
556
575
&stackId,
557
576
&changeId,
577
+
&parentAt,
558
578
&parentChangeId,
559
579
)
560
580
if err != nil {
581
+
fmt.Printf("its the place you think it is and heres the row %s\n", row)
561
582
return nil, err
562
583
}
563
584
···
587
608
if changeId.Valid {
588
609
pull.ChangeId = changeId.String
589
610
}
611
+
if parentAt.Valid {
612
+
parsedParentAt, err := syntax.ParseATURI(parentAt.String)
613
+
if err != nil {
614
+
return nil, err
615
+
}
616
+
pull.ParentAt = &parsedParentAt
617
+
}
590
618
if parentChangeId.Valid {
591
619
pull.ParentChangeId = parentChangeId.String
592
620
}
+31
-2
appview/pulls/pulls.go
+31
-2
appview/pulls/pulls.go
···
1693
1693
newStack, err := newStack(f, user, targetBranch, patch, pull.PullSource, stackId)
1694
1694
if err != nil {
1695
1695
log.Println("failed to create resubmitted stack", err)
1696
-
s.pages.Notice(w, "pull-merge-error", "Failed to merge pull request. Try again later.")
1696
+
s.pages.Notice(w, "pull-resubmit-error", "Failed to merge pull request. Try again later.")
1697
1697
return
1698
1698
}
1699
1699
1700
1700
// find the diff between the stacks, first, map them by changeId
1701
1701
origById := make(map[string]*db.Pull)
1702
1702
newById := make(map[string]*db.Pull)
1703
+
chIdToAtUri := make(map[string]*syntax.ATURI)
1703
1704
for _, p := range origStack {
1704
1705
origById[p.ChangeId] = p
1706
+
1707
+
// build map from change id to existing at uris
1708
+
pAtUri, err := syntax.ParseATURI(fmt.Sprintf("at://%s/%s/%s", user.Did, tangled.RepoPullNSID, p.Rkey))
1709
+
if err != nil {
1710
+
log.Println(
1711
+
"failed to parse string %s into an AT URI while resubmitting stack. this should not be possible",
1712
+
fmt.Sprintf("at://%s/%s/%s", user.Did, tangled.RepoPullNSID, p.Rkey))
1713
+
s.pages.Notice(w, "pull-resubmit-error", "Failed to merge pull request. Try again later.")
1714
+
return
1715
+
}
1716
+
chIdToAtUri[p.ChangeId] = &pAtUri
1705
1717
}
1706
1718
for _, p := range newStack {
1719
+
// if change id has already been given a PR use its at uri instead of the newly created (and thus incorrect)
1720
+
// one made by newStack
1721
+
if ppAt, ok := chIdToAtUri[p.ParentChangeId]; ok {
1722
+
p.ParentAt = ppAt
1723
+
}
1724
+
1707
1725
newById[p.ChangeId] = p
1708
1726
}
1709
1727
···
1751
1769
// we still need to update the hash in submission.Patch and submission.SourceRev
1752
1770
if patchutil.Equal(newFiles, origFiles) &&
1753
1771
origHeader.Title == newHeader.Title &&
1754
-
origHeader.Body == newHeader.Body {
1772
+
origHeader.Body == newHeader.Body &&
1773
+
op.ParentChangeId == np.ParentChangeId {
1755
1774
unchanged[op.ChangeId] = struct{}{}
1756
1775
} else {
1757
1776
updated[op.ChangeId] = struct{}{}
···
1825
1844
1826
1845
record := op.AsRecord()
1827
1846
record.Patch = submission.Patch
1847
+
record.StackInfo.Parent = (*string)(np.ParentAt)
1828
1848
1829
1849
writes = append(writes, &comatproto.RepoApplyWrites_Input_Writes_Elem{
1830
1850
RepoApplyWrites_Update: &comatproto.RepoApplyWrites_Update{
···
2173
2193
// the stack is identified by a UUID
2174
2194
var stack db.Stack
2175
2195
parentChangeId := ""
2196
+
var parentAt *syntax.ATURI = nil
2176
2197
for _, fp := range formatPatches {
2177
2198
// all patches must have a jj change-id
2178
2199
changeId, err := fp.ChangeId()
···
2203
2224
2204
2225
StackId: stackId,
2205
2226
ChangeId: changeId,
2227
+
ParentAt: parentAt,
2206
2228
ParentChangeId: parentChangeId,
2207
2229
}
2208
2230
2209
2231
stack = append(stack, &pull)
2210
2232
2211
2233
parentChangeId = changeId
2234
+
// this is a bit of an ugly way to create the ATURI but its the best we can do with the data flow here
2235
+
parsedParentAt, err := syntax.ParseATURI(fmt.Sprintf("at://%s/%s/%s", user.Did, tangled.RepoPullNSID, pull.Rkey));
2236
+
parentAt = &parsedParentAt
2237
+
if (err != nil) {
2238
+
return nil, fmt.Errorf("failed to parse string %s into an AT URI. this should not be possible",
2239
+
fmt.Sprintf("at://%s/%s/%s", user.Did, tangled.RepoPullNSID, pull.Rkey))
2240
+
}
2212
2241
}
2213
2242
2214
2243
return stack, nil
+1
cmd/gen.go
+1
cmd/gen.go
+21
lexicons/pulls/pull.json
+21
lexicons/pulls/pull.json
···
29
29
"patch": {
30
30
"type": "string"
31
31
},
32
+
"stackInfo": {
33
+
"type": "ref",
34
+
"ref": "#stackInfo"
35
+
},
32
36
"source": {
33
37
"type": "ref",
34
38
"ref": "#source"
···
76
80
"format": "at-uri"
77
81
}
78
82
}
83
+
},
84
+
"stackInfo": {
85
+
"type": "object",
86
+
"required": [
87
+
"changeId"
88
+
],
89
+
"properties": {
90
+
"changeId": {
91
+
"type": "string",
92
+
"description": "Change ID of this commit/change."
93
+
},
94
+
"parent": {
95
+
"type": "string",
96
+
"description": "AT-URI of the PR for the parent commit/change in the change stack.",
97
+
"format": "at-uri"
98
+
}
99
+
}
79
100
}
80
101
}
81
102
}