diff --git a/backuper.go b/backuper.go index 47560a3..3848d03 100644 --- a/backuper.go +++ b/backuper.go @@ -18,7 +18,10 @@ type Mask struct { Path string // Маски имени файла - MaskList []string + FileNameMaskList []string + + // Маски пути + FilePathMaskList []string // Вкючать файлы в покаталогах Recursive bool @@ -166,9 +169,9 @@ func (b *Config) doBackup(index *Index) error { func (b *Config) fileList(fileNames chan File) { errorCount := 0 - for _, v := range b.Masks { - if v.Recursive { - err := filepath.WalkDir(v.Path, func(path string, d fs.DirEntry, err error) error { + for _, mask := range b.Masks { + if mask.Recursive { + err := filepath.WalkDir(mask.Path, func(path string, d fs.DirEntry, err error) error { if err != nil { errorCount++ b.logf(LogLevelCritical, "Ошибка при поиске файлов: %v\n", err) @@ -182,15 +185,14 @@ func (b *Config) fileList(fileNames chan File) { return nil } - if !v.Recursive && filepath.Dir(path) != v.Path { + path = filepath.ToSlash(path) + + if !mask.Recursive && filepath.Dir(path) != mask.Path { return nil } - // fileName := filepath.Base(path) - fileName := path // TODO: тестирование - маска действует на весь путь - - if isFileMatchMasks(v.MaskList, fileName) { - if !isFileMatchMasks(b.GlobalExcludeMasks, fileName) { + if isFilePathMatchMasks(mask.FilePathMaskList, path) && isFileNameMatchMasks(mask.FileNameMaskList, path) { + if !isFilePathMatchMasks(b.GlobalExcludeFilePathMasks, path) && !isFileNameMatchMasks(b.GlobalExcludeFileNameMasks, path) { info, err := os.Stat(path) if err != nil { errorCount++ @@ -213,7 +215,7 @@ func (b *Config) fileList(fileNames chan File) { b.logf(LogLevelCritical, "Ошибка при получении списка файлов: %v\n", err) } } else { - allFilesAndDirs, err := filepath.Glob(filepath.Join(v.Path, "*")) + allFilesAndDirs, err := filepath.Glob(filepath.Join(mask.Path, "*")) if err != nil { errorCount++ b.logf(LogLevelCritical, "Ошибка при получении списка файлов: %v\n", err) @@ -234,8 +236,8 @@ func (b *Config) fileList(fileNames chan File) { //fileName := filepath.Base(fileOrDirPath) fileName := fileOrDirPath // TODO: тестирование, маска должна накладываться на путь - if isFileMatchMasks(v.MaskList, fileName) { - if !isFileMatchMasks(b.GlobalExcludeMasks, fileName) { + if isFilePathMatchMasks(mask.FilePathMaskList, fileName) && isFileNameMatchMasks(mask.FileNameMaskList, fileName) { + if !isFilePathMatchMasks(b.GlobalExcludeFilePathMasks, fileName) && !isFileNameMatchMasks(b.GlobalExcludeFileNameMasks, fileName) { file := File{ SourcePath: fileOrDirPath, DestinationPath: filepath.ToSlash(fileOrDirPath), @@ -254,16 +256,6 @@ func (b *Config) fileList(fileNames chan File) { close(fileNames) } -func isFileMatchMasks(masks []string, fileName string) bool { - for _, mask := range masks { - if match, _ := filepath.Match(filepath.ToSlash(mask), filepath.ToSlash(fileName)); match { - return true - } - } - - return false -} - func (b *Config) addFileToTarWriter(filePath string, tarWriter *tar.Writer) error { b.logf(LogLevelDebug, "Добавление файла %s...\n", filePath) diff --git a/config.go b/config.go index 1669630..277276e 100644 --- a/config.go +++ b/config.go @@ -19,10 +19,13 @@ type Config struct { FileName string // Маски файлов для включения в архив - Masks []Mask + Masks []*Mask - // Маски файлов/путей для исключения из всех масок - GlobalExcludeMasks []string + // Маски файлов для исключения + GlobalExcludeFileNameMasks []string + + // Маски путей для исключения + GlobalExcludeFilePathMasks []string // Логгер Logger LoggerConfig @@ -70,6 +73,12 @@ func LoadConfig(filePath string) (*Config, error) { config.logger = Logger{logger: log.New(os.Stderr, "", 0), MinimalLogLevel: config.Logger.MinimalLogLevel} + for _, mask := range config.Masks { + if len(mask.FilePathMaskList) == 0 { + mask.FilePathMaskList = []string{"*"} + } + } + configFilePath, err := filepath.Abs(filePath) if err != nil { return nil, err diff --git a/examples/config.toml b/examples/config.toml index bd09ddb..84e43a2 100644 --- a/examples/config.toml +++ b/examples/config.toml @@ -6,5 +6,5 @@ MinimalLogLevel = 1 [[Masks]] Path = "/home/user/go/src" -MaskList = ["*.go", "*/go.mod", "*/go.sum"] +FileNameMaskList = ["*.go", "go.mod", "go.sum"] Recursive = true diff --git a/go.mod b/go.mod index a12ec01..9327a7f 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ require ( github.com/klauspost/compress v1.16.0 github.com/nxshock/progressmessage v0.0.0-20210730035634-63cec26e1e83 github.com/stretchr/testify v1.8.2 + github.com/tidwall/match v1.1.1 ) require ( diff --git a/go.sum b/go.sum index 1881fba..9c4658c 100644 --- a/go.sum +++ b/go.sum @@ -16,6 +16,8 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= +github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/index.go b/index.go index 54f5d9e..169f39e 100644 --- a/index.go +++ b/index.go @@ -69,7 +69,7 @@ func (index *Index) GetFilesLocation(mask string, t time.Time) ([]File, error) { var files2 []File for fileName := range index.Files { - if isFileMatchMasks([]string{mask}, fileName) { + if isFilePathMatchMasks([]string{mask}, fileName) { files := index.Files[fileName] file := files[0] diff --git a/utils.go b/utils.go index 6ccbc67..3d16c99 100644 --- a/utils.go +++ b/utils.go @@ -2,7 +2,10 @@ package main import ( "fmt" + "path/filepath" "strings" + + "github.com/tidwall/match" ) /*func winPathToRelative(s string) string { @@ -53,3 +56,23 @@ func stringIn(s string, ss []string) (bool, int) { return false, -1 } + +func isFileNameMatchMasks(masks []string, fileName string) bool { + for _, mask := range masks { + if match.Match(filepath.Base(fileName), mask) { + return true + } + } + + return false +} + +func isFilePathMatchMasks(masks []string, fileName string) bool { + for _, mask := range masks { + if match.Match(fileName, mask) { + return true + } + } + + return false +}