From f7e3179d7e6691c78ae924e929a02422ed62a156 Mon Sep 17 00:00:00 2001 From: Gabriel Monteiro Nepomuceno Date: Thu, 22 Jul 2021 16:19:51 +0100 Subject: [PATCH] Add basic module support for variable completion (#551) * Add basic module support for variable completion * Correct debug leftovers and standard file path use default go * Remove vscode specific debug file --- .gitignore | 1 + .vscode/launch.json | 20 +++++++++++++ go.mod | 2 +- go.sum | 5 ++-- internal/state/module.go | 32 +++++++++++++++++++++ internal/state/state.go | 6 ++++ internal/terraform/module/module_manager.go | 5 ++-- internal/terraform/module/module_ops.go | 17 +++++++++-- 8 files changed, 80 insertions(+), 8 deletions(-) create mode 100644 .vscode/launch.json diff --git a/.gitignore b/.gitignore index 801b3ad75..f13022484 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ internal/schemas/*log* internal/schemas/providers.tf internal/schemas/schemas_gen.go internal/schemas/data/ +terraform-ls diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 000000000..e0a51d45b --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,20 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Debug Server", + "type": "go", + "request": "launch", + "mode": "auto", + "program": "${workspaceFolder}", + "args": [ + "serve", + "--port", + "30337" + ] + } + ] +} \ No newline at end of file diff --git a/go.mod b/go.mod index eb327fb71..3f1cbc0bb 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( github.com/hashicorp/terraform-exec v0.14.0 github.com/hashicorp/terraform-json v0.12.0 github.com/hashicorp/terraform-registry-address v0.0.0-20210412075316-9b2996cce896 - github.com/hashicorp/terraform-schema v0.0.0-20210617130010-ab6887832578 + github.com/hashicorp/terraform-schema v0.0.0-20210722111916-2c53a3129d11 github.com/kylelemons/godebug v1.1.0 // indirect github.com/mh-cbon/go-fmt-fail v0.0.0-20160815164508-67765b3fbcb5 github.com/mitchellh/cli v1.1.2 diff --git a/go.sum b/go.sum index 9aa8ee756..25bbd062d 100644 --- a/go.sum +++ b/go.sum @@ -202,13 +202,12 @@ github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2p github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hashicorp/terraform-exec v0.14.0 h1:UQoUcxKTZZXhyyK68Cwn4mApT4mnFPmEXPiqaHL9r+w= github.com/hashicorp/terraform-exec v0.14.0/go.mod h1:qrAASDq28KZiMPDnQ02sFS9udcqEkRly002EA2izXTA= -github.com/hashicorp/terraform-json v0.11.0/go.mod h1:pmbq9o4EuL43db5+0ogX10Yofv1nozM+wskr/bGFJpI= github.com/hashicorp/terraform-json v0.12.0 h1:8czPgEEWWPROStjkWPUnTQDXmpmZPlkQAwYYLETaTvw= github.com/hashicorp/terraform-json v0.12.0/go.mod h1:pmbq9o4EuL43db5+0ogX10Yofv1nozM+wskr/bGFJpI= github.com/hashicorp/terraform-registry-address v0.0.0-20210412075316-9b2996cce896 h1:1FGtlkJw87UsTMg5s8jrekrHmUPUJaMcu6ELiVhQrNw= github.com/hashicorp/terraform-registry-address v0.0.0-20210412075316-9b2996cce896/go.mod h1:bzBPnUIkI0RxauU8Dqo+2KrZZ28Cf48s8V6IHt3p4co= -github.com/hashicorp/terraform-schema v0.0.0-20210617130010-ab6887832578 h1:r2zk8WVjkHqFCylDTukWwICfuZDh/5+p0S7A/MbHkeY= -github.com/hashicorp/terraform-schema v0.0.0-20210617130010-ab6887832578/go.mod h1:I401Q0vqx1AvDdh+ND7sC12x+C2sqmY5vTkc7FBjSvM= +github.com/hashicorp/terraform-schema v0.0.0-20210722111916-2c53a3129d11 h1:AmgdvpxCaq1rb90drpXqOafdPSR4084bOBtDthYrd7Y= +github.com/hashicorp/terraform-schema v0.0.0-20210722111916-2c53a3129d11/go.mod h1:2rBfUJC+1kyVzt5R/6pRa+d9HbpZrf8sMjQZdh8rSCM= github.com/hashicorp/terraform-svchost v0.0.0-20200729002733-f050f53b9734 h1:HKLsbzeOsfXmKNpr3GiT18XAblV0BjCbzL8KQAMZGa0= github.com/hashicorp/terraform-svchost v0.0.0-20200729002733-f050f53b9734/go.mod h1:kNDNcF7sN4DocDLBkQYz73HGKwN1ANB1blq4lIYLYvg= github.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw= diff --git a/internal/state/module.go b/internal/state/module.go index 7f3225d5b..da0b03f58 100644 --- a/internal/state/module.go +++ b/internal/state/module.go @@ -1,6 +1,8 @@ package state import ( + "path/filepath" + "github.com/hashicorp/go-memdb" "github.com/hashicorp/go-version" "github.com/hashicorp/hcl-lang/lang" @@ -247,6 +249,36 @@ func (s *ModuleStore) ModuleByPath(path string) (*Module, error) { return mod, nil } +func (s *ModuleStore) ModuleCalls(modPath string) ([]tfmod.ModuleCall, error) { + result := make([]tfmod.ModuleCall, 0) + modList, err := s.List() + for _, mod := range modList { + if mod.ModManifest != nil { + for _, record := range mod.ModManifest.Records { + result = append(result, tfmod.ModuleCall{ + SourceAddr: record.SourceAddr, + Path: filepath.Join(modPath, record.Dir), + }) + } + } + } + return result, err +} + +func (s *ModuleStore) ModuleMeta(modPath string) (*tfmod.Meta, error) { + mod, err := s.ModuleByPath(modPath) + if err != nil { + return nil, err + } + return &tfmod.Meta{ + Path: mod.Path, + ProviderReferences: mod.Meta.ProviderReferences, + ProviderRequirements: mod.Meta.ProviderRequirements, + CoreRequirements: mod.Meta.CoreRequirements, + Variables: mod.Meta.Variables, + }, nil +} + func moduleByPath(txn *memdb.Txn, path string) (*Module, error) { obj, err := txn.First(moduleTableName, "id", path) if err != nil { diff --git a/internal/state/state.go b/internal/state/state.go index edd6f2930..8faff52da 100644 --- a/internal/state/state.go +++ b/internal/state/state.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/go-memdb" "github.com/hashicorp/go-version" tfaddr "github.com/hashicorp/terraform-registry-address" + tfmod "github.com/hashicorp/terraform-schema/module" tfschema "github.com/hashicorp/terraform-schema/schema" ) @@ -64,6 +65,11 @@ type ModuleReader interface { List() ([]*Module, error) } +type ModuleCallReader interface { + ModuleCalls(modPath string) ([]tfmod.ModuleCall, error) + ModuleMeta(modPath string) (*tfmod.Meta, error) +} + type ProviderSchemaStore struct { db *memdb.MemDB tableName string diff --git a/internal/terraform/module/module_manager.go b/internal/terraform/module/module_manager.go index e88544868..6edc9db57 100644 --- a/internal/terraform/module/module_manager.go +++ b/internal/terraform/module/module_manager.go @@ -110,7 +110,7 @@ func (mm *moduleManager) SchemaForModule(modPath string) (*schema.BodySchema, er return nil, err } - return schemaForModule(mod, mm.schemaStore) + return schemaForModule(mod, mm.schemaStore, mm.moduleStore) } func (mm *moduleManager) SchemaForVariables(modPath string) (*schema.BodySchema, error) { @@ -123,7 +123,7 @@ func (mm *moduleManager) SchemaForVariables(modPath string) (*schema.BodySchema, return tfschema.SchemaForVariables(mod.Meta.Variables) } -func schemaForModule(mod *state.Module, schemaReader state.SchemaReader) (*schema.BodySchema, error) { +func schemaForModule(mod *state.Module, schemaReader state.SchemaReader, modReader state.ModuleCallReader) (*schema.BodySchema, error) { var coreSchema *schema.BodySchema coreRequirements := make(version.Constraints, 0) if mod.TerraformVersion != nil { @@ -143,6 +143,7 @@ func schemaForModule(mod *state.Module, schemaReader state.SchemaReader) (*schem sm := tfschema.NewSchemaMerger(coreSchema) sm.SetSchemaReader(schemaReader) sm.SetTerraformVersion(mod.TerraformVersion) + sm.SetModuleReader(modReader) meta := &tfmodule.Meta{ Path: mod.Path, diff --git a/internal/terraform/module/module_ops.go b/internal/terraform/module/module_ops.go index 0209e67f6..999bd63fc 100644 --- a/internal/terraform/module/module_ops.go +++ b/internal/terraform/module/module_ops.go @@ -296,8 +296,21 @@ func ParseModuleManifest(fs filesystem.Filesystem, modStore *state.ModuleStore, } return err } + if mm != nil { + for _, modRecord := range mm.Records { + modModulePath := filepath.Join(modPath, modRecord.Dir) + _, err := modStore.ModuleByPath(modModulePath) + if err != nil { + modStore.Add(modModulePath) + ParseModuleConfiguration(fs, modStore, modModulePath) + ParseVariables(fs, modStore, modModulePath) + LoadModuleMetadata(modStore, modModulePath) + } + } + } sErr := modStore.UpdateModManifest(modPath, mm, err) + if sErr != nil { return sErr } @@ -361,7 +374,7 @@ func DecodeReferenceTargets(modStore *state.ModuleStore, schemaReader state.Sche } } - fullSchema, schemaErr := schemaForModule(mod, schemaReader) + fullSchema, schemaErr := schemaForModule(mod, schemaReader, modStore) if schemaErr != nil { sErr := modStore.UpdateReferenceTargets(modPath, lang.ReferenceTargets{}, schemaErr) if sErr != nil { @@ -403,7 +416,7 @@ func DecodeReferenceOrigins(modStore *state.ModuleStore, schemaReader state.Sche } } - fullSchema, schemaErr := schemaForModule(mod, schemaReader) + fullSchema, schemaErr := schemaForModule(mod, schemaReader, modStore) if schemaErr != nil { sErr := modStore.UpdateReferenceOrigins(modPath, lang.ReferenceOrigins{}, schemaErr) if sErr != nil {