cli: Remove legacy positional path arguments
Several commands continued to support the legacy positional path argument to specify a working directory. This functionality has been replaced with the global -chdir flag, which is specified before any other arguments, including the sub-command name. This commit removes support for the trailing path parameter from most commands. The only command which still supports a path argument is fmt, which also supports "-" to indicate receiving configuration from standard input. Any invocation of a command with an invalid trailing path parameter will result in a short error message, pointing at the -chdir alternative. There are many test updates in this commit, almost all of which are migrations from using positional arguments to specify a working directory. Because of the layer at which these tests run, we are unable to use the -chdir argument, so the churn in test files is larger than ideal. Sorry!
This commit is contained in:
parent
9c16e5726e
commit
ca23a096d8
|
@ -7,6 +7,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/hashicorp/terraform/backend"
|
||||
"github.com/hashicorp/terraform/plans/planfile"
|
||||
"github.com/hashicorp/terraform/repl"
|
||||
"github.com/hashicorp/terraform/states"
|
||||
"github.com/hashicorp/terraform/tfdiags"
|
||||
|
@ -50,6 +51,12 @@ func (c *ApplyCommand) Run(args []string) int {
|
|||
var diags tfdiags.Diagnostics
|
||||
|
||||
args = cmdFlags.Args()
|
||||
var planPath string
|
||||
if len(args) > 0 {
|
||||
planPath = args[0]
|
||||
args = args[1:]
|
||||
}
|
||||
|
||||
configPath, err := ModulePath(args)
|
||||
if err != nil {
|
||||
c.Ui.Error(err.Error())
|
||||
|
@ -62,11 +69,14 @@ func (c *ApplyCommand) Run(args []string) int {
|
|||
return 1
|
||||
}
|
||||
|
||||
// Check if the path is a plan
|
||||
planFile, err := c.PlanFile(configPath)
|
||||
if err != nil {
|
||||
c.Ui.Error(err.Error())
|
||||
return 1
|
||||
// Try to load plan if path is specified
|
||||
var planFile *planfile.Reader
|
||||
if planPath != "" {
|
||||
planFile, err = c.PlanFile(planPath)
|
||||
if err != nil {
|
||||
c.Ui.Error(err.Error())
|
||||
return 1
|
||||
}
|
||||
}
|
||||
if c.Destroy && planFile != nil {
|
||||
c.Ui.Error("Destroy can't be called with a plan file.")
|
||||
|
@ -297,7 +307,7 @@ Options:
|
|||
|
||||
func (c *ApplyCommand) helpDestroy() string {
|
||||
helpText := `
|
||||
Usage: terraform destroy [options] [DIR]
|
||||
Usage: terraform destroy [options]
|
||||
|
||||
Destroy Terraform-managed infrastructure.
|
||||
|
||||
|
|
|
@ -26,6 +26,12 @@ import (
|
|||
)
|
||||
|
||||
func TestApply(t *testing.T) {
|
||||
// Create a temporary working directory that is empty
|
||||
td := tempDir(t)
|
||||
testCopyDir(t, testFixturePath("apply"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
statePath := testTempFile(t)
|
||||
|
||||
p := applyFixtureProvider()
|
||||
|
@ -41,7 +47,6 @@ func TestApply(t *testing.T) {
|
|||
args := []string{
|
||||
"-state", statePath,
|
||||
"-auto-approve",
|
||||
testFixturePath("apply"),
|
||||
}
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
||||
|
@ -59,6 +64,12 @@ func TestApply(t *testing.T) {
|
|||
|
||||
// test apply with locked state
|
||||
func TestApply_lockedState(t *testing.T) {
|
||||
// Create a temporary working directory that is empty
|
||||
td := tempDir(t)
|
||||
testCopyDir(t, testFixturePath("apply"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
statePath := testTempFile(t)
|
||||
|
||||
unlock, err := testLockState(testDataDir, statePath)
|
||||
|
@ -79,7 +90,6 @@ func TestApply_lockedState(t *testing.T) {
|
|||
args := []string{
|
||||
"-state", statePath,
|
||||
"-auto-approve",
|
||||
testFixturePath("apply"),
|
||||
}
|
||||
if code := c.Run(args); code == 0 {
|
||||
t.Fatal("expected error")
|
||||
|
@ -93,6 +103,12 @@ func TestApply_lockedState(t *testing.T) {
|
|||
|
||||
// test apply with locked state, waiting for unlock
|
||||
func TestApply_lockedStateWait(t *testing.T) {
|
||||
// Create a temporary working directory that is empty
|
||||
td := tempDir(t)
|
||||
testCopyDir(t, testFixturePath("apply"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
statePath := testTempFile(t)
|
||||
|
||||
unlock, err := testLockState(testDataDir, statePath)
|
||||
|
@ -121,7 +137,6 @@ func TestApply_lockedStateWait(t *testing.T) {
|
|||
"-state", statePath,
|
||||
"-lock-timeout", "4s",
|
||||
"-auto-approve",
|
||||
testFixturePath("apply"),
|
||||
}
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("lock should have succeeded in less than 3s: %s", ui.ErrorWriter)
|
||||
|
@ -157,6 +172,12 @@ func (t *hwm) Max() int {
|
|||
}
|
||||
|
||||
func TestApply_parallelism(t *testing.T) {
|
||||
// Create a temporary working directory that is empty
|
||||
td := tempDir(t)
|
||||
testCopyDir(t, testFixturePath("parallelism"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
statePath := testTempFile(t)
|
||||
|
||||
par := 4
|
||||
|
@ -217,7 +238,6 @@ func TestApply_parallelism(t *testing.T) {
|
|||
"-state", statePath,
|
||||
"-auto-approve",
|
||||
fmt.Sprintf("-parallelism=%d", par),
|
||||
testFixturePath("parallelism"),
|
||||
}
|
||||
|
||||
// Run in a goroutine. We can get any errors from the ui.OutputWriter
|
||||
|
@ -258,6 +278,12 @@ func TestApply_parallelism(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestApply_configInvalid(t *testing.T) {
|
||||
// Create a temporary working directory that is empty
|
||||
td := tempDir(t)
|
||||
testCopyDir(t, testFixturePath("apply-config-invalid"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
p := testProvider()
|
||||
ui := new(cli.MockUi)
|
||||
c := &ApplyCommand{
|
||||
|
@ -270,7 +296,6 @@ func TestApply_configInvalid(t *testing.T) {
|
|||
args := []string{
|
||||
"-state", testTempFile(t),
|
||||
"-auto-approve",
|
||||
testFixturePath("apply-config-invalid"),
|
||||
}
|
||||
if code := c.Run(args); code != 1 {
|
||||
t.Fatalf("bad: \n%s", ui.OutputWriter.String())
|
||||
|
@ -278,7 +303,12 @@ func TestApply_configInvalid(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestApply_defaultState(t *testing.T) {
|
||||
td := testTempDir(t)
|
||||
// Create a temporary working directory that is empty
|
||||
td := tempDir(t)
|
||||
testCopyDir(t, testFixturePath("apply"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
statePath := filepath.Join(td, DefaultStateFilename)
|
||||
|
||||
// Change to the temporary directory
|
||||
|
@ -308,7 +338,6 @@ func TestApply_defaultState(t *testing.T) {
|
|||
|
||||
args := []string{
|
||||
"-auto-approve",
|
||||
testFixturePath("apply"),
|
||||
}
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
||||
|
@ -325,6 +354,12 @@ func TestApply_defaultState(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestApply_error(t *testing.T) {
|
||||
// Create a temporary working directory that is empty
|
||||
td := tempDir(t)
|
||||
testCopyDir(t, testFixturePath("apply-error"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
statePath := testTempFile(t)
|
||||
|
||||
p := testProvider()
|
||||
|
@ -376,7 +411,6 @@ func TestApply_error(t *testing.T) {
|
|||
args := []string{
|
||||
"-state", statePath,
|
||||
"-auto-approve",
|
||||
testFixturePath("apply-error"),
|
||||
}
|
||||
if ui.ErrorWriter != nil {
|
||||
t.Logf("stdout:\n%s", ui.OutputWriter.String())
|
||||
|
@ -400,6 +434,12 @@ func TestApply_error(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestApply_input(t *testing.T) {
|
||||
// Create a temporary working directory that is empty
|
||||
td := tempDir(t)
|
||||
testCopyDir(t, testFixturePath("apply-input"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
// Disable test mode so input would be asked
|
||||
test = false
|
||||
defer func() { test = true }()
|
||||
|
@ -426,7 +466,6 @@ func TestApply_input(t *testing.T) {
|
|||
args := []string{
|
||||
"-state", statePath,
|
||||
"-auto-approve",
|
||||
testFixturePath("apply-input"),
|
||||
}
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
||||
|
@ -444,6 +483,12 @@ result = foo
|
|||
// When only a partial set of the variables are set, Terraform
|
||||
// should still ask for the unset ones by default (with -input=true)
|
||||
func TestApply_inputPartial(t *testing.T) {
|
||||
// Create a temporary working directory that is empty
|
||||
td := tempDir(t)
|
||||
testCopyDir(t, testFixturePath("apply-input-partial"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
// Disable test mode so input would be asked
|
||||
test = false
|
||||
defer func() { test = true }()
|
||||
|
@ -467,7 +512,6 @@ func TestApply_inputPartial(t *testing.T) {
|
|||
"-state", statePath,
|
||||
"-auto-approve",
|
||||
"-var", "foo=foovalue",
|
||||
testFixturePath("apply-input-partial"),
|
||||
}
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
||||
|
@ -484,14 +528,11 @@ foo = foovalue
|
|||
}
|
||||
|
||||
func TestApply_noArgs(t *testing.T) {
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
if err := os.Chdir(testFixturePath("apply")); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
defer os.Chdir(cwd)
|
||||
// Create a temporary working directory that is empty
|
||||
td := tempDir(t)
|
||||
testCopyDir(t, testFixturePath("apply"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
statePath := testTempFile(t)
|
||||
|
||||
|
@ -517,9 +558,6 @@ func TestApply_noArgs(t *testing.T) {
|
|||
}
|
||||
|
||||
state := testStateRead(t, statePath)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
if state == nil {
|
||||
t.Fatal("state should not be nil")
|
||||
}
|
||||
|
@ -800,6 +838,12 @@ func TestApply_planNoModuleFiles(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestApply_refresh(t *testing.T) {
|
||||
// Create a temporary working directory that is empty
|
||||
td := tempDir(t)
|
||||
testCopyDir(t, testFixturePath("apply"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
originalState := states.BuildState(func(s *states.SyncState) {
|
||||
s.SetResourceInstanceCurrent(
|
||||
addrs.Resource{
|
||||
|
@ -831,7 +875,6 @@ func TestApply_refresh(t *testing.T) {
|
|||
args := []string{
|
||||
"-state", statePath,
|
||||
"-auto-approve",
|
||||
testFixturePath("apply"),
|
||||
}
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
||||
|
@ -861,6 +904,12 @@ func TestApply_refresh(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestApply_shutdown(t *testing.T) {
|
||||
// Create a temporary working directory that is empty
|
||||
td := tempDir(t)
|
||||
testCopyDir(t, testFixturePath("apply-shutdown"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
cancelled := make(chan struct{})
|
||||
shutdownCh := make(chan struct{})
|
||||
|
||||
|
@ -920,7 +969,6 @@ func TestApply_shutdown(t *testing.T) {
|
|||
args := []string{
|
||||
"-state", statePath,
|
||||
"-auto-approve",
|
||||
testFixturePath("apply-shutdown"),
|
||||
}
|
||||
if code := c.Run(args); code != 1 {
|
||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
||||
|
@ -943,6 +991,12 @@ func TestApply_shutdown(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestApply_state(t *testing.T) {
|
||||
// Create a temporary working directory that is empty
|
||||
td := tempDir(t)
|
||||
testCopyDir(t, testFixturePath("apply"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
originalState := states.BuildState(func(s *states.SyncState) {
|
||||
s.SetResourceInstanceCurrent(
|
||||
addrs.Resource{
|
||||
|
@ -986,7 +1040,6 @@ func TestApply_state(t *testing.T) {
|
|||
args := []string{
|
||||
"-state", statePath,
|
||||
"-auto-approve",
|
||||
testFixturePath("apply"),
|
||||
}
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
||||
|
@ -1031,6 +1084,12 @@ func TestApply_state(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestApply_stateNoExist(t *testing.T) {
|
||||
// Create a temporary working directory that is empty
|
||||
td := tempDir(t)
|
||||
testCopyDir(t, testFixturePath("apply"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
p := applyFixtureProvider()
|
||||
ui := new(cli.MockUi)
|
||||
c := &ApplyCommand{
|
||||
|
@ -1042,7 +1101,6 @@ func TestApply_stateNoExist(t *testing.T) {
|
|||
|
||||
args := []string{
|
||||
"idontexist.tfstate",
|
||||
testFixturePath("apply"),
|
||||
}
|
||||
if code := c.Run(args); code != 1 {
|
||||
t.Fatalf("bad: \n%s", ui.OutputWriter.String())
|
||||
|
@ -1050,6 +1108,12 @@ func TestApply_stateNoExist(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestApply_sensitiveOutput(t *testing.T) {
|
||||
// Create a temporary working directory that is empty
|
||||
td := tempDir(t)
|
||||
testCopyDir(t, testFixturePath("apply-sensitive-output"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
p := testProvider()
|
||||
ui := new(cli.MockUi)
|
||||
c := &ApplyCommand{
|
||||
|
@ -1064,7 +1128,6 @@ func TestApply_sensitiveOutput(t *testing.T) {
|
|||
args := []string{
|
||||
"-state", statePath,
|
||||
"-auto-approve",
|
||||
testFixturePath("apply-sensitive-output"),
|
||||
}
|
||||
|
||||
if code := c.Run(args); code != 0 {
|
||||
|
@ -1081,6 +1144,12 @@ func TestApply_sensitiveOutput(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestApply_vars(t *testing.T) {
|
||||
// Create a temporary working directory that is empty
|
||||
td := tempDir(t)
|
||||
testCopyDir(t, testFixturePath("apply-vars"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
statePath := testTempFile(t)
|
||||
|
||||
p := testProvider()
|
||||
|
@ -1120,7 +1189,6 @@ func TestApply_vars(t *testing.T) {
|
|||
"-auto-approve",
|
||||
"-var", "foo=bar",
|
||||
"-state", statePath,
|
||||
testFixturePath("apply-vars"),
|
||||
}
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
||||
|
@ -1132,6 +1200,12 @@ func TestApply_vars(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestApply_varFile(t *testing.T) {
|
||||
// Create a temporary working directory that is empty
|
||||
td := tempDir(t)
|
||||
testCopyDir(t, testFixturePath("apply-vars"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
varFilePath := testTempFile(t)
|
||||
if err := ioutil.WriteFile(varFilePath, []byte(applyVarFile), 0644); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
|
@ -1176,7 +1250,6 @@ func TestApply_varFile(t *testing.T) {
|
|||
"-auto-approve",
|
||||
"-var-file", varFilePath,
|
||||
"-state", statePath,
|
||||
testFixturePath("apply-vars"),
|
||||
}
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
||||
|
@ -1188,23 +1261,19 @@ func TestApply_varFile(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestApply_varFileDefault(t *testing.T) {
|
||||
varFileDir := testTempDir(t)
|
||||
varFilePath := filepath.Join(varFileDir, "terraform.tfvars")
|
||||
// Create a temporary working directory that is empty
|
||||
td := tempDir(t)
|
||||
testCopyDir(t, testFixturePath("apply-vars"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
varFilePath := filepath.Join(td, "terraform.tfvars")
|
||||
if err := ioutil.WriteFile(varFilePath, []byte(applyVarFile), 0644); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
statePath := testTempFile(t)
|
||||
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
if err := os.Chdir(varFileDir); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
defer os.Chdir(cwd)
|
||||
|
||||
p := testProvider()
|
||||
ui := new(cli.MockUi)
|
||||
c := &ApplyCommand{
|
||||
|
@ -1241,7 +1310,6 @@ func TestApply_varFileDefault(t *testing.T) {
|
|||
args := []string{
|
||||
"-auto-approve",
|
||||
"-state", statePath,
|
||||
testFixturePath("apply-vars"),
|
||||
}
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
||||
|
@ -1253,23 +1321,19 @@ func TestApply_varFileDefault(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestApply_varFileDefaultJSON(t *testing.T) {
|
||||
varFileDir := testTempDir(t)
|
||||
varFilePath := filepath.Join(varFileDir, "terraform.tfvars.json")
|
||||
// Create a temporary working directory that is empty
|
||||
td := tempDir(t)
|
||||
testCopyDir(t, testFixturePath("apply-vars"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
varFilePath := filepath.Join(td, "terraform.tfvars.json")
|
||||
if err := ioutil.WriteFile(varFilePath, []byte(applyVarFileJSON), 0644); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
statePath := testTempFile(t)
|
||||
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
if err := os.Chdir(varFileDir); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
defer os.Chdir(cwd)
|
||||
|
||||
p := testProvider()
|
||||
ui := new(cli.MockUi)
|
||||
c := &ApplyCommand{
|
||||
|
@ -1306,7 +1370,6 @@ func TestApply_varFileDefaultJSON(t *testing.T) {
|
|||
args := []string{
|
||||
"-auto-approve",
|
||||
"-state", statePath,
|
||||
testFixturePath("apply-vars"),
|
||||
}
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
||||
|
@ -1318,6 +1381,12 @@ func TestApply_varFileDefaultJSON(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestApply_backup(t *testing.T) {
|
||||
// Create a temporary working directory that is empty
|
||||
td := tempDir(t)
|
||||
testCopyDir(t, testFixturePath("apply"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
originalState := states.BuildState(func(s *states.SyncState) {
|
||||
s.SetResourceInstanceCurrent(
|
||||
addrs.Resource{
|
||||
|
@ -1358,7 +1427,6 @@ func TestApply_backup(t *testing.T) {
|
|||
"-auto-approve",
|
||||
"-state", statePath,
|
||||
"-backup", backupPath,
|
||||
testFixturePath("apply"),
|
||||
}
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
||||
|
@ -1389,6 +1457,12 @@ func TestApply_backup(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestApply_disableBackup(t *testing.T) {
|
||||
// Create a temporary working directory that is empty
|
||||
td := tempDir(t)
|
||||
testCopyDir(t, testFixturePath("apply"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
originalState := testState()
|
||||
statePath := testStateFile(t, originalState)
|
||||
|
||||
|
@ -1412,7 +1486,6 @@ func TestApply_disableBackup(t *testing.T) {
|
|||
"-auto-approve",
|
||||
"-state", statePath,
|
||||
"-backup", "-",
|
||||
testFixturePath("apply"),
|
||||
}
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
||||
|
@ -1462,6 +1535,12 @@ func TestApply_disableBackup(t *testing.T) {
|
|||
|
||||
// Test that the Terraform env is passed through
|
||||
func TestApply_terraformEnv(t *testing.T) {
|
||||
// Create a temporary working directory that is empty
|
||||
td := tempDir(t)
|
||||
testCopyDir(t, testFixturePath("apply-terraform-env"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
statePath := testTempFile(t)
|
||||
|
||||
p := testProvider()
|
||||
|
@ -1476,7 +1555,6 @@ func TestApply_terraformEnv(t *testing.T) {
|
|||
args := []string{
|
||||
"-auto-approve",
|
||||
"-state", statePath,
|
||||
testFixturePath("apply-terraform-env"),
|
||||
}
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
||||
|
@ -1495,7 +1573,7 @@ output = default
|
|||
func TestApply_terraformEnvNonDefault(t *testing.T) {
|
||||
// Create a temporary working directory that is empty
|
||||
td := tempDir(t)
|
||||
os.MkdirAll(td, 0755)
|
||||
testCopyDir(t, testFixturePath("apply-terraform-env"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
|
@ -1531,7 +1609,6 @@ func TestApply_terraformEnvNonDefault(t *testing.T) {
|
|||
|
||||
args := []string{
|
||||
"-auto-approve",
|
||||
testFixturePath("apply-terraform-env"),
|
||||
}
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
||||
|
|
|
@ -47,29 +47,25 @@ is configured to use a non-local backend. This backend doesn't support this
|
|||
operation.
|
||||
`
|
||||
|
||||
// ModulePath returns the path to the root module from the CLI args.
|
||||
// ModulePath returns the path to the root module and validates CLI arguments.
|
||||
//
|
||||
// This centralizes the logic for any commands that expect a module path
|
||||
// on their CLI args. This will verify that only one argument is given
|
||||
// and that it is a path to configuration.
|
||||
// This centralizes the logic for any commands that previously accepted
|
||||
// a module path via CLI arguments. This will error if any extraneous arguments
|
||||
// are given and suggest using the -chdir flag instead.
|
||||
//
|
||||
// If your command accepts more than one arg, then change the slice bounds
|
||||
// to pass validation.
|
||||
func ModulePath(args []string) (string, error) {
|
||||
// TODO: test
|
||||
|
||||
if len(args) > 1 {
|
||||
return "", fmt.Errorf("Too many command line arguments. Configuration path expected.")
|
||||
if len(args) > 0 {
|
||||
return "", fmt.Errorf("Too many command line arguments. Did you mean to use -chdir?")
|
||||
}
|
||||
|
||||
if len(args) == 0 {
|
||||
path, err := os.Getwd()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Error getting pwd: %s", err)
|
||||
}
|
||||
|
||||
return path, nil
|
||||
path, err := os.Getwd()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Error getting pwd: %s", err)
|
||||
}
|
||||
|
||||
return args[0], nil
|
||||
return path, nil
|
||||
}
|
||||
|
|
|
@ -175,7 +175,7 @@ func (c *ConsoleCommand) modePiped(session *repl.Session, ui cli.Ui) int {
|
|||
|
||||
func (c *ConsoleCommand) Help() string {
|
||||
helpText := `
|
||||
Usage: terraform console [options] [DIR]
|
||||
Usage: terraform console [options]
|
||||
|
||||
Starts an interactive console for experimenting with Terraform
|
||||
interpolations.
|
||||
|
@ -187,9 +187,6 @@ Usage: terraform console [options] [DIR]
|
|||
|
||||
This command will never modify your state.
|
||||
|
||||
DIR can be set to a directory with a Terraform state to load. By
|
||||
default, this will default to the current working directory.
|
||||
|
||||
Options:
|
||||
|
||||
-state=path Path to read state. Defaults to "terraform.tfstate"
|
||||
|
|
|
@ -52,11 +52,13 @@ func TestConsole_basic(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestConsole_tfvars(t *testing.T) {
|
||||
tmp, cwd := testCwd(t)
|
||||
defer testFixCwd(t, tmp, cwd)
|
||||
td := tempDir(t)
|
||||
testCopyDir(t, testFixturePath("apply-vars"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
// Write a terraform.tvars
|
||||
varFilePath := filepath.Join(tmp, "terraform.tfvars")
|
||||
varFilePath := filepath.Join(td, "terraform.tfvars")
|
||||
if err := ioutil.WriteFile(varFilePath, []byte(applyVarFile), 0644); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
@ -85,9 +87,7 @@ func TestConsole_tfvars(t *testing.T) {
|
|||
defer testStdinPipe(t, strings.NewReader("var.foo\n"))()
|
||||
outCloser := testStdoutCapture(t, &output)
|
||||
|
||||
args := []string{
|
||||
testFixturePath("apply-vars"),
|
||||
}
|
||||
args := []string{}
|
||||
code := c.Run(args)
|
||||
outCloser()
|
||||
if code != 0 {
|
||||
|
@ -106,9 +106,13 @@ func TestConsole_unsetRequiredVars(t *testing.T) {
|
|||
// "terraform console" producing an interactive prompt for those variables
|
||||
// or producing errors. Instead, it should allow evaluation in that
|
||||
// partial context but see the unset variables values as being unknown.
|
||||
|
||||
tmp, cwd := testCwd(t)
|
||||
defer testFixCwd(t, tmp, cwd)
|
||||
//
|
||||
// This test fixture includes variable "foo" {}, which we are
|
||||
// intentionally not setting here.
|
||||
td := tempDir(t)
|
||||
testCopyDir(t, testFixturePath("apply-vars"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
p := testProvider()
|
||||
p.GetSchemaResponse = &providers.GetSchemaResponse{
|
||||
|
@ -134,11 +138,7 @@ func TestConsole_unsetRequiredVars(t *testing.T) {
|
|||
defer testStdinPipe(t, strings.NewReader("var.foo\n"))()
|
||||
outCloser := testStdoutCapture(t, &output)
|
||||
|
||||
args := []string{
|
||||
// This test fixture includes variable "foo" {}, which we are
|
||||
// intentionally not setting here.
|
||||
testFixturePath("apply-vars"),
|
||||
}
|
||||
args := []string{}
|
||||
code := c.Run(args)
|
||||
outCloser()
|
||||
|
||||
|
@ -152,8 +152,10 @@ func TestConsole_unsetRequiredVars(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestConsole_variables(t *testing.T) {
|
||||
tmp, cwd := testCwd(t)
|
||||
defer testFixCwd(t, tmp, cwd)
|
||||
td := tempDir(t)
|
||||
testCopyDir(t, testFixturePath("variables"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
p := testProvider()
|
||||
ui := cli.NewMockUi()
|
||||
|
@ -171,9 +173,7 @@ func TestConsole_variables(t *testing.T) {
|
|||
"local.snack_bar\n": "[\n \"popcorn\",\n (sensitive),\n]\n",
|
||||
}
|
||||
|
||||
args := []string{
|
||||
testFixturePath("variables"),
|
||||
}
|
||||
args := []string{}
|
||||
|
||||
for cmd, val := range commands {
|
||||
var output bytes.Buffer
|
||||
|
@ -214,9 +214,7 @@ func TestConsole_modules(t *testing.T) {
|
|||
"local.foo\n": "3\n",
|
||||
}
|
||||
|
||||
args := []string{
|
||||
testFixturePath("modules"),
|
||||
}
|
||||
args := []string{}
|
||||
|
||||
for cmd, val := range commands {
|
||||
var output bytes.Buffer
|
||||
|
|
|
@ -9,8 +9,10 @@ import (
|
|||
)
|
||||
|
||||
func TestGet(t *testing.T) {
|
||||
tmp, cwd := testCwd(t)
|
||||
defer testFixCwd(t, tmp, cwd)
|
||||
td := tempDir(t)
|
||||
testCopyDir(t, testFixturePath("get"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
ui := new(cli.MockUi)
|
||||
c := &GetCommand{
|
||||
|
@ -21,9 +23,7 @@ func TestGet(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
args := []string{
|
||||
testFixturePath("get"),
|
||||
}
|
||||
args := []string{}
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ func TestGet_multipleArgs(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestGet_noArgs(t *testing.T) {
|
||||
func TestGet_update(t *testing.T) {
|
||||
td := tempDir(t)
|
||||
testCopyDir(t, testFixturePath("get"), td)
|
||||
defer os.RemoveAll(td)
|
||||
|
@ -68,33 +68,8 @@ func TestGet_noArgs(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
args := []string{}
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
|
||||
}
|
||||
|
||||
output := ui.OutputWriter.String()
|
||||
if !strings.Contains(output, "- foo in") {
|
||||
t.Fatalf("doesn't look like get: %s", output)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGet_update(t *testing.T) {
|
||||
tmp, cwd := testCwd(t)
|
||||
defer testFixCwd(t, tmp, cwd)
|
||||
|
||||
ui := new(cli.MockUi)
|
||||
c := &GetCommand{
|
||||
Meta: Meta{
|
||||
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||
Ui: ui,
|
||||
dataDir: tempDir(t),
|
||||
},
|
||||
}
|
||||
|
||||
args := []string{
|
||||
"-update",
|
||||
testFixturePath("get"),
|
||||
}
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/terraform/plans"
|
||||
"github.com/hashicorp/terraform/plans/planfile"
|
||||
"github.com/hashicorp/terraform/tfdiags"
|
||||
|
||||
"github.com/hashicorp/terraform/backend"
|
||||
|
@ -36,7 +36,13 @@ func (c *GraphCommand) Run(args []string) int {
|
|||
return 1
|
||||
}
|
||||
|
||||
configPath, err := ModulePath(cmdFlags.Args())
|
||||
args = cmdFlags.Args()
|
||||
var planPath string
|
||||
if len(args) > 0 {
|
||||
planPath = args[0]
|
||||
args = args[1:]
|
||||
}
|
||||
configPath, err := ModulePath(args)
|
||||
if err != nil {
|
||||
c.Ui.Error(err.Error())
|
||||
return 1
|
||||
|
@ -48,16 +54,14 @@ func (c *GraphCommand) Run(args []string) int {
|
|||
return 1
|
||||
}
|
||||
|
||||
// Check if the path is a plan
|
||||
var plan *plans.Plan
|
||||
planFile, err := c.PlanFile(configPath)
|
||||
if err != nil {
|
||||
c.Ui.Error(err.Error())
|
||||
return 1
|
||||
}
|
||||
if planFile != nil {
|
||||
// Reset for backend loading
|
||||
configPath = ""
|
||||
// Try to load plan if path is specified
|
||||
var planFile *planfile.Reader
|
||||
if planPath != "" {
|
||||
planFile, err = c.PlanFile(planPath)
|
||||
if err != nil {
|
||||
c.Ui.Error(err.Error())
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
var diags tfdiags.Diagnostics
|
||||
|
@ -112,7 +116,7 @@ func (c *GraphCommand) Run(args []string) int {
|
|||
|
||||
// Determine the graph type
|
||||
graphType := terraform.GraphTypePlan
|
||||
if plan != nil {
|
||||
if planFile != nil {
|
||||
graphType = terraform.GraphTypeApply
|
||||
}
|
||||
|
||||
|
@ -163,10 +167,10 @@ func (c *GraphCommand) Run(args []string) int {
|
|||
|
||||
func (c *GraphCommand) Help() string {
|
||||
helpText := `
|
||||
Usage: terraform graph [options] [DIR]
|
||||
Usage: terraform graph [options]
|
||||
|
||||
Outputs the visual execution graph of Terraform resources according to
|
||||
configuration files in DIR (or the current directory if omitted).
|
||||
configuration files in the current directory.
|
||||
|
||||
The graph is outputted in DOT format. The typical program that can
|
||||
read this format is GraphViz, but many web services are also available
|
||||
|
|
|
@ -14,8 +14,10 @@ import (
|
|||
)
|
||||
|
||||
func TestGraph(t *testing.T) {
|
||||
tmp, cwd := testCwd(t)
|
||||
defer testFixCwd(t, tmp, cwd)
|
||||
td := tempDir(t)
|
||||
testCopyDir(t, testFixturePath("graph"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
ui := new(cli.MockUi)
|
||||
c := &GraphCommand{
|
||||
|
@ -25,9 +27,7 @@ func TestGraph(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
args := []string{
|
||||
testFixturePath("graph"),
|
||||
}
|
||||
args := []string{}
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
|
||||
}
|
||||
|
@ -57,14 +57,10 @@ func TestGraph_multipleArgs(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGraph_noArgs(t *testing.T) {
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
if err := os.Chdir(testFixturePath("graph")); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
defer os.Chdir(cwd)
|
||||
td := tempDir(t)
|
||||
testCopyDir(t, testFixturePath("graph"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
ui := new(cli.MockUi)
|
||||
c := &GraphCommand{
|
||||
|
|
|
@ -4,7 +4,6 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/hcl/v2"
|
||||
|
@ -59,11 +58,11 @@ func (c *InitCommand) Run(args []string) int {
|
|||
c.pluginPath = flagPluginPath
|
||||
}
|
||||
|
||||
// Validate the arg count
|
||||
// Validate the arg count and get the working directory
|
||||
args = cmdFlags.Args()
|
||||
if len(args) > 1 {
|
||||
c.Ui.Error("The init command expects at most one argument.\n")
|
||||
cmdFlags.Usage()
|
||||
path, err := ModulePath(args)
|
||||
if err != nil {
|
||||
c.Ui.Error(err.Error())
|
||||
return 1
|
||||
}
|
||||
|
||||
|
@ -72,20 +71,6 @@ func (c *InitCommand) Run(args []string) int {
|
|||
return 1
|
||||
}
|
||||
|
||||
// Get our pwd. We don't always need it but always getting it is easier
|
||||
// than the logic to determine if it is or isn't needed.
|
||||
pwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error getting pwd: %s", err))
|
||||
return 1
|
||||
}
|
||||
|
||||
// If an argument is provided then it overrides our working directory.
|
||||
path := pwd
|
||||
if len(args) == 1 {
|
||||
path = args[0]
|
||||
}
|
||||
|
||||
// This will track whether we outputted anything so that we know whether
|
||||
// to output a newline before the success message
|
||||
var header bool
|
||||
|
@ -924,7 +909,7 @@ func (c *InitCommand) AutocompleteFlags() complete.Flags {
|
|||
|
||||
func (c *InitCommand) Help() string {
|
||||
helpText := `
|
||||
Usage: terraform init [options] [DIR]
|
||||
Usage: terraform init [options]
|
||||
|
||||
Initialize a new or existing Terraform working directory by creating
|
||||
initial files, loading any remote state, downloading modules, etc.
|
||||
|
@ -939,9 +924,6 @@ Usage: terraform init [options] [DIR]
|
|||
state. Even so, if you have important information, please back it up prior
|
||||
to running this command, just in case.
|
||||
|
||||
If no arguments are given, the configuration in this working directory
|
||||
is initialized.
|
||||
|
||||
Options:
|
||||
|
||||
-backend=true Configure the backend for this configuration.
|
||||
|
|
|
@ -72,42 +72,6 @@ func TestInit_multipleArgs(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestInit_fromModule_explicitDest(t *testing.T) {
|
||||
td := tempDir(t)
|
||||
os.MkdirAll(td, 0755)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
ui := new(cli.MockUi)
|
||||
c := &InitCommand{
|
||||
Meta: Meta{
|
||||
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||
Ui: ui,
|
||||
},
|
||||
}
|
||||
|
||||
if _, err := os.Stat(DefaultStateFilename); err == nil {
|
||||
// This should never happen; it indicates a bug in another test
|
||||
// is causing a terraform.tfstate to get left behind in our directory
|
||||
// here, which can interfere with our init process in a way that
|
||||
// isn't relevant to this test.
|
||||
fullPath, _ := filepath.Abs(DefaultStateFilename)
|
||||
t.Fatalf("some other test has left terraform.tfstate behind:\n%s", fullPath)
|
||||
}
|
||||
|
||||
args := []string{
|
||||
"-from-module=" + testFixturePath("init"),
|
||||
td,
|
||||
}
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
|
||||
}
|
||||
|
||||
if _, err := os.Stat(filepath.Join(td, "hello.tf")); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInit_fromModule_cwdDest(t *testing.T) {
|
||||
// Create a temporary working directory that is empty
|
||||
td := tempDir(t)
|
||||
|
@ -161,6 +125,10 @@ func TestInit_fromModule_dstInSrc(t *testing.T) {
|
|||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
if err := os.Chdir("foo"); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
ui := new(cli.MockUi)
|
||||
c := &InitCommand{
|
||||
Meta: Meta{
|
||||
|
@ -170,8 +138,7 @@ func TestInit_fromModule_dstInSrc(t *testing.T) {
|
|||
}
|
||||
|
||||
args := []string{
|
||||
"-from-module=.",
|
||||
"foo",
|
||||
"-from-module=./..",
|
||||
}
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
|
||||
|
@ -212,7 +179,7 @@ func TestInit_get(t *testing.T) {
|
|||
func TestInit_getUpgradeModules(t *testing.T) {
|
||||
// Create a temporary working directory that is empty
|
||||
td := tempDir(t)
|
||||
os.MkdirAll(td, 0755)
|
||||
testCopyDir(t, testFixturePath("init-get"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
|
@ -227,7 +194,6 @@ func TestInit_getUpgradeModules(t *testing.T) {
|
|||
args := []string{
|
||||
"-get=true",
|
||||
"-upgrade",
|
||||
testFixturePath("init-get"),
|
||||
}
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("command did not complete successfully:\n%s", ui.ErrorWriter.String())
|
||||
|
@ -484,7 +450,7 @@ func TestInit_backendConfigFilePowershellConfusion(t *testing.T) {
|
|||
}
|
||||
|
||||
output := ui.ErrorWriter.String()
|
||||
if got, want := output, `Module directory ./input.config does not exist`; !strings.Contains(got, want) {
|
||||
if got, want := output, `Too many command line arguments`; !strings.Contains(got, want) {
|
||||
t.Fatalf("wrong output\ngot:\n%s\n\nwant: message containing %q", got, want)
|
||||
}
|
||||
}
|
||||
|
@ -681,41 +647,6 @@ func TestInit_backendCli_no_config_block(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestInit_targetSubdir(t *testing.T) {
|
||||
// Create a temporary working directory that is empty
|
||||
td := tempDir(t)
|
||||
os.MkdirAll(td, 0755)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
// copy the source into a subdir
|
||||
testCopyDir(t, testFixturePath("init-backend"), filepath.Join(td, "source"))
|
||||
|
||||
ui := new(cli.MockUi)
|
||||
c := &InitCommand{
|
||||
Meta: Meta{
|
||||
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||
Ui: ui,
|
||||
},
|
||||
}
|
||||
|
||||
args := []string{
|
||||
"source",
|
||||
}
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
|
||||
}
|
||||
|
||||
if _, err := os.Stat(filepath.Join(td, DefaultDataDir, DefaultStateFilename)); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
// a data directory should not have been added to out working dir
|
||||
if _, err := os.Stat(filepath.Join(td, "source", DefaultDataDir)); !os.IsNotExist(err) {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInit_backendReinitWithExtra(t *testing.T) {
|
||||
td := tempDir(t)
|
||||
testCopyDir(t, testFixturePath("init-backend-empty"), td)
|
||||
|
@ -913,11 +844,11 @@ func TestInit_getProvider(t *testing.T) {
|
|||
ui := new(cli.MockUi)
|
||||
providerSource, close := newMockProviderSource(t, map[string][]string{
|
||||
// looking for an exact version
|
||||
"exact": []string{"1.2.3"},
|
||||
"exact": {"1.2.3"},
|
||||
// config requires >= 2.3.3
|
||||
"greater-than": []string{"2.3.4", "2.3.3", "2.3.0"},
|
||||
"greater-than": {"2.3.4", "2.3.3", "2.3.0"},
|
||||
// config specifies
|
||||
"between": []string{"3.4.5", "2.3.4", "1.2.3"},
|
||||
"between": {"3.4.5", "2.3.4", "1.2.3"},
|
||||
})
|
||||
defer close()
|
||||
m := Meta{
|
||||
|
@ -1015,10 +946,10 @@ func TestInit_getProviderSource(t *testing.T) {
|
|||
ui := new(cli.MockUi)
|
||||
providerSource, close := newMockProviderSource(t, map[string][]string{
|
||||
// looking for an exact version
|
||||
"acme/alpha": []string{"1.2.3"},
|
||||
"acme/alpha": {"1.2.3"},
|
||||
// config doesn't specify versions for other providers
|
||||
"registry.example.com/acme/beta": []string{"1.0.0"},
|
||||
"gamma": []string{"2.0.0"},
|
||||
"registry.example.com/acme/beta": {"1.0.0"},
|
||||
"gamma": {"2.0.0"},
|
||||
})
|
||||
defer close()
|
||||
m := Meta{
|
||||
|
@ -1166,8 +1097,8 @@ func TestInit_getProviderDetectedLegacy(t *testing.T) {
|
|||
// unknown provider, and the registry source will allow us to look up the
|
||||
// appropriate namespace if possible.
|
||||
providerSource, psClose := newMockProviderSource(t, map[string][]string{
|
||||
"hashicorp/foo": []string{"1.2.3"},
|
||||
"terraform-providers/baz": []string{"2.3.4"}, // this will not be installed
|
||||
"hashicorp/foo": {"1.2.3"},
|
||||
"terraform-providers/baz": {"2.3.4"}, // this will not be installed
|
||||
})
|
||||
defer psClose()
|
||||
registrySource, rsClose := testRegistrySource(t)
|
||||
|
@ -1223,15 +1154,14 @@ func TestInit_getProviderDetectedLegacy(t *testing.T) {
|
|||
func TestInit_providerSource(t *testing.T) {
|
||||
// Create a temporary working directory that is empty
|
||||
td := tempDir(t)
|
||||
configDirName := "init-required-providers"
|
||||
testCopyDir(t, testFixturePath(configDirName), filepath.Join(td, configDirName))
|
||||
testCopyDir(t, testFixturePath("init-required-providers"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
providerSource, close := newMockProviderSource(t, map[string][]string{
|
||||
"test": []string{"1.2.3", "1.2.4"},
|
||||
"test-beta": []string{"1.2.4"},
|
||||
"source": []string{"1.2.2", "1.2.3", "1.2.1"},
|
||||
"test": {"1.2.3", "1.2.4"},
|
||||
"test-beta": {"1.2.4"},
|
||||
"source": {"1.2.2", "1.2.3", "1.2.1"},
|
||||
})
|
||||
defer close()
|
||||
|
||||
|
@ -1246,7 +1176,7 @@ func TestInit_providerSource(t *testing.T) {
|
|||
Meta: m,
|
||||
}
|
||||
|
||||
args := []string{configDirName}
|
||||
args := []string{}
|
||||
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
|
||||
|
@ -1330,15 +1260,14 @@ func TestInit_cancel(t *testing.T) {
|
|||
// platforms) were sent to it, testing that it is interruptible.
|
||||
|
||||
td := tempDir(t)
|
||||
configDirName := "init-required-providers"
|
||||
testCopyDir(t, testFixturePath(configDirName), filepath.Join(td, configDirName))
|
||||
testCopyDir(t, testFixturePath("init-required-providers"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
providerSource, closeSrc := newMockProviderSource(t, map[string][]string{
|
||||
"test": []string{"1.2.3", "1.2.4"},
|
||||
"test-beta": []string{"1.2.4"},
|
||||
"source": []string{"1.2.2", "1.2.3", "1.2.1"},
|
||||
"test": {"1.2.3", "1.2.4"},
|
||||
"test-beta": {"1.2.4"},
|
||||
"source": {"1.2.2", "1.2.3", "1.2.1"},
|
||||
})
|
||||
defer closeSrc()
|
||||
|
||||
|
@ -1359,7 +1288,7 @@ func TestInit_cancel(t *testing.T) {
|
|||
Meta: m,
|
||||
}
|
||||
|
||||
args := []string{configDirName}
|
||||
args := []string{}
|
||||
|
||||
if code := c.Run(args); code == 0 {
|
||||
t.Fatalf("succeeded; wanted error")
|
||||
|
@ -1382,11 +1311,11 @@ func TestInit_getUpgradePlugins(t *testing.T) {
|
|||
|
||||
providerSource, close := newMockProviderSource(t, map[string][]string{
|
||||
// looking for an exact version
|
||||
"exact": []string{"1.2.3"},
|
||||
"exact": {"1.2.3"},
|
||||
// config requires >= 2.3.3
|
||||
"greater-than": []string{"2.3.4", "2.3.3", "2.3.0"},
|
||||
"greater-than": {"2.3.4", "2.3.3", "2.3.0"},
|
||||
// config specifies > 1.0.0 , < 3.0.0
|
||||
"between": []string{"3.4.5", "2.3.4", "1.2.3"},
|
||||
"between": {"3.4.5", "2.3.4", "1.2.3"},
|
||||
})
|
||||
defer close()
|
||||
|
||||
|
@ -1398,8 +1327,8 @@ func TestInit_getUpgradePlugins(t *testing.T) {
|
|||
}
|
||||
|
||||
installFakeProviderPackages(t, &m, map[string][]string{
|
||||
"exact": []string{"0.0.1"},
|
||||
"greater-than": []string{"2.3.3"},
|
||||
"exact": {"0.0.1"},
|
||||
"greater-than": {"2.3.3"},
|
||||
})
|
||||
|
||||
c := &InitCommand{
|
||||
|
@ -1506,11 +1435,11 @@ func TestInit_getProviderMissing(t *testing.T) {
|
|||
|
||||
providerSource, close := newMockProviderSource(t, map[string][]string{
|
||||
// looking for exact version 1.2.3
|
||||
"exact": []string{"1.2.4"},
|
||||
"exact": {"1.2.4"},
|
||||
// config requires >= 2.3.3
|
||||
"greater-than": []string{"2.3.4", "2.3.3", "2.3.0"},
|
||||
"greater-than": {"2.3.4", "2.3.3", "2.3.0"},
|
||||
// config specifies
|
||||
"between": []string{"3.4.5", "2.3.4", "1.2.3"},
|
||||
"between": {"3.4.5", "2.3.4", "1.2.3"},
|
||||
})
|
||||
defer close()
|
||||
|
||||
|
@ -1716,14 +1645,14 @@ func TestInit_pluginDirProviders(t *testing.T) {
|
|||
// for a moment that they are provider cache directories just because that
|
||||
// allows us to lean on our existing test helper functions to do this.
|
||||
for i, def := range [][]string{
|
||||
[]string{"exact", "1.2.3"},
|
||||
[]string{"greater-than", "2.3.4"},
|
||||
[]string{"between", "2.3.4"},
|
||||
{"exact", "1.2.3"},
|
||||
{"greater-than", "2.3.4"},
|
||||
{"between", "2.3.4"},
|
||||
} {
|
||||
name, version := def[0], def[1]
|
||||
dir := providercache.NewDir(pluginPath[i])
|
||||
installFakeProviderPackagesElsewhere(t, dir, map[string][]string{
|
||||
name: []string{version},
|
||||
name: {version},
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -1789,7 +1718,7 @@ func TestInit_pluginDirProvidersDoesNotGet(t *testing.T) {
|
|||
// but we should ignore it because -plugin-dir is set and thus this
|
||||
// source is temporarily overridden during install.
|
||||
providerSource, close := newMockProviderSource(t, map[string][]string{
|
||||
"between": []string{"2.3.4"},
|
||||
"between": {"2.3.4"},
|
||||
})
|
||||
defer close()
|
||||
|
||||
|
@ -1816,13 +1745,13 @@ func TestInit_pluginDirProvidersDoesNotGet(t *testing.T) {
|
|||
// for a moment that they are provider cache directories just because that
|
||||
// allows us to lean on our existing test helper functions to do this.
|
||||
for i, def := range [][]string{
|
||||
[]string{"exact", "1.2.3"},
|
||||
[]string{"greater-than", "2.3.4"},
|
||||
{"exact", "1.2.3"},
|
||||
{"greater-than", "2.3.4"},
|
||||
} {
|
||||
name, version := def[0], def[1]
|
||||
dir := providercache.NewDir(pluginPath[i])
|
||||
installFakeProviderPackagesElsewhere(t, dir, map[string][]string{
|
||||
name: []string{version},
|
||||
name: {version},
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -47,21 +47,6 @@ func (c *PlanCommand) Run(args []string) int {
|
|||
return 1
|
||||
}
|
||||
|
||||
// Check if the path is a plan, which is not permitted
|
||||
planFileReader, err := c.PlanFile(configPath)
|
||||
if err != nil {
|
||||
c.Ui.Error(err.Error())
|
||||
return 1
|
||||
}
|
||||
if planFileReader != nil {
|
||||
c.showDiagnostics(tfdiags.Sourceless(
|
||||
tfdiags.Error,
|
||||
"Invalid configuration directory",
|
||||
fmt.Sprintf("Cannot pass a saved plan file to the 'terraform plan' command. To apply a saved plan, use: terraform apply %s", configPath),
|
||||
))
|
||||
return 1
|
||||
}
|
||||
|
||||
var diags tfdiags.Diagnostics
|
||||
|
||||
var backendConfig *configs.Backend
|
||||
|
@ -191,7 +176,7 @@ func (c *PlanCommand) Run(args []string) int {
|
|||
|
||||
func (c *PlanCommand) Help() string {
|
||||
helpText := `
|
||||
Usage: terraform plan [options] [DIR]
|
||||
Usage: terraform plan [options]
|
||||
|
||||
Generates a speculative execution plan, showing what actions Terraform
|
||||
would take to apply the current configuration. This command will not
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"bytes"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
|
@ -98,6 +99,11 @@ func TestPlan_plan(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestPlan_destroy(t *testing.T) {
|
||||
td := tempDir(t)
|
||||
testCopyDir(t, testFixturePath("plan"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
originalState := states.BuildState(func(s *states.SyncState) {
|
||||
s.SetResourceInstanceCurrent(
|
||||
addrs.Resource{
|
||||
|
@ -131,7 +137,6 @@ func TestPlan_destroy(t *testing.T) {
|
|||
"-destroy",
|
||||
"-out", outPath,
|
||||
"-state", statePath,
|
||||
testFixturePath("plan"),
|
||||
}
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
||||
|
@ -146,8 +151,10 @@ func TestPlan_destroy(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestPlan_noState(t *testing.T) {
|
||||
tmp, cwd := testCwd(t)
|
||||
defer testFixCwd(t, tmp, cwd)
|
||||
td := tempDir(t)
|
||||
testCopyDir(t, testFixturePath("plan"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
p := planFixtureProvider()
|
||||
ui := new(cli.MockUi)
|
||||
|
@ -158,9 +165,7 @@ func TestPlan_noState(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
args := []string{
|
||||
testFixturePath("plan"),
|
||||
}
|
||||
args := []string{}
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
||||
}
|
||||
|
@ -179,10 +184,11 @@ func TestPlan_noState(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestPlan_outPath(t *testing.T) {
|
||||
tmp, cwd := testCwd(t)
|
||||
defer testFixCwd(t, tmp, cwd)
|
||||
td := tempDir(t)
|
||||
testCopyDir(t, testFixturePath("plan"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
td := testTempDir(t)
|
||||
outPath := filepath.Join(td, "test.plan")
|
||||
|
||||
p := planFixtureProvider()
|
||||
|
@ -200,7 +206,6 @@ func TestPlan_outPath(t *testing.T) {
|
|||
|
||||
args := []string{
|
||||
"-out", outPath,
|
||||
testFixturePath("plan"),
|
||||
}
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
||||
|
@ -210,6 +215,11 @@ func TestPlan_outPath(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestPlan_outPathNoChange(t *testing.T) {
|
||||
td := tempDir(t)
|
||||
testCopyDir(t, testFixturePath("plan"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
originalState := states.BuildState(func(s *states.SyncState) {
|
||||
s.SetResourceInstanceCurrent(
|
||||
addrs.Resource{
|
||||
|
@ -232,7 +242,6 @@ func TestPlan_outPathNoChange(t *testing.T) {
|
|||
})
|
||||
statePath := testStateFile(t, originalState)
|
||||
|
||||
td := testTempDir(t)
|
||||
outPath := filepath.Join(td, "test.plan")
|
||||
|
||||
p := planFixtureProvider()
|
||||
|
@ -247,7 +256,6 @@ func TestPlan_outPathNoChange(t *testing.T) {
|
|||
args := []string{
|
||||
"-out", outPath,
|
||||
"-state", statePath,
|
||||
testFixturePath("plan"),
|
||||
}
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
||||
|
@ -360,8 +368,11 @@ func TestPlan_outBackend(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestPlan_refreshFalse(t *testing.T) {
|
||||
tmp, cwd := testCwd(t)
|
||||
defer testFixCwd(t, tmp, cwd)
|
||||
// Create a temporary working directory that is empty
|
||||
td := tempDir(t)
|
||||
testCopyDir(t, testFixturePath("plan"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
p := planFixtureProvider()
|
||||
ui := new(cli.MockUi)
|
||||
|
@ -374,7 +385,6 @@ func TestPlan_refreshFalse(t *testing.T) {
|
|||
|
||||
args := []string{
|
||||
"-refresh=false",
|
||||
testFixturePath("plan"),
|
||||
}
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
||||
|
@ -386,6 +396,12 @@ func TestPlan_refreshFalse(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestPlan_state(t *testing.T) {
|
||||
// Create a temporary working directory that is empty
|
||||
td := tempDir(t)
|
||||
testCopyDir(t, testFixturePath("plan"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
originalState := testState()
|
||||
statePath := testStateFile(t, originalState)
|
||||
|
||||
|
@ -400,7 +416,6 @@ func TestPlan_state(t *testing.T) {
|
|||
|
||||
args := []string{
|
||||
"-state", statePath,
|
||||
testFixturePath("plan"),
|
||||
}
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
||||
|
@ -422,18 +437,16 @@ func TestPlan_state(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestPlan_stateDefault(t *testing.T) {
|
||||
// Create a temporary working directory that is empty
|
||||
td := tempDir(t)
|
||||
testCopyDir(t, testFixturePath("plan"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
// Generate state and move it to the default path
|
||||
originalState := testState()
|
||||
statePath := testStateFile(t, originalState)
|
||||
|
||||
// Change to that directory
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
if err := os.Chdir(filepath.Dir(statePath)); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
defer os.Chdir(cwd)
|
||||
os.Rename(statePath, path.Join(td, "terraform.tfstate"))
|
||||
|
||||
p := planFixtureProvider()
|
||||
ui := new(cli.MockUi)
|
||||
|
@ -444,10 +457,7 @@ func TestPlan_stateDefault(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
args := []string{
|
||||
"-state", statePath,
|
||||
testFixturePath("plan"),
|
||||
}
|
||||
args := []string{}
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
||||
}
|
||||
|
@ -514,8 +524,11 @@ func TestPlan_validate(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestPlan_vars(t *testing.T) {
|
||||
tmp, cwd := testCwd(t)
|
||||
defer testFixCwd(t, tmp, cwd)
|
||||
// Create a temporary working directory that is empty
|
||||
td := tempDir(t)
|
||||
testCopyDir(t, testFixturePath("plan-vars"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
p := planVarsFixtureProvider()
|
||||
ui := new(cli.MockUi)
|
||||
|
@ -535,7 +548,6 @@ func TestPlan_vars(t *testing.T) {
|
|||
|
||||
args := []string{
|
||||
"-var", "foo=bar",
|
||||
testFixturePath("plan-vars"),
|
||||
}
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
||||
|
@ -547,8 +559,11 @@ func TestPlan_vars(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestPlan_varsUnset(t *testing.T) {
|
||||
tmp, cwd := testCwd(t)
|
||||
defer testFixCwd(t, tmp, cwd)
|
||||
// Create a temporary working directory that is empty
|
||||
td := tempDir(t)
|
||||
testCopyDir(t, testFixturePath("plan-vars"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
// The plan command will prompt for interactive input of var.foo.
|
||||
// We'll answer "bar" to that prompt, which should then allow this
|
||||
|
@ -569,9 +584,7 @@ func TestPlan_varsUnset(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
args := []string{
|
||||
testFixturePath("plan-vars"),
|
||||
}
|
||||
args := []string{}
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
||||
}
|
||||
|
@ -581,8 +594,11 @@ func TestPlan_varsUnset(t *testing.T) {
|
|||
// processing of user input:
|
||||
// https://github.com/hashicorp/terraform/issues/26035
|
||||
func TestPlan_providerArgumentUnset(t *testing.T) {
|
||||
tmp, cwd := testCwd(t)
|
||||
defer testFixCwd(t, tmp, cwd)
|
||||
// Create a temporary working directory that is empty
|
||||
td := tempDir(t)
|
||||
testCopyDir(t, testFixturePath("plan"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
// Disable test mode so input would be asked
|
||||
test = false
|
||||
|
@ -631,17 +647,18 @@ func TestPlan_providerArgumentUnset(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
args := []string{
|
||||
testFixturePath("plan"),
|
||||
}
|
||||
args := []string{}
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestPlan_varFile(t *testing.T) {
|
||||
tmp, cwd := testCwd(t)
|
||||
defer testFixCwd(t, tmp, cwd)
|
||||
// Create a temporary working directory that is empty
|
||||
td := tempDir(t)
|
||||
testCopyDir(t, testFixturePath("plan-vars"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
varFilePath := testTempFile(t)
|
||||
if err := ioutil.WriteFile(varFilePath, []byte(planVarFile), 0644); err != nil {
|
||||
|
@ -666,7 +683,6 @@ func TestPlan_varFile(t *testing.T) {
|
|||
|
||||
args := []string{
|
||||
"-var-file", varFilePath,
|
||||
testFixturePath("plan-vars"),
|
||||
}
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
||||
|
@ -678,21 +694,17 @@ func TestPlan_varFile(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestPlan_varFileDefault(t *testing.T) {
|
||||
varFileDir := testTempDir(t)
|
||||
varFilePath := filepath.Join(varFileDir, "terraform.tfvars")
|
||||
// Create a temporary working directory that is empty
|
||||
td := tempDir(t)
|
||||
testCopyDir(t, testFixturePath("plan-vars"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
varFilePath := filepath.Join(td, "terraform.tfvars")
|
||||
if err := ioutil.WriteFile(varFilePath, []byte(planVarFile), 0644); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
if err := os.Chdir(varFileDir); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
defer os.Chdir(cwd)
|
||||
|
||||
p := planVarsFixtureProvider()
|
||||
ui := new(cli.MockUi)
|
||||
c := &PlanCommand{
|
||||
|
@ -709,9 +721,7 @@ func TestPlan_varFileDefault(t *testing.T) {
|
|||
return
|
||||
}
|
||||
|
||||
args := []string{
|
||||
testFixturePath("plan-vars"),
|
||||
}
|
||||
args := []string{}
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
||||
}
|
||||
|
@ -722,8 +732,11 @@ func TestPlan_varFileDefault(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestPlan_varFileWithDecls(t *testing.T) {
|
||||
tmp, cwd := testCwd(t)
|
||||
defer testFixCwd(t, tmp, cwd)
|
||||
// Create a temporary working directory that is empty
|
||||
td := tempDir(t)
|
||||
testCopyDir(t, testFixturePath("plan-vars"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
varFilePath := testTempFile(t)
|
||||
if err := ioutil.WriteFile(varFilePath, []byte(planVarFileWithDecl), 0644); err != nil {
|
||||
|
@ -741,7 +754,6 @@ func TestPlan_varFileWithDecls(t *testing.T) {
|
|||
|
||||
args := []string{
|
||||
"-var-file", varFilePath,
|
||||
testFixturePath("plan-vars"),
|
||||
}
|
||||
if code := c.Run(args); code == 0 {
|
||||
t.Fatalf("succeeded; want failure\n\n%s", ui.OutputWriter.String())
|
||||
|
@ -796,6 +808,12 @@ func TestPlan_detailedExitcode_emptyDiff(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestPlan_shutdown(t *testing.T) {
|
||||
// Create a temporary working directory that is empty
|
||||
td := tempDir(t)
|
||||
testCopyDir(t, testFixturePath("apply-shutdown"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
cancelled := make(chan struct{})
|
||||
shutdownCh := make(chan struct{})
|
||||
|
||||
|
@ -847,14 +865,7 @@ func TestPlan_shutdown(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
code := c.Run([]string{
|
||||
// Unfortunately it seems like this test can inadvertently pick up
|
||||
// leftover state from other tests without this. Ideally we should
|
||||
// find which test is leaving a terraform.tfstate behind and stop it
|
||||
// doing that, but this will stop this test flapping for now.
|
||||
"-state=nonexistent.tfstate",
|
||||
testFixturePath("apply-shutdown"),
|
||||
})
|
||||
code := c.Run([]string{})
|
||||
if code != 1 {
|
||||
t.Errorf("wrong exit code %d; want 1\noutput:\n%s", code, ui.OutputWriter.String())
|
||||
}
|
||||
|
|
|
@ -104,7 +104,7 @@ func (c *RefreshCommand) Run(args []string) int {
|
|||
|
||||
func (c *RefreshCommand) Help() string {
|
||||
helpText := `
|
||||
Usage: terraform refresh [options] [dir]
|
||||
Usage: terraform refresh [options]
|
||||
|
||||
Update the state file of your infrastructure with metadata that matches
|
||||
the physical resources they are tracking.
|
||||
|
|
|
@ -27,6 +27,12 @@ import (
|
|||
var equateEmpty = cmpopts.EquateEmpty()
|
||||
|
||||
func TestRefresh(t *testing.T) {
|
||||
// Create a temporary working directory that is empty
|
||||
td := tempDir(t)
|
||||
testCopyDir(t, testFixturePath("refresh"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
state := testState()
|
||||
statePath := testStateFile(t, state)
|
||||
|
||||
|
@ -49,7 +55,6 @@ func TestRefresh(t *testing.T) {
|
|||
|
||||
args := []string{
|
||||
"-state", statePath,
|
||||
testFixturePath("refresh"),
|
||||
}
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
||||
|
@ -100,9 +105,7 @@ func TestRefresh_empty(t *testing.T) {
|
|||
}),
|
||||
}
|
||||
|
||||
args := []string{
|
||||
td,
|
||||
}
|
||||
args := []string{}
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
||||
}
|
||||
|
@ -113,6 +116,12 @@ func TestRefresh_empty(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestRefresh_lockedState(t *testing.T) {
|
||||
// Create a temporary working directory that is empty
|
||||
td := tempDir(t)
|
||||
testCopyDir(t, testFixturePath("refresh"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
state := testState()
|
||||
statePath := testStateFile(t, state)
|
||||
|
||||
|
@ -141,7 +150,6 @@ func TestRefresh_lockedState(t *testing.T) {
|
|||
|
||||
args := []string{
|
||||
"-state", statePath,
|
||||
testFixturePath("refresh"),
|
||||
}
|
||||
|
||||
if code := c.Run(args); code == 0 {
|
||||
|
@ -214,6 +222,12 @@ func TestRefresh_cwd(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestRefresh_defaultState(t *testing.T) {
|
||||
// Create a temporary working directory that is empty
|
||||
td := tempDir(t)
|
||||
testCopyDir(t, testFixturePath("refresh"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
originalState := testState()
|
||||
|
||||
// Write the state file in a temporary directory with the
|
||||
|
@ -258,7 +272,6 @@ func TestRefresh_defaultState(t *testing.T) {
|
|||
|
||||
args := []string{
|
||||
"-state", statePath,
|
||||
testFixturePath("refresh"),
|
||||
}
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
||||
|
@ -290,6 +303,12 @@ func TestRefresh_defaultState(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestRefresh_outPath(t *testing.T) {
|
||||
// Create a temporary working directory that is empty
|
||||
td := tempDir(t)
|
||||
testCopyDir(t, testFixturePath("refresh"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
state := testState()
|
||||
statePath := testStateFile(t, state)
|
||||
|
||||
|
@ -322,7 +341,6 @@ func TestRefresh_outPath(t *testing.T) {
|
|||
args := []string{
|
||||
"-state", statePath,
|
||||
"-state-out", outPath,
|
||||
testFixturePath("refresh"),
|
||||
}
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
||||
|
@ -353,6 +371,12 @@ func TestRefresh_outPath(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestRefresh_var(t *testing.T) {
|
||||
// Create a temporary working directory that is empty
|
||||
td := tempDir(t)
|
||||
testCopyDir(t, testFixturePath("refresh-var"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
state := testState()
|
||||
statePath := testStateFile(t, state)
|
||||
|
||||
|
@ -369,7 +393,6 @@ func TestRefresh_var(t *testing.T) {
|
|||
args := []string{
|
||||
"-var", "foo=bar",
|
||||
"-state", statePath,
|
||||
testFixturePath("refresh-var"),
|
||||
}
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
||||
|
@ -384,6 +407,12 @@ func TestRefresh_var(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestRefresh_varFile(t *testing.T) {
|
||||
// Create a temporary working directory that is empty
|
||||
td := tempDir(t)
|
||||
testCopyDir(t, testFixturePath("refresh-var"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
state := testState()
|
||||
statePath := testStateFile(t, state)
|
||||
|
||||
|
@ -405,7 +434,6 @@ func TestRefresh_varFile(t *testing.T) {
|
|||
args := []string{
|
||||
"-var-file", varFilePath,
|
||||
"-state", statePath,
|
||||
testFixturePath("refresh-var"),
|
||||
}
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
||||
|
@ -420,6 +448,12 @@ func TestRefresh_varFile(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestRefresh_varFileDefault(t *testing.T) {
|
||||
// Create a temporary working directory that is empty
|
||||
td := tempDir(t)
|
||||
testCopyDir(t, testFixturePath("refresh-var"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
state := testState()
|
||||
statePath := testStateFile(t, state)
|
||||
|
||||
|
@ -433,24 +467,13 @@ func TestRefresh_varFileDefault(t *testing.T) {
|
|||
}
|
||||
p.GetSchemaResponse = refreshVarFixtureSchema()
|
||||
|
||||
varFileDir := testTempDir(t)
|
||||
varFilePath := filepath.Join(varFileDir, "terraform.tfvars")
|
||||
varFilePath := filepath.Join(td, "terraform.tfvars")
|
||||
if err := ioutil.WriteFile(varFilePath, []byte(refreshVarFile), 0644); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
if err := os.Chdir(varFileDir); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
defer os.Chdir(cwd)
|
||||
|
||||
args := []string{
|
||||
"-state", statePath,
|
||||
testFixturePath("refresh-var"),
|
||||
}
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
||||
|
@ -465,6 +488,12 @@ func TestRefresh_varFileDefault(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestRefresh_varsUnset(t *testing.T) {
|
||||
// Create a temporary working directory that is empty
|
||||
td := tempDir(t)
|
||||
testCopyDir(t, testFixturePath("refresh-unset-var"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
// Disable test mode so input would be asked
|
||||
test = false
|
||||
defer func() { test = true }()
|
||||
|
@ -497,7 +526,6 @@ func TestRefresh_varsUnset(t *testing.T) {
|
|||
|
||||
args := []string{
|
||||
"-state", statePath,
|
||||
testFixturePath("refresh-unset-var"),
|
||||
}
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
||||
|
@ -505,6 +533,12 @@ func TestRefresh_varsUnset(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestRefresh_backup(t *testing.T) {
|
||||
// Create a temporary working directory that is empty
|
||||
td := tempDir(t)
|
||||
testCopyDir(t, testFixturePath("refresh"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
state := testState()
|
||||
statePath := testStateFile(t, state)
|
||||
|
||||
|
@ -553,7 +587,6 @@ func TestRefresh_backup(t *testing.T) {
|
|||
"-state", statePath,
|
||||
"-state-out", outPath,
|
||||
"-backup", backupPath,
|
||||
testFixturePath("refresh"),
|
||||
}
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
||||
|
@ -584,6 +617,12 @@ func TestRefresh_backup(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestRefresh_disableBackup(t *testing.T) {
|
||||
// Create a temporary working directory that is empty
|
||||
td := tempDir(t)
|
||||
testCopyDir(t, testFixturePath("refresh"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
state := testState()
|
||||
statePath := testStateFile(t, state)
|
||||
|
||||
|
@ -617,7 +656,6 @@ func TestRefresh_disableBackup(t *testing.T) {
|
|||
"-state", statePath,
|
||||
"-state-out", outPath,
|
||||
"-backup", "-",
|
||||
testFixturePath("refresh"),
|
||||
}
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
||||
|
@ -653,6 +691,12 @@ func TestRefresh_disableBackup(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestRefresh_displaysOutputs(t *testing.T) {
|
||||
// Create a temporary working directory that is empty
|
||||
td := tempDir(t)
|
||||
testCopyDir(t, testFixturePath("refresh-output"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
state := testState()
|
||||
statePath := testStateFile(t, state)
|
||||
|
||||
|
@ -679,7 +723,6 @@ func TestRefresh_displaysOutputs(t *testing.T) {
|
|||
|
||||
args := []string{
|
||||
"-state", statePath,
|
||||
testFixturePath("refresh-output"),
|
||||
}
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
||||
|
|
|
@ -30,8 +30,8 @@ func (c *UnlockCommand) Run(args []string) int {
|
|||
}
|
||||
|
||||
args = cmdFlags.Args()
|
||||
if len(args) == 0 {
|
||||
c.Ui.Error("unlock requires a lock id argument")
|
||||
if len(args) != 1 {
|
||||
c.Ui.Error("Expected a single argument: LOCK_ID")
|
||||
return cli.RunResultHelp
|
||||
}
|
||||
|
||||
|
@ -116,7 +116,7 @@ func (c *UnlockCommand) Run(args []string) int {
|
|||
|
||||
func (c *UnlockCommand) Help() string {
|
||||
helpText := `
|
||||
Usage: terraform force-unlock LOCK_ID [DIR]
|
||||
Usage: terraform force-unlock LOCK_ID
|
||||
|
||||
Manually unlock the state for the defined configuration.
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ func TestUnlock(t *testing.T) {
|
|||
"-force",
|
||||
}
|
||||
|
||||
if code := c.Run(args); code != 1 {
|
||||
if code := c.Run(args); code != cli.RunResultHelp {
|
||||
t.Fatalf("bad: %d\n%s\n%s", code, ui.OutputWriter.String(), ui.ErrorWriter.String())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,8 +35,8 @@ func (c *WorkspaceDeleteCommand) Run(args []string) int {
|
|||
}
|
||||
|
||||
args = cmdFlags.Args()
|
||||
if len(args) == 0 {
|
||||
c.Ui.Error("expected NAME.\n")
|
||||
if len(args) != 1 {
|
||||
c.Ui.Error("Expected a single argument: NAME.\n")
|
||||
return cli.RunResultHelp
|
||||
}
|
||||
|
||||
|
@ -182,7 +182,7 @@ func (c *WorkspaceDeleteCommand) AutocompleteFlags() complete.Flags {
|
|||
|
||||
func (c *WorkspaceDeleteCommand) Help() string {
|
||||
helpText := `
|
||||
Usage: terraform workspace delete [OPTIONS] NAME [DIR]
|
||||
Usage: terraform workspace delete [OPTIONS] NAME
|
||||
|
||||
Delete a Terraform workspace
|
||||
|
||||
|
|
|
@ -91,7 +91,7 @@ func (c *WorkspaceListCommand) AutocompleteFlags() complete.Flags {
|
|||
|
||||
func (c *WorkspaceListCommand) Help() string {
|
||||
helpText := `
|
||||
Usage: terraform workspace list [DIR]
|
||||
Usage: terraform workspace list
|
||||
|
||||
List Terraform workspaces.
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ func (c *WorkspaceNewCommand) Run(args []string) int {
|
|||
}
|
||||
|
||||
args = cmdFlags.Args()
|
||||
if len(args) == 0 {
|
||||
if len(args) != 1 {
|
||||
c.Ui.Error("Expected a single argument: NAME.\n")
|
||||
return cli.RunResultHelp
|
||||
}
|
||||
|
@ -176,7 +176,7 @@ func (c *WorkspaceNewCommand) AutocompleteFlags() complete.Flags {
|
|||
|
||||
func (c *WorkspaceNewCommand) Help() string {
|
||||
helpText := `
|
||||
Usage: terraform workspace new [OPTIONS] NAME [DIR]
|
||||
Usage: terraform workspace new [OPTIONS] NAME
|
||||
|
||||
Create a new Terraform workspace.
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ func (c *WorkspaceSelectCommand) Run(args []string) int {
|
|||
}
|
||||
|
||||
args = cmdFlags.Args()
|
||||
if len(args) == 0 {
|
||||
if len(args) != 1 {
|
||||
c.Ui.Error("Expected a single argument: NAME.\n")
|
||||
return cli.RunResultHelp
|
||||
}
|
||||
|
@ -129,7 +129,7 @@ func (c *WorkspaceSelectCommand) AutocompleteFlags() complete.Flags {
|
|||
|
||||
func (c *WorkspaceSelectCommand) Help() string {
|
||||
helpText := `
|
||||
Usage: terraform workspace select NAME [DIR]
|
||||
Usage: terraform workspace select NAME
|
||||
|
||||
Select a different Terraform workspace.
|
||||
|
||||
|
|
Loading…
Reference in New Issue