diff options
author | Sunny <me@darkowlzz.space> | 2017-12-18 01:50:42 +0530 |
---|---|---|
committer | Sunny <me@darkowlzz.space> | 2017-12-20 00:32:59 +0530 |
commit | 4ead334dbdf371b75d26dc682e930d1338b8ce35 (patch) | |
tree | 2b3750f66ad65575baa879e408b650aea671edd2 /worktree.go | |
parent | 757a26038e5404f94523ba07d017d1b38bcbf6dd (diff) | |
download | go-git-4ead334dbdf371b75d26dc682e930d1338b8ce35.tar.gz |
git: Worktree.Grep() support multiple patterns and pathspecs
Signed-off-by: Sunny <me@darkowlzz.space>
Diffstat (limited to 'worktree.go')
-rw-r--r-- | worktree.go | 84 |
1 files changed, 61 insertions, 23 deletions
diff --git a/worktree.go b/worktree.go index 2c35ffb..a23397e 100644 --- a/worktree.go +++ b/worktree.go @@ -765,50 +765,88 @@ func (w *Worktree) Grep(opts *GrepOptions) ([]GrepResult, error) { // findMatchInFiles takes a FileIter, worktree name and GrepOptions, and // returns a slice of GrepResult containing the result of regex pattern matching -// in the file content. +// in content of all the files. func findMatchInFiles(fileiter *object.FileIter, treeName string, opts *GrepOptions) ([]GrepResult, error) { var results []GrepResult - // Iterate through the files and look for any matches. err := fileiter.ForEach(func(file *object.File) error { - // Check if the file name matches with the pathspec. - if opts.PathSpec != nil && !opts.PathSpec.MatchString(file.Name) { + var fileInPathSpec bool + + // When no pathspecs are provided, search all the files. + if len(opts.PathSpecs) == 0 { + fileInPathSpec = true + } + + // Check if the file name matches with the pathspec. Break out of the + // loop once a match is found. + for _, pathSpec := range opts.PathSpecs { + if pathSpec != nil && pathSpec.MatchString(file.Name) { + fileInPathSpec = true + break + } + } + + // If the file does not match with any of the pathspec, skip it. + if !fileInPathSpec { return nil } - content, err := file.Contents() + grepResults, err := findMatchInFile(file, treeName, opts) if err != nil { return err } + results = append(results, grepResults...) + + return nil + }) + + return results, err +} - // Split the content and make parseable line-by-line. - contentByLine := strings.Split(content, "\n") - for lineNum, cnt := range contentByLine { - addToResult := false - // Match the pattern and content. - if opts.Pattern != nil && opts.Pattern.MatchString(cnt) { +// findMatchInFile takes a single File, worktree name and GrepOptions, +// and returns a slice of GrepResult containing the result of regex pattern +// matching in the given file. +func findMatchInFile(file *object.File, treeName string, opts *GrepOptions) ([]GrepResult, error) { + var grepResults []GrepResult + + content, err := file.Contents() + if err != nil { + return grepResults, err + } + + // Split the file content and parse line-by-line. + contentByLine := strings.Split(content, "\n") + for lineNum, cnt := range contentByLine { + addToResult := false + + // Match the patterns and content. Break out of the loop once a + // match is found. + for _, pattern := range opts.Patterns { + if pattern != nil && pattern.MatchString(cnt) { // Add to result only if invert match is not enabled. if !opts.InvertMatch { addToResult = true + break } } else if opts.InvertMatch { - // If matching fails, and invert match is enabled, add to results. + // If matching fails, and invert match is enabled, add to + // results. addToResult = true + break } + } - if addToResult { - results = append(results, GrepResult{ - FileName: file.Name, - LineNumber: lineNum + 1, - Content: cnt, - TreeName: treeName, - }) - } + if addToResult { + grepResults = append(grepResults, GrepResult{ + FileName: file.Name, + LineNumber: lineNum + 1, + Content: cnt, + TreeName: treeName, + }) } - return nil - }) + } - return results, err + return grepResults, nil } func rmFileAndDirIfEmpty(fs billy.Filesystem, name string) error { |