Skip to content

Commit

Permalink
Add well known error for required_version issues
Browse files Browse the repository at this point in the history
  • Loading branch information
paultyng committed Aug 31, 2020
1 parent 05e87e9 commit e7016f3
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 2 deletions.
2 changes: 1 addition & 1 deletion tfexec/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ func (tf *Terraform) runTerraformCmd(cmd *exec.Cmd) error {

err := cmd.Run()
if err != nil {
return parseError(err, errBuf.String())
return tf.parseError(err, errBuf.String())
}
return nil
}
Expand Down
43 changes: 42 additions & 1 deletion tfexec/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,42 @@ var (
noConfigErrRegexp = regexp.MustCompile(`Error: No configuration files`)

workspaceDoesNotExistRegexp = regexp.MustCompile(`Workspace "(.+)" doesn't exist.`)

tfVersionMismatchErrRegexp = regexp.MustCompile(`Error: The currently running version of Terraform doesn't meet the|Error: Unsupported Terraform Core version`)
tfVersionMismatchConstraintRegexp = regexp.MustCompile(`required_version = "(.+)"|Required version: (.+)\b`)
)

func parseError(err error, stderr string) error {
func (tf *Terraform) parseError(err error, stderr string) error {
if _, ok := err.(*exec.ExitError); !ok {
return err
}

switch {
case tfVersionMismatchErrRegexp.MatchString(stderr):
constraint := ""
constraints := tfVersionMismatchConstraintRegexp.FindStringSubmatch(stderr)
for i := 1; i < len(constraints); i++ {
constraint = strings.TrimSpace(constraints[i])
if constraint != "" {
break
}
}

if constraint == "" {
// hardcode a value here for weird cases (incl. 0.12)
constraint = "unknown"
}

// only set this if it happened to be cached already
ver := ""
if tf != nil && tf.execVersion != nil {
ver = tf.execVersion.String()
}

return &ErrTFVersionMismatch{
Constraint: constraint,
TFVersion: ver,
}
case missingVarErrRegexp.MatchString(stderr):
name := ""
names := missingVarNameRegexp.FindStringSubmatch(stderr)
Expand Down Expand Up @@ -63,6 +91,19 @@ func (e *ErrNoSuitableBinary) Error() string {
return fmt.Sprintf("no suitable terraform binary could be found: %s", e.err.Error())
}

// ErrTFVersionMismatch is returned when the running Terraform version is not compatible with the
// value specified for required_version in the terraform block.
type ErrTFVersionMismatch struct {
TFVersion string

// Constraint is not returned in the error messaging on 0.12
Constraint string
}

func (e *ErrTFVersionMismatch) Error() string {
return "terraform core version not supported by configuration"
}

// ErrVersionMismatch is returned when the detected Terraform version is not compatible with the
// command or flags being used in this invocation.
type ErrVersionMismatch struct {
Expand Down
29 changes: 29 additions & 0 deletions tfexec/internal/e2etest/errors_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,32 @@ func TestMissingVar(t *testing.T) {
}
})
}

func TestTFVersionMismatch(t *testing.T) {
runTest(t, "tf99", func(t *testing.T, tfv *version.Version, tf *tfexec.Terraform) {
// force cache version for error messaging
_, _, err := tf.Version(context.Background(), true)
if err != nil {
t.Fatal(err)
}

err = tf.Init(context.Background())
if err == nil {
t.Fatal("expected error, but didn't find one")
}

var e *tfexec.ErrTFVersionMismatch
if !errors.As(err, &e) {
t.Fatalf("expected ErrTFVersionMismatch, got %T, %s", err, err)
}

// in 0.12, we just return "unknown" as the specifics are not included in the error messaging
if e.Constraint != "unknown" && e.Constraint != ">99.0.0" {
t.Fatalf("unexpected constraint %q", e.Constraint)
}

if e.TFVersion != tfv.String() {
t.Fatalf("expected %q, got %q", tfv.String(), e.TFVersion)
}
})
}
3 changes: 3 additions & 0 deletions tfexec/internal/e2etest/testdata/tf99/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
terraform {
required_version = ">99.0.0"
}

0 comments on commit e7016f3

Please sign in to comment.