forked from tangled.org/core
this repo has no description

lexicons: pulls: add stack information to pull records

Signed-off-by: nelind <nel.n.lindberg@gmail.com>

nel.pet 9e2d0347 62a536c7

verified
Changed files
+293 -14
api
appview
db
models
pulls
cmd
lexicons
pulls
+202 -1
api/tangled/cbor_gen.go
··· 7420 7420 } 7421 7421 7422 7422 cw := cbg.NewCborWriter(w) 7423 - fieldCount := 7 7423 + fieldCount := 8 7424 7424 7425 7425 if t.Body == nil { 7426 7426 fieldCount-- 7427 7427 } 7428 7428 7429 7429 if t.Source == nil { 7430 + fieldCount-- 7431 + } 7432 + 7433 + if t.StackInfo == nil { 7430 7434 fieldCount-- 7431 7435 } 7432 7436 ··· 7588 7592 if _, err := cw.WriteString(string(t.CreatedAt)); err != nil { 7589 7593 return err 7590 7594 } 7595 + 7596 + // t.StackInfo (tangled.RepoPull_StackInfo) (struct) 7597 + if t.StackInfo != nil { 7598 + 7599 + if len("stackInfo") > 1000000 { 7600 + return xerrors.Errorf("Value in field \"stackInfo\" was too long") 7601 + } 7602 + 7603 + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("stackInfo"))); err != nil { 7604 + return err 7605 + } 7606 + if _, err := cw.WriteString(string("stackInfo")); err != nil { 7607 + return err 7608 + } 7609 + 7610 + if err := t.StackInfo.MarshalCBOR(cw); err != nil { 7611 + return err 7612 + } 7613 + } 7591 7614 return nil 7592 7615 } 7593 7616 ··· 7737 7760 7738 7761 t.CreatedAt = string(sval) 7739 7762 } 7763 + // t.StackInfo (tangled.RepoPull_StackInfo) (struct) 7764 + case "stackInfo": 7765 + 7766 + { 7767 + 7768 + b, err := cr.ReadByte() 7769 + if err != nil { 7770 + return err 7771 + } 7772 + if b != cbg.CborNull[0] { 7773 + if err := cr.UnreadByte(); err != nil { 7774 + return err 7775 + } 7776 + t.StackInfo = new(RepoPull_StackInfo) 7777 + if err := t.StackInfo.UnmarshalCBOR(cr); err != nil { 7778 + return xerrors.Errorf("unmarshaling t.StackInfo pointer: %w", err) 7779 + } 7780 + } 7781 + 7782 + } 7740 7783 7741 7784 default: 7742 7785 // Field doesn't exist on this type, so ignore it ··· 7934 7977 } 7935 7978 7936 7979 t.CreatedAt = string(sval) 7980 + } 7981 + 7982 + default: 7983 + // Field doesn't exist on this type, so ignore it 7984 + if err := cbg.ScanForLinks(r, func(cid.Cid) {}); err != nil { 7985 + return err 7986 + } 7987 + } 7988 + } 7989 + 7990 + return nil 7991 + } 7992 + func (t *RepoPull_StackInfo) MarshalCBOR(w io.Writer) error { 7993 + if t == nil { 7994 + _, err := w.Write(cbg.CborNull) 7995 + return err 7996 + } 7997 + 7998 + cw := cbg.NewCborWriter(w) 7999 + fieldCount := 2 8000 + 8001 + if t.Parent == nil { 8002 + fieldCount-- 8003 + } 8004 + 8005 + if _, err := cw.Write(cbg.CborEncodeMajorType(cbg.MajMap, uint64(fieldCount))); err != nil { 8006 + return err 8007 + } 8008 + 8009 + // t.Parent (string) (string) 8010 + if t.Parent != nil { 8011 + 8012 + if len("parent") > 1000000 { 8013 + return xerrors.Errorf("Value in field \"parent\" was too long") 8014 + } 8015 + 8016 + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("parent"))); err != nil { 8017 + return err 8018 + } 8019 + if _, err := cw.WriteString(string("parent")); err != nil { 8020 + return err 8021 + } 8022 + 8023 + if t.Parent == nil { 8024 + if _, err := cw.Write(cbg.CborNull); err != nil { 8025 + return err 8026 + } 8027 + } else { 8028 + if len(*t.Parent) > 1000000 { 8029 + return xerrors.Errorf("Value in field t.Parent was too long") 8030 + } 8031 + 8032 + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(*t.Parent))); err != nil { 8033 + return err 8034 + } 8035 + if _, err := cw.WriteString(string(*t.Parent)); err != nil { 8036 + return err 8037 + } 8038 + } 8039 + } 8040 + 8041 + // t.ChangeId (string) (string) 8042 + if len("changeId") > 1000000 { 8043 + return xerrors.Errorf("Value in field \"changeId\" was too long") 8044 + } 8045 + 8046 + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("changeId"))); err != nil { 8047 + return err 8048 + } 8049 + if _, err := cw.WriteString(string("changeId")); err != nil { 8050 + return err 8051 + } 8052 + 8053 + if len(t.ChangeId) > 1000000 { 8054 + return xerrors.Errorf("Value in field t.ChangeId was too long") 8055 + } 8056 + 8057 + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.ChangeId))); err != nil { 8058 + return err 8059 + } 8060 + if _, err := cw.WriteString(string(t.ChangeId)); err != nil { 8061 + return err 8062 + } 8063 + return nil 8064 + } 8065 + 8066 + func (t *RepoPull_StackInfo) UnmarshalCBOR(r io.Reader) (err error) { 8067 + *t = RepoPull_StackInfo{} 8068 + 8069 + cr := cbg.NewCborReader(r) 8070 + 8071 + maj, extra, err := cr.ReadHeader() 8072 + if err != nil { 8073 + return err 8074 + } 8075 + defer func() { 8076 + if err == io.EOF { 8077 + err = io.ErrUnexpectedEOF 8078 + } 8079 + }() 8080 + 8081 + if maj != cbg.MajMap { 8082 + return fmt.Errorf("cbor input should be of type map") 8083 + } 8084 + 8085 + if extra > cbg.MaxLength { 8086 + return fmt.Errorf("RepoPull_StackInfo: map struct too large (%d)", extra) 8087 + } 8088 + 8089 + n := extra 8090 + 8091 + nameBuf := make([]byte, 8) 8092 + for i := uint64(0); i < n; i++ { 8093 + nameLen, ok, err := cbg.ReadFullStringIntoBuf(cr, nameBuf, 1000000) 8094 + if err != nil { 8095 + return err 8096 + } 8097 + 8098 + if !ok { 8099 + // Field doesn't exist on this type, so ignore it 8100 + if err := cbg.ScanForLinks(cr, func(cid.Cid) {}); err != nil { 8101 + return err 8102 + } 8103 + continue 8104 + } 8105 + 8106 + switch string(nameBuf[:nameLen]) { 8107 + // t.Parent (string) (string) 8108 + case "parent": 8109 + 8110 + { 8111 + b, err := cr.ReadByte() 8112 + if err != nil { 8113 + return err 8114 + } 8115 + if b != cbg.CborNull[0] { 8116 + if err := cr.UnreadByte(); err != nil { 8117 + return err 8118 + } 8119 + 8120 + sval, err := cbg.ReadStringWithMax(cr, 1000000) 8121 + if err != nil { 8122 + return err 8123 + } 8124 + 8125 + t.Parent = (*string)(&sval) 8126 + } 8127 + } 8128 + // t.ChangeId (string) (string) 8129 + case "changeId": 8130 + 8131 + { 8132 + sval, err := cbg.ReadStringWithMax(cr, 1000000) 8133 + if err != nil { 8134 + return err 8135 + } 8136 + 8137 + t.ChangeId = string(sval) 7937 8138 } 7938 8139 7939 8140 default:
+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. ··· 31 32 Branch string `json:"branch" cborgen:"branch"` 32 33 Repo *string `json:"repo,omitempty" cborgen:"repo,omitempty"` 33 34 Sha string `json:"sha" cborgen:"sha"` 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. 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"` 34 43 } 35 44 36 45 // RepoPull_Target is a "target" in the sh.tangled.repo.pull schema.
+7
appview/db/db.go
··· 1094 1094 }) 1095 1095 conn.ExecContext(ctx, "pragma foreign_keys = on;") 1096 1096 1097 + runMigration(conn, "add-parent-at-for-stacks-to-pulls", func(tx *sql.Tx) error { 1098 + _, err := tx.Exec(` 1099 + alter table pulls add column parent_at text; 1100 + `) 1101 + return err 1102 + }) 1103 + 1097 1104 return &DB{db}, nil 1098 1105 } 1099 1106
+17 -4
appview/db/pulls.go
··· 47 47 } 48 48 } 49 49 50 - var stackId, changeId, parentChangeId *string 50 + var stackId, changeId, parentAt, parentChangeId *string 51 51 if pull.StackId != "" { 52 52 stackId = &pull.StackId 53 53 } 54 54 if pull.ChangeId != "" { 55 55 changeId = &pull.ChangeId 56 + } 57 + if pull.ParentAt != nil { 58 + parentAt = (*string)(pull.ParentAt) 56 59 } 57 60 if pull.ParentChangeId != "" { 58 61 parentChangeId = &pull.ParentChangeId ··· 61 64 result, err := tx.Exec( 62 65 ` 63 66 insert into pulls ( 64 - repo_at, owner_did, pull_id, title, target_branch, body, rkey, state, source_branch, source_repo_at, stack_id, change_id, parent_change_id 67 + 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 65 68 ) 66 - values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, 69 + values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, 67 70 pull.RepoAt, 68 71 pull.OwnerDid, 69 72 pull.PullId, ··· 76 79 sourceRepoAt, 77 80 stackId, 78 81 changeId, 82 + parentAt, 79 83 parentChangeId, 80 84 ) 81 85 if err != nil { ··· 145 149 source_repo_at, 146 150 stack_id, 147 151 change_id, 152 + parent_at, 148 153 parent_change_id 149 154 from 150 155 pulls ··· 163 168 for rows.Next() { 164 169 var pull models.Pull 165 170 var createdAt string 166 - var sourceBranch, sourceRepoAt, stackId, changeId, parentChangeId sql.NullString 171 + var sourceBranch, sourceRepoAt, stackId, changeId, parentAt, parentChangeId sql.NullString 167 172 err := rows.Scan( 168 173 &pull.ID, 169 174 &pull.OwnerDid, ··· 179 184 &sourceRepoAt, 180 185 &stackId, 181 186 &changeId, 187 + &parentAt, 182 188 &parentChangeId, 183 189 ) 184 190 if err != nil { ··· 209 215 } 210 216 if changeId.Valid { 211 217 pull.ChangeId = changeId.String 218 + } 219 + if parentAt.Valid { 220 + parentAtParsed, err := syntax.ParseATURI(parentAt.String) 221 + if err != nil { 222 + return nil, err 223 + } 224 + pull.ParentAt = &parentAtParsed 212 225 } 213 226 if parentChangeId.Valid { 214 227 pull.ParentChangeId = parentChangeId.String
+5
appview/models/pull.go
··· 70 70 // stacking 71 71 StackId string // nullable string 72 72 ChangeId string // nullable string 73 + ParentAt *syntax.ATURI 73 74 ParentChangeId string // nullable string 74 75 75 76 // meta ··· 99 100 }, 100 101 Patch: p.LatestPatch(), 101 102 Source: source, 103 + StackInfo: &tangled.RepoPull_StackInfo{ 104 + ChangeId: p.ChangeId, 105 + Parent: (*string)(p.ParentAt), 106 + }, 102 107 } 103 108 return record 104 109 }
+24 -2
appview/pulls/pulls.go
··· 29 29 30 30 "github.com/bluekeyes/go-gitdiff/gitdiff" 31 31 comatproto "github.com/bluesky-social/indigo/api/atproto" 32 + "github.com/bluesky-social/indigo/atproto/syntax" 32 33 lexutil "github.com/bluesky-social/indigo/lex/util" 33 34 indigoxrpc "github.com/bluesky-social/indigo/xrpc" 34 35 "github.com/go-chi/chi/v5" ··· 1836 1837 newStack, err := newStack(f, user, targetBranch, patch, pull.PullSource, stackId) 1837 1838 if err != nil { 1838 1839 log.Println("failed to create resubmitted stack", err) 1839 - s.pages.Notice(w, "pull-merge-error", "Failed to merge pull request. Try again later.") 1840 + s.pages.Notice(w, "pull-resubmit-error", "Failed to merge pull request. Try again later.") 1840 1841 return 1841 1842 } 1842 1843 1843 1844 // find the diff between the stacks, first, map them by changeId 1845 + 1844 1846 origById := make(map[string]*models.Pull) 1845 1847 newById := make(map[string]*models.Pull) 1848 + chIdToAtUri := make(map[string]*syntax.ATURI) 1849 + 1846 1850 for _, p := range origStack { 1847 1851 origById[p.ChangeId] = p 1852 + 1853 + // build map from change id to existing at uris (ignore error as it shouldnt be possible here) 1854 + pAtUri, _ := syntax.ParseATURI(fmt.Sprintf("at://%s/%s/%s", user.Did, tangled.RepoPullNSID, p.Rkey)) 1855 + chIdToAtUri[p.ChangeId] = &pAtUri 1848 1856 } 1849 1857 for _, p := range newStack { 1858 + // if change id has already been given a PR use its at uri instead of the newly created (and thus incorrect) 1859 + // one made by newStack 1860 + if ppAt, ok := chIdToAtUri[p.ParentChangeId]; ok { 1861 + p.ParentAt = ppAt 1862 + } 1863 + 1850 1864 newById[p.ChangeId] = p 1851 1865 } 1852 1866 ··· 1894 1908 // we still need to update the hash in submission.Patch and submission.SourceRev 1895 1909 if patchutil.Equal(newFiles, origFiles) && 1896 1910 origHeader.Title == newHeader.Title && 1897 - origHeader.Body == newHeader.Body { 1911 + origHeader.Body == newHeader.Body && 1912 + op.ParentChangeId == np.ParentChangeId { 1898 1913 unchanged[op.ChangeId] = struct{}{} 1899 1914 } else { 1900 1915 updated[op.ChangeId] = struct{}{} ··· 1978 1993 1979 1994 record := op.AsRecord() 1980 1995 record.Patch = submission.Patch 1996 + record.StackInfo.Parent = (*string)(np.ParentAt) 1981 1997 1982 1998 writes = append(writes, &comatproto.RepoApplyWrites_Input_Writes_Elem{ 1983 1999 RepoApplyWrites_Update: &comatproto.RepoApplyWrites_Update{ ··· 2343 2359 // the stack is identified by a UUID 2344 2360 var stack models.Stack 2345 2361 parentChangeId := "" 2362 + var parentAt *syntax.ATURI = nil 2346 2363 for _, fp := range formatPatches { 2347 2364 // all patches must have a jj change-id 2348 2365 changeId, err := fp.ChangeId() ··· 2373 2390 2374 2391 StackId: stackId, 2375 2392 ChangeId: changeId, 2393 + ParentAt: parentAt, 2376 2394 ParentChangeId: parentChangeId, 2377 2395 } 2378 2396 2379 2397 stack = append(stack, &pull) 2380 2398 2381 2399 parentChangeId = changeId 2400 + // this is a bit of an ugly way to create the ATURI but its the best we can do with the data flow here 2401 + // (igore error as it shouldnt be possible here) 2402 + parsedParentAt, _ := syntax.ParseATURI(fmt.Sprintf("at://%s/%s/%s", user.Did, tangled.RepoPullNSID, pull.Rkey)); 2403 + parentAt = &parsedParentAt 2382 2404 } 2383 2405 2384 2406 return stack, nil
+1
cmd/gen.go
··· 49 49 tangled.RepoIssueState{}, 50 50 tangled.RepoPull{}, 51 51 tangled.RepoPullComment{}, 52 + tangled.RepoPull_StackInfo{}, 52 53 tangled.RepoPull_Source{}, 53 54 tangled.RepoPullStatus{}, 54 55 tangled.RepoPull_Target{},
+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" ··· 73 77 }, 74 78 "repo": { 75 79 "type": "string", 80 + "format": "at-uri" 81 + } 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.", 76 97 "format": "at-uri" 77 98 } 78 99 }