From 6efbe62a9e0753a1eff8bf6179b7b4e5e8b5d74a Mon Sep 17 00:00:00 2001 From: David Newhall II Date: Mon, 21 Sep 2026 12:27:28 -0700 Subject: [PATCH] Keep a watched archive searchable when recursion is disabled. xtractr now honors ExcludeSuffix for a path that is the archive, so listing every suffix made disable_recursion skip the file instead of only its nested archives. Co-authored-by: Cursor --- pkg/unpackerr/folder.go | 26 ++++++++------------------ pkg/unpackerr/folder_recursion_test.go | 17 ++++++++++------- 2 files changed, 18 insertions(+), 25 deletions(-) diff --git a/pkg/unpackerr/folder.go b/pkg/unpackerr/folder.go index 1ce5506a..be013055 100644 --- a/pkg/unpackerr/folder.go +++ b/pkg/unpackerr/folder.go @@ -86,7 +86,7 @@ func (u *Unpackerr) extractTrackedItem(name string, folder *Folder, now time.Tim return } - exclude := folderExcludeSuffixes(name, folder.Config) + exclude := folderExcludeSuffixes(folder.Config) if folder.Config.MoveBack { found := xtractr.FindCompressedFiles(xtractr.Filter{ @@ -155,24 +155,14 @@ func (u *Unpackerr) skipR00Extraction(name string, now time.Time) bool { } // folderExcludeSuffixes returns archive suffixes to ignore when scanning for items to extract. -// For watched archive files with disable_recursion enabled, exclude all archive suffixes so -// extracted nested archives are not picked up by follow-up scans in the extraction library. -func folderExcludeSuffixes(path string, cfg *FolderConfig) []string { - exclude := []string{} - if !cfg.ExtractISOs { - exclude = append(exclude, ".iso") - } - - if !cfg.DisableRecursion { - return exclude - } - - stat, err := os.Stat(path) - if err != nil || stat.IsDir() || !xtractr.IsArchiveFile(path) { - return exclude +// xtractr applies this list even when the search path is the archive itself, so a watched +// archive must stay searchable. Nested archives are skipped with DisableRecursion. +func folderExcludeSuffixes(cfg *FolderConfig) []string { + if cfg.ExtractISOs { + return nil } - return append(exclude, xtractr.SupportedExtensions()...) + return []string{".iso"} } func getFileList(path string) []os.FileInfo { @@ -660,7 +650,7 @@ func (u *Unpackerr) folderArchiveCount(name string, folder *Folder) int { found := xtractr.FindCompressedFiles(xtractr.Filter{ Path: name, - ExcludeSuffix: folderExcludeSuffixes(name, cfg), + ExcludeSuffix: folderExcludeSuffixes(cfg), AllowSymlinks: cfg.AllowSymlinks, }) diff --git a/pkg/unpackerr/folder_recursion_test.go b/pkg/unpackerr/folder_recursion_test.go index 8e3f9a16..faa550a6 100644 --- a/pkg/unpackerr/folder_recursion_test.go +++ b/pkg/unpackerr/folder_recursion_test.go @@ -53,8 +53,7 @@ func TestFolderDisableRecursionFalseExtractsNested(t *testing.T) { func TestFolderExcludeSuffixesDirectoryDoesNotExcludeAllArchives(t *testing.T) { t.Parallel() - dir := t.TempDir() - exclude := folderExcludeSuffixes(dir, &FolderConfig{DisableRecursion: true, ExtractISOs: false}) + exclude := folderExcludeSuffixes(&FolderConfig{DisableRecursion: true, ExtractISOs: false}) if !containsString(exclude, ".iso") { t.Fatalf("expected .iso exclusion when extract_isos=false; got: %v", exclude) @@ -65,14 +64,18 @@ func TestFolderExcludeSuffixesDirectoryDoesNotExcludeAllArchives(t *testing.T) { } } -func TestFolderExcludeSuffixesArchiveExcludesAllWhenDisableRecursion(t *testing.T) { +func TestFolderExcludeSuffixesArchiveStaysSearchableWhenDisableRecursion(t *testing.T) { t.Parallel() archivePath := makeNestedZipFixture(t) - exclude := folderExcludeSuffixes(archivePath, &FolderConfig{DisableRecursion: true, ExtractISOs: false}) + exclude := folderExcludeSuffixes(&FolderConfig{DisableRecursion: true, ExtractISOs: false}) - if !containsString(exclude, ".zip") { - t.Fatalf("expected archive suffix exclusions for watched archive file; got: %v", exclude) + if containsString(exclude, ".zip") { + t.Fatalf("watched archive suffix must stay searchable; got: %v", exclude) + } + + if xtractr.FindCompressedFiles(xtractr.Filter{Path: archivePath, ExcludeSuffix: exclude}).Count() != 1 { + t.Fatal("expected FindCompressedFiles to return the watched archive") } } @@ -80,7 +83,7 @@ func runExtraction(t *testing.T, archivePath string, disableRecursion bool) *xtr t.Helper() cfg := &FolderConfig{DisableRecursion: disableRecursion, ExtractISOs: false} - exclude := folderExcludeSuffixes(archivePath, cfg) + exclude := folderExcludeSuffixes(cfg) queue := xtractr.NewQueue(&xtractr.Config{ Parallel: 1,