ContextLineNumber int
IsFuzzy bool
MaxLineLength int // the maximum length of a line to parse, exceeding chars will be truncated
+ PathspecList []string
}
func GrepSearch(ctx context.Context, repo *Repository, search string, opts GrepOptions) ([]*GrepResult, error) {
cmd.AddOptionValues("-e", strings.TrimLeft(search, "-"))
}
cmd.AddDynamicArguments(util.IfZero(opts.RefName, "HEAD"))
+ cmd.AddDashesAndList(opts.PathspecList...)
opts.MaxResultLimit = util.IfZero(opts.MaxResultLimit, 50)
stderr := bytes.Buffer{}
err = cmd.Run(&RunOpts{
},
}, res)
+ res, err = GrepSearch(context.Background(), repo, "void", GrepOptions{PathspecList: []string{":(glob)java-hello/*"}})
+ assert.NoError(t, err)
+ assert.Equal(t, []*GrepResult{
+ {
+ Filename: "java-hello/main.java",
+ LineNumbers: []int{3},
+ LineCodes: []string{" public static void main(String[] args)"},
+ },
+ }, res)
+
+ res, err = GrepSearch(context.Background(), repo, "void", GrepOptions{PathspecList: []string{":(glob,exclude)java-hello/*"}})
+ assert.NoError(t, err)
+ assert.Equal(t, []*GrepResult{
+ {
+ Filename: "main.vendor.java",
+ LineNumbers: []int{3},
+ LineCodes: []string{" public static void main(String[] args)"},
+ },
+ }, res)
+
res, err = GrepSearch(context.Background(), repo, "void", GrepOptions{MaxResultLimit: 1})
assert.NoError(t, err)
assert.Equal(t, []*GrepResult{
--- /dev/null
+// Copyright 2024 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package setting
+
+import "github.com/gobwas/glob"
+
+type GlobMatcher struct {
+ compiledGlob glob.Glob
+ patternString string
+}
+
+var _ glob.Glob = (*GlobMatcher)(nil)
+
+func (g *GlobMatcher) Match(s string) bool {
+ return g.compiledGlob.Match(s)
+}
+
+func (g *GlobMatcher) PatternString() string {
+ return g.patternString
+}
+
+func GlobMatcherCompile(pattern string, separators ...rune) (*GlobMatcher, error) {
+ g, err := glob.Compile(pattern, separators...)
+ if err != nil {
+ return nil, err
+ }
+ return &GlobMatcher{
+ compiledGlob: g,
+ patternString: pattern,
+ }, nil
+}
"time"
"code.gitea.io/gitea/modules/log"
-
- "github.com/gobwas/glob"
)
// Indexer settings
RepoConnStr string
RepoIndexerName string
MaxIndexerFileSize int64
- IncludePatterns []glob.Glob
- ExcludePatterns []glob.Glob
+ IncludePatterns []*GlobMatcher
+ ExcludePatterns []*GlobMatcher
ExcludeVendored bool
}{
IssueType: "bleve",
}
// IndexerGlobFromString parses a comma separated list of patterns and returns a glob.Glob slice suited for repo indexing
-func IndexerGlobFromString(globstr string) []glob.Glob {
- extarr := make([]glob.Glob, 0, 10)
+func IndexerGlobFromString(globstr string) []*GlobMatcher {
+ extarr := make([]*GlobMatcher, 0, 10)
for _, expr := range strings.Split(strings.ToLower(globstr), ",") {
expr = strings.TrimSpace(expr)
if expr != "" {
- if g, err := glob.Compile(expr, '.', '/'); err != nil {
+ if g, err := GlobMatcherCompile(expr, '.', '/'); err != nil {
log.Info("Invalid glob expression '%s' (skipped): %v", expr, err)
} else {
extarr = append(extarr, g)
const tplSearch base.TplName = "repo/search"
+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
+}
+
// Search render repository search page
func Search(ctx *context.Context) {
language := ctx.FormTrim("l")
ctx.Data["CodeIndexerUnavailable"] = !code_indexer.IsAvailable(ctx)
}
} else {
- res, err := git.GrepSearch(ctx, ctx.Repo.GitRepo, keyword, git.GrepOptions{ContextLineNumber: 3, IsFuzzy: isFuzzy})
+ 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(),
+ })
if err != nil {
+ // TODO: if no branch exists, it reports: exit status 128, fatal: this operation must be run in a work tree.
ctx.ServerError("GrepSearch", err)
return
}
--- /dev/null
+// Copyright 2024 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package repo
+
+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())
+}