Glob matching for exclude

This commit is contained in:
Laurence Withers 2023-05-13 12:30:39 +01:00
parent 8b56504cd7
commit b481db737e
3 changed files with 21 additions and 10 deletions

1
go.mod
View File

@ -3,6 +3,7 @@ module src.lwithers.me.uk/go/gg
go 1.20
require (
github.com/bmatcuk/doublestar/v4 v4.6.0
github.com/logrusorgru/aurora/v4 v4.0.0
github.com/spf13/cobra v1.7.0
golang.org/x/sys v0.8.0

2
go.sum
View File

@ -1,3 +1,5 @@
github.com/bmatcuk/doublestar/v4 v4.6.0 h1:HTuxyug8GyFbRkrffIpzNCSK4luc0TY3wzXvzIZhEXc=
github.com/bmatcuk/doublestar/v4 v4.6.0/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=

28
main.go
View File

@ -5,17 +5,18 @@ package main
import (
"errors"
"fmt"
"os"
"path/filepath"
"regexp"
"github.com/bmatcuk/doublestar/v4"
"github.com/spf13/cobra"
"golang.org/x/sys/unix"
)
// TODO:
// - bold of escaped output doesn't work
// - ignore files by extension (or glob?)
func main() {
if err := rootCmd.Execute(); err != nil {
@ -42,7 +43,11 @@ as paths to scan.
Search defaults to case-sensitive but the -i flag may be passed to make regular
expression searches case-insensitive. Alternatively, the "(?i)" construct may be
added to a regular expression to make that specific expression case insensitive.
Fixed pattern matches are always case-sensitive.`,
Fixed pattern matches are always case-sensitive.
Files and directories can be excluded with the -x option. This supports bash-style
globs with '*', '?', '[a-z]', '{this,that}', or '/**/' to match zero or more
directories. By default, .git and vim swap files are ignored.`,
RunE: run,
}
@ -53,10 +58,9 @@ var (
searchFixed []string
searchBytes [][]byte
searchPath []string
ignoreList []string
excludeList []string
binaryFile notPlainTextFlag
minifiedFile notPlainTextFlag
ignoreMap map[string]struct{}
ignoreCase bool
noColour bool
display *Display
@ -66,7 +70,7 @@ var (
func init() {
rootCmd.Flags().StringSliceVarP(&searchRegexp, "grep", "e", nil, "pattern to match (regular expression)")
rootCmd.Flags().StringSliceVarP(&searchFixed, "fixed", "Q", nil, "pattern to match (fixed string)")
rootCmd.Flags().StringSliceVarP(&ignoreList, "exclude", "x", []string{".git"}, "files/directories to exclude")
rootCmd.Flags().StringSliceVarP(&excludeList, "exclude", "x", []string{".git", ".*.swp"}, "files/directories to exclude")
rootCmd.Flags().BoolVarP(&ignoreCase, "ignore-case", "i", false, "make all searches case insensitive")
rootCmd.Flags().BoolVarP(&noColour, "no-colour", "C", false, "disable colour output")
rootCmd.Flags().Var(&binaryFile, "binary", "what to do with binary files")
@ -89,9 +93,10 @@ func run(c *cobra.Command, args []string) error {
searchPath = append(searchPath, ".")
}
ignoreMap = make(map[string]struct{}, len(ignoreList))
for _, i := range ignoreList {
ignoreMap[i] = struct{}{}
for _, x := range excludeList {
if !doublestar.ValidatePattern(x) {
return fmt.Errorf("invalid exclude pattern %q", x)
}
}
for _, r := range searchRegexp {
@ -126,12 +131,15 @@ func recurse(path string) error {
}
var errs []error
NextFile:
for _, de := range d {
name := de.Name()
fullPath := filepath.Join(path, name)
if _, ignored := ignoreMap[name]; ignored {
continue
for _, x := range excludeList {
if exclude, _ := doublestar.Match(x, fullPath); exclude {
continue NextFile
}
}
if err := search(fullPath); err != nil {