Skip to content

Commit

Permalink
Introduce validation of tfvars files (WIP)
Browse files Browse the repository at this point in the history
  • Loading branch information
radeksimko committed Sep 19, 2023
1 parent 47cef5e commit e043d35
Show file tree
Hide file tree
Showing 6 changed files with 116 additions and 7 deletions.
20 changes: 20 additions & 0 deletions internal/indexer/document_change.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,26 @@ func (idx *Indexer) DocumentChanged(ctx context.Context, modHandle document.DirH
}
ids = append(ids, parseVarsId)

validationOptions, err := lsctx.ValidationOptions(ctx)
if err != nil {
return ids, err
}

if validationOptions.EarlyValidation {
_, err = idx.jobStore.EnqueueJob(ctx, job.Job{
Dir: modHandle,
Func: func(ctx context.Context) error {
return module.SchemaVariablesValidation(ctx, idx.modStore, idx.schemaStore, modHandle.Path())
},
Type: op.OpTypeSchemaVarsValidation.String(),
DependsOn: append(modIds, parseVarsId),
IgnoreState: true,
})
if err != nil {
return ids, err
}
}

varsRefsId, err := idx.jobStore.EnqueueJob(ctx, job.Job{
Dir: modHandle,
Func: func(ctx context.Context) error {
Expand Down
21 changes: 21 additions & 0 deletions internal/indexer/document_open.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"context"

"github.com/hashicorp/go-multierror"
lsctx "github.com/hashicorp/terraform-ls/internal/context"
"github.com/hashicorp/terraform-ls/internal/document"
"github.com/hashicorp/terraform-ls/internal/job"
"github.com/hashicorp/terraform-ls/internal/terraform/exec"
Expand Down Expand Up @@ -72,6 +73,26 @@ func (idx *Indexer) DocumentOpened(ctx context.Context, modHandle document.DirHa
}
ids = append(ids, parseVarsId)

validationOptions, err := lsctx.ValidationOptions(ctx)
if err != nil {
return ids, err
}

if validationOptions.EarlyValidation {
_, err = idx.jobStore.EnqueueJob(ctx, job.Job{
Dir: modHandle,
Func: func(ctx context.Context) error {
return module.SchemaVariablesValidation(ctx, idx.modStore, idx.schemaStore, modHandle.Path())
},
Type: op.OpTypeSchemaVarsValidation.String(),
DependsOn: append(modIds, parseVarsId),
IgnoreState: true,
})
if err != nil {
return ids, err
}
}

varsRefsId, err := idx.jobStore.EnqueueJob(ctx, job.Job{
Dir: modHandle,
Func: func(ctx context.Context) error {
Expand Down
2 changes: 1 addition & 1 deletion internal/state/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -988,7 +988,7 @@ func (s *ModuleStore) SetModuleDiagnosticsState(path string, source ast.Diagnost
func (s *ModuleStore) UpdateVarsDiagnostics(path string, source ast.DiagnosticSource, diags ast.VarsDiags) error {
txn := s.db.Txn(true)
txn.Defer(func() {
s.SetVarsDiagnosticsState(path, ast.HCLParsingSource, op.OpStateLoaded)
s.SetVarsDiagnosticsState(path, source, op.OpStateLoaded)
})
defer txn.Abort()

Expand Down
70 changes: 68 additions & 2 deletions internal/terraform/module/module_ops.go
Original file line number Diff line number Diff line change
Expand Up @@ -688,6 +688,8 @@ func SchemaValidation(ctx context.Context, modStore *state.ModuleStore, schemaRe
ModuleReader: modStore,
SchemaReader: schemaReader,
})

// TODO: specify validators
d.SetContext(idecoder.DecoderContext(ctx))

moduleDecoder, err := d.Path(lang.Path{
Expand All @@ -700,8 +702,72 @@ func SchemaValidation(ctx context.Context, modStore *state.ModuleStore, schemaRe

var rErr error
rpcContext := lsctx.RPCContext(ctx)
isSingleFileChange := rpcContext.Method == "textDocument/didChange"
if isSingleFileChange {
if rpcContext.Method == "textDocument/didChange" && lsctx.IsLanguageId(ctx, ilsp.Terraform.String()) {
filename := path.Base(rpcContext.URI)
// We only revalidate a single file that changed
var fileDiags hcl.Diagnostics
fileDiags, rErr = moduleDecoder.ValidateFile(ctx, filename)

modDiags, ok := mod.ModuleDiagnostics[ast.SchemaValidationSource]
if !ok {
modDiags = make(ast.ModDiags)
}
modDiags[ast.ModFilename(filename)] = fileDiags

sErr := modStore.UpdateModuleDiagnostics(modPath, ast.SchemaValidationSource, modDiags)
if sErr != nil {
return sErr
}
} else {
// We validate the whole module, e.g. on open
var diags lang.DiagnosticsMap
diags, rErr = moduleDecoder.Validate(ctx)

sErr := modStore.UpdateModuleDiagnostics(modPath, ast.SchemaValidationSource, ast.ModDiagsFromMap(diags))
if sErr != nil {
return sErr
}
}

return rErr
}

func SchemaVariablesValidation(ctx context.Context, modStore *state.ModuleStore, schemaReader state.SchemaReader, modPath string) error {
// TODO
mod, err := modStore.ModuleByPath(modPath)
if err != nil {
return err
}

// Avoid validation if it is already in progress or already finished
if mod.ModuleDiagnosticsState[ast.SchemaValidationSource] != op.OpStateUnknown && !job.IgnoreState(ctx) {
return job.StateNotChangedErr{Dir: document.DirHandleFromPath(modPath)}
}

err = modStore.SetModuleDiagnosticsState(modPath, ast.SchemaValidationSource, op.OpStateLoading)
if err != nil {
return err
}

d := decoder.NewDecoder(&idecoder.PathReader{
ModuleReader: modStore,
SchemaReader: schemaReader,
})

// TODO: specify validators
d.SetContext(idecoder.DecoderContext(ctx))

moduleDecoder, err := d.Path(lang.Path{
Path: modPath,
LanguageID: ilsp.Tfvars.String(),
})
if err != nil {
return err
}

var rErr error
rpcContext := lsctx.RPCContext(ctx)
if rpcContext.Method == "textDocument/didChange" && lsctx.IsLanguageId(ctx, ilsp.Tfvars.String()) {
filename := path.Base(rpcContext.URI)
// We only revalidate a single file that changed
var fileDiags hcl.Diagnostics
Expand Down
9 changes: 5 additions & 4 deletions internal/terraform/module/operation/op_type_string.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions internal/terraform/module/operation/operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ const (
OpTypeParseProviderVersions
OpTypePreloadEmbeddedSchema
OpTypeSchemaValidation
OpTypeSchemaVarsValidation
OpTypeReferenceValidation
OpTypeTerraformValidate
)

0 comments on commit e043d35

Please sign in to comment.