···393393 db.Exec("pragma foreign_keys = off;")394394 runMigration(db, "recreate-pulls-column-for-stacking-support", func(tx *sql.Tx) error {395395 _, err := tx.Exec(`396396- -- disable fk to not delete submissions table397397- pragma foreign_keys = off;398398-399396 create table pulls_new (400397 -- identifiers401398 id integer primary key autoincrement,···443446444447 drop table pulls;445448 alter table pulls_new rename to pulls;446446-447447- -- reenable fk448448- pragma foreign_keys = on;449449 `)450450 return err451451 })452452 db.Exec("pragma foreign_keys = on;")453453454454->>>>>>> Conflict 1 of 1 ends455454 return &DB{db}, nil456455}457456
+37-2
appview/db/pulls.go
···4949func (p PullState) IsClosed() bool {5050 return p == PullClosed5151}5252-func (p PullState) IsDelete() bool {5252+func (p PullState) IsDeleted() bool {5353 return p == PullDeleted5454}5555···885885886886func SetPullState(e Execer, repoAt syntax.ATURI, pullId int, pullState PullState) error {887887 _, err := e.Exec(888888- `update pulls set state = ? where repo_at = ? and pull_id = ? and state <> ?`,888888+ `update pulls set state = ? where repo_at = ? and pull_id = ? and (state <> ? or state <> ?)`,889889 pullState,890890 repoAt,891891 pullId,892892 PullDeleted, // only update state of non-deleted pulls893893+ PullMerged, // only update state of non-merged pulls893894 )894895 return err895896}···10331032 return pulls, nil10341033}1035103410351035+func GetAbandonedPulls(e Execer, stackId string) ([]*Pull, error) {10361036+ pulls, err := GetPulls(10371037+ e,10381038+ FilterEq("stack_id", stackId),10391039+ FilterEq("state", PullDeleted),10401040+ )10411041+ if err != nil {10421042+ return nil, err10431043+ }10441044+10451045+ return pulls, nil10461046+}10471047+10361048// position of this pull in the stack10371049func (stack Stack) Position(pull *Pull) int {10381050 return slices.IndexFunc(stack, func(p *Pull) bool {···11091095 combined.WriteString("\n")11101096 }11111097 return combined.String()10981098+}10991099+11001100+// filter out PRs that are "active"11011101+//11021102+// PRs that are still open are active11031103+func (stack Stack) Mergeable() Stack {11041104+ var mergeable Stack11051105+11061106+ for _, p := range stack {11071107+ // stop at the first merged PR11081108+ if p.State == PullMerged || p.State == PullClosed {11091109+ break11101110+ }11111111+11121112+ // skip over deleted PRs11131113+ if p.State != PullDeleted {11141114+ mergeable = append(mergeable, p)11151115+ }11161116+ }11171117+11181118+ return mergeable11121119}
···178178 log.Println("failed to get stack", err)179179 return180180 }181181+ abandonedPulls, err := db.GetAbandonedPulls(s.db, pr.StackId)182182+ if err != nil {183183+ log.Println("failed to get abandoned pulls", err)184184+ return185185+ }181186182187 ctx = context.WithValue(ctx, "stack", stack)188188+ ctx = context.WithValue(ctx, "abandonedPulls", abandonedPulls)183189 }184190185191 next.ServeHTTP(w, r.WithContext(ctx))
+25-44
appview/state/pull.go
···7575 RoundNumber: roundNumber,7676 MergeCheck: mergeCheckResponse,7777 ResubmitCheck: resubmitResult,7878+ Stack: stack,7879 })7980 return8081 }···98979998 // can be nil if this pull is not stacked10099 stack, _ := r.Context().Value("stack").(db.Stack)100100+ abandonedPulls, _ := r.Context().Value("abandonedPulls").([]*db.Pull)101101102102 totalIdents := 1103103 for _, submission := range pull.Submissions {···134132 }135133136134 s.pages.RepoSinglePull(w, pages.RepoSinglePullParams{137137- LoggedInUser: user,138138- RepoInfo: f.RepoInfo(s, user),139139- DidHandleMap: didHandleMap,140140- Pull: pull,141141- Stack: stack,142142- MergeCheck: mergeCheckResponse,143143- ResubmitCheck: resubmitResult,135135+ LoggedInUser: user,136136+ RepoInfo: f.RepoInfo(s, user),137137+ DidHandleMap: didHandleMap,138138+ Pull: pull,139139+ Stack: stack,140140+ AbandonedPulls: abandonedPulls,141141+ MergeCheck: mergeCheckResponse,142142+ ResubmitCheck: resubmitResult,144143 })145144}146145···170167 if pull.IsStacked() {171168 // combine patches of substack172169 subStack := stack.Below(pull)173173-174170 // collect the portion of the stack that is mergeable175175- var mergeable db.Stack176176- for _, p := range subStack {177177- // stop at the first merged PR178178- if p.State == db.PullMerged || p.State == db.PullClosed {179179- break180180- }181181-182182- // skip over deleted PRs183183- if p.State != db.PullDeleted {184184- mergeable = append(mergeable, p)185185- }186186- }187187-171171+ mergeable := subStack.Mergeable()172172+ // combine each patch188173 patch = mergeable.CombinedPatch()189174 }190175···216225}217226218227func (s *State) resubmitCheck(f *FullyResolvedRepo, pull *db.Pull, stack db.Stack) pages.ResubmitResult {219219- if pull.State == db.PullMerged || pull.PullSource == nil {228228+ if pull.State == db.PullMerged || pull.State == db.PullDeleted || pull.PullSource == nil {220229 return pages.Unknown221230 }222231···894903 return895904 }896905906906+ client, err := s.oauth.AuthorizedClient(r)907907+ if err != nil {908908+ log.Println("failed to get authorized client", err)909909+ s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")910910+ return911911+ }912912+897913 tx, err := s.db.BeginTx(r.Context(), nil)898914 if err != nil {899915 log.Println("failed to start tx")···945947 })946948 if err != nil {947949 log.Println("failed to create pull request", err)948948- s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")949949- return950950- }951951- client, err := s.oauth.AuthorizedClient(r)952952- if err != nil {953953- log.Println("failed to get authorized client", err)954950 s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")955951 return956952 }···1812182018131821 // combine patches of substack18141822 subStack := stack.Below(pull)18151815-18161823 // collect the portion of the stack that is mergeable18171817- for _, p := range subStack {18181818- // stop at the first merged/closed PR18191819- if p.State == db.PullMerged || p.State == db.PullClosed {18201820- break18211821- }18221822-18231823- // skip over deleted PRs18241824- if p.State == db.PullDeleted {18251825- continue18261826- }18271827-18281828- pullsToMerge = append(pullsToMerge, p)18291829- }18241824+ mergeable := subStack.Mergeable()18251825+ // add to total patch18261826+ pullsToMerge = append(pullsToMerge, mergeable...)18301827 }1831182818321829 patch := pullsToMerge.CombinedPatch()···19952014 var pullsToReopen []*db.Pull19962015 pullsToReopen = append(pullsToReopen, pull)1997201619981998- // if this PR is stacked, then we want to reopen all PRs below this one on the stack20172017+ // if this PR is stacked, then we want to reopen all PRs above this one on the stack19992018 if pull.IsStacked() {20002019 stack := r.Context().Value("stack").(db.Stack)20012001- subStack := stack.StrictlyBelow(pull)20202020+ subStack := stack.StrictlyAbove(pull)20022021 pullsToReopen = append(pullsToReopen, subStack...)20032022 }20042023