diff --git a/pkg/plugins/manager/loader/finder/local.go b/pkg/plugins/manager/loader/finder/local.go index a46ab30bc70..9428a4bac2b 100644 --- a/pkg/plugins/manager/loader/finder/local.go +++ b/pkg/plugins/manager/loader/finder/local.go @@ -57,7 +57,11 @@ func (l *Local) Find(ctx context.Context, src plugins.PluginSource) ([]*plugins. continue } - paths, err := l.getAbsPluginJSONPaths(path) + followDistFolder := true + if src.PluginClass(ctx) == plugins.ClassCore { + followDistFolder = false + } + paths, err := l.getAbsPluginJSONPaths(path, followDistFolder) if err != nil { return nil, err } @@ -154,7 +158,7 @@ func (l *Local) readPluginJSON(pluginJSONPath string) (plugins.JSONData, error) return plugin, nil } -func (l *Local) getAbsPluginJSONPaths(path string) ([]string, error) { +func (l *Local) getAbsPluginJSONPaths(path string, followDistFolder bool) ([]string, error) { var pluginJSONPaths []string var err error @@ -163,7 +167,7 @@ func (l *Local) getAbsPluginJSONPaths(path string) ([]string, error) { return []string{}, err } - if err = walk(path, true, true, + if err = walk(path, true, true, followDistFolder, func(currentPath string, fi os.FileInfo, err error) error { if err != nil { if errors.Is(err, os.ErrNotExist) { diff --git a/pkg/plugins/manager/loader/finder/local_test.go b/pkg/plugins/manager/loader/finder/local_test.go index 42cefb50a1a..8b2be26565e 100644 --- a/pkg/plugins/manager/loader/finder/local_test.go +++ b/pkg/plugins/manager/loader/finder/local_test.go @@ -274,7 +274,7 @@ func TestFinder_Find(t *testing.T) { func TestFinder_getAbsPluginJSONPaths(t *testing.T) { t.Run("When scanning a folder that doesn't exists shouldn't return an error", func(t *testing.T) { origWalk := walk - walk = func(path string, followSymlinks, detectSymlinkInfiniteLoop bool, walkFn util.WalkFunc) error { + walk = func(path string, followSymlinks, detectSymlinkInfiniteLoop, followDistFolder bool, walkFn util.WalkFunc) error { return walkFn(path, nil, os.ErrNotExist) } t.Cleanup(func() { @@ -282,14 +282,14 @@ func TestFinder_getAbsPluginJSONPaths(t *testing.T) { }) finder := NewLocalFinder(false) - paths, err := finder.getAbsPluginJSONPaths("test") + paths, err := finder.getAbsPluginJSONPaths("test", true) require.NoError(t, err) require.Empty(t, paths) }) t.Run("When scanning a folder that lacks permission shouldn't return an error", func(t *testing.T) { origWalk := walk - walk = func(path string, followSymlinks, detectSymlinkInfiniteLoop bool, walkFn util.WalkFunc) error { + walk = func(path string, followSymlinks, detectSymlinkInfiniteLoop, followDistFolder bool, walkFn util.WalkFunc) error { return walkFn(path, nil, os.ErrPermission) } t.Cleanup(func() { @@ -297,14 +297,14 @@ func TestFinder_getAbsPluginJSONPaths(t *testing.T) { }) finder := NewLocalFinder(false) - paths, err := finder.getAbsPluginJSONPaths("test") + paths, err := finder.getAbsPluginJSONPaths("test", true) require.NoError(t, err) require.Empty(t, paths) }) t.Run("When scanning a folder that returns a non-handled error should return that error", func(t *testing.T) { origWalk := walk - walk = func(path string, followSymlinks, detectSymlinkInfiniteLoop bool, walkFn util.WalkFunc) error { + walk = func(path string, followSymlinks, detectSymlinkInfiniteLoop, followDistFolder bool, walkFn util.WalkFunc) error { return walkFn(path, nil, errors.New("random error")) } t.Cleanup(func() { @@ -312,10 +312,28 @@ func TestFinder_getAbsPluginJSONPaths(t *testing.T) { }) finder := NewLocalFinder(false) - paths, err := finder.getAbsPluginJSONPaths("test") + paths, err := finder.getAbsPluginJSONPaths("test", true) require.Error(t, err) require.Empty(t, paths) }) + + t.Run("should forward if the dist folder should be evaluated", func(t *testing.T) { + origWalk := walk + walk = func(path string, followSymlinks, detectSymlinkInfiniteLoop, followDistFolder bool, walkFn util.WalkFunc) error { + if followDistFolder { + return walkFn(path, nil, errors.New("unexpected followDistFolder")) + } + return walkFn(path, nil, filepath.SkipDir) + } + t.Cleanup(func() { + walk = origWalk + }) + + finder := NewLocalFinder(false) + paths, err := finder.getAbsPluginJSONPaths("test", false) + require.ErrorIs(t, err, filepath.SkipDir) + require.Empty(t, paths) + }) } var fsComparer = cmp.Comparer(func(fs1 plugins.FS, fs2 plugins.FS) bool { diff --git a/pkg/util/filepath.go b/pkg/util/filepath.go index 1034245ac59..527457aadbb 100644 --- a/pkg/util/filepath.go +++ b/pkg/util/filepath.go @@ -21,7 +21,7 @@ type WalkFunc func(resolvedPath string, info os.FileInfo, err error) error // can detect infinite loops while following sym links. // It solves the issue where your WalkFunc needs a path relative to the symbolic link // (resolving links within walkfunc loses the path to the symbolic link for each traversal). -func Walk(path string, followSymlinks bool, detectSymlinkInfiniteLoop bool, walkFn WalkFunc) error { +func Walk(path string, followSymlinks bool, detectSymlinkInfiniteLoop bool, followDistFolder bool, walkFn WalkFunc) error { info, err := os.Lstat(path) if err != nil { return err @@ -34,7 +34,7 @@ func Walk(path string, followSymlinks bool, detectSymlinkInfiniteLoop bool, walk symlinkPathsFollowed = make(map[string]bool, 8) } } - return walk(path, info, resolvedPath, symlinkPathsFollowed, walkFn) + return walk(path, info, resolvedPath, symlinkPathsFollowed, followDistFolder, walkFn) } // walk walks the path. It is a helper/sibling function to Walk. @@ -43,7 +43,7 @@ func Walk(path string, followSymlinks bool, detectSymlinkInfiniteLoop bool, walk // // If resolvedPath is "", then we are not following symbolic links. // If symlinkPathsFollowed is not nil, then we need to detect infinite loop. -func walk(path string, info os.FileInfo, resolvedPath string, symlinkPathsFollowed map[string]bool, walkFn WalkFunc) error { +func walk(path string, info os.FileInfo, resolvedPath string, symlinkPathsFollowed map[string]bool, followDistFolder bool, walkFn WalkFunc) error { if info == nil { return errors.New("walk: Nil FileInfo passed") } @@ -81,7 +81,7 @@ func walk(path string, info os.FileInfo, resolvedPath string, symlinkPathsFollow if err != nil { return err } - return walk(path, info2, path2, symlinkPathsFollowed, walkFn) + return walk(path, info2, path2, symlinkPathsFollowed, followDistFolder, walkFn) } else if info.IsDir() { list, err := os.ReadDir(path) if err != nil { @@ -102,12 +102,13 @@ func walk(path string, info os.FileInfo, resolvedPath string, symlinkPathsFollow subFiles = append(subFiles, subFile{path: path2, resolvedPath: resolvedPath2, fileInfo: fileInfo}) } - if containsDistFolder(subFiles) { + if containsDistFolder(subFiles) && followDistFolder { err := walk( filepath.Join(path, "dist"), info, filepath.Join(resolvedPath, "dist"), symlinkPathsFollowed, + followDistFolder, walkFn) if err != nil { @@ -115,7 +116,7 @@ func walk(path string, info os.FileInfo, resolvedPath string, symlinkPathsFollow } } else { for _, p := range subFiles { - err = walk(p.path, p.fileInfo, p.resolvedPath, symlinkPathsFollowed, walkFn) + err = walk(p.path, p.fileInfo, p.resolvedPath, symlinkPathsFollowed, followDistFolder, walkFn) if err != nil { return err