add execVersion, improve env handling
diff --git a/tfexec/terraform.go b/tfexec/terraform.go
index 87d0479..4eb1123 100644
--- a/tfexec/terraform.go
+++ b/tfexec/terraform.go
@@ -14,15 +14,16 @@
 )
 
 type Terraform struct {
-	execPath   string
-	workingDir string
-	Env        []string
+	execPath    string
+	workingDir  string
+	execVersion string
+	env         []string
 }
 
 // NewTerraform returns a Terraform struct with default values for all fields.
 // If a blank execPath is supplied, NewTerraform will attempt to locate an
 // appropriate binary on the system PATH.
-func NewTerraform(workingDir string, execPath string) (*Terraform, error) {
+func NewTerraform(workingDir string, execPath string, env map[string]string) (*Terraform, error) {
 	var err error
 	if workingDir == "" {
 		return nil, fmt.Errorf("Terraform cannot be initialised with empty workdir")
@@ -37,16 +38,65 @@
 		if err != nil {
 			return nil, err
 		}
+
 	}
-	// TODO for maximum helpfulness, check execPath looks like a terraform binary
-
-	passthroughEnv := os.Environ()
-
-	return &Terraform{
+	tf := Terraform{
 		execPath:   execPath,
 		workingDir: workingDir,
-		Env:        passthroughEnv,
-	}, nil
+		env:        getTerraformEnv(env),
+	}
+
+	execVersion, err := tf.version()
+	if err != nil {
+		return nil, fmt.Errorf("error running 'terraform version': %s", err)
+	}
+
+	tf.execVersion = execVersion
+
+	return &tf, nil
+}
+
+func getTerraformEnv(env map[string]string) []string {
+	var ret []string
+
+	if env == nil {
+		for _, e := range os.Environ() {
+			ret = append(ret, e)
+		}
+	}
+
+	// always propagate CHECKPOINT_DISABLE env var unless it is
+	// explicitly overridden
+	c := os.Getenv("CHECKPOINT_DISABLE")
+	if c != "" {
+		ret = append(ret, "CHECKPOINT_DISABLE="+c)
+	}
+
+	for k, v := range env {
+		ret = append(ret, k+"="+v)
+	}
+
+	return ret
+}
+
+func (tf *Terraform) version() (string, error) {
+	versionCmd := tf.buildTerraformCmd(context.Background(), "version")
+	var errBuf strings.Builder
+	var outBuf bytes.Buffer
+	versionCmd.Stderr = &errBuf
+	versionCmd.Stdout = &outBuf
+
+	err := versionCmd.Run()
+	if err != nil {
+		fmt.Println(errBuf.String())
+		return "", fmt.Errorf("%s, %s", err, errBuf.String())
+	}
+
+	// fmt.Println(outBuf.String())
+
+	// parse it
+
+	return outBuf.String(), nil
 }
 
 type initConfig struct {
diff --git a/tfexec/terraform_cmd.go b/tfexec/terraform_cmd.go
index ee6e005..d42e28e 100644
--- a/tfexec/terraform_cmd.go
+++ b/tfexec/terraform_cmd.go
@@ -3,28 +3,21 @@
 import (
 	"context"
 	"fmt"
-	"os"
 	"os/exec"
 	"strconv"
 )
 
-func (t *Terraform) buildTerraformCmd(ctx context.Context, args ...string) *exec.Cmd {
-	var env []string
-	for _, e := range os.Environ() {
-		env = append(env, e)
-	}
+func (tf *Terraform) buildTerraformCmd(ctx context.Context, args ...string) *exec.Cmd {
+	env := append(tf.env, "TF_LOG=") // so logging can't pollute our stderr output
 
-	env = append(env, "TF_LOG=") // so logging can't pollute our stderr output
-	env = append(env, "TF_INPUT=0")
-
-	cmd := exec.CommandContext(ctx, t.execPath, args...)
-	cmd.Env = t.Env
-	cmd.Dir = t.workingDir
+	cmd := exec.CommandContext(ctx, tf.execPath, args...)
+	cmd.Env = env
+	cmd.Dir = tf.workingDir
 
 	return cmd
 }
 
-func (t *Terraform) InitCmd(ctx context.Context, opts ...InitOption) *exec.Cmd {
+func (tf *Terraform) InitCmd(ctx context.Context, opts ...InitOption) *exec.Cmd {
 	c := defaultInitOptions
 
 	for _, o := range opts {
@@ -66,10 +59,10 @@
 		}
 	}
 
-	return t.buildTerraformCmd(ctx, args...)
+	return tf.buildTerraformCmd(ctx, args...)
 }
 
-func (t *Terraform) ApplyCmd(ctx context.Context, opts ...ApplyOption) *exec.Cmd {
+func (tf *Terraform) ApplyCmd(ctx context.Context, opts ...ApplyOption) *exec.Cmd {
 	c := defaultApplyOptions
 
 	for _, o := range opts {
@@ -117,10 +110,10 @@
 		args = append(args, c.dirOrPlan)
 	}
 
-	return t.buildTerraformCmd(ctx, args...)
+	return tf.buildTerraformCmd(ctx, args...)
 }
 
-func (t *Terraform) DestroyCmd(ctx context.Context, opts ...DestroyOption) *exec.Cmd {
+func (tf *Terraform) DestroyCmd(ctx context.Context, opts ...DestroyOption) *exec.Cmd {
 	c := defaultDestroyOptions
 
 	for _, o := range opts {
@@ -163,7 +156,7 @@
 		}
 	}
 
-	return t.buildTerraformCmd(ctx, args...)
+	return tf.buildTerraformCmd(ctx, args...)
 }
 
 func (tf *Terraform) PlanCmd(ctx context.Context, opts ...PlanOption) *exec.Cmd {
@@ -285,9 +278,9 @@
 	return tf.buildTerraformCmd(ctx, allArgs...)
 }
 
-func (t *Terraform) ProvidersSchemaCmd(ctx context.Context, args ...string) *exec.Cmd {
+func (tf *Terraform) ProvidersSchemaCmd(ctx context.Context, args ...string) *exec.Cmd {
 	allArgs := []string{"providers", "schema", "-json", "-no-color"}
 	allArgs = append(allArgs, args...)
 
-	return t.buildTerraformCmd(ctx, allArgs...)
+	return tf.buildTerraformCmd(ctx, allArgs...)
 }
diff --git a/tfexec/terraform_test.go b/tfexec/terraform_test.go
index c13b1fd..45d371e 100644
--- a/tfexec/terraform_test.go
+++ b/tfexec/terraform_test.go
@@ -20,7 +20,10 @@
 const testTerraformStateFileName = "terraform.tfstate"
 
 func TestInitCmd(t *testing.T) {
-	tf, err := NewTerraform("/dev/null", "")
+	td := testTempDir(t)
+	defer os.RemoveAll(td)
+
+	tf, err := NewTerraform(td, "", nil)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -49,7 +52,10 @@
 }
 
 func TestPlanCmd(t *testing.T) {
-	tf, err := NewTerraform("/dev/null", "")
+	td := testTempDir(t)
+	defer os.RemoveAll(td)
+
+	tf, err := NewTerraform(td, "", nil)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -78,7 +84,10 @@
 }
 
 func TestApplyCmd(t *testing.T) {
-	tf, err := NewTerraform("/dev/null", "")
+	td := testTempDir(t)
+	defer os.RemoveAll(td)
+
+	tf, err := NewTerraform(td, "", nil)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -95,7 +104,10 @@
 }
 
 func TestDestroyCmd(t *testing.T) {
-	tf, err := NewTerraform("/dev/null", "")
+	td := testTempDir(t)
+	defer os.RemoveAll(td)
+
+	tf, err := NewTerraform(td, "", nil)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -124,7 +136,10 @@
 }
 
 func TestImportCmd(t *testing.T) {
-	tf, err := NewTerraform("/dev/null", "")
+	td := testTempDir(t)
+	defer os.RemoveAll(td)
+
+	tf, err := NewTerraform(td, "", nil)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -162,7 +177,10 @@
 }
 
 func TestOutputCmd(t *testing.T) {
-	tf, err := NewTerraform("/dev/null", "")
+	td := testTempDir(t)
+	defer os.RemoveAll(td)
+
+	tf, err := NewTerraform(td, "", nil)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -192,7 +210,10 @@
 }
 
 func TestStateShowCmd(t *testing.T) {
-	tf, err := NewTerraform("/dev/null", "")
+	td := testTempDir(t)
+	defer os.RemoveAll(td)
+
+	tf, err := NewTerraform(td, "", nil)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -210,7 +231,10 @@
 }
 
 func TestProvidersSchemaCmd(t *testing.T) {
-	tf, err := NewTerraform("/dev/null", "")
+	td := testTempDir(t)
+	defer os.RemoveAll(td)
+
+	tf, err := NewTerraform(td, "", nil)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -231,7 +255,7 @@
 	td := testTempDir(t)
 	defer os.RemoveAll(td)
 
-	tf, err := NewTerraform(td, "")
+	tf, err := NewTerraform(td, "", nil)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -285,7 +309,7 @@
 	td := testTempDir(t)
 	defer os.RemoveAll(td)
 
-	tf, err := NewTerraform(td, "")
+	tf, err := NewTerraform(td, "", nil)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -313,7 +337,7 @@
 	td := testTempDir(t)
 	defer os.RemoveAll(td)
 
-	tf, err := NewTerraform(td, "")
+	tf, err := NewTerraform(td, "", nil)
 	if err != nil {
 		t.Fatal(err)
 	}