gopkg.in/alecthomas/gometalinter.v3@v3.0.0/_linters/src/github.com/client9/misspell/ignore/glob.go (about) 1 package ignore 2 3 import ( 4 "bytes" 5 "fmt" 6 7 "github.com/gobwas/glob" 8 ) 9 10 // Matcher defines an interface for filematchers 11 // 12 type Matcher interface { 13 Match(string) bool 14 True() bool 15 MarshalText() ([]byte, error) 16 } 17 18 // MultiMatch has matching on a list of matchers 19 type MultiMatch struct { 20 matchers []Matcher 21 } 22 23 // NewMultiMatch creates a new MultiMatch instance 24 func NewMultiMatch(matchers []Matcher) *MultiMatch { 25 return &MultiMatch{matchers: matchers} 26 } 27 28 // Match satifies the Matcher iterface 29 func (mm *MultiMatch) Match(arg string) bool { 30 // Normal: OR 31 // false, false -> false 32 // false, true -> true 33 // true, false -> true 34 // true, true -> true 35 36 // Invert: 37 // false, false -> false 38 // false, true -> false 39 // true, false -> true 40 // true, true -> false 41 use := false 42 for _, m := range mm.matchers { 43 if m.Match(arg) { 44 use = m.True() 45 } 46 } 47 return use 48 49 } 50 51 // True returns true 52 func (mm *MultiMatch) True() bool { return true } 53 54 // MarshalText satifies the ?? interface 55 func (mm *MultiMatch) MarshalText() ([]byte, error) { 56 return []byte("multi"), nil 57 } 58 59 // GlobMatch handle glob matching 60 type GlobMatch struct { 61 orig string 62 matcher glob.Glob 63 normal bool 64 } 65 66 // NewGlobMatch creates a new GlobMatch instance or error 67 func NewGlobMatch(arg []byte) (*GlobMatch, error) { 68 truth := true 69 if len(arg) > 0 && arg[0] == '!' { 70 truth = false 71 arg = arg[1:] 72 } 73 if bytes.IndexByte(arg, '/') == -1 { 74 return NewBaseGlobMatch(string(arg), truth) 75 } 76 return NewPathGlobMatch(string(arg), truth) 77 } 78 79 // NewBaseGlobMatch compiles a new matcher. 80 // Arg true should be set to false if the output is inverted. 81 func NewBaseGlobMatch(arg string, truth bool) (*GlobMatch, error) { 82 g, err := glob.Compile(arg) 83 if err != nil { 84 return nil, err 85 } 86 return &GlobMatch{orig: arg, matcher: g, normal: truth}, nil 87 } 88 89 // NewPathGlobMatch compiles a new matcher. 90 // Arg true should be set to false if the output is inverted. 91 func NewPathGlobMatch(arg string, truth bool) (*GlobMatch, error) { 92 // if starts with "/" then glob only applies to top level 93 if len(arg) > 0 && arg[0] == '/' { 94 arg = arg[1:] 95 } 96 97 // create path-aware glob 98 g, err := glob.Compile(arg, '/') 99 if err != nil { 100 return nil, err 101 } 102 return &GlobMatch{orig: arg, matcher: g, normal: truth}, nil 103 } 104 105 // True returns true if this should be evaluated normally ("true is true") 106 // and false if the result should be inverted ("false is true") 107 // 108 func (g *GlobMatch) True() bool { return g.normal } 109 110 // MarshalText is really a debug function 111 func (g *GlobMatch) MarshalText() ([]byte, error) { 112 return []byte(fmt.Sprintf("\"%s: %v %s\"", "GlobMatch", g.normal, g.orig)), nil 113 } 114 115 // Match satisfies the Matcher interface 116 func (g *GlobMatch) Match(file string) bool { 117 return g.matcher.Match(file) 118 }