diff --git a/pkg/helmexec/exec.go b/pkg/helmexec/exec.go index 5c35d1aa..4b061266 100644 --- a/pkg/helmexec/exec.go +++ b/pkg/helmexec/exec.go @@ -114,37 +114,50 @@ type PluginMetadata struct { } func GetPluginVersion(name, pluginsDir string) (*semver.Version, error) { - // Scan pluginsDir for subdirectories containing plugin.yaml - entries, err := os.ReadDir(pluginsDir) - if err != nil { - // If directory doesn't exist, treat as plugin not installed - if os.IsNotExist(err) { - return nil, fmt.Errorf("plugin %s not installed", name) - } - return nil, err - } + pluginDirs := filepath.SplitList(pluginsDir) - for _, entry := range entries { - if !entry.IsDir() { + var firstReadErr error + for _, dir := range pluginDirs { + if dir == "" { continue } - pluginFile := filepath.Join(pluginsDir, entry.Name(), "plugin.yaml") - data, err := os.ReadFile(pluginFile) + entries, err := os.ReadDir(dir) if err != nil { - continue // Skip if plugin.yaml doesn't exist in this directory + if os.IsNotExist(err) { + continue + } + if firstReadErr == nil { + firstReadErr = err + } + continue } - var metadata PluginMetadata - if err := yaml.Unmarshal(data, &metadata); err != nil { - continue // Skip if plugin.yaml is malformed - } + for _, entry := range entries { + if !entry.IsDir() { + continue + } - if metadata.Name == name { - return semver.NewVersion(metadata.Version) + pluginFile := filepath.Join(dir, entry.Name(), "plugin.yaml") + data, err := os.ReadFile(pluginFile) + if err != nil { + continue + } + + var metadata PluginMetadata + if err := yaml.Unmarshal(data, &metadata); err != nil { + continue + } + + if metadata.Name == name { + return semver.NewVersion(metadata.Version) + } } } + if firstReadErr != nil { + return nil, firstReadErr + } return nil, fmt.Errorf("plugin %s not installed", name) } diff --git a/pkg/helmexec/exec_test.go b/pkg/helmexec/exec_test.go index 66ab9890..c468c8f5 100644 --- a/pkg/helmexec/exec_test.go +++ b/pkg/helmexec/exec_test.go @@ -1315,6 +1315,29 @@ func Test_GetPluginVersion(t *testing.T) { } } +func Test_GetPluginVersion_XDGPaths(t *testing.T) { + v3ExpectedVersion := "3.15.0" + v4ExpectedVersion := "4.7.4" + v3PluginDirPath := "../../test/plugins/secrets/3.15.0" + v4PluginDirPath := "../../test/plugins/secrets/4.7.4" + + sep := string(os.PathListSeparator) + xdgPaths := "nonexistent/path" + sep + v3PluginDirPath + sep + "another/nonexistent" + + pluginVersion, err := GetPluginVersion("secrets", xdgPaths) + require.NoError(t, err) + assert.Equal(t, v3ExpectedVersion, pluginVersion.String()) + + xdgPathsV4 := v4PluginDirPath + sep + "nonexistent/path" + pluginVersion, err = GetPluginVersion("secrets", xdgPathsV4) + require.NoError(t, err) + assert.Equal(t, v4ExpectedVersion, pluginVersion.String()) + + _, err = GetPluginVersion("nonexistent-plugin", xdgPaths) + require.Error(t, err) + assert.Contains(t, err.Error(), "plugin nonexistent-plugin not installed") +} + func Test_GetVersion(t *testing.T) { helm2Runner := mockRunner{output: []byte("Client: v2.16.1+ge13bc94\n")} helm, err := New("helm", HelmExecOptions{}, NewLogger(os.Stdout, "info"), "", "dev", &helm2Runner)