Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve messaging when TF installation is not found #401

Merged
merged 1 commit into from
Feb 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions internal/langserver/errors/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package errors

import (
e "errors"

"github.com/hashicorp/terraform-ls/internal/terraform/module"
)

func EnrichTfExecError(err error) error {
if module.IsTerraformNotFound(err) {
return e.New("Terraform (CLI) is required. " +
"Please install Terraform or make it available in $PATH")
}
return err
}
3 changes: 2 additions & 1 deletion internal/langserver/handlers/command/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/creachadair/jrpc2/code"
lsctx "github.com/hashicorp/terraform-ls/internal/context"
"github.com/hashicorp/terraform-ls/internal/langserver/cmd"
"github.com/hashicorp/terraform-ls/internal/langserver/errors"
"github.com/hashicorp/terraform-ls/internal/langserver/progress"
ilsp "github.com/hashicorp/terraform-ls/internal/lsp"
lsp "github.com/hashicorp/terraform-ls/internal/protocol"
Expand Down Expand Up @@ -40,7 +41,7 @@ func TerraformInitHandler(ctx context.Context, args cmd.CommandArgs) (interface{

tfExec, err := module.TerraformExecutorForModule(ctx, mod)
if err != nil {
return nil, err
return nil, errors.EnrichTfExecError(err)
}

progress.Begin(ctx, "Initializing")
Expand Down
3 changes: 2 additions & 1 deletion internal/langserver/handlers/command/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
lsctx "github.com/hashicorp/terraform-ls/internal/context"
"github.com/hashicorp/terraform-ls/internal/langserver/cmd"
"github.com/hashicorp/terraform-ls/internal/langserver/diagnostics"
"github.com/hashicorp/terraform-ls/internal/langserver/errors"
"github.com/hashicorp/terraform-ls/internal/langserver/progress"
ilsp "github.com/hashicorp/terraform-ls/internal/lsp"
lsp "github.com/hashicorp/terraform-ls/internal/protocol"
Expand Down Expand Up @@ -41,7 +42,7 @@ func TerraformValidateHandler(ctx context.Context, args cmd.CommandArgs) (interf

tfExec, err := module.TerraformExecutorForModule(ctx, mod)
if err != nil {
return nil, err
return nil, errors.EnrichTfExecError(err)
}

notifier, err := lsctx.Diagnostics(ctx)
Expand Down
8 changes: 8 additions & 0 deletions internal/langserver/handlers/did_open.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/google/uuid"
lsctx "github.com/hashicorp/terraform-ls/internal/context"
"github.com/hashicorp/terraform-ls/internal/langserver/cmd"
"github.com/hashicorp/terraform-ls/internal/langserver/errors"
"github.com/hashicorp/terraform-ls/internal/langserver/handlers/command"
ilsp "github.com/hashicorp/terraform-ls/internal/lsp"
lsp "github.com/hashicorp/terraform-ls/internal/protocol"
Expand Down Expand Up @@ -89,9 +90,16 @@ func (lh *logHandler) TextDocumentDidOpen(ctx context.Context, params lsp.DidOpe
return err
}

_, tfExecErr := module.TerraformExecPath(ctx, mod)

if walker.IsWalking() || mod.ProviderSchemaState() == module.OpStateLoading {
// avoid raising false warnings if operations are still in-flight
lh.logger.Printf("walker has not finished walking yet, data may be inaccurate for %s", f.FullPath())
} else if tfExecErr != nil {
jrpc2.PushNotify(ctx, "window/showMessage", lsp.ShowMessageParams{
Type: lsp.Error,
Message: errors.EnrichTfExecError(tfExecErr).Error(),
})
} else if len(sources) == 0 {
// TODO: Only notify once per f.Dir() per session
dh := ilsp.FileHandlerFromDirPath(f.Dir())
Expand Down
3 changes: 2 additions & 1 deletion internal/langserver/handlers/formatting.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (

lsctx "github.com/hashicorp/terraform-ls/internal/context"
"github.com/hashicorp/terraform-ls/internal/hcl"
"github.com/hashicorp/terraform-ls/internal/langserver/errors"
ilsp "github.com/hashicorp/terraform-ls/internal/lsp"
lsp "github.com/hashicorp/terraform-ls/internal/protocol"
"github.com/hashicorp/terraform-ls/internal/terraform/module"
Expand Down Expand Up @@ -32,7 +33,7 @@ func (h *logHandler) TextDocumentFormatting(ctx context.Context, params lsp.Docu

tfExec, err := module.TerraformExecutorForModule(ctx, mod)
if err != nil {
return edits, err
return edits, errors.EnrichTfExecError(err)
}

file, err := fs.GetDocument(fh)
Expand Down
14 changes: 14 additions & 0 deletions internal/terraform/module/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,17 @@ func IsModuleNotFound(err error) bool {
_, ok := err.(*ModuleNotFoundErr)
return ok
}

type NoTerraformExecPathErr struct{}

func (NoTerraformExecPathErr) Error() string {
return "No exec path provided for terraform"
}

func IsTerraformNotFound(err error) bool {
if err == nil {
return false
}
_, ok := err.(NoTerraformExecPathErr)
return ok
}
34 changes: 19 additions & 15 deletions internal/terraform/module/terraform_executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,17 @@ func TerraformExecutorForModule(ctx context.Context, mod Module) (exec.Terraform
return nil, fmt.Errorf("no terraform executor provided")
}

var tfExec exec.TerraformExecutor
var err error
execPath, err := TerraformExecPath(ctx, mod)
if err != nil {
return nil, err
}

opts, ok := exec.ExecutorOptsFromContext(ctx)
if ok && opts.ExecPath != "" {
tfExec, err = newExecutor(mod.Path(), opts.ExecPath)
if err != nil {
return nil, err
}
} else if mod.TerraformExecPath() != "" {
tfExec, err = newExecutor(mod.Path(), mod.TerraformExecPath())
if err != nil {
return nil, err
}
} else {
return nil, fmt.Errorf("no exec path provided for terraform")
tfExec, err := newExecutor(mod.Path(), execPath)
if err != nil {
return nil, err
}

opts, ok := exec.ExecutorOptsFromContext(ctx)
if ok && opts.ExecLogPath != "" {
tfExec.SetExecLogPath(opts.ExecLogPath)
}
Expand All @@ -40,3 +33,14 @@ func TerraformExecutorForModule(ctx context.Context, mod Module) (exec.Terraform

return tfExec, nil
}

func TerraformExecPath(ctx context.Context, mod Module) (string, error) {
opts, ok := exec.ExecutorOptsFromContext(ctx)
if ok && opts.ExecPath != "" {
return opts.ExecPath, nil
} else if mod.TerraformExecPath() != "" {
return mod.TerraformExecPath(), nil
} else {
return "", NoTerraformExecPathErr{}
}
}