-
Notifications
You must be signed in to change notification settings - Fork 116
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add supports for cmd: terraform add (#209)
* add supports for cmd: terraform add * refine per review comments * tiny fix * use strings.Builder as writer as we returns string
- Loading branch information
Showing
5 changed files
with
183 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
package tfexec | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"os/exec" | ||
"strconv" | ||
"strings" | ||
) | ||
|
||
type addConfig struct { | ||
fromState bool | ||
out string | ||
includeOptional bool | ||
provider string | ||
reattachInfo ReattachInfo | ||
} | ||
|
||
var defaultAddOptions = addConfig{} | ||
|
||
type AddOption interface { | ||
configureAdd(*addConfig) | ||
} | ||
|
||
func (opt *FromStateOption) configureAdd(conf *addConfig) { | ||
conf.fromState = opt.fromState | ||
} | ||
|
||
func (opt *OutOption) configureAdd(conf *addConfig) { | ||
conf.out = opt.path | ||
} | ||
|
||
func (opt *IncludeOptionalOption) configureAdd(conf *addConfig) { | ||
conf.includeOptional = opt.includeOptional | ||
} | ||
|
||
func (opt *ProviderOption) configureAdd(conf *addConfig) { | ||
conf.provider = opt.provider | ||
} | ||
|
||
func (opt *ReattachOption) configureAdd(conf *addConfig) { | ||
conf.reattachInfo = opt.info | ||
} | ||
|
||
// Add represents the `terraform add` subcommand (added in 1.1.0). | ||
// | ||
// Note that this function signature and behaviour is subject | ||
// to breaking changes including removal of that function | ||
// until final 1.1.0 Terraform version (with this command) is released. | ||
func (tf *Terraform) Add(ctx context.Context, address string, opts ...AddOption) (string, error) { | ||
cmd, err := tf.addCmd(ctx, address, opts...) | ||
if err != nil { | ||
return "", err | ||
} | ||
|
||
var outBuf strings.Builder | ||
cmd.Stdout = mergeWriters(cmd.Stdout, &outBuf) | ||
|
||
if err := tf.runTerraformCmd(ctx, cmd); err != nil { | ||
return "", err | ||
} | ||
|
||
return outBuf.String(), nil | ||
} | ||
|
||
func (tf *Terraform) addCmd(ctx context.Context, address string, opts ...AddOption) (*exec.Cmd, error) { | ||
err := tf.compatible(ctx, tf1_1_0, nil) | ||
if err != nil { | ||
return nil, fmt.Errorf("terraform add was added in 1.1.0: %w", err) | ||
} | ||
|
||
c := defaultAddOptions | ||
|
||
for _, o := range opts { | ||
o.configureAdd(&c) | ||
} | ||
|
||
args := []string{"add"} | ||
|
||
args = append(args, "-from-state="+strconv.FormatBool(c.fromState)) | ||
if c.out != "" { | ||
args = append(args, "-out="+c.out) | ||
} | ||
args = append(args, "-optional="+strconv.FormatBool(c.includeOptional)) | ||
if c.provider != "" { | ||
args = append(args, "-provider="+c.provider) | ||
} | ||
|
||
args = append(args, address) | ||
|
||
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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
package tfexec | ||
|
||
import ( | ||
"context" | ||
"testing" | ||
|
||
"github.com/hashicorp/terraform-exec/tfexec/internal/testutil" | ||
) | ||
|
||
func TestAddCmd(t *testing.T) { | ||
td := testTempDir(t) | ||
|
||
tf, err := NewTerraform(td, tfVersion(t, testutil.Latest_v1_1)) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
// empty env, to avoid environ mismatch in testing | ||
tf.SetEnv(map[string]string{}) | ||
|
||
t.Run("default", func(t *testing.T) { | ||
addCmd, err := tf.addCmd(context.Background(), "my-addr") | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
assertCmd(t, []string{ | ||
"add", | ||
"-from-state=false", | ||
"-optional=false", | ||
"my-addr", | ||
}, nil, addCmd) | ||
}) | ||
|
||
t.Run("override-default", func(t *testing.T) { | ||
addCmd, err := tf.addCmd(context.Background(), | ||
"my-addr", | ||
FromState(true), | ||
Out("out"), | ||
IncludeOptional(true), | ||
Provider("my-provider"), | ||
) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
assertCmd(t, []string{ | ||
"add", | ||
"-from-state=true", | ||
"-out=out", | ||
"-optional=true", | ||
"-provider=my-provider", | ||
"my-addr", | ||
}, nil, addCmd) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters