code.gitea.io/gitea@v1.22.3/routers/web/repo/search.go (about) 1 // Copyright 2017 The Gitea Authors. All rights reserved. 2 // SPDX-License-Identifier: MIT 3 4 package repo 5 6 import ( 7 "net/http" 8 "strings" 9 10 "code.gitea.io/gitea/models/db" 11 "code.gitea.io/gitea/modules/base" 12 "code.gitea.io/gitea/modules/git" 13 code_indexer "code.gitea.io/gitea/modules/indexer/code" 14 "code.gitea.io/gitea/modules/setting" 15 "code.gitea.io/gitea/services/context" 16 ) 17 18 const tplSearch base.TplName = "repo/search" 19 20 func indexSettingToGitGrepPathspecList() (list []string) { 21 for _, expr := range setting.Indexer.IncludePatterns { 22 list = append(list, ":(glob)"+expr.PatternString()) 23 } 24 for _, expr := range setting.Indexer.ExcludePatterns { 25 list = append(list, ":(glob,exclude)"+expr.PatternString()) 26 } 27 return list 28 } 29 30 // Search render repository search page 31 func Search(ctx *context.Context) { 32 language := ctx.FormTrim("l") 33 keyword := ctx.FormTrim("q") 34 35 isFuzzy := ctx.FormOptionalBool("fuzzy").ValueOrDefault(true) 36 37 ctx.Data["Keyword"] = keyword 38 ctx.Data["Language"] = language 39 ctx.Data["IsFuzzy"] = isFuzzy 40 ctx.Data["PageIsViewCode"] = true 41 ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled 42 43 if keyword == "" { 44 ctx.HTML(http.StatusOK, tplSearch) 45 return 46 } 47 48 page := ctx.FormInt("page") 49 if page <= 0 { 50 page = 1 51 } 52 53 var total int 54 var searchResults []*code_indexer.Result 55 var searchResultLanguages []*code_indexer.SearchResultLanguages 56 if setting.Indexer.RepoIndexerEnabled { 57 var err error 58 total, searchResults, searchResultLanguages, err = code_indexer.PerformSearch(ctx, &code_indexer.SearchOptions{ 59 RepoIDs: []int64{ctx.Repo.Repository.ID}, 60 Keyword: keyword, 61 IsKeywordFuzzy: isFuzzy, 62 Language: language, 63 Paginator: &db.ListOptions{ 64 Page: page, 65 PageSize: setting.UI.RepoSearchPagingNum, 66 }, 67 }) 68 if err != nil { 69 if code_indexer.IsAvailable(ctx) { 70 ctx.ServerError("SearchResults", err) 71 return 72 } 73 ctx.Data["CodeIndexerUnavailable"] = true 74 } else { 75 ctx.Data["CodeIndexerUnavailable"] = !code_indexer.IsAvailable(ctx) 76 } 77 } else { 78 res, err := git.GrepSearch(ctx, ctx.Repo.GitRepo, keyword, git.GrepOptions{ 79 ContextLineNumber: 1, 80 IsFuzzy: isFuzzy, 81 RefName: git.RefNameFromBranch(ctx.Repo.BranchName).String(), // BranchName should be default branch or the first existing branch 82 PathspecList: indexSettingToGitGrepPathspecList(), 83 }) 84 if err != nil { 85 // TODO: if no branch exists, it reports: exit status 128, fatal: this operation must be run in a work tree. 86 ctx.ServerError("GrepSearch", err) 87 return 88 } 89 total = len(res) 90 pageStart := min((page-1)*setting.UI.RepoSearchPagingNum, len(res)) 91 pageEnd := min(page*setting.UI.RepoSearchPagingNum, len(res)) 92 res = res[pageStart:pageEnd] 93 for _, r := range res { 94 searchResults = append(searchResults, &code_indexer.Result{ 95 RepoID: ctx.Repo.Repository.ID, 96 Filename: r.Filename, 97 CommitID: ctx.Repo.CommitID, 98 // UpdatedUnix: not supported yet 99 // Language: not supported yet 100 // Color: not supported yet 101 Lines: code_indexer.HighlightSearchResultCode(r.Filename, "", r.LineNumbers, strings.Join(r.LineCodes, "\n")), 102 }) 103 } 104 } 105 106 ctx.Data["Repo"] = ctx.Repo.Repository 107 ctx.Data["SearchResults"] = searchResults 108 ctx.Data["SearchResultLanguages"] = searchResultLanguages 109 110 pager := context.NewPagination(total, setting.UI.RepoSearchPagingNum, page, 5) 111 pager.SetDefaultParams(ctx) 112 pager.AddParamString("l", language) 113 ctx.Data["Page"] = pager 114 115 ctx.HTML(http.StatusOK, tplSearch) 116 }