Skip to content

Commit 09e6149

Browse files
committed
revert and recover go-gitea#28304
1 parent f627267 commit 09e6149

File tree

7 files changed

+48
-223
lines changed

7 files changed

+48
-223
lines changed

models/issues/issue_search.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
type IssuesOptions struct { //nolint
2424
db.Paginator
2525
RepoIDs []int64 // overwrites RepoCond if the length is not 0
26+
AllPublic bool // include also all public repositories
2627
RepoCond builder.Cond
2728
AssigneeID int64
2829
PosterID int64
@@ -197,6 +198,12 @@ func applyRepoConditions(sess *xorm.Session, opts *IssuesOptions) *xorm.Session
197198
} else if len(opts.RepoIDs) > 1 {
198199
opts.RepoCond = builder.In("issue.repo_id", opts.RepoIDs)
199200
}
201+
if opts.AllPublic {
202+
if opts.RepoCond == nil {
203+
opts.RepoCond = builder.NewCond()
204+
}
205+
opts.RepoCond = opts.RepoCond.Or(builder.In("issue.repo_id", builder.Select("id").From("repository").Where(builder.Eq{"is_private": false})))
206+
}
200207
if opts.RepoCond != nil {
201208
sess.And(opts.RepoCond)
202209
}

modules/indexer/issues/db/options.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ func ToDBOptions(ctx context.Context, options *internal.SearchOptions) (*issue_m
5656
opts := &issue_model.IssuesOptions{
5757
Paginator: options.Paginator,
5858
RepoIDs: options.RepoIDs,
59+
AllPublic: options.AllPublic,
5960
RepoCond: nil,
6061
AssigneeID: convertID(options.AssigneeID),
6162
PosterID: convertID(options.PosterID),

modules/indexer/issues/dboptions.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ func ToSearchOptions(keyword string, opts *issues_model.IssuesOptions) *SearchOp
1212
searchOpt := &SearchOptions{
1313
Keyword: keyword,
1414
RepoIDs: opts.RepoIDs,
15-
AllPublic: false,
15+
AllPublic: opts.AllPublic,
1616
IsPull: opts.IsPull,
1717
IsClosed: opts.IsClosed,
1818
}

modules/indexer/issues/indexer.go

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import (
1313

1414
db_model "code.gitea.io/gitea/models/db"
1515
repo_model "code.gitea.io/gitea/models/repo"
16-
"code.gitea.io/gitea/modules/container"
1716
"code.gitea.io/gitea/modules/graceful"
1817
"code.gitea.io/gitea/modules/indexer/issues/bleve"
1918
"code.gitea.io/gitea/modules/indexer/issues/db"
@@ -314,30 +313,3 @@ func CountIssues(ctx context.Context, opts *SearchOptions) (int64, error) {
314313
_, total, err := SearchIssues(ctx, opts)
315314
return total, err
316315
}
317-
318-
// CountIssuesByRepo counts issues by options and group by repo id.
319-
// It's not a complete implementation, since it requires the caller should provide the repo ids.
320-
// That means opts.RepoIDs must be specified, and opts.AllPublic must be false.
321-
// It's good enough for the current usage, and it can be improved if needed.
322-
// TODO: use "group by" of the indexer engines to implement it.
323-
func CountIssuesByRepo(ctx context.Context, opts *SearchOptions) (map[int64]int64, error) {
324-
if len(opts.RepoIDs) == 0 {
325-
return nil, fmt.Errorf("opts.RepoIDs must be specified")
326-
}
327-
if opts.AllPublic {
328-
return nil, fmt.Errorf("opts.AllPublic must be false")
329-
}
330-
331-
repoIDs := container.SetOf(opts.RepoIDs...).Values()
332-
ret := make(map[int64]int64, len(repoIDs))
333-
// TODO: it could be faster if do it in parallel for some indexer engines. Improve it if users report it's slow.
334-
for _, repoID := range repoIDs {
335-
count, err := CountIssues(ctx, opts.Copy(func(o *internal.SearchOptions) { o.RepoIDs = []int64{repoID} }))
336-
if err != nil {
337-
return nil, err
338-
}
339-
ret[repoID] = count
340-
}
341-
342-
return ret, nil
343-
}

routers/web/user/home.go

Lines changed: 21 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ import (
2525
"code.gitea.io/gitea/modules/base"
2626
"code.gitea.io/gitea/modules/container"
2727
issue_indexer "code.gitea.io/gitea/modules/indexer/issues"
28-
"code.gitea.io/gitea/modules/json"
2928
"code.gitea.io/gitea/modules/log"
3029
"code.gitea.io/gitea/modules/markup"
3130
"code.gitea.io/gitea/modules/markup/markdown"
@@ -349,7 +348,6 @@ func Pulls(ctx *context.Context) {
349348

350349
ctx.Data["Title"] = ctx.Tr("pull_requests")
351350
ctx.Data["PageIsPulls"] = true
352-
ctx.Data["SingleRepoAction"] = "pull"
353351
buildIssueOverview(ctx, unit.TypePullRequests)
354352
}
355353

@@ -363,7 +361,6 @@ func Issues(ctx *context.Context) {
363361

364362
ctx.Data["Title"] = ctx.Tr("issues")
365363
ctx.Data["PageIsIssues"] = true
366-
ctx.Data["SingleRepoAction"] = "issue"
367364
buildIssueOverview(ctx, unit.TypeIssues)
368365
}
369366

@@ -489,6 +486,13 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
489486
opts.RepoIDs = []int64{0}
490487
}
491488
}
489+
if ctx.Doer.ID == ctxUser.ID && filterMode != issues_model.FilterModeYourRepositories {
490+
// If the doer is the same as the context user, which means the doer is viewing his own dashboard,
491+
// it's not enough to show the repos that the doer owns or has been explicitly granted access to,
492+
// because the doer may create issues or be mentioned in any public repo.
493+
// So we need search issues in all public repos.
494+
opts.AllPublic = true
495+
}
492496

493497
switch filterMode {
494498
case issues_model.FilterModeAll:
@@ -513,14 +517,6 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
513517
isShowClosed := ctx.FormString("state") == "closed"
514518
opts.IsClosed = optional.Some(isShowClosed)
515519

516-
// Filter repos and count issues in them. Count will be used later.
517-
// USING NON-FINAL STATE OF opts FOR A QUERY.
518-
issueCountByRepo, err := issue_indexer.CountIssuesByRepo(ctx, issue_indexer.ToSearchOptions(keyword, opts))
519-
if err != nil {
520-
ctx.ServerError("CountIssuesByRepo", err)
521-
return
522-
}
523-
524520
// Make sure page number is at least 1. Will be posted to ctx.Data.
525521
page := ctx.FormInt("page")
526522
if page <= 1 {
@@ -545,17 +541,6 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
545541
}
546542
opts.LabelIDs = labelIDs
547543

548-
// Parse ctx.FormString("repos") and remember matched repo IDs for later.
549-
// Gets set when clicking filters on the issues overview page.
550-
selectedRepoIDs := getRepoIDs(ctx.FormString("repos"))
551-
// Remove repo IDs that are not accessible to the user.
552-
selectedRepoIDs = slices.DeleteFunc(selectedRepoIDs, func(v int64) bool {
553-
return !accessibleRepos.Contains(v)
554-
})
555-
if len(selectedRepoIDs) > 0 {
556-
opts.RepoIDs = selectedRepoIDs
557-
}
558-
559544
// ------------------------------
560545
// Get issues as defined by opts.
561546
// ------------------------------
@@ -576,41 +561,6 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
576561
}
577562
}
578563

579-
// ----------------------------------
580-
// Add repository pointers to Issues.
581-
// ----------------------------------
582-
583-
// Remove repositories that should not be shown,
584-
// which are repositories that have no issues and are not selected by the user.
585-
selectedRepos := container.SetOf(selectedRepoIDs...)
586-
for k, v := range issueCountByRepo {
587-
if v == 0 && !selectedRepos.Contains(k) {
588-
delete(issueCountByRepo, k)
589-
}
590-
}
591-
592-
// showReposMap maps repository IDs to their Repository pointers.
593-
showReposMap, err := loadRepoByIDs(ctx, ctxUser, issueCountByRepo, unitType)
594-
if err != nil {
595-
if repo_model.IsErrRepoNotExist(err) {
596-
ctx.NotFound("GetRepositoryByID", err)
597-
return
598-
}
599-
ctx.ServerError("loadRepoByIDs", err)
600-
return
601-
}
602-
603-
// a RepositoryList
604-
showRepos := repo_model.RepositoryListOfMap(showReposMap)
605-
sort.Sort(showRepos)
606-
607-
// maps pull request IDs to their CommitStatus. Will be posted to ctx.Data.
608-
for _, issue := range issues {
609-
if issue.Repo == nil {
610-
issue.Repo = showReposMap[issue.RepoID]
611-
}
612-
}
613-
614564
commitStatuses, lastStatus, err := pull_service.GetIssuesAllCommitStatus(ctx, issues)
615565
if err != nil {
616566
ctx.ServerError("GetIssuesLastCommitStatus", err)
@@ -620,7 +570,7 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
620570
// -------------------------------
621571
// Fill stats to post to ctx.Data.
622572
// -------------------------------
623-
issueStats, err := getUserIssueStats(ctx, filterMode, issue_indexer.ToSearchOptions(keyword, opts), ctx.Doer.ID)
573+
issueStats, err := getUserIssueStats(ctx, ctxUser, filterMode, issue_indexer.ToSearchOptions(keyword, opts))
624574
if err != nil {
625575
ctx.ServerError("getUserIssueStats", err)
626576
return
@@ -633,25 +583,6 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
633583
} else {
634584
shownIssues = int(issueStats.ClosedCount)
635585
}
636-
if len(opts.RepoIDs) != 0 {
637-
shownIssues = 0
638-
for _, repoID := range opts.RepoIDs {
639-
shownIssues += int(issueCountByRepo[repoID])
640-
}
641-
}
642-
643-
var allIssueCount int64
644-
for _, issueCount := range issueCountByRepo {
645-
allIssueCount += issueCount
646-
}
647-
ctx.Data["TotalIssueCount"] = allIssueCount
648-
649-
if len(opts.RepoIDs) == 1 {
650-
repo := showReposMap[opts.RepoIDs[0]]
651-
if repo != nil {
652-
ctx.Data["SingleRepoLink"] = repo.Link()
653-
}
654-
}
655586

656587
ctx.Data["IsShowClosed"] = isShowClosed
657588

@@ -688,12 +619,9 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
688619
}
689620
ctx.Data["CommitLastStatus"] = lastStatus
690621
ctx.Data["CommitStatuses"] = commitStatuses
691-
ctx.Data["Repos"] = showRepos
692-
ctx.Data["Counts"] = issueCountByRepo
693622
ctx.Data["IssueStats"] = issueStats
694623
ctx.Data["ViewType"] = viewType
695624
ctx.Data["SortType"] = sortType
696-
ctx.Data["RepoIDs"] = selectedRepoIDs
697625
ctx.Data["IsShowClosed"] = isShowClosed
698626
ctx.Data["SelectLabels"] = selectedLabels
699627

@@ -703,15 +631,9 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
703631
ctx.Data["State"] = "open"
704632
}
705633

706-
// Convert []int64 to string
707-
reposParam, _ := json.Marshal(opts.RepoIDs)
708-
709-
ctx.Data["ReposParam"] = string(reposParam)
710-
711634
pager := context.NewPagination(shownIssues, setting.UI.IssuePagingNum, page, 5)
712635
pager.AddParam(ctx, "q", "Keyword")
713636
pager.AddParam(ctx, "type", "ViewType")
714-
pager.AddParam(ctx, "repos", "ReposParam")
715637
pager.AddParam(ctx, "sort", "SortType")
716638
pager.AddParam(ctx, "state", "State")
717639
pager.AddParam(ctx, "labels", "SelectLabels")
@@ -722,55 +644,6 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
722644
ctx.HTML(http.StatusOK, tplIssues)
723645
}
724646

725-
func getRepoIDs(reposQuery string) []int64 {
726-
if len(reposQuery) == 0 || reposQuery == "[]" {
727-
return []int64{}
728-
}
729-
if !issueReposQueryPattern.MatchString(reposQuery) {
730-
log.Warn("issueReposQueryPattern does not match query: %q", reposQuery)
731-
return []int64{}
732-
}
733-
734-
var repoIDs []int64
735-
// remove "[" and "]" from string
736-
reposQuery = reposQuery[1 : len(reposQuery)-1]
737-
// for each ID (delimiter ",") add to int to repoIDs
738-
for _, rID := range strings.Split(reposQuery, ",") {
739-
// Ensure nonempty string entries
740-
if rID != "" && rID != "0" {
741-
rIDint64, err := strconv.ParseInt(rID, 10, 64)
742-
if err == nil {
743-
repoIDs = append(repoIDs, rIDint64)
744-
}
745-
}
746-
}
747-
748-
return repoIDs
749-
}
750-
751-
func loadRepoByIDs(ctx *context.Context, ctxUser *user_model.User, issueCountByRepo map[int64]int64, unitType unit.Type) (map[int64]*repo_model.Repository, error) {
752-
totalRes := make(map[int64]*repo_model.Repository, len(issueCountByRepo))
753-
repoIDs := make([]int64, 0, 500)
754-
for id := range issueCountByRepo {
755-
if id <= 0 {
756-
continue
757-
}
758-
repoIDs = append(repoIDs, id)
759-
if len(repoIDs) == 500 {
760-
if err := repo_model.FindReposMapByIDs(ctx, repoIDs, totalRes); err != nil {
761-
return nil, err
762-
}
763-
repoIDs = repoIDs[:0]
764-
}
765-
}
766-
if len(repoIDs) > 0 {
767-
if err := repo_model.FindReposMapByIDs(ctx, repoIDs, totalRes); err != nil {
768-
return nil, err
769-
}
770-
}
771-
return totalRes, nil
772-
}
773-
774647
// ShowSSHKeys output all the ssh keys of user by uid
775648
func ShowSSHKeys(ctx *context.Context) {
776649
keys, err := db.Find[asymkey_model.PublicKey](ctx, asymkey_model.FindPublicKeyOptions{
@@ -887,8 +760,15 @@ func UsernameSubRoute(ctx *context.Context) {
887760
}
888761
}
889762

890-
func getUserIssueStats(ctx *context.Context, filterMode int, opts *issue_indexer.SearchOptions, doerID int64) (*issues_model.IssueStats, error) {
763+
func getUserIssueStats(ctx *context.Context, ctxUser *user_model.User, filterMode int, opts *issue_indexer.SearchOptions) (*issues_model.IssueStats, error) {
764+
doerID := ctx.Doer.ID
765+
891766
opts = opts.Copy(func(o *issue_indexer.SearchOptions) {
767+
// If the doer is the same as the context user, which means the doer is viewing his own dashboard,
768+
// it's not enough to show the repos that the doer owns or has been explicitly granted access to,
769+
// because the doer may create issues or be mentioned in any public repo.
770+
// So we need search issues in all public repos.
771+
o.AllPublic = doerID == ctxUser.ID
892772
o.AssigneeID = nil
893773
o.PosterID = nil
894774
o.MentionID = nil
@@ -904,7 +784,10 @@ func getUserIssueStats(ctx *context.Context, filterMode int, opts *issue_indexer
904784
{
905785
openClosedOpts := opts.Copy()
906786
switch filterMode {
907-
case issues_model.FilterModeAll, issues_model.FilterModeYourRepositories:
787+
case issues_model.FilterModeAll:
788+
// no-op
789+
case issues_model.FilterModeYourRepositories:
790+
openClosedOpts.AllPublic = false
908791
case issues_model.FilterModeAssign:
909792
openClosedOpts.AssigneeID = &doerID
910793
case issues_model.FilterModeCreate:
@@ -928,7 +811,7 @@ func getUserIssueStats(ctx *context.Context, filterMode int, opts *issue_indexer
928811
}
929812
}
930813

931-
ret.YourRepositoriesCount, err = issue_indexer.CountIssues(ctx, opts)
814+
ret.YourRepositoriesCount, err = issue_indexer.CountIssues(ctx, opts.Copy(func(o *issue_indexer.SearchOptions) { o.AllPublic = false }))
932815
if err != nil {
933816
return nil, err
934817
}

routers/web/user/home_test.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,7 @@ func TestArchivedIssues(t *testing.T) {
4747
// Assert: One Issue (ID 30) from one Repo (ID 50) is retrieved, while nothing from archived Repo 51 is retrieved
4848
assert.EqualValues(t, http.StatusOK, ctx.Resp.Status())
4949

50-
assert.EqualValues(t, map[int64]int64{50: 1}, ctx.Data["Counts"])
5150
assert.Len(t, ctx.Data["Issues"], 1)
52-
assert.Len(t, ctx.Data["Repos"], 1)
5351
}
5452

5553
func TestIssues(t *testing.T) {
@@ -62,10 +60,8 @@ func TestIssues(t *testing.T) {
6260
Issues(ctx)
6361
assert.EqualValues(t, http.StatusOK, ctx.Resp.Status())
6462

65-
assert.EqualValues(t, map[int64]int64{1: 1, 2: 1}, ctx.Data["Counts"])
6663
assert.EqualValues(t, true, ctx.Data["IsShowClosed"])
6764
assert.Len(t, ctx.Data["Issues"], 1)
68-
assert.Len(t, ctx.Data["Repos"], 2)
6965
}
7066

7167
func TestPulls(t *testing.T) {

0 commit comments

Comments
 (0)