diff --git a/command/import.go b/command/import.go index 93ab80495..6d72adae4 100644 --- a/command/import.go +++ b/command/import.go @@ -62,9 +62,11 @@ func (c *ImportCommand) Run(args []string) int { var diags tfdiags.Diagnostics // Parse the provided resource address. - traversal, travDiags := hclsyntax.ParseTraversalAbs([]byte(args[0]), "", hcl.Pos{Line: 1, Column: 1}) + traversalSrc := []byte(args[0]) + traversal, travDiags := hclsyntax.ParseTraversalAbs(traversalSrc, "", hcl.Pos{Line: 1, Column: 1}) diags = diags.Append(travDiags) if travDiags.HasErrors() { + c.registerSynthConfigSource("", traversalSrc) // so we can include a source snippet c.showDiagnostics(diags) c.Ui.Info(importCommandInvalidAddressReference) return 1 @@ -72,6 +74,7 @@ func (c *ImportCommand) Run(args []string) int { addr, addrDiags := addrs.ParseAbsResourceInstance(traversal) diags = diags.Append(addrDiags) if addrDiags.HasErrors() { + c.registerSynthConfigSource("", traversalSrc) // so we can include a source snippet c.showDiagnostics(diags) c.Ui.Info(importCommandInvalidAddressReference) return 1 diff --git a/command/import_test.go b/command/import_test.go index 0f2c381d7..148182147 100644 --- a/command/import_test.go +++ b/command/import_test.go @@ -594,7 +594,7 @@ func TestImport_dataResource(t *testing.T) { } msg := ui.ErrorWriter.String() - if want := `resource address must refer to a managed resource`; !strings.Contains(msg, want) { + if want := `A managed resource address is required`; !strings.Contains(msg, want) { t.Errorf("incorrect message\nwant substring: %s\ngot:\n%s", want, msg) } } @@ -624,7 +624,7 @@ func TestImport_invalidResourceAddr(t *testing.T) { } msg := ui.ErrorWriter.String() - if want := `invalid resource address "bananas"`; !strings.Contains(msg, want) { + if want := `Error: Invalid address`; !strings.Contains(msg, want) { t.Errorf("incorrect message\nwant substring: %s\ngot:\n%s", want, msg) } } @@ -654,7 +654,7 @@ func TestImport_targetIsModule(t *testing.T) { } msg := ui.ErrorWriter.String() - if want := `resource address must include a full resource spec`; !strings.Contains(msg, want) { + if want := `Error: Invalid address`; !strings.Contains(msg, want) { t.Errorf("incorrect message\nwant substring: %s\ngot:\n%s", want, msg) } } diff --git a/command/meta_config.go b/command/meta_config.go index dd2315c50..5a7385a31 100644 --- a/command/meta_config.go +++ b/command/meta_config.go @@ -309,6 +309,25 @@ func (m *Meta) modulesDir() string { return filepath.Join(m.DataDir(), "modules") } +// registerSynthConfigSource allows commands to add synthetic additional source +// buffers to the config loader's cache of sources (as returned by +// configSources), which is useful when a command is directly parsing something +// from the command line that may produce diagnostics, so that diagnostic +// snippets can still be produced. +// +// If this is called before a configLoader has been initialized then it will +// try to initialize the loader but ignore any initialization failure, turning +// the call into a no-op. (We presume that a caller will later call a different +// function that also initializes the config loader as a side effect, at which +// point those errors can be returned.) +func (m *Meta) registerSynthConfigSource(filename string, src []byte) { + loader, err := m.initConfigLoader() + if err != nil || loader == nil { + return // treated as no-op, since this is best-effort + } + loader.Parser().ForceFileSource(filename, src) +} + // initConfigLoader initializes the shared configuration loader if it isn't // already initialized. //