github.com/jxskiss/gopkg/v2@v2.14.9-0.20240514120614-899f3e7952b4/internal/logfilter/filter.go (about) 1 package logfilter 2 3 import ( 4 "fmt" 5 "strings" 6 7 "github.com/gobwas/glob" 8 ) 9 10 type FileNameFilter struct { 11 rule string 12 allowRule string 13 denyRule string 14 errs []error 15 16 allowAll bool 17 allowGlobs []glob.Glob 18 19 denyAll bool 20 denyGlobs []glob.Glob 21 } 22 23 func NewFileNameFilter(rule string) (*FileNameFilter, []error) { 24 lf := &FileNameFilter{rule: rule} 25 if rule == "" { 26 lf.allowAll = true 27 return lf, nil 28 } 29 directives := strings.Split(rule, ";") 30 for _, r := range directives { 31 if r == "" { 32 continue 33 } 34 if strings.HasPrefix(r, "allow=") { 35 lf.parseAllowRule(r) 36 } 37 if strings.HasPrefix(r, "deny=") { 38 lf.parseDenyRule(r) 39 } 40 } 41 if len(lf.allowGlobs) == 0 { 42 lf.allowAll = true 43 } 44 return lf, lf.errs 45 } 46 47 func (f *FileNameFilter) parseAllowRule(rule string) { 48 f.allowRule = rule 49 // Remove the prefix "allow=". 50 globStrs := strings.Split(rule[6:], ",") 51 for _, s := range globStrs { 52 if s == "" { 53 continue 54 } 55 if s == "all" { 56 f.allowGlobs = nil 57 break 58 } 59 g, err := glob.Compile("**"+s, '/') 60 if err != nil { 61 f.errs = append(f.errs, fmt.Errorf("cannot compile filter pattern %q: %w", s, err)) 62 continue 63 } 64 f.allowGlobs = append(f.allowGlobs, g) 65 } 66 } 67 68 func (f *FileNameFilter) parseDenyRule(rule string) { 69 f.denyRule = rule 70 // Remove the prefix "deny=". 71 globStrs := strings.Split(rule[5:], ",") 72 for _, s := range globStrs { 73 if s == "" { 74 continue 75 } 76 if s == "all" { 77 f.denyAll = true 78 f.denyGlobs = nil 79 break 80 } 81 g, err := glob.Compile("**"+s, '/') 82 if err != nil { 83 f.errs = append(f.errs, fmt.Errorf("cannot compile filter pattern %q: %w", s, err)) 84 continue 85 } 86 f.denyGlobs = append(f.denyGlobs, g) 87 } 88 } 89 90 func (f *FileNameFilter) Allow(fileName string) bool { 91 // not allow-all, check allow rules 92 if !f.allowAll { 93 for _, g := range f.allowGlobs { 94 if g.Match(fileName) { 95 return true 96 } 97 } 98 return false 99 } 100 101 // allow-all, check deny rules 102 if !f.denyAll { 103 for _, g := range f.denyGlobs { 104 if g.Match(fileName) { 105 return false 106 } 107 } 108 } 109 return !f.denyAll 110 }