github.com/joshdk/godel@v0.0.0-20170529232908-862138a45aee/apps/okgo/checkoutput/filter.go (about) 1 // Copyright 2016 Palantir Technologies, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package checkoutput 16 17 import ( 18 "regexp" 19 20 "github.com/palantir/pkg/matcher" 21 "github.com/palantir/pkg/pkgpath" 22 "github.com/pkg/errors" 23 ) 24 25 type Filterer interface { 26 Filter(line Issue) (bool, error) 27 } 28 29 func ApplyFilters(lineInfo []Issue, filters []Filterer) ([]Issue, error) { 30 output := make([]Issue, 0, len(lineInfo)) 31 for _, currLine := range lineInfo { 32 filterOutCurrLine := false 33 var err error 34 for _, currLineFilter := range filters { 35 if filterOutCurrLine, err = currLineFilter.Filter(currLine); err != nil { 36 return nil, errors.Wrapf(err, "failed to apply filter to lineInfo %v", currLine) 37 } else if filterOutCurrLine { 38 break 39 } 40 } 41 if !filterOutCurrLine { 42 output = append(output, currLine) 43 } 44 } 45 return output, nil 46 } 47 48 func NamePathFilter(namePattern string) Filterer { 49 return MatcherFilter(matcher.Name(namePattern)) 50 } 51 52 func RelativePathFilter(relativePathToExclude string) Filterer { 53 return MatcherFilter(matcher.Path(relativePathToExclude)) 54 } 55 56 type matcherFilter struct { 57 m matcher.Matcher 58 } 59 60 func (f matcherFilter) Filter(line Issue) (bool, error) { 61 currLineRelativePath, err := line.Path(pkgpath.Relative) 62 if err != nil { 63 return false, errors.Wrapf(err, "failed to convert line %v to relative path", line) 64 } 65 return f.m != nil && f.m.Match(currLineRelativePath), nil 66 } 67 68 func MatcherFilter(matcher matcher.Matcher) Filterer { 69 return &matcherFilter{m: matcher} 70 } 71 72 type msgRegexpFilter struct { 73 exp string 74 } 75 76 // cache for regular expressions. Used so that the msgRegexpFilter can store a string rather than a regexp, but avoids 77 // re-compiling the same regular expression repeatedly. Not thread-safe, but OK. 78 var regExpCache = make(map[string]*regexp.Regexp) 79 80 func (f msgRegexpFilter) Filter(line Issue) (bool, error) { 81 exp, ok := regExpCache[f.exp] 82 if !ok { 83 // not cached -- compile regexp and add to cache 84 exp = regexp.MustCompile(f.exp) 85 regExpCache[f.exp] = exp 86 } 87 return exp.MatchString(line.Message()), nil 88 } 89 90 func MessageRegexpFilter(messagePattern string) Filterer { 91 // add to cache 92 regExpCache[messagePattern] = regexp.MustCompile(messagePattern) 93 return msgRegexpFilter{exp: messagePattern} 94 }