command: Accept a "provider source" from the main package

Following the same approach we use for other CLI-Config-able objects like
the service discovery system, the main package is responsible for
producing a suitable implementation of this interface which the command
package can then use.

When unit testing in the command package we can then substitute mocks as
necessary, following the dependency inversion principle.
This commit is contained in:
Martin Atkins 2020-01-16 17:42:41 -08:00
parent 2672ddba02
commit e9d0822b2a
3 changed files with 17 additions and 2 deletions

View File

@ -23,6 +23,7 @@ import (
"github.com/hashicorp/terraform/configs/configload"
"github.com/hashicorp/terraform/helper/experiment"
"github.com/hashicorp/terraform/helper/wrappedstreams"
"github.com/hashicorp/terraform/internal/getproviders"
"github.com/hashicorp/terraform/providers"
"github.com/hashicorp/terraform/provisioners"
"github.com/hashicorp/terraform/terraform"
@ -74,6 +75,11 @@ type Meta struct {
// into the given directory.
PluginCacheDir string
// ProviderSource allows determining the available versions of a provider
// and determines where a distribution package for a particular
// provider version can be obtained.
ProviderSource getproviders.Source
// OverrideDataDir, if non-empty, overrides the return value of the
// DataDir method for situations where the local .terraform/ directory
// is not suitable, e.g. because of a read-only filesystem.

View File

@ -12,6 +12,7 @@ import (
"github.com/hashicorp/terraform/command"
"github.com/hashicorp/terraform/command/cliconfig"
"github.com/hashicorp/terraform/command/webbrowser"
"github.com/hashicorp/terraform/internal/getproviders"
pluginDiscovery "github.com/hashicorp/terraform/plugin/discovery"
)
@ -37,7 +38,7 @@ const (
OutputPrefix = "o:"
)
func initCommands(config *cliconfig.Config, services *disco.Disco) {
func initCommands(config *cliconfig.Config, services *disco.Disco, providerSrc getproviders.Source) {
var inAutomation bool
if v := os.Getenv(runningInAutomationEnvName); v != "" {
inAutomation = true
@ -67,6 +68,7 @@ func initCommands(config *cliconfig.Config, services *disco.Disco) {
Ui: Ui,
Services: services,
ProviderSource: providerSrc,
BrowserLauncher: webbrowser.NewNativeLauncher(),
RunningInAutomation: inAutomation,

View File

@ -17,6 +17,7 @@ import (
"github.com/hashicorp/terraform/command/format"
"github.com/hashicorp/terraform/helper/logging"
"github.com/hashicorp/terraform/httpclient"
"github.com/hashicorp/terraform/internal/getproviders"
"github.com/hashicorp/terraform/version"
"github.com/mattn/go-colorable"
"github.com/mattn/go-shellwords"
@ -164,12 +165,18 @@ func wrappedMain() int {
services := disco.NewWithCredentialsSource(credsSrc)
services.SetUserAgent(httpclient.TerraformUserAgent(version.String()))
// For the moment, we just always use the registry source to install
// direct from a registry. In future there should be a mechanism to
// configure providers sources from the CLI config, which will then
// change how we construct this object.
providerSrc := getproviders.NewRegistrySource(services)
// Initialize the backends.
backendInit.Init(services)
// In tests, Commands may already be set to provide mock commands
if Commands == nil {
initCommands(config, services)
initCommands(config, services, providerSrc)
}
// Run checkpoint