diff options
author | Eekle <96976531+Eekle@users.noreply.github.com> | 2022-05-21 10:15:40 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-05-21 17:15:40 +0800 |
commit | 876cad0064b8799da1ed82c2d7d2bf689ba5cfe7 (patch) | |
tree | a1653e973de1cf1f80515af4f81db3546485f696 /models | |
parent | ba7750d6e74f689ed045e9926bffa402c2e23a70 (diff) | |
download | gitea-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.go | 13 | ||||
-rw-r--r-- | models/repo_list_test.go | 27 |
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 { |