2017-10-27 09:10:54 +03:00
// Copyright 2017 The Gitea Authors. All rights reserved.
2022-11-27 21:20:29 +03:00
// SPDX-License-Identifier: MIT
2017-10-27 09:10:54 +03:00
package repo
import (
2021-04-05 18:30:52 +03:00
"net/http"
2024-03-24 19:05:00 +03:00
"strings"
2017-10-27 09:10:54 +03:00
2024-03-16 13:32:45 +03:00
"code.gitea.io/gitea/models/db"
2017-10-27 09:10:54 +03:00
"code.gitea.io/gitea/modules/base"
2024-03-24 19:05:00 +03:00
"code.gitea.io/gitea/modules/git"
2019-12-23 15:31:16 +03:00
code_indexer "code.gitea.io/gitea/modules/indexer/code"
2017-10-27 09:10:54 +03:00
"code.gitea.io/gitea/modules/setting"
2024-02-27 10:12:22 +03:00
"code.gitea.io/gitea/services/context"
2017-10-27 09:10:54 +03:00
)
const tplSearch base . TplName = "repo/search"
2024-05-03 12:13:48 +03:00
func indexSettingToGitGrepPathspecList ( ) ( list [ ] string ) {
for _ , expr := range setting . Indexer . IncludePatterns {
list = append ( list , ":(glob)" + expr . PatternString ( ) )
}
for _ , expr := range setting . Indexer . ExcludePatterns {
list = append ( list , ":(glob,exclude)" + expr . PatternString ( ) )
}
return list
}
2017-10-27 09:10:54 +03:00
// Search render repository search page
func Search ( ctx * context . Context ) {
2021-08-11 18:08:52 +03:00
language := ctx . FormTrim ( "l" )
keyword := ctx . FormTrim ( "q" )
2022-10-11 02:12:03 +03:00
2024-03-15 02:24:59 +03:00
isFuzzy := ctx . FormOptionalBool ( "fuzzy" ) . ValueOrDefault ( true )
2022-10-11 02:12:03 +03:00
ctx . Data [ "Keyword" ] = keyword
ctx . Data [ "Language" ] = language
2024-03-15 02:24:59 +03:00
ctx . Data [ "IsFuzzy" ] = isFuzzy
2022-10-11 02:12:03 +03:00
ctx . Data [ "PageIsViewCode" ] = true
2024-05-01 15:32:52 +03:00
ctx . Data [ "IsRepoIndexerEnabled" ] = setting . Indexer . RepoIndexerEnabled
2022-10-11 02:12:03 +03:00
if keyword == "" {
ctx . HTML ( http . StatusOK , tplSearch )
return
}
2021-07-29 04:42:15 +03:00
page := ctx . FormInt ( "page" )
2017-10-27 09:10:54 +03:00
if page <= 0 {
page = 1
}
2021-01-27 13:00:35 +03:00
2024-03-24 19:05:00 +03:00
var total int
var searchResults [ ] * code_indexer . Result
var searchResultLanguages [ ] * code_indexer . SearchResultLanguages
if setting . Indexer . RepoIndexerEnabled {
var err error
total , searchResults , searchResultLanguages , err = code_indexer . PerformSearch ( ctx , & code_indexer . SearchOptions {
RepoIDs : [ ] int64 { ctx . Repo . Repository . ID } ,
Keyword : keyword ,
IsKeywordFuzzy : isFuzzy ,
Language : language ,
Paginator : & db . ListOptions {
Page : page ,
PageSize : setting . UI . RepoSearchPagingNum ,
} ,
} )
if err != nil {
if code_indexer . IsAvailable ( ctx ) {
ctx . ServerError ( "SearchResults" , err )
return
}
ctx . Data [ "CodeIndexerUnavailable" ] = true
} else {
ctx . Data [ "CodeIndexerUnavailable" ] = ! code_indexer . IsAvailable ( ctx )
2022-01-27 11:30:51 +03:00
}
} else {
2024-05-03 12:13:48 +03:00
res , err := git . GrepSearch ( ctx , ctx . Repo . GitRepo , keyword , git . GrepOptions {
ContextLineNumber : 1 ,
IsFuzzy : isFuzzy ,
RefName : git . RefNameFromBranch ( ctx . Repo . BranchName ) . String ( ) , // BranchName should be default branch or the first existing branch
PathspecList : indexSettingToGitGrepPathspecList ( ) ,
} )
2024-03-24 19:05:00 +03:00
if err != nil {
2024-05-03 12:13:48 +03:00
// TODO: if no branch exists, it reports: exit status 128, fatal: this operation must be run in a work tree.
2024-03-24 19:05:00 +03:00
ctx . ServerError ( "GrepSearch" , err )
return
}
total = len ( res )
pageStart := min ( ( page - 1 ) * setting . UI . RepoSearchPagingNum , len ( res ) )
pageEnd := min ( page * setting . UI . RepoSearchPagingNum , len ( res ) )
res = res [ pageStart : pageEnd ]
for _ , r := range res {
searchResults = append ( searchResults , & code_indexer . Result {
RepoID : ctx . Repo . Repository . ID ,
Filename : r . Filename ,
CommitID : ctx . Repo . CommitID ,
// UpdatedUnix: not supported yet
// Language: not supported yet
// Color: not supported yet
2024-04-02 20:48:27 +03:00
Lines : code_indexer . HighlightSearchResultCode ( r . Filename , "" , r . LineNumbers , strings . Join ( r . LineCodes , "\n" ) ) ,
2024-03-24 19:05:00 +03:00
} )
}
2017-10-27 09:10:54 +03:00
}
2022-10-11 02:12:03 +03:00
2024-03-15 02:24:59 +03:00
ctx . Data [ "Repo" ] = ctx . Repo . Repository
2017-10-27 09:10:54 +03:00
ctx . Data [ "SearchResults" ] = searchResults
2020-02-20 22:53:55 +03:00
ctx . Data [ "SearchResultLanguages" ] = searchResultLanguages
2019-04-20 07:15:19 +03:00
pager := context . NewPagination ( total , setting . UI . RepoSearchPagingNum , page , 5 )
pager . SetDefaultParams ( ctx )
2024-03-16 15:07:56 +03:00
pager . AddParamString ( "l" , language )
2019-04-20 07:15:19 +03:00
ctx . Data [ "Page" ] = pager
2021-04-05 18:30:52 +03:00
ctx . HTML ( http . StatusOK , tplSearch )
2017-10-27 09:10:54 +03:00
}