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.
This commit is contained in:
Martin Atkins 2017-04-13 14:13:02 -07:00
parent 551bc9c4a4
commit bcd395e6bd
2 changed files with 104 additions and 0 deletions

View File

@ -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
}

View File

@ -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")
}
}