summaryrefslogtreecommitdiffstats
path: root/models
diff options
context:
space:
mode:
authorEekle <96976531+Eekle@users.noreply.github.com>2022-05-21 10:15:40 +0100
committerGitHub <noreply@github.com>2022-05-21 17:15:40 +0800
commit876cad0064b8799da1ed82c2d7d2bf689ba5cfe7 (patch)
treea1653e973de1cf1f80515af4f81db3546485f696 /models
parentba7750d6e74f689ed045e9926bffa402c2e23a70 (diff)
downloadgitea-876cad0064b8799da1ed82c2d7d2bf689ba5cfe7.tar.gz
gitea-876cad0064b8799da1ed82c2d7d2bf689ba5cfe7.zip
Allows repo search to match against "owner/repo" pattern strings (#19754)
* Allows repo search to match against "owner/repo" pattern strings * Gofumpt * Adds test case for "owner/repo" style repo search * With "owner/repo" search terms, prioritise results which match the owner field * Fixes unquoted SQL string in repo search
Diffstat (limited to 'models')
-rw-r--r--models/repo_list.go13
-rw-r--r--models/repo_list_test.go27
2 files changed, 39 insertions, 1 deletions
diff --git a/models/repo_list.go b/models/repo_list.go
index d1974d77e7..906b7548d4 100644
--- a/models/repo_list.go
+++ b/models/repo_list.go
@@ -459,6 +459,15 @@ func SearchRepositoryCondition(opts *SearchRepoOptions) builder.Cond {
likes := builder.NewCond()
for _, v := range strings.Split(opts.Keyword, ",") {
likes = likes.Or(builder.Like{"lower_name", strings.ToLower(v)})
+
+ // If the string looks like "org/repo", match against that pattern too
+ if opts.TeamID == 0 && strings.Count(opts.Keyword, "/") == 1 {
+ pieces := strings.Split(opts.Keyword, "/")
+ ownerName := pieces[0]
+ repoName := pieces[1]
+ likes = likes.Or(builder.And(builder.Like{"owner_name", strings.ToLower(ownerName)}, builder.Like{"lower_name", strings.ToLower(repoName)}))
+ }
+
if opts.IncludeDescription {
likes = likes.Or(builder.Like{"LOWER(description)", strings.ToLower(v)})
}
@@ -549,6 +558,10 @@ func searchRepositoryByCondition(ctx context.Context, opts *SearchRepoOptions, c
if opts.PriorityOwnerID > 0 {
opts.OrderBy = db.SearchOrderBy(fmt.Sprintf("CASE WHEN owner_id = %d THEN 0 ELSE owner_id END, %s", opts.PriorityOwnerID, opts.OrderBy))
+ } else if strings.Count(opts.Keyword, "/") == 1 {
+ // With "owner/repo" search times, prioritise results which match the owner field
+ orgName := strings.Split(opts.Keyword, "/")[0]
+ opts.OrderBy = db.SearchOrderBy(fmt.Sprintf("CASE WHEN owner_name LIKE '%s' THEN 0 ELSE 1 END, %s", orgName, opts.OrderBy))
}
sess := db.GetEngine(ctx)
diff --git a/models/repo_list_test.go b/models/repo_list_test.go
index 4722b073a3..d45e10fb80 100644
--- a/models/repo_list_test.go
+++ b/models/repo_list_test.go
@@ -5,6 +5,7 @@
package models
import (
+ "strings"
"testing"
"code.gitea.io/gitea/models/db"
@@ -261,6 +262,16 @@ func TestSearchRepository(t *testing.T) {
opts: &SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, Template: util.OptionalBoolTrue},
count: 2,
},
+ {
+ name: "OwnerSlashRepoSearch",
+ opts: &SearchRepoOptions{Keyword: "user/repo2", ListOptions: db.ListOptions{Page: 1, PageSize: 10}, Private: true, OwnerID: 0},
+ count: 3,
+ },
+ {
+ name: "OwnerSlashSearch",
+ opts: &SearchRepoOptions{Keyword: "user20/", ListOptions: db.ListOptions{Page: 1, PageSize: 10}, Private: true, OwnerID: 0},
+ count: 4,
+ },
}
for _, testCase := range testCases {
@@ -285,7 +296,21 @@ func TestSearchRepository(t *testing.T) {
assert.NotEmpty(t, repo.Name)
if len(testCase.opts.Keyword) > 0 {
- assert.Contains(t, repo.Name, testCase.opts.Keyword)
+ // Keyword match condition is different for search terms of form "owner/repo"
+ if strings.Count(testCase.opts.Keyword, "/") == 1 {
+ // May still match as a whole...
+ wholeMatch := strings.Contains(repo.Name, testCase.opts.Keyword)
+
+ pieces := strings.Split(testCase.opts.Keyword, "/")
+ ownerName := pieces[0]
+ repoName := pieces[1]
+ // ... or match in parts
+ splitMatch := strings.Contains(repo.OwnerName, ownerName) && strings.Contains(repo.Name, repoName)
+
+ assert.True(t, wholeMatch || splitMatch, "Keyword '%s' does not match repo '%s/%s'", testCase.opts.Keyword, repo.Owner.Name, repo.Name)
+ } else {
+ assert.Contains(t, repo.Name, testCase.opts.Keyword)
+ }
}
if !testCase.opts.Private {