From 6f2b52971d6d1cf912164a75d62bc2128cf3ae45 Mon Sep 17 00:00:00 2001 From: Alex Goodman Date: Fri, 2 Jul 2021 10:18:41 -0400 Subject: [PATCH] directory resolver indexer should report one progressable (#457) Signed-off-by: Alex Goodman --- syft/source/directory_resolver.go | 60 +++++++++++++------------- syft/source/directory_resolver_test.go | 3 +- 2 files changed, 32 insertions(+), 31 deletions(-) diff --git a/syft/source/directory_resolver.go b/syft/source/directory_resolver.go index 73cee6d9f..0f886b22b 100644 --- a/syft/source/directory_resolver.go +++ b/syft/source/directory_resolver.go @@ -62,7 +62,7 @@ func newDirectoryResolver(root string, pathFilters ...pathFilterFn) (*directoryR return &resolver, indexAllRoots(root, resolver.indexTree) } -func (r *directoryResolver) indexTree(root string) ([]string, error) { +func (r *directoryResolver) indexTree(root string, stager *progress.Stage) ([]string, error) { log.Infof("indexing filesystem path=%q", root) var err error root, err = filepath.Abs(root) @@ -70,8 +70,6 @@ func (r *directoryResolver) indexTree(root string) ([]string, error) { return nil, err } var roots []string - stager, prog := indexingProgress(root) - defer prog.SetCompleted() return roots, filepath.Walk(root, func(path string, info os.FileInfo, err error) error { @@ -294,6 +292,35 @@ func isUnixSystemRuntimePath(path string) bool { return internal.HasAnyOfPrefixes(path, unixSystemRuntimePrefixes...) } +func indexAllRoots(root string, indexer func(string, *progress.Stage) ([]string, error)) error { + // why account for multiple roots? To cover cases when there is a symlink that references above the root path, + // in which case we need to additionally index where the link resolves to. it's for this reason why the filetree + // must be relative to the root of the filesystem (and not just relative to the given path). + pathsToIndex := []string{root} + stager, prog := indexingProgress(root) + defer prog.SetCompleted() +loop: + for { + var currentPath string + switch len(pathsToIndex) { + case 0: + break loop + case 1: + currentPath, pathsToIndex = pathsToIndex[0], nil + default: + currentPath, pathsToIndex = pathsToIndex[0], pathsToIndex[1:] + } + + additionalRoots, err := indexer(currentPath, stager) + if err != nil { + return fmt.Errorf("unable to index filesystem path=%q: %w", currentPath, err) + } + pathsToIndex = append(pathsToIndex, additionalRoots...) + } + + return nil +} + func indexingProgress(path string) (*progress.Stage, *progress.Manual) { stage := &progress.Stage{} prog := &progress.Manual{ @@ -314,30 +341,3 @@ func indexingProgress(path string) (*progress.Stage, *progress.Manual) { return stage, prog } - -func indexAllRoots(root string, indexer func(string) ([]string, error)) error { - // why account for multiple roots? To cover cases when there is a symlink that references above the root path, - // in which case we need to additionally index where the link resolves to. it's for this reason why the filetree - // must be relative to the root of the filesystem (and not just relative to the given path). - pathsToIndex := []string{root} -loop: - for { - var currentPath string - switch len(pathsToIndex) { - case 0: - break loop - case 1: - currentPath, pathsToIndex = pathsToIndex[0], nil - default: - currentPath, pathsToIndex = pathsToIndex[0], pathsToIndex[1:] - } - - additionalRoots, err := indexer(currentPath) - if err != nil { - return fmt.Errorf("unable to index filesystem path=%q: %w", currentPath, err) - } - pathsToIndex = append(pathsToIndex, additionalRoots...) - } - - return nil -} diff --git a/syft/source/directory_resolver_test.go b/syft/source/directory_resolver_test.go index 61741f927..b0c3f71b4 100644 --- a/syft/source/directory_resolver_test.go +++ b/syft/source/directory_resolver_test.go @@ -9,6 +9,7 @@ import ( "github.com/anchore/stereoscope/pkg/file" "github.com/stretchr/testify/assert" + "github.com/wagoodman/go-progress" ) func TestDirectoryResolver_FilesByPath(t *testing.T) { @@ -350,7 +351,7 @@ type indexerMock struct { additionalRoots map[string][]string } -func (m *indexerMock) indexer(s string) ([]string, error) { +func (m *indexerMock) indexer(s string, _ *progress.Stage) ([]string, error) { m.observedRoots = append(m.observedRoots, s) return m.additionalRoots[s], nil }