diff --git a/internal/terraform/rootmodule/errors.go b/internal/terraform/rootmodule/errors.go index a017710ee..d064fef9e 100644 --- a/internal/terraform/rootmodule/errors.go +++ b/internal/terraform/rootmodule/errors.go @@ -14,3 +14,11 @@ func (e *RootModuleNotFoundErr) Error() string { } return "root module not found" } + +func IsRootModuleNotFound(err error) bool { + if err == nil { + return false + } + _, ok := err.(*RootModuleNotFoundErr) + return ok +} diff --git a/internal/terraform/rootmodule/root_module_manager.go b/internal/terraform/rootmodule/root_module_manager.go index 73f405f7f..31c8158a1 100644 --- a/internal/terraform/rootmodule/root_module_manager.go +++ b/internal/terraform/rootmodule/root_module_manager.go @@ -159,15 +159,42 @@ func (rmm *rootModuleManager) ParserForDir(path string) (lang.Parser, error) { return rm.Parser(), nil } -func (rmm *rootModuleManager) TerraformExecutorForDir(path string) (*exec.Executor, error) { +func (rmm *rootModuleManager) TerraformExecutorForDir(ctx context.Context, path string) (*exec.Executor, error) { rm, err := rmm.RootModuleByPath(path) - if err != nil { - return nil, err + if err != nil && IsRootModuleNotFound(err) { + return rmm.terraformExecutorForDir(ctx, path) } return rm.TerraformExecutor(), nil } +func (rmm *rootModuleManager) terraformExecutorForDir(ctx context.Context, dir string) (*exec.Executor, error) { + tfPath := rmm.tfExecPath + if tfPath == "" { + var err error + d := &discovery.Discovery{} + tfPath, err = d.LookPath() + if err != nil { + return nil, err + } + } + + tf := exec.NewExecutor(ctx, tfPath) + + tf.SetWorkdir(dir) + tf.SetLogger(rmm.logger) + + if rmm.tfExecLogPath != "" { + tf.SetExecLogPath(rmm.tfExecLogPath) + } + + if rmm.tfExecTimeout != 0 { + tf.SetTimeout(rmm.tfExecTimeout) + } + + return tf, nil +} + // rootModuleDirFromPath strips known lock file paths and filenames // to get the directory path of the relevant rootModule func rootModuleDirFromFilePath(filePath string) string { diff --git a/internal/terraform/rootmodule/types.go b/internal/terraform/rootmodule/types.go index f99099051..69558b8e9 100644 --- a/internal/terraform/rootmodule/types.go +++ b/internal/terraform/rootmodule/types.go @@ -18,7 +18,7 @@ type ParserFinder interface { } type TerraformExecFinder interface { - TerraformExecutorForDir(path string) (*exec.Executor, error) + TerraformExecutorForDir(ctx context.Context, path string) (*exec.Executor, error) } type RootModuleCandidateFinder interface { diff --git a/langserver/handlers/formatting.go b/langserver/handlers/formatting.go index 9b0faa4e6..7bf838e29 100644 --- a/langserver/handlers/formatting.go +++ b/langserver/handlers/formatting.go @@ -28,7 +28,7 @@ func (h *logHandler) TextDocumentFormatting(ctx context.Context, params lsp.Docu return edits, err } - tf, err := tff.TerraformExecutorForDir(fh.Dir()) + tf, err := tff.TerraformExecutorForDir(ctx, fh.Dir()) if err != nil { // TODO: detect no root module found error // -> find OS-wide executor instead