Add upgrade0.13 command (#178)

diff --git a/tfexec/upgrade013.go b/tfexec/upgrade013.go
new file mode 100644
index 0000000..f1f444e
--- /dev/null
+++ b/tfexec/upgrade013.go
@@ -0,0 +1,68 @@
+package tfexec
+
+import (
+	"context"
+	"fmt"
+	"os/exec"
+)
+
+type upgrade013Config struct {
+	dir string
+
+	reattachInfo ReattachInfo
+}
+
+var defaultUpgrade013Options = upgrade013Config{}
+
+// Upgrade013Option represents options used in the Destroy method.
+type Upgrade013Option interface {
+	configureUpgrade013(*upgrade013Config)
+}
+
+func (opt *DirOption) configureUpgrade013(conf *upgrade013Config) {
+	conf.dir = opt.path
+}
+
+func (opt *ReattachOption) configureUpgrade013(conf *upgrade013Config) {
+	conf.reattachInfo = opt.info
+}
+
+// Upgrade013 represents the terraform 0.13upgrade subcommand.
+func (tf *Terraform) Upgrade013(ctx context.Context, opts ...Upgrade013Option) error {
+	cmd, err := tf.upgrade013Cmd(ctx, opts...)
+	if err != nil {
+		return err
+	}
+	return tf.runTerraformCmd(ctx, cmd)
+}
+
+func (tf *Terraform) upgrade013Cmd(ctx context.Context, opts ...Upgrade013Option) (*exec.Cmd, error) {
+	err := tf.compatible(ctx, tf0_13_0, tf0_14_0)
+	if err != nil {
+		return nil, fmt.Errorf("terraform 0.13upgrade is only supported in 0.13 releases: %w", err)
+	}
+
+	c := defaultUpgrade013Options
+
+	for _, o := range opts {
+		o.configureUpgrade013(&c)
+	}
+
+	args := []string{"0.13upgrade", "-no-color", "-yes"}
+
+	// optional positional argument
+	if c.dir != "" {
+		args = append(args, c.dir)
+	}
+
+	mergeEnv := map[string]string{}
+	if c.reattachInfo != nil {
+		reattachStr, err := c.reattachInfo.marshalString()
+		if err != nil {
+			return nil, err
+		}
+		mergeEnv[reattachEnvVar] = reattachStr
+	}
+
+	return tf.buildTerraformCmd(ctx, mergeEnv, args...), nil
+}
diff --git a/tfexec/upgrade013_test.go b/tfexec/upgrade013_test.go
new file mode 100644
index 0000000..7a6220d
--- /dev/null
+++ b/tfexec/upgrade013_test.go
@@ -0,0 +1,85 @@
+package tfexec
+
+import (
+	"context"
+	"errors"
+	"fmt"
+	"testing"
+
+	"github.com/hashicorp/terraform-exec/tfexec/internal/testutil"
+)
+
+func TestUpgrade013(t *testing.T) {
+	td := testTempDir(t)
+
+	t.Run("defaults", func(t *testing.T) {
+		tf, err := NewTerraform(td, tfVersion(t, testutil.Latest013))
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		// empty env, to avoid environ mismatch in testing
+		tf.SetEnv(map[string]string{})
+
+		upgrade013Cmd, err := tf.upgrade013Cmd(context.Background())
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		assertCmd(t, []string{
+			"0.13upgrade",
+			"-no-color",
+			"-yes",
+		}, nil, upgrade013Cmd)
+	})
+
+	t.Run("override all defaults", func(t *testing.T) {
+		tf, err := NewTerraform(td, tfVersion(t, testutil.Latest013))
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		// empty env, to avoid environ mismatch in testing
+		tf.SetEnv(map[string]string{})
+
+		upgrade013Cmd, err := tf.upgrade013Cmd(context.Background(), Dir("upgrade013dir"))
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		assertCmd(t, []string{
+			"0.13upgrade",
+			"-no-color",
+			"-yes",
+			"upgrade013dir",
+		}, nil, upgrade013Cmd)
+	})
+
+	unsupportedVersions := []string{
+		testutil.Latest011,
+		testutil.Latest012,
+		testutil.Latest014,
+		testutil.Latest015,
+	}
+	for _, tfv := range unsupportedVersions {
+		t.Run(fmt.Sprintf("unsupported on %s", tfv), func(t *testing.T) {
+			tf, err := NewTerraform(td, tfVersion(t, tfv))
+			if err != nil {
+				t.Fatal(err)
+			}
+
+			// empty env, to avoid environ mismatch in testing
+			tf.SetEnv(map[string]string{})
+
+			_, err = tf.upgrade013Cmd(context.Background())
+			if err == nil {
+				t.Fatalf("expected unsupported version %s to fail", tfv)
+			}
+
+			var expectedErr *ErrVersionMismatch
+			if !errors.As(err, &expectedErr) {
+				t.Fatalf("error doesn't match: %#v", err)
+			}
+		})
+	}
+}
diff --git a/tfexec/version.go b/tfexec/version.go
index b6496ab..2e842a8 100644
--- a/tfexec/version.go
+++ b/tfexec/version.go
@@ -10,13 +10,14 @@
 	"strings"
 
 	"github.com/hashicorp/go-version"
-	"github.com/hashicorp/terraform-json"
+	tfjson "github.com/hashicorp/terraform-json"
 )
 
 var (
 	tf0_7_7  = version.Must(version.NewVersion("0.7.7"))
 	tf0_12_0 = version.Must(version.NewVersion("0.12.0"))
 	tf0_13_0 = version.Must(version.NewVersion("0.13.0"))
+	tf0_14_0 = version.Must(version.NewVersion("0.14.0"))
 	tf0_15_0 = version.Must(version.NewVersion("0.15.0"))
 )