From bcd395e6bdfd255183cacf9c7b2ebe439374f602 Mon Sep 17 00:00:00 2001 From: Martin Atkins Date: Thu, 13 Apr 2017 14:13:02 -0700 Subject: [PATCH] plugin/discovery: Allow overriding the paths of certain plugin names The .terraformrc file allows the user to override the executable location for certain plugins. This mechanism allows us to retain that behavior for a deprecation period by treating such executables as an unversioned plugin for the given name and excluding all other candidates for that name, thus ensuring that the override will "win". Users must eventually transition away from using this mechanism and use vendor directories instead, because these unversioned overrides will never match for a provider referenced with non-zero version constraints. --- plugin/discovery/meta_set.go | 30 +++++++++++++ plugin/discovery/meta_set_test.go | 74 +++++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+) diff --git a/plugin/discovery/meta_set.go b/plugin/discovery/meta_set.go index 72c0019b3d..37220f5157 100644 --- a/plugin/discovery/meta_set.go +++ b/plugin/discovery/meta_set.go @@ -149,3 +149,33 @@ func (s PluginMetaSet) ConstrainVersions(reqd map[string]semver.Range) map[strin } return ret } + +// OverridePaths returns a new set where any existing plugins with the given +// names are removed and replaced with the single path given in the map. +// +// This is here only to continue to support the legacy way of overriding +// plugin binaries in the .terraformrc file. It treats all given plugins +// as pre-versioning (version 0.0.0). This mechanism will eventually be +// phased out, with vendor directories being the intended replacement. +func (s PluginMetaSet) OverridePaths(paths map[string]string) PluginMetaSet { + ret := make(PluginMetaSet) + for p := range s { + if _, ok := paths[p.Name]; ok { + // Skip plugins that we're overridding + continue + } + + ret.Add(p) + } + + // Now add the metadata for overriding plugins + for name, path := range paths { + ret.Add(PluginMeta{ + Name: name, + Version: "0.0.0", + Path: path, + }) + } + + return ret +} diff --git a/plugin/discovery/meta_set_test.go b/plugin/discovery/meta_set_test.go index 15fc7bae5b..21aaed29de 100644 --- a/plugin/discovery/meta_set_test.go +++ b/plugin/discovery/meta_set_test.go @@ -343,3 +343,77 @@ func TestPluginMetaSetConstrainVersions(t *testing.T) { } } + +func TestPluginMetaSetOverridePaths(t *testing.T) { + + metas := []PluginMeta{ + { + Name: "foo", + Version: "1.0.0", + Path: "test-foo-1", + }, + { + Name: "foo", + Version: "2.0.0", + Path: "test-foo-2", + }, + { + Name: "foo", + Version: "3.0.0", + Path: "test-foo-3", + }, + { + Name: "bar", + Version: "0.0.5", + Path: "test-bar-5", + }, + { + Name: "bar", + Version: "0.0.6", + Path: "test-bar-6", + }, + { + Name: "baz", + Version: "0.0.1", + Path: "test-bar", + }, + } + s := make(PluginMetaSet) + + for _, p := range metas { + s.Add(p) + } + + ns := s.OverridePaths(map[string]string{ + "foo": "override-foo", + "fun": "override-fun", + }) + + if got, want := ns.Count(), 5; got != want { + t.Errorf("got %d metas; want %d", got, want) + } + + if !ns.Has(metas[3]) { + t.Errorf("new set is missing %#v", metas[3]) + } + if !ns.Has(metas[4]) { + t.Errorf("new set is missing %#v", metas[4]) + } + if !ns.Has(metas[5]) { + t.Errorf("new set is missing %#v", metas[5]) + } + if !ns.Has(PluginMeta{ + Name: "foo", + Version: "0.0.0", + Path: "override-foo", + }) { + t.Errorf("new set is missing 'foo' override") + } + if !ns.Has(PluginMeta{ + Name: "fun", + Version: "0.0.0", + Path: "override-fun", + }) { + t.Errorf("new set is missing 'fun' override") + } +}