-
-
Notifications
You must be signed in to change notification settings - Fork 5.8k
Rework suggestion backend #33538
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rework suggestion backend #33538
Changes from 10 commits
ce2287f
684d744
a2822a0
be910cc
f37f389
094df8c
e24690d
8157fd6
e952ac7
b68eda5
e99ee8a
fd0d877
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,13 +6,10 @@ package repo | |
import ( | ||
"net/http" | ||
|
||
"code.gitea.io/gitea/models/db" | ||
issues_model "code.gitea.io/gitea/models/issues" | ||
"code.gitea.io/gitea/models/unit" | ||
issue_indexer "code.gitea.io/gitea/modules/indexer/issues" | ||
"code.gitea.io/gitea/modules/optional" | ||
"code.gitea.io/gitea/modules/structs" | ||
"code.gitea.io/gitea/services/context" | ||
issue_service "code.gitea.io/gitea/services/issue" | ||
) | ||
|
||
// IssueSuggestions returns a list of issue suggestions | ||
|
@@ -29,54 +26,11 @@ func IssueSuggestions(ctx *context.Context) { | |
isPull = optional.Some(false) | ||
} | ||
|
||
searchOpt := &issue_indexer.SearchOptions{ | ||
Paginator: &db.ListOptions{ | ||
Page: 0, | ||
PageSize: 5, | ||
}, | ||
Keyword: keyword, | ||
RepoIDs: []int64{ctx.Repo.Repository.ID}, | ||
IsPull: isPull, | ||
IsClosed: nil, | ||
SortBy: issue_indexer.SortByUpdatedDesc, | ||
} | ||
|
||
ids, _, err := issue_indexer.SearchIssues(ctx, searchOpt) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK. Github will search both title and content but the title-matchted issue will be listed first. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Maybe GitHub uses search engine's ranking, not simply put something first. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe we can merge this first. Searching content is not usable from my side. |
||
if err != nil { | ||
ctx.ServerError("SearchIssues", err) | ||
return | ||
} | ||
issues, err := issues_model.GetIssuesByIDs(ctx, ids, true) | ||
suggestions, err := issue_service.GetSuggestion(ctx, ctx.Repo.Repository, isPull, keyword) | ||
if err != nil { | ||
ctx.ServerError("FindIssuesByIDs", err) | ||
ctx.ServerError("GetSuggestion", err) | ||
return | ||
} | ||
|
||
suggestions := make([]*structs.Issue, 0, len(issues)) | ||
|
||
for _, issue := range issues { | ||
suggestion := &structs.Issue{ | ||
ID: issue.ID, | ||
Index: issue.Index, | ||
Title: issue.Title, | ||
State: issue.State(), | ||
} | ||
|
||
if issue.IsPull { | ||
if err := issue.LoadPullRequest(ctx); err != nil { | ||
ctx.ServerError("LoadPullRequest", err) | ||
return | ||
} | ||
if issue.PullRequest != nil { | ||
suggestion.PullRequest = &structs.PullRequestMeta{ | ||
HasMerged: issue.PullRequest.HasMerged, | ||
IsWorkInProgress: issue.PullRequest.IsWorkInProgress(ctx), | ||
} | ||
} | ||
} | ||
|
||
suggestions = append(suggestions, suggestion) | ||
} | ||
|
||
ctx.JSON(http.StatusOK, suggestions) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
// Copyright 2025 The Gitea Authors. All rights reserved. | ||
// SPDX-License-Identifier: MIT | ||
|
||
package issue | ||
|
||
import ( | ||
"context" | ||
"strconv" | ||
|
||
issues_model "code.gitea.io/gitea/models/issues" | ||
repo_model "code.gitea.io/gitea/models/repo" | ||
"code.gitea.io/gitea/modules/optional" | ||
"code.gitea.io/gitea/modules/structs" | ||
) | ||
|
||
func GetSuggestion(ctx context.Context, repo *repo_model.Repository, isPull optional.Option[bool], keyword string) ([]*structs.Issue, error) { | ||
var issues issues_model.IssueList | ||
var err error | ||
pageSize := 5 | ||
if keyword == "" { | ||
issues, err = issues_model.FindLatestUpdatedIssues(ctx, repo.ID, isPull, pageSize) | ||
if err != nil { | ||
return nil, err | ||
} | ||
} else { | ||
indexKeyword, _ := strconv.ParseInt(keyword, 10, 64) | ||
var issueByIndex *issues_model.Issue | ||
var excludedID int64 | ||
if indexKeyword > 0 { | ||
issueByIndex, err = issues_model.GetIssueByIndex(ctx, repo.ID, indexKeyword) | ||
if err != nil && !issues_model.IsErrIssueNotExist(err) { | ||
return nil, err | ||
} | ||
if issueByIndex != nil { | ||
excludedID = issueByIndex.ID | ||
pageSize-- | ||
} | ||
} | ||
|
||
issues, err = issues_model.FindIssuesSuggestionByKeyword(ctx, repo.ID, keyword, isPull, excludedID, pageSize) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
if issueByIndex != nil { | ||
issues = append([]*issues_model.Issue{issueByIndex}, issues...) | ||
} | ||
} | ||
|
||
if err := issues.LoadPullRequests(ctx); err != nil { | ||
return nil, err | ||
} | ||
|
||
suggestions := make([]*structs.Issue, 0, len(issues)) | ||
for _, issue := range issues { | ||
suggestion := &structs.Issue{ | ||
ID: issue.ID, | ||
Index: issue.Index, | ||
Title: issue.Title, | ||
State: issue.State(), | ||
} | ||
|
||
if issue.IsPull && issue.PullRequest != nil { | ||
suggestion.PullRequest = &structs.PullRequestMeta{ | ||
HasMerged: issue.PullRequest.HasMerged, | ||
IsWorkInProgress: issue.PullRequest.IsWorkInProgress(ctx), | ||
} | ||
} | ||
suggestions = append(suggestions, suggestion) | ||
} | ||
|
||
return suggestions, nil | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
// Copyright 2025 The Gitea Authors. All rights reserved. | ||
// SPDX-License-Identifier: MIT | ||
|
||
package issue | ||
|
||
import ( | ||
"testing" | ||
|
||
"code.gitea.io/gitea/models/db" | ||
repo_model "code.gitea.io/gitea/models/repo" | ||
"code.gitea.io/gitea/models/unittest" | ||
"code.gitea.io/gitea/modules/optional" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func Test_Suggestion(t *testing.T) { | ||
assert.NoError(t, unittest.PrepareTestDatabase()) | ||
|
||
repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) | ||
|
||
testCases := []struct { | ||
keyword string | ||
isPull optional.Option[bool] | ||
expectedIndexes []int64 | ||
}{ | ||
{ | ||
keyword: "", | ||
expectedIndexes: []int64{5, 1, 4, 2, 3}, | ||
}, | ||
{ | ||
keyword: "1", | ||
expectedIndexes: []int64{1}, | ||
}, | ||
{ | ||
keyword: "issue", | ||
expectedIndexes: []int64{4, 1, 2, 3}, | ||
}, | ||
{ | ||
keyword: "pull", | ||
expectedIndexes: []int64{5}, | ||
}, | ||
} | ||
|
||
for _, testCase := range testCases { | ||
t.Run(testCase.keyword, func(t *testing.T) { | ||
issues, err := GetSuggestion(db.DefaultContext, repo1, testCase.isPull, testCase.keyword) | ||
assert.NoError(t, err) | ||
|
||
issueIndexes := make([]int64, 0, len(issues)) | ||
for _, issue := range issues { | ||
issueIndexes = append(issueIndexes, issue.Index) | ||
} | ||
assert.EqualValues(t, testCase.expectedIndexes, issueIndexes) | ||
}) | ||
} | ||
} |
Uh oh!
There was an error while loading. Please reload this page.