aboutsummaryrefslogtreecommitdiffstats
path: root/modules/indexer/code/gitgrep
diff options
context:
space:
mode:
Diffstat (limited to 'modules/indexer/code/gitgrep')
-rw-r--r--modules/indexer/code/gitgrep/gitgrep.go66
-rw-r--r--modules/indexer/code/gitgrep/gitgrep_test.go19
2 files changed, 85 insertions, 0 deletions
diff --git a/modules/indexer/code/gitgrep/gitgrep.go b/modules/indexer/code/gitgrep/gitgrep.go
new file mode 100644
index 0000000000..6f6e0b47b9
--- /dev/null
+++ b/modules/indexer/code/gitgrep/gitgrep.go
@@ -0,0 +1,66 @@
+// Copyright 2025 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package gitgrep
+
+import (
+ "context"
+ "fmt"
+ "strings"
+
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/indexer"
+ code_indexer "code.gitea.io/gitea/modules/indexer/code"
+ "code.gitea.io/gitea/modules/setting"
+)
+
+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
+}
+
+func PerformSearch(ctx context.Context, page int, repoID int64, gitRepo *git.Repository, ref git.RefName, keyword string, searchMode indexer.SearchModeType) (searchResults []*code_indexer.Result, total int, err error) {
+ grepMode := git.GrepModeWords
+ switch searchMode {
+ case indexer.SearchModeExact:
+ grepMode = git.GrepModeExact
+ case indexer.SearchModeRegexp:
+ grepMode = git.GrepModeRegexp
+ }
+ res, err := git.GrepSearch(ctx, gitRepo, keyword, git.GrepOptions{
+ ContextLineNumber: 1,
+ GrepMode: grepMode,
+ RefName: ref.String(),
+ PathspecList: indexSettingToGitGrepPathspecList(),
+ })
+ if err != nil {
+ // TODO: if no branch exists, it reports: exit status 128, fatal: this operation must be run in a work tree.
+ return nil, 0, fmt.Errorf("git.GrepSearch: %w", err)
+ }
+ commitID, err := gitRepo.GetRefCommitID(ref.String())
+ if err != nil {
+ return nil, 0, fmt.Errorf("gitRepo.GetRefCommitID: %w", err)
+ }
+
+ 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: repoID,
+ Filename: r.Filename,
+ CommitID: commitID,
+ // UpdatedUnix: not supported yet
+ // Language: not supported yet
+ // Color: not supported yet
+ Lines: code_indexer.HighlightSearchResultCode(r.Filename, "", r.LineNumbers, strings.Join(r.LineCodes, "\n")),
+ })
+ }
+ return searchResults, total, nil
+}
diff --git a/modules/indexer/code/gitgrep/gitgrep_test.go b/modules/indexer/code/gitgrep/gitgrep_test.go
new file mode 100644
index 0000000000..97dda9d966
--- /dev/null
+++ b/modules/indexer/code/gitgrep/gitgrep_test.go
@@ -0,0 +1,19 @@
+// Copyright 2024 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package gitgrep
+
+import (
+ "testing"
+
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/test"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestIndexSettingToGitGrepPathspecList(t *testing.T) {
+ defer test.MockVariableValue(&setting.Indexer.IncludePatterns, setting.IndexerGlobFromString("a"))()
+ defer test.MockVariableValue(&setting.Indexer.ExcludePatterns, setting.IndexerGlobFromString("b"))()
+ assert.Equal(t, []string{":(glob)a", ":(glob,exclude)b"}, indexSettingToGitGrepPathspecList())
+}