From cd6017519e4dd5a9f69ca164fd12e7dec7e9ef07 Mon Sep 17 00:00:00 2001 From: PhatPhuckDave Date: Thu, 7 Aug 2025 10:44:59 +0200 Subject: [PATCH] refactor: replace custom ignore logic with doublestar glob matching, improve logging, and update deps to use github.com/bmatcuk/doublestar/v4 while removing unused modules --- go.mod | 3 +-- go.sum | 6 ++--- main.go | 78 +++++++++++++++++++++++++++++++++++++++++++++------------ 3 files changed, 65 insertions(+), 22 deletions(-) diff --git a/go.mod b/go.mod index 6f257a7..788463c 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.23.6 require ( git.site.quack-lab.dev/dave/cylogger v1.3.0 - git.site.quack-lab.dev/dave/cyutils v1.1.3 + github.com/bmatcuk/doublestar/v4 v4.9.1 github.com/djherbis/times v1.6.0 ) @@ -13,7 +13,6 @@ require ( github.com/hexops/valast v1.5.0 // indirect golang.org/x/mod v0.7.0 // indirect golang.org/x/sys v0.3.0 // indirect - golang.org/x/time v0.12.0 // indirect golang.org/x/tools v0.4.0 // indirect mvdan.cc/gofumpt v0.4.0 // indirect ) diff --git a/go.sum b/go.sum index e4a422c..a643352 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,7 @@ git.site.quack-lab.dev/dave/cylogger v1.3.0 h1:eTWPUD+ThVi8kGIsRcE0XDeoH3yFb5miFEODyKUdWJw= git.site.quack-lab.dev/dave/cylogger v1.3.0/go.mod h1:wctgZplMvroA4X6p8f4B/LaCKtiBcT1Pp+L14kcS8jk= -git.site.quack-lab.dev/dave/cyutils v1.1.3 h1:9Y1GhrPrVLut36hceZwuFm0IMlAFerl6ATRPa9tGHFM= -git.site.quack-lab.dev/dave/cyutils v1.1.3/go.mod h1:fBjALu2Cp2u2bDr+E4zbGVMBeIgFzROg+4TCcTNAiQU= +github.com/bmatcuk/doublestar/v4 v4.9.1 h1:X8jg9rRZmJd4yRy7ZeNDRnM+T3ZfHv15JiBJ/avrEXE= +github.com/bmatcuk/doublestar/v4 v4.9.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= github.com/djherbis/times v1.6.0 h1:w2ctJ92J8fBvWPxugmXIv7Nz7Q3iDMKNx9v5ocVH20c= github.com/djherbis/times v1.6.0/go.mod h1:gOHeRAz2h+VJNZ5Gmc/o7iD9k4wW7NMVqieYCY99oc0= github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= @@ -27,8 +27,6 @@ golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE= -golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= golang.org/x/tools v0.4.0 h1:7mTAgkunk3fr4GAloyyCasadO6h9zSsQZbwvcaIciV4= golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= mvdan.cc/gofumpt v0.4.0 h1:JVf4NN1mIpHogBj7ABpgOyZc65/UUOkKQFkoURsz4MM= diff --git a/main.go b/main.go index efa93f4..2b39e62 100644 --- a/main.go +++ b/main.go @@ -11,6 +11,7 @@ import ( logger "git.site.quack-lab.dev/dave/cylogger" + "github.com/bmatcuk/doublestar/v4" "github.com/djherbis/times" ) @@ -70,8 +71,8 @@ func getEnv(key, def string) string { } func scanRoot() { - log := logger.Default.WithPrefix("scanRoot") - log.Info("Scanning root directory...") + log := logger.Default.WithPrefix("scanRoot").WithPrefix(constants.ROOT) + log.Info("Scanning root directory") filepath.Walk(constants.ROOT, func(path string, info os.FileInfo, err error) error { if err != nil { log.Error("Error scanning %s: %s", path, err) @@ -80,21 +81,25 @@ func scanRoot() { path = filepath.ToSlash(path) if path == constants.ROOT { - log.Info("Skipping root directory %s...", path) + log.Info("Skipping root directory %s", path) return nil } // I forgot why this code was here... It doesn't make sense to me now // if info.IsDir() { - // log.Info("Skipping directory %s...", path) + // log.Info("Skipping directory %s", path) // return filepath.SkipDir // } // We hope that IGNORED_DIRECTORIES is a small list, so we can afford to iterate over it // In fact iteration should be faster for small lists rather than hashing for _, ignoredDir := range constants.IGNORED_DIRECTORIES { - log.Info("Ignored directories: %s", constants.IGNORED_DIRECTORIES) - if strings.HasPrefix(path, ignoredDir) { + matched, err := doublestar.Match(ignoredDir, path) + if err != nil { + log.Error("Error matching %s: %v", path, err) + continue + } + if matched { log.Info("Ignoring directory %s", path) return filepath.SkipDir } @@ -201,28 +206,68 @@ func deleteFile(path string) { numFilesDeleted++ } +func shouldIgnore(path string) bool { + log := logger.Default.WithPrefix("shouldIgnore").WithPrefix(path) + for _, ignoredDir := range constants.IGNORED_DIRECTORIES { + log.Debug("Checking if %s matches %s", ignoredDir, path) + matched, err := doublestar.Match(ignoredDir, path) + if err != nil { + log.Error("Error matching %s: %v", path, err) + continue + } + if matched { + log.Debug("Directory is ignored, skipping") + return true + } + } + log.Debug("Directory is not ignored") + return false +} + func cleanRoot() { log := logger.Default.WithPrefix("cleanRoot") - var files, err = os.ReadDir(constants.ROOT) + files, err := doublestar.Glob(os.DirFS(constants.ROOT), "**") if err != nil { log.Error("Error reading root directory %s: %s", constants.ROOT, err) return } for _, file := range files { - if !file.IsDir() { - continue - } - var empty, err = isDirEmpty(constants.ROOT + "/" + file.Name()) + fullpath := filepath.Join(constants.ROOT, file) + filelog := log.WithPrefix(file) + + var info os.FileInfo + filelog.Debug("Getting file info") + info, err = os.Stat(fullpath) if err != nil { - log.Error("Error checking if directory %s is empty: %s", file.Name(), err) + filelog.Error("Error getting file info %v", err) continue } - log.Info("Directory %s isempty: %t", file.Name(), empty) + filelog.Trace("File info: %+v", info) + + if !info.IsDir() { + filelog.Info("File is not a directory, skipping") + continue + } + + filelog.Debug("Checking if directory is ignored") + if shouldIgnore(fullpath) { + filelog.Info("Directory is ignored, skipping") + continue + } + filelog.Debug("Directory is not ignored, checking if it is empty") + + var empty, err = isDirEmpty(fullpath) + if err != nil { + filelog.Error("Error checking if directory - is empty: %v", err) + continue + } + + filelog.Info("Directory isempty: %t", empty) if empty { - log.Info("Deleting empty directory %s", file.Name()) - var err = os.RemoveAll(constants.ROOT + "/" + file.Name()) + filelog.Info("Deleting empty directory") + var err = os.RemoveAll(fullpath) if err != nil { - log.Error("Error deleting empty directory %s: %s", file.Name(), err) + filelog.Error("Error deleting empty directory %v", err) } } } @@ -289,6 +334,7 @@ func main() { IGNORED_DIRECTORIES = append(IGNORED_DIRECTORIES, strings.Split(ignoredEnv, ",")...) } IGNORED_DIRECTORIES = append(IGNORED_DIRECTORIES, ROOT_ARCHIVE) + IGNORED_DIRECTORIES = append(IGNORED_DIRECTORIES, ROOT) for key, dir := range IGNORED_DIRECTORIES { IGNORED_DIRECTORIES[key] = filepath.ToSlash(strings.TrimSpace(dir)) }