-
Notifications
You must be signed in to change notification settings - Fork 131
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
Validate On Save #340
Validate On Save #340
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package handlers | ||
|
||
import ( | ||
"context" | ||
|
||
lsctx "github.com/hashicorp/terraform-ls/internal/context" | ||
"github.com/hashicorp/terraform-ls/internal/langserver/cmd" | ||
"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" | ||
) | ||
|
||
func (lh *logHandler) TextDocumentDidSave(ctx context.Context, params lsp.DidSaveTextDocumentParams) error { | ||
expFeatures, err := lsctx.ExperimentalFeatures(ctx) | ||
if err != nil { | ||
return err | ||
} | ||
if !expFeatures.ValidateOnSave { | ||
return nil | ||
} | ||
|
||
fh := ilsp.FileHandlerFromDocumentURI(params.TextDocument.URI) | ||
dh := ilsp.FileHandlerFromDirPath(fh.Dir()) | ||
|
||
_, err = command.TerraformValidateHandler(ctx, cmd.CommandArgs{ | ||
"uri": dh.URI(), | ||
}) | ||
|
||
return err | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -394,9 +394,44 @@ func (rm *rootModule) ExecuteTerraformValidate(ctx context.Context) (map[string] | |
} | ||
|
||
// an entry for each file should exist, even if there are no diags | ||
for filename := range rm.pFilesMap { | ||
for filename := range rm.parsedFiles() { | ||
diagsMap[filename] = make(hcl.Diagnostics, 0) | ||
} | ||
// since validation applies to linked modules, create an entry for all | ||
// files of linked modules | ||
for _, m := range rm.moduleManifest.Records { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a reason for reading the module manifest here? Could we not create the entries "lazily" automatically below? e.g. something like diags, ok := diagsMap[d.Range.Filename]
if !ok {
diagsMap[d.Range.Filename] = make(hcl.Diagnostics, 0)
diags = diagsMap[d.Range.Filename]
} I understand there is a need for filtering out submodule diags, but couldn't this be done via something like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ah I don't believe so no, the point of this is to create an entry in the map for every possible file, so that clearing diagnostics over the protocol works correctly. I also authored this a while though so I can't describe it in detail, but we can revisit/refactor in follow ups |
||
if m.IsRoot() { | ||
// skip root modules | ||
continue | ||
} | ||
if m.IsExternal() { | ||
// skip external modules | ||
continue | ||
} | ||
|
||
absPath := filepath.Join(rm.moduleManifest.rootDir, m.Dir) | ||
infos, err := rm.filesystem.ReadDir(absPath) | ||
if err != nil { | ||
return diagsMap, fmt.Errorf("failed to read module at %q: %w", absPath, err) | ||
} | ||
|
||
for _, info := range infos { | ||
if info.IsDir() { | ||
// We only care about files | ||
continue | ||
} | ||
|
||
name := info.Name() | ||
if !strings.HasSuffix(name, ".tf") || IsIgnoredFile(name) { | ||
continue | ||
} | ||
|
||
// map entries are relative to the parent module path | ||
filename := filepath.Join(m.Dir, name) | ||
|
||
diagsMap[filename] = make(hcl.Diagnostics, 0) | ||
} | ||
} | ||
|
||
validationDiags, err := rm.tfExec.Validate(ctx) | ||
if err != nil { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch! Looks like this was previously prone to race conditions if we were parsing files (and hence writing into the map) while also reading from that map.