diff --git a/plugin/discovery/find.go b/plugin/discovery/find.go index 539b9358c5..e42bb49f68 100644 --- a/plugin/discovery/find.go +++ b/plugin/discovery/find.go @@ -4,11 +4,14 @@ import ( "io/ioutil" "log" "path/filepath" + "regexp" "runtime" "strings" ) -const machineName = runtime.GOOS + "_" + runtime.GOARCH +// Store the machine name for excluding legacy plugins in new-style directories. +// This is a var to override in testing +var machineName = runtime.GOOS + "_" + runtime.GOARCH // FindPlugins looks in the given directories for files whose filenames // suggest that they are plugins of the given kind (e.g. "provider") and @@ -41,66 +44,53 @@ func FindPluginPaths(kind string, dirs []string) []string { // This is just a thin wrapper around findPluginPaths so that we can // use the latter in tests with a fake machineName so we can use our // test fixtures. - return findPluginPaths(kind, machineName, dirs) + return findPluginPaths(kind, dirs) } -func findPluginPaths(kind string, machineName string, dirs []string) []string { +func findPluginPaths(kind string, dirs []string) []string { + hasMachineSuffix := regexp.MustCompile(machineName + "/?").MatchString + prefix := "terraform-" + kind + "-" ret := make([]string, 0, len(dirs)) - for _, baseDir := range dirs { - baseItems, err := ioutil.ReadDir(baseDir) + for _, dir := range dirs { + items, err := ioutil.ReadDir(dir) if err != nil { // Ignore missing dirs, non-dirs, etc continue } - log.Printf("[DEBUG] checking for plugins in %q", baseDir) + log.Printf("[DEBUG] checking for plugins in %q", dir) + + isMachineDir := hasMachineSuffix(dir) - for _, item := range baseItems { + for _, item := range items { fullName := item.Name() - if fullName == machineName && item.Mode().IsDir() { - // Current-style $GOOS-$GOARCH directory prefix - machineDir := filepath.Join(baseDir, machineName) - machineItems, err := ioutil.ReadDir(machineDir) + if !strings.HasPrefix(fullName, prefix) { + log.Printf("[DEBUG] skipping %q, not a plugin", fullName) + continue + } + + // New-style paths must have a version segment in filename + if strings.Contains(strings.ToLower(fullName), "_v") { + absPath, err := filepath.Abs(filepath.Join(dir, fullName)) if err != nil { + log.Printf("[ERROR] plugin filepath error: %s", err) continue } - log.Printf("[DEBUG] checking for plugins in %q", machineDir) - - for _, item := range machineItems { - fullName := item.Name() - - if !strings.HasPrefix(fullName, prefix) { - continue - } - - // New-style paths must have a version segment in filename - if !strings.Contains(strings.ToLower(fullName), "_v") { - continue - } - - absPath, err := filepath.Abs(filepath.Join(machineDir, fullName)) - if err != nil { - continue - } - - log.Printf("[DEBUG] found plugin %q", fullName) - - ret = append(ret, filepath.Clean(absPath)) - } - + log.Printf("[DEBUG] found plugin %q", fullName) + ret = append(ret, filepath.Clean(absPath)) continue } - // FIXME: we pass in GOOS_GOARCH paths directly, so these may not be "legacy" - if strings.HasPrefix(fullName, prefix) { + if !isMachineDir { // Legacy style with files directly in the base directory - absPath, err := filepath.Abs(filepath.Join(baseDir, fullName)) + absPath, err := filepath.Abs(filepath.Join(dir, fullName)) if err != nil { + log.Printf("[ERROR] plugin filepath error: %s", err) continue } diff --git a/plugin/discovery/find_test.go b/plugin/discovery/find_test.go index a788882bb0..58e2946d18 100644 --- a/plugin/discovery/find_test.go +++ b/plugin/discovery/find_test.go @@ -7,12 +7,15 @@ import ( "testing" ) +func init() { + machineName = "mockos_mockarch" +} + func TestFindPluginPaths(t *testing.T) { got := findPluginPaths( "foo", - "mockos_mockarch", []string{ - "test-fixtures/current-style-plugins", + "test-fixtures/current-style-plugins/mockos_mockarch", "test-fixtures/legacy-style-plugins", "test-fixtures/non-existent", "test-fixtures/not-a-dir",