chore: simplify and cleanup

Signed-off-by: Keith Zantow <keith.zantow@anchore.com>
This commit is contained in:
Keith Zantow
2026-09-22 00:23:36 -04:00
parent 53cd4254e4
commit 47cafae01b
75 changed files with 3128 additions and 8623 deletions
+36 -55
View File
@@ -4,85 +4,66 @@ import (
"context"
"fmt"
"os"
"sync"
"github.com/anchore/syft/internal/log"
"github.com/anchore/syft/internal/tmpdir"
)
// workDirName prefixes the directory holding one archive's content and entries, so a scan's leftovers
// are recognizable. Tests that sample what is on disk match on it.
// workDirName prefixes the directory holding one archive's overflow files.
const workDirName = "syft-archive"
// WorkDir is the scratch space one archive writes into, created lazily the first time something needs
// to write - an archive's own bytes spilling out of memory, or its entries spilling into the overflow
// blob.
//
// Eager creation would put one directory on disk per archive opened, whether or not it ever wrote a
// byte; most do not, and a scan walks far more archives than it spills. So the path is asked for at
// the point of writing. A nil *WorkDir has no path and fails the write.
// WorkDir is the scratch directory one archive writes overflow into. It is created on first use, so
// an archive that stays in memory never touches the filesystem.
type WorkDir struct {
mu sync.Mutex
tempDir *tmpdir.TempDir
// create makes the directory and returns it with the func that removes it. Called at most once.
create func() (string, func(), error)
path string
remove func()
err error
done bool
created bool
path string
remove func()
err error
}
// NewWorkDir returns the lazily-created work directory for one archive, rooted under the scan's temp
// root (internal/tmpdir) when the context carries one - so files land where the caller configured and
// are removed together if an archive's own cleanup is missed - otherwise the system temp dir.
// NewWorkDir returns a work directory under the scan's temp root when ctx carries one (see
// internal/tmpdir), otherwise under the system temp directory.
func NewWorkDir(ctx context.Context) *WorkDir {
return &WorkDir{create: func() (string, func(), error) {
if td := tmpdir.FromContext(ctx); td != nil {
dir, cleanup, err := td.NewChild(workDirName) //nolint:gocritic // cleanup is returned, not deferred here
if err != nil {
return "", nil, fmt.Errorf("unable to create temp dir for archive extraction: %w", err)
}
return dir, cleanup, nil
}
dir, err := os.MkdirTemp("", workDirName+"-")
if err != nil {
return "", nil, fmt.Errorf("unable to create temp dir for archive extraction: %w", err)
}
return dir, func() {
if rmErr := os.RemoveAll(dir); rmErr != nil {
log.WithFields("dir", dir, "error", rmErr).Trace("unable to remove archive temp dir")
}
}, nil
}}
return &WorkDir{tempDir: tmpdir.FromContext(ctx)}
}
// Path returns the directory, creating it on the first call. Later calls return the same result,
// including the same failure.
// Path returns the directory, creating it on the first call.
func (w *WorkDir) Path() (string, error) {
if w == nil {
return "", fmt.Errorf("no work directory for archive content")
}
w.mu.Lock()
defer w.mu.Unlock()
if !w.done {
if !w.created {
w.created = true
w.path, w.remove, w.err = w.create()
w.done = true
}
return w.path, w.err
}
// Remove deletes the directory and its contents, and does nothing if it was never created. Safe to
// call more than once.
func (w *WorkDir) Remove() {
if w == nil {
return
func (w *WorkDir) create() (string, func(), error) {
if w.tempDir != nil {
dir, remove, err := w.tempDir.NewChild(workDirName) //nolint:gocritic // the cleanup is returned, not deferred
if err != nil {
return "", nil, fmt.Errorf("unable to create temp dir for archive extraction: %w", err)
}
return dir, remove, nil
}
w.mu.Lock()
defer w.mu.Unlock()
if w.remove == nil {
dir, err := os.MkdirTemp("", workDirName+"-")
if err != nil {
return "", nil, fmt.Errorf("unable to create temp dir for archive extraction: %w", err)
}
return dir, func() {
if err := os.RemoveAll(dir); err != nil {
log.WithFields("dir", dir, "error", err).Trace("unable to remove archive temp dir")
}
}, nil
}
// Remove deletes the directory if it was created. Safe to call more than once.
func (w *WorkDir) Remove() {
if w == nil || w.remove == nil {
return
}
w.remove()