Skip to content

Commit

Permalink
tfexec: Initial support for Terraform -chdir global option
Browse files Browse the repository at this point in the history
Reference: #99
  • Loading branch information
bflad committed Feb 2, 2021
1 parent d34849f commit 2ef0e98
Show file tree
Hide file tree
Showing 28 changed files with 944 additions and 67 deletions.
31 changes: 30 additions & 1 deletion tfexec/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@ import (

type applyConfig struct {
backup string
chdir string
dirOrPlan string
lock bool

// LockTimeout must be a string with time unit, e.g. '10s'
lockTimeout string
parallelism int
planArg string
reattachInfo ReattachInfo
refresh bool
state string
Expand Down Expand Up @@ -77,10 +79,18 @@ func (opt *VarOption) configureApply(conf *applyConfig) {
conf.vars = append(conf.vars, opt.assignment)
}

func (opt *ChdirOption) configureApply(conf *applyConfig) {
conf.chdir = opt.path
}

func (opt *DirOrPlanOption) configureApply(conf *applyConfig) {
conf.dirOrPlan = opt.path
}

func (opt *PlanArgOption) configureApply(conf *applyConfig) {
conf.planArg = opt.path
}

func (opt *ReattachOption) configureApply(conf *applyConfig) {
conf.reattachInfo = opt.info
}
Expand All @@ -98,10 +108,25 @@ func (tf *Terraform) applyCmd(ctx context.Context, opts ...ApplyOption) (*exec.C
c := defaultApplyOptions

for _, o := range opts {
switch o.(type) {
case *ChdirOption:
err := tf.compatible(ctx, tf0_14_0, nil)
if err != nil {
return nil, fmt.Errorf("-chdir was added in Terraform 0.14: %w", err)
}
}

o.configureApply(&c)
}

args := []string{"apply", "-no-color", "-auto-approve", "-input=false"}
var args []string

// global opts
if c.chdir != "" {
args = append(args, "-chdir="+c.chdir)
}

args = append(args, []string{"apply", "-no-color", "-auto-approve", "-input=false"}...)

// string opts: only pass if set
if c.backup != "" {
Expand Down Expand Up @@ -142,6 +167,10 @@ func (tf *Terraform) applyCmd(ctx context.Context, opts ...ApplyOption) (*exec.C
args = append(args, c.dirOrPlan)
}

if c.planArg != "" {
args = append(args, c.planArg)
}

mergeEnv := map[string]string{}
if c.reattachInfo != nil {
reattachStr, err := c.reattachInfo.marshalString()
Expand Down
44 changes: 43 additions & 1 deletion tfexec/apply_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
func TestApplyCmd(t *testing.T) {
td := testTempDir(t)

tf, err := NewTerraform(td, tfVersion(t, testutil.Latest012))
tf, err := NewTerraform(td, tfVersion(t, testutil.Latest014))
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -60,4 +60,46 @@ func TestApplyCmd(t *testing.T) {
"testfile",
}, nil, applyCmd)
})

t.Run("chdir", func(t *testing.T) {
applyCmd, err := tf.applyCmd(context.Background(),
Chdir("testpath"),
)

if err != nil {
t.Fatal(err)
}

assertCmd(t, []string{
"-chdir=testpath",
"apply",
"-no-color",
"-auto-approve",
"-input=false",
"-lock=true",
"-parallelism=10",
"-refresh=true",
}, nil, applyCmd)
})

t.Run("plan", func(t *testing.T) {
applyCmd, err := tf.applyCmd(context.Background(),
PlanArg("testplan"),
)

if err != nil {
t.Fatal(err)
}

assertCmd(t, []string{
"apply",
"-no-color",
"-auto-approve",
"-input=false",
"-lock=true",
"-parallelism=10",
"-refresh=true",
"testplan",
}, nil, applyCmd)
})
}
22 changes: 21 additions & 1 deletion tfexec/destroy.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

type destroyConfig struct {
backup string
chdir string
dir string
lock bool

Expand Down Expand Up @@ -38,6 +39,10 @@ type DestroyOption interface {
configureDestroy(*destroyConfig)
}

func (opt *ChdirOption) configureDestroy(conf *destroyConfig) {
conf.chdir = opt.path
}

func (opt *DirOption) configureDestroy(conf *destroyConfig) {
conf.dir = opt.path
}
Expand Down Expand Up @@ -99,10 +104,25 @@ func (tf *Terraform) destroyCmd(ctx context.Context, opts ...DestroyOption) (*ex
c := defaultDestroyOptions

for _, o := range opts {
switch o.(type) {
case *ChdirOption:
err := tf.compatible(ctx, tf0_14_0, nil)
if err != nil {
return nil, fmt.Errorf("-chdir was added in Terraform 0.14: %w", err)
}
}

o.configureDestroy(&c)
}

args := []string{"destroy", "-no-color", "-auto-approve", "-input=false"}
var args []string

// global opts
if c.chdir != "" {
args = append(args, "-chdir="+c.chdir)
}

args = append(args, []string{"destroy", "-no-color", "-auto-approve", "-input=false"}...)

// string opts: only pass if set
if c.backup != "" {
Expand Down
24 changes: 23 additions & 1 deletion tfexec/destroy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
func TestDestroyCmd(t *testing.T) {
td := testTempDir(t)

tf, err := NewTerraform(td, tfVersion(t, testutil.Latest012))
tf, err := NewTerraform(td, tfVersion(t, testutil.Latest014))
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -62,4 +62,26 @@ func TestDestroyCmd(t *testing.T) {
"destroydir",
}, nil, destroyCmd)
})

t.Run("chdir", func(t *testing.T) {
destroyCmd, err := tf.destroyCmd(context.Background(),
Chdir("testpath"),
)

if err != nil {
t.Fatal(err)
}

assertCmd(t, []string{
"-chdir=testpath",
"destroy",
"-no-color",
"-auto-approve",
"-input=false",
"-lock-timeout=0s",
"-lock=true",
"-parallelism=10",
"-refresh=true",
}, nil, destroyCmd)
})
}
21 changes: 18 additions & 3 deletions tfexec/fmt.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ import (
)

type formatConfig struct {
recursive bool
chdir string
dir string
recursive bool
}

var defaultFormatConfig = formatConfig{
Expand All @@ -23,14 +24,18 @@ type FormatOption interface {
configureFormat(*formatConfig)
}

func (opt *RecursiveOption) configureFormat(conf *formatConfig) {
conf.recursive = opt.recursive
func (opt *ChdirOption) configureFormat(conf *formatConfig) {
conf.chdir = opt.path
}

func (opt *DirOption) configureFormat(conf *formatConfig) {
conf.dir = opt.path
}

func (opt *RecursiveOption) configureFormat(conf *formatConfig) {
conf.recursive = opt.recursive
}

// FormatString formats a passed string, given a path to Terraform.
func FormatString(ctx context.Context, execPath string, content string) (string, error) {
tf, err := NewTerraform(filepath.Dir(execPath), execPath)
Expand Down Expand Up @@ -136,6 +141,11 @@ func (tf *Terraform) formatCmd(ctx context.Context, args []string, opts ...Forma

for _, o := range opts {
switch o.(type) {
case *ChdirOption:
err := tf.compatible(ctx, tf0_14_0, nil)
if err != nil {
return nil, fmt.Errorf("-chdir was added in Terraform 0.14: %w", err)
}
case *RecursiveOption:
err := tf.compatible(ctx, tf0_12_0, nil)
if err != nil {
Expand All @@ -148,6 +158,11 @@ func (tf *Terraform) formatCmd(ctx context.Context, args []string, opts ...Forma

args = append([]string{"fmt", "-no-color"}, args...)

// global opts
if c.chdir != "" {
args = append([]string{"-chdir=" + c.chdir}, args...)
}

if c.recursive {
args = append(args, "-recursive")
}
Expand Down
32 changes: 30 additions & 2 deletions tfexec/fmt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,49 @@ import (
"context"
"errors"
"testing"

"github.com/hashicorp/terraform-exec/tfexec/internal/testutil"
)

func TestFormat(t *testing.T) {
td := testTempDir(t)

tf, err := NewTerraform(td, tfVersion(t, "0.7.6"))
tf, err := NewTerraform(td, tfVersion(t, testutil.Latest014))
if err != nil {
t.Fatal(err)
}

// empty env, to avoid environ mismatch in testing
tf.SetEnv(map[string]string{})

t.Run("chdir", func(t *testing.T) {
fmtCmd, err := tf.formatCmd(context.Background(),
[]string{"testfile"},
Chdir("testpath"),
)

if err != nil {
t.Fatal(err)
}

assertCmd(t, []string{
"-chdir=testpath",
"fmt",
"-no-color",
"testfile",
}, nil, fmtCmd)
})

t.Run("too old version", func(t *testing.T) {
_, err := tf.formatCmd(context.Background(), []string{})
tf, err := NewTerraform(td, tfVersion(t, "0.7.6"))
if err != nil {
t.Fatal(err)
}

// empty env, to avoid environ mismatch in testing
tf.SetEnv(map[string]string{})

_, err = tf.formatCmd(context.Background(), []string{})
if err == nil {
t.Fatal("expected old version to fail")
}
Expand Down
23 changes: 22 additions & 1 deletion tfexec/import.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package tfexec

import (
"context"
"fmt"
"os/exec"
"strconv"
)
Expand All @@ -10,6 +11,7 @@ type importConfig struct {
addr string
id string
backup string
chdir string
config string
allowMissingConfig bool
lock bool
Expand All @@ -36,6 +38,10 @@ func (opt *BackupOption) configureImport(conf *importConfig) {
conf.backup = opt.path
}

func (opt *ChdirOption) configureImport(conf *importConfig) {
conf.chdir = opt.path
}

func (opt *ConfigOption) configureImport(conf *importConfig) {
conf.config = opt.path
}
Expand Down Expand Up @@ -85,10 +91,25 @@ func (tf *Terraform) importCmd(ctx context.Context, address, id string, opts ...
c := defaultImportOptions

for _, o := range opts {
switch o.(type) {
case *ChdirOption:
err := tf.compatible(ctx, tf0_14_0, nil)
if err != nil {
return nil, fmt.Errorf("-chdir was added in Terraform 0.14: %w", err)
}
}

o.configureImport(&c)
}

args := []string{"import", "-no-color", "-input=false"}
var args []string

// global opts
if c.chdir != "" {
args = append(args, "-chdir="+c.chdir)
}

args = append(args, []string{"import", "-no-color", "-input=false"}...)

// string opts: only pass if set
if c.backup != "" {
Expand Down

0 comments on commit 2ef0e98

Please sign in to comment.