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  }