command: show a special error message when importing in an empty dir

If users run "terraform import" in a directory with no Terraform
configuration files, it's likely that they've made a mistake either by
being in the wrong directory or forgetting to use the -config option
on the command line.

To help users find their mistake in this case, we'll now produce a
specialized error message for this situation:

    Error: No Terraform configuration files

    The directory /home/user/example does not contain any Terraform
    configuration files (.tf or .tf.json). To specify a different
    configuration directory, use the -config="..." command line option.

While here, this also converts some of the other existing messages to
diagnostics so that we can show any configuration warnings along with
the error message, and move towards the new standard error presentation.
This commit is contained in:
Martin Atkins 2017-12-08 10:22:07 -08:00
parent a7677e761a
commit f1079257ac
3 changed files with 66 additions and 19 deletions

View File

@ -6,12 +6,13 @@ import (
"os"
"strings"
"github.com/hashicorp/terraform/tfdiags"
"github.com/hashicorp/hcl2/hcl"
"github.com/hashicorp/terraform/backend"
"github.com/hashicorp/terraform/config"
"github.com/hashicorp/terraform/config/module"
"github.com/hashicorp/terraform/terraform"
"github.com/hashicorp/terraform/tfdiags"
)
// ImportCommand is a cli.Command implementation that imports resources
@ -78,6 +79,19 @@ func (c *ImportCommand) Run(args []string) int {
// Load the module
var mod *module.Tree
if configPath != "" {
if empty, _ := config.IsEmptyDir(configPath); empty {
diags = diags.Append(&hcl.Diagnostic{
Severity: hcl.DiagError,
Summary: "No Terraform configuration files",
Detail: fmt.Sprintf(
"The directory %s does not contain any Terraform configuration files (.tf or .tf.json). To specify a different configuration directory, use the -config=\"...\" command line option.",
configPath,
),
})
c.showDiagnostics(diags)
return 1
}
var modDiags tfdiags.Diagnostics
mod, modDiags = c.Module(configPath)
diags = diags.Append(modDiags)
@ -94,11 +108,15 @@ func (c *ImportCommand) Run(args []string) int {
targetMod := mod.Child(addr.Path)
if targetMod == nil {
modulePath := addr.WholeModuleAddress().String()
if modulePath == "" {
c.Ui.Error(importCommandMissingConfigMsg)
} else {
c.Ui.Error(fmt.Sprintf(importCommandMissingModuleFmt, modulePath))
}
diags = diags.Append(&hcl.Diagnostic{
Severity: hcl.DiagError,
Summary: "Import to non-existent module",
Detail: fmt.Sprintf(
"%s is not defined in the configuration. Please add configuration for this module before importing into it.",
modulePath,
),
})
c.showDiagnostics(diags)
return 1
}
rcs := targetMod.Config().Resources
@ -114,6 +132,14 @@ func (c *ImportCommand) Run(args []string) int {
if modulePath == "" {
modulePath = "the root module"
}
c.showDiagnostics(diags)
// This is not a diagnostic because currently our diagnostics printer
// doesn't support having a code example in the detail, and there's
// a code example in this message.
// TODO: Improve the diagnostics printer so we can use it for this
// message.
c.Ui.Error(fmt.Sprintf(
importCommandMissingResourceFmt,
addr, modulePath, addr.Type, addr.Name,
@ -296,18 +322,7 @@ const importCommandResourceModeMsg = `Error: resource address must refer to a ma
Data resources cannot be imported.
`
const importCommandMissingConfigMsg = `Error: no configuration files in this directory.
"terraform import" can only be run in a Terraform configuration directory.
Create one or more .tf files in this directory to import here.
`
const importCommandMissingModuleFmt = `Error: %s does not exist in the configuration.
Please add the configuration for the module before importing resources into it.
`
const importCommandMissingResourceFmt = `Error: resource address %q does not exist in the configuration.
const importCommandMissingResourceFmt = `[reset][bold][red]Error:[reset][bold] resource address %q does not exist in the configuration.[reset]
Before importing this resource, please create its configuration in %s. For example:

View File

@ -444,6 +444,36 @@ func TestImport_allowMissingResourceConfig(t *testing.T) {
testStateOutput(t, statePath, testImportStr)
}
func TestImport_emptyConfig(t *testing.T) {
defer testChdir(t, testFixturePath("empty"))()
statePath := testTempFile(t)
p := testProvider()
ui := new(cli.MockUi)
c := &ImportCommand{
Meta: Meta{
testingOverrides: metaOverridesForProvider(p),
Ui: ui,
},
}
args := []string{
"-state", statePath,
"test_instance.foo",
"bar",
}
code := c.Run(args)
if code != 1 {
t.Fatalf("import succeeded; expected failure")
}
msg := ui.ErrorWriter.String()
if want := `No Terraform configuration files`; !strings.Contains(msg, want) {
t.Errorf("incorrect message\nwant substring: %s\ngot:\n%s", want, msg)
}
}
func TestImport_missingResourceConfig(t *testing.T) {
defer testChdir(t, testFixturePath("import-missing-resource-config"))()
@ -499,7 +529,7 @@ func TestImport_missingModuleConfig(t *testing.T) {
}
msg := ui.ErrorWriter.String()
if want := `module.baz does not exist in the configuration`; !strings.Contains(msg, want) {
if want := `module.baz is not defined in the configuration`; !strings.Contains(msg, want) {
t.Errorf("incorrect message\nwant substring: %s\ngot:\n%s", want, msg)
}
}

View File

@ -0,0 +1,2 @@
This directory is intentionally empty, for testing any specialized error
messages that deal with empty configuration directories.