diff --git a/command/push.go b/command/push.go index bad5a7ac4..1cced2d91 100644 --- a/command/push.go +++ b/command/push.go @@ -12,7 +12,7 @@ import ( "github.com/hashicorp/atlas-go/v1" "github.com/hashicorp/terraform/backend" "github.com/hashicorp/terraform/config" - "github.com/hashicorp/terraform/terraform" + "github.com/hashicorp/terraform/version" ) type PushCommand struct { @@ -174,7 +174,7 @@ func (c *PushCommand) Run(args []string) int { } } - client.DefaultHeader.Set(terraform.VersionHeader, terraform.Version) + client.DefaultHeader.Set(version.Header, version.Version) if atlasToken != "" { client.Token = atlasToken diff --git a/command/refresh_test.go b/command/refresh_test.go index 5a0cfd357..6106e53c5 100644 --- a/command/refresh_test.go +++ b/command/refresh_test.go @@ -12,6 +12,7 @@ import ( "github.com/hashicorp/terraform/helper/copy" "github.com/hashicorp/terraform/state" "github.com/hashicorp/terraform/terraform" + "github.com/hashicorp/terraform/version" "github.com/mitchellh/cli" ) @@ -353,7 +354,7 @@ func TestRefresh_pastState(t *testing.T) { t.Fatalf("bad:\n\n%s", actual) } - if newState.TFVersion != terraform.Version { + if newState.TFVersion != version.Version { t.Fatalf("bad:\n\n%s", newState.TFVersion) } } diff --git a/state/remote/gcs.go b/state/remote/gcs.go index 8ea682fef..bfd5118cd 100644 --- a/state/remote/gcs.go +++ b/state/remote/gcs.go @@ -12,13 +12,14 @@ import ( "strings" "github.com/hashicorp/terraform/helper/pathorcontents" - "github.com/hashicorp/terraform/terraform" "golang.org/x/net/context" "golang.org/x/oauth2" "golang.org/x/oauth2/google" "golang.org/x/oauth2/jwt" "google.golang.org/api/googleapi" "google.golang.org/api/storage/v1" + + version "github.com/hashicorp/terraform/version" ) // accountFile represents the structure of the credentials JSON @@ -99,7 +100,7 @@ func gcsFactory(conf map[string]string) (Client, error) { return nil, err } } - versionString := terraform.Version + versionString := version.Version userAgent := fmt.Sprintf( "(%s %s) Terraform/%s", runtime.GOOS, runtime.GOARCH, versionString) diff --git a/state/state.go b/state/state.go index 293fc0daa..d9708d1b4 100644 --- a/state/state.go +++ b/state/state.go @@ -15,6 +15,7 @@ import ( uuid "github.com/hashicorp/go-uuid" "github.com/hashicorp/terraform/terraform" + "github.com/hashicorp/terraform/version" ) var rngSource *rand.Rand @@ -158,7 +159,7 @@ func NewLockInfo() *LockInfo { info := &LockInfo{ ID: id, Who: fmt.Sprintf("%s@%s", userName, host), - Version: terraform.Version, + Version: version.Version, Created: time.Now().UTC(), } return info diff --git a/svchost/disco/disco.go b/svchost/disco/disco.go index 3bd9307e0..291842bbe 100644 --- a/svchost/disco/disco.go +++ b/svchost/disco/disco.go @@ -20,7 +20,7 @@ import ( cleanhttp "github.com/hashicorp/go-cleanhttp" "github.com/hashicorp/terraform/svchost" "github.com/hashicorp/terraform/svchost/auth" - "github.com/hashicorp/terraform/terraform" + "github.com/hashicorp/terraform/version" ) const ( @@ -30,7 +30,7 @@ const ( maxDiscoDocBytes = 1 * 1024 * 1024 // 1MB - to prevent abusive services from using loads of our memory ) -var userAgent = fmt.Sprintf("Terraform/%s (service discovery)", terraform.VersionString()) +var userAgent = fmt.Sprintf("Terraform/%s (service discovery)", version.String()) var httpTransport = cleanhttp.DefaultPooledTransport() // overridden during tests, to skip TLS verification // Disco is the main type in this package, which allows discovery on given diff --git a/terraform/context.go b/terraform/context.go index 724ce39ed..ed756c88d 100644 --- a/terraform/context.go +++ b/terraform/context.go @@ -12,6 +12,7 @@ import ( "github.com/hashicorp/hcl" "github.com/hashicorp/terraform/config" "github.com/hashicorp/terraform/config/module" + "github.com/hashicorp/terraform/version" ) // InputMode defines what sort of input will be asked for when Input @@ -154,7 +155,7 @@ func NewContext(opts *ContextOpts) (*Context, error) { // Explicitly reset our state version to our current version so that // any operations we do will write out that our latest version // has run. - state.TFVersion = Version + state.TFVersion = version.Version // Determine parallelism, default to 10. We do this both to limit // CPU pressure but also to have an extra guard against rate throttling @@ -532,7 +533,7 @@ func (c *Context) Plan() (*Plan, error) { State: c.state, Targets: c.targets, - TerraformVersion: VersionString(), + TerraformVersion: version.String(), ProviderSHA256s: c.providerSHA256s, } diff --git a/terraform/context_test.go b/terraform/context_test.go index 3b96d2a63..b7064bef0 100644 --- a/terraform/context_test.go +++ b/terraform/context_test.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/go-version" "github.com/hashicorp/terraform/flatmap" + tfversion "github.com/hashicorp/terraform/version" ) func TestNewContextRequiredVersion(t *testing.T) { @@ -62,9 +63,9 @@ func TestNewContextRequiredVersion(t *testing.T) { for i, tc := range cases { t.Run(fmt.Sprintf("%d-%s", i, tc.Name), func(t *testing.T) { // Reset the version for the tests - old := SemVersion - SemVersion = version.Must(version.NewVersion(tc.Version)) - defer func() { SemVersion = old }() + old := tfversion.SemVer + tfversion.SemVer = version.Must(version.NewVersion(tc.Version)) + defer func() { tfversion.SemVer = old }() name := "context-required-version" if tc.Module != "" { @@ -108,7 +109,7 @@ func TestNewContextState(t *testing.T) { "equal TFVersion": { &ContextOpts{ - State: &State{TFVersion: Version}, + State: &State{TFVersion: tfversion.Version}, }, false, }, @@ -139,7 +140,7 @@ func TestNewContextState(t *testing.T) { } // Version should always be set to our current - if ctx.state.TFVersion != Version { + if ctx.state.TFVersion != tfversion.Version { t.Fatalf("%s: state not set to current version", k) } } diff --git a/terraform/eval_diff.go b/terraform/eval_diff.go index c35f9083f..bbc2b3667 100644 --- a/terraform/eval_diff.go +++ b/terraform/eval_diff.go @@ -6,6 +6,7 @@ import ( "strings" "github.com/hashicorp/terraform/config" + "github.com/hashicorp/terraform/version" ) // EvalCompareDiff is an EvalNode implementation that compares two diffs @@ -60,7 +61,7 @@ func (n *EvalCompareDiff) Eval(ctx EvalContext) (interface{}, error) { "\n"+ "Also include as much context as you can about your config, state, "+ "and the steps you performed to trigger this error.\n", - n.Info.Id, Version, n.Info.Id, reason, one, two) + n.Info.Id, version.Version, n.Info.Id, reason, one, two) } return nil, nil diff --git a/terraform/plan.go b/terraform/plan.go index 8611628e3..0c13cdafd 100644 --- a/terraform/plan.go +++ b/terraform/plan.go @@ -10,6 +10,7 @@ import ( "sync" "github.com/hashicorp/terraform/config/module" + "github.com/hashicorp/terraform/version" ) func init() { @@ -119,7 +120,7 @@ func (p *Plan) contextOpts(base *ContextOpts) (*ContextOpts, error) { log.Println("[WARNING] Plan state and ContextOpts state are not equal") } - thisVersion := VersionString() + thisVersion := version.String() if p.TerraformVersion != "" && p.TerraformVersion != thisVersion { return nil, fmt.Errorf( "plan was created with a different version of Terraform (created with %s, but running %s)", diff --git a/terraform/state.go b/terraform/state.go index 2d58c2dac..89a404847 100644 --- a/terraform/state.go +++ b/terraform/state.go @@ -20,6 +20,8 @@ import ( "github.com/hashicorp/terraform/config" "github.com/mitchellh/copystructure" "github.com/satori/go.uuid" + + tfversion "github.com/hashicorp/terraform/version" ) const ( @@ -664,7 +666,7 @@ func (s *State) FromFutureTerraform() bool { } v := version.Must(version.NewVersion(s.TFVersion)) - return SemVersion.LessThan(v) + return tfversion.SemVer.LessThan(v) } func (s *State) Init() { @@ -1908,7 +1910,7 @@ func ReadState(src io.Reader) (*State, error) { result = v3State default: return nil, fmt.Errorf("Terraform %s does not support state version %d, please update.", - SemVersion.String(), versionIdentifier.Version) + tfversion.SemVer.String(), versionIdentifier.Version) } // If we reached this place we must have a result set @@ -1952,7 +1954,7 @@ func ReadStateV2(jsonBytes []byte) (*State, error) { // version that we don't understand if state.Version > StateVersion { return nil, fmt.Errorf("Terraform %s does not support state version %d, please update.", - SemVersion.String(), state.Version) + tfversion.SemVer.String(), state.Version) } // Make sure the version is semantic @@ -1987,7 +1989,7 @@ func ReadStateV3(jsonBytes []byte) (*State, error) { // version that we don't understand if state.Version > StateVersion { return nil, fmt.Errorf("Terraform %s does not support state version %d, please update.", - SemVersion.String(), state.Version) + tfversion.SemVer.String(), state.Version) } // Make sure the version is semantic diff --git a/terraform/user_agent.go b/terraform/user_agent.go index 700be2ae2..76bdae099 100644 --- a/terraform/user_agent.go +++ b/terraform/user_agent.go @@ -3,6 +3,8 @@ package terraform import ( "fmt" "runtime" + + "github.com/hashicorp/terraform/version" ) // The standard Terraform User-Agent format @@ -10,5 +12,5 @@ const UserAgent = "Terraform %s (%s)" // Generate a UserAgent string func UserAgentString() string { - return fmt.Sprintf(UserAgent, VersionString(), runtime.Version()) + return fmt.Sprintf(UserAgent, version.String(), runtime.Version()) } diff --git a/terraform/version.go b/terraform/version.go index 1034aaddb..ac730154f 100644 --- a/terraform/version.go +++ b/terraform/version.go @@ -1,31 +1,10 @@ package terraform import ( - "fmt" - - "github.com/hashicorp/go-version" + "github.com/hashicorp/terraform/version" ) -// The main version number that is being run at the moment. -const Version = "0.10.8" - -// A pre-release marker for the version. If this is "" (empty string) -// then it means that it is a final release. Otherwise, this is a pre-release -// such as "dev" (in development), "beta", "rc1", etc. -var VersionPrerelease = "dev" - -// SemVersion is an instance of version.Version. This has the secondary -// benefit of verifying during tests and init time that our version is a -// proper semantic version, which should always be the case. -var SemVersion = version.Must(version.NewVersion(Version)) - -// VersionHeader is the header name used to send the current terraform version -// in http requests. -const VersionHeader = "Terraform-Version" - +// TODO: update providers to use the version package directly func VersionString() string { - if VersionPrerelease != "" { - return fmt.Sprintf("%s-%s", Version, VersionPrerelease) - } - return Version + return version.String() } diff --git a/terraform/version_required.go b/terraform/version_required.go index 723ec3963..1f4304578 100644 --- a/terraform/version_required.go +++ b/terraform/version_required.go @@ -6,6 +6,8 @@ import ( "github.com/hashicorp/go-version" "github.com/hashicorp/terraform/config" "github.com/hashicorp/terraform/config/module" + + tfversion "github.com/hashicorp/terraform/version" ) // CheckRequiredVersion verifies that any version requirements specified by @@ -49,7 +51,7 @@ func CheckRequiredVersion(m *module.Tree) error { tf.RequiredVersion, err) } - if !cs.Check(SemVersion) { + if !cs.Check(tfversion.SemVer) { return fmt.Errorf( "The currently running version of Terraform doesn't meet the\n"+ "version requirements explicitly specified by the configuration.\n"+ @@ -62,7 +64,7 @@ func CheckRequiredVersion(m *module.Tree) error { " Current version: %s", module, tf.RequiredVersion, - SemVersion) + tfversion.SemVer) } return nil diff --git a/version.go b/version.go index 4959e0fe2..baefdc2d9 100644 --- a/version.go +++ b/version.go @@ -1,10 +1,12 @@ package main -import "github.com/hashicorp/terraform/terraform" +import ( + "github.com/hashicorp/terraform/version" +) // The git commit that was compiled. This will be filled in by the compiler. var GitCommit string -const Version = terraform.Version +const Version = version.Version -var VersionPrerelease = terraform.VersionPrerelease +var VersionPrerelease = version.Prerelease diff --git a/version/version.go b/version/version.go new file mode 100644 index 000000000..b889bb0b5 --- /dev/null +++ b/version/version.go @@ -0,0 +1,36 @@ +// The version package provides a location to set the release versions for all +// packages to consume, without creating import cycles. +// +// This pckage should not import any other terraform packages. +package version + +import ( + "fmt" + + version "github.com/hashicorp/go-version" +) + +// The main version number that is being run at the moment. +const Version = "0.10.8" + +// A pre-release marker for the version. If this is "" (empty string) +// then it means that it is a final release. Otherwise, this is a pre-release +// such as "dev" (in development), "beta", "rc1", etc. +var Prerelease = "dev" + +// SemVer is an instance of version.Version. This has the secondary +// benefit of verifying during tests and init time that our version is a +// proper semantic version, which should always be the case. +var SemVer = version.Must(version.NewVersion(Version)) + +// Header is the header name used to send the current terraform version +// in http requests. +const Header = "Terraform-Version" + +// String returns the complete version string, including prerelease +func String() string { + if Prerelease != "" { + return fmt.Sprintf("%s-%s", Version, Prerelease) + } + return Version +}