2025-04-26 19:33:14 +08:00

153 lines
4.5 KiB
Go

package common
import (
"bufio"
"os"
"path/filepath"
"regexp"
"strings"
log "github.com/sirupsen/logrus"
)
// CreateIgnorePattern creates one pattern from all path patterns
func CreateIgnorePattern(paths []string) (*regexp.Regexp, error) {
var err error
for i, path := range paths {
if _, err = regexp.Compile(path); err != nil {
return nil, err
}
if !filepath.IsAbs(path) {
absPath, err := filepath.Abs(path)
if err == nil {
paths = append(paths, absPath)
}
} else {
relPath, err := filepath.Rel("/", path)
if err == nil {
paths = append(paths, relPath)
}
}
paths[i] = "(" + path + ")"
}
ignore := `^` + strings.Join(paths, "|") + `$`
return regexp.Compile(ignore)
}
// SetIgnoreDirPaths sets paths to ignore
func (ui *UI) SetIgnoreDirPaths(paths []string) {
log.Printf("Ignoring dirs %s", strings.Join(paths, ", "))
ui.IgnoreDirPaths = make(map[string]struct{}, len(paths)*2)
for _, path := range paths {
ui.IgnoreDirPaths[path] = struct{}{}
if !filepath.IsAbs(path) {
if absPath, err := filepath.Abs(path); err == nil {
ui.IgnoreDirPaths[absPath] = struct{}{}
}
} else {
if relPath, err := filepath.Rel("/", path); err == nil {
ui.IgnoreDirPaths[relPath] = struct{}{}
}
}
}
}
// SetIgnoreDirPatterns sets regular patterns of dirs to ignore
func (ui *UI) SetIgnoreDirPatterns(paths []string) error {
var err error
log.Printf("Ignoring dir patterns %s", strings.Join(paths, ", "))
ui.IgnoreDirPathPatterns, err = CreateIgnorePattern(paths)
return err
}
// SetIgnoreFromFile sets regular patterns of dirs to ignore
func (ui *UI) SetIgnoreFromFile(ignoreFile string) error {
var err error
var paths []string
log.Printf("Reading ignoring dir patterns from file '%s'", ignoreFile)
file, err := os.Open(ignoreFile)
if err != nil {
return err
}
defer file.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
paths = append(paths, scanner.Text())
}
if err := scanner.Err(); err != nil {
return err
}
ui.IgnoreDirPathPatterns, err = CreateIgnorePattern(paths)
return err
}
// SetIgnoreHidden sets flags if hidden dirs should be ignored
func (ui *UI) SetIgnoreHidden(value bool) {
log.Printf("Ignoring hidden dirs")
ui.IgnoreHidden = value
}
// ShouldDirBeIgnored returns true if given path should be ignored
func (ui *UI) ShouldDirBeIgnored(name, path string) bool {
_, shouldIgnore := ui.IgnoreDirPaths[path]
if shouldIgnore {
log.Printf("Directory %s ignored", path)
}
return shouldIgnore
}
// ShouldDirBeIgnoredUsingPattern returns true if given path should be ignored
func (ui *UI) ShouldDirBeIgnoredUsingPattern(name, path string) bool {
shouldIgnore := ui.IgnoreDirPathPatterns.MatchString(path)
if shouldIgnore {
log.Printf("Directory %s ignored", path)
}
return shouldIgnore
}
// IsHiddenDir returns if the dir name begins with dot
func (ui *UI) IsHiddenDir(name, path string) bool {
shouldIgnore := name[0] == '.'
if shouldIgnore {
log.Printf("Directory %s ignored", path)
}
return shouldIgnore
}
// CreateIgnoreFunc returns function for detecting if dir should be ignored
// nolint: gocyclo // Why: This function is a switch statement that is not too complex
func (ui *UI) CreateIgnoreFunc() ShouldDirBeIgnored {
switch {
case len(ui.IgnoreDirPaths) > 0 && ui.IgnoreDirPathPatterns == nil && !ui.IgnoreHidden:
return ui.ShouldDirBeIgnored
case len(ui.IgnoreDirPaths) > 0 && ui.IgnoreDirPathPatterns != nil && !ui.IgnoreHidden:
return func(name, path string) bool {
return ui.ShouldDirBeIgnored(name, path) || ui.ShouldDirBeIgnoredUsingPattern(name, path)
}
case len(ui.IgnoreDirPaths) > 0 && ui.IgnoreDirPathPatterns != nil && ui.IgnoreHidden:
return func(name, path string) bool {
return ui.ShouldDirBeIgnored(name, path) || ui.ShouldDirBeIgnoredUsingPattern(name, path) || ui.IsHiddenDir(name, path)
}
case len(ui.IgnoreDirPaths) == 0 && ui.IgnoreDirPathPatterns != nil && ui.IgnoreHidden:
return func(name, path string) bool {
return ui.ShouldDirBeIgnoredUsingPattern(name, path) || ui.IsHiddenDir(name, path)
}
case len(ui.IgnoreDirPaths) == 0 && ui.IgnoreDirPathPatterns != nil && !ui.IgnoreHidden:
return ui.ShouldDirBeIgnoredUsingPattern
case len(ui.IgnoreDirPaths) == 0 && ui.IgnoreDirPathPatterns == nil && ui.IgnoreHidden:
return ui.IsHiddenDir
case len(ui.IgnoreDirPaths) > 0 && ui.IgnoreDirPathPatterns == nil && ui.IgnoreHidden:
return func(name, path string) bool {
return ui.ShouldDirBeIgnored(name, path) || ui.IsHiddenDir(name, path)
}
default:
return func(name, path string) bool { return false }
}
}