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

This commit is contained in:
2025-08-07 10:44:59 +02:00
parent 37b08d27f5
commit cd6017519e
3 changed files with 65 additions and 22 deletions

3
go.mod
View File

@@ -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
)

6
go.sum
View File

@@ -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=

78
main.go
View File

@@ -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))
}