You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

search.go 3.5KB

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