-
Notifications
You must be signed in to change notification settings - Fork 131
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Update hcl-lang to b66451 * Expose registry client to completion hooks * Use Range when creating module calls * Implement completion for local module sources * Extend TF registry for getting module versions * Implement completion for module versions * Implement completion for registry module sources * Expose algolia credentials on main * Review feedback * Update goreleaser config with Algolia credentials * Add logging to registry hook
- Loading branch information
Showing
20 changed files
with
748 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package main | ||
|
||
// Algolia application ID which should be used for searching Terraform registry modules | ||
var algoliaAppID = "" | ||
|
||
// Algolia API key which should be used for searching Terraform registry modules | ||
var algoliaAPIKey = "" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package algolia | ||
|
||
import "context" | ||
|
||
var credentialsKey struct{} | ||
|
||
type Credentials struct { | ||
AppID string | ||
APIKey string | ||
} | ||
|
||
func WithCredentials(ctx context.Context, appID, apiKey string) context.Context { | ||
return context.WithValue(ctx, credentialsKey, Credentials{ | ||
AppID: appID, | ||
APIKey: apiKey, | ||
}) | ||
} | ||
|
||
func CredentialsFromContext(ctx context.Context) (Credentials, bool) { | ||
credentials, ok := ctx.Value(credentialsKey).(Credentials) | ||
return credentials, ok | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
package hooks | ||
|
||
import ( | ||
"context" | ||
"path/filepath" | ||
"testing" | ||
|
||
"github.com/google/go-cmp/cmp" | ||
"github.com/hashicorp/hcl-lang/decoder" | ||
"github.com/hashicorp/hcl-lang/lang" | ||
"github.com/hashicorp/terraform-ls/internal/state" | ||
"github.com/zclconf/go-cty/cty" | ||
) | ||
|
||
func TestHooks_LocalModuleSources(t *testing.T) { | ||
ctx := context.Background() | ||
tmpDir := t.TempDir() | ||
|
||
ctx = decoder.WithPath(ctx, lang.Path{ | ||
Path: tmpDir, | ||
LanguageID: "terraform", | ||
}) | ||
s, err := state.NewStateStore() | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
h := &Hooks{ | ||
ModStore: s.Modules, | ||
} | ||
|
||
modules := []string{ | ||
tmpDir, | ||
filepath.Join(tmpDir, "alpha"), | ||
filepath.Join(tmpDir, "beta"), | ||
filepath.Join(tmpDir, "..", "gamma"), | ||
filepath.Join(".terraform", "modules", "web_server_sg"), | ||
filepath.Join(tmpDir, "any.terraformany"), | ||
filepath.Join(tmpDir, "any.terraform"), | ||
filepath.Join(tmpDir, ".terraformany"), | ||
} | ||
|
||
for _, mod := range modules { | ||
err := s.Modules.Add(mod) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
} | ||
|
||
expectedCandidates := []decoder.Candidate{ | ||
{ | ||
Label: "\"./.terraformany\"", | ||
Detail: "local", | ||
Kind: lang.StringCandidateKind, | ||
RawInsertText: "\"./.terraformany\"", | ||
}, | ||
{ | ||
Label: "\"./alpha\"", | ||
Detail: "local", | ||
Kind: lang.StringCandidateKind, | ||
RawInsertText: "\"./alpha\"", | ||
}, | ||
{ | ||
Label: "\"./any.terraform\"", | ||
Detail: "local", | ||
Kind: lang.StringCandidateKind, | ||
RawInsertText: "\"./any.terraform\"", | ||
}, | ||
{ | ||
Label: "\"./any.terraformany\"", | ||
Detail: "local", | ||
Kind: lang.StringCandidateKind, | ||
RawInsertText: "\"./any.terraformany\"", | ||
}, | ||
{ | ||
Label: "\"./beta\"", | ||
Detail: "local", | ||
Kind: lang.StringCandidateKind, | ||
RawInsertText: "\"./beta\"", | ||
}, | ||
{ | ||
Label: "\"../gamma\"", | ||
Detail: "local", | ||
Kind: lang.StringCandidateKind, | ||
RawInsertText: "\"../gamma\"", | ||
}, | ||
} | ||
|
||
candidates, _ := h.LocalModuleSources(ctx, cty.StringVal("")) | ||
if diff := cmp.Diff(expectedCandidates, candidates); diff != "" { | ||
t.Fatalf("mismatched candidates: %s", diff) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
package hooks | ||
|
||
import ( | ||
"context" | ||
"strings" | ||
|
||
"github.com/algolia/algoliasearch-client-go/v3/algolia/opt" | ||
"github.com/hashicorp/hcl-lang/decoder" | ||
"github.com/hashicorp/hcl-lang/lang" | ||
"github.com/zclconf/go-cty/cty" | ||
) | ||
|
||
type RegistryModule struct { | ||
FullName string `json:"full-name"` | ||
Description string `json:"description"` | ||
} | ||
|
||
const algoliaModuleIndex = "tf-registry:prod:modules" | ||
|
||
func (h *Hooks) fetchModulesFromAlgolia(ctx context.Context, term string) ([]RegistryModule, error) { | ||
modules := make([]RegistryModule, 0) | ||
|
||
index := h.AlgoliaClient.InitIndex(algoliaModuleIndex) | ||
params := []interface{}{ | ||
ctx, // transport.Request will magically extract the context from here | ||
opt.AttributesToRetrieve("full-name", "description"), | ||
opt.HitsPerPage(10), | ||
} | ||
|
||
res, err := index.Search(term, params...) | ||
if err != nil { | ||
return modules, err | ||
} | ||
|
||
err = res.UnmarshalHits(&modules) | ||
if err != nil { | ||
return modules, err | ||
|
||
} | ||
|
||
return modules, nil | ||
} | ||
|
||
func (h *Hooks) RegistryModuleSources(ctx context.Context, value cty.Value) ([]decoder.Candidate, error) { | ||
candidates := make([]decoder.Candidate, 0) | ||
prefix := value.AsString() | ||
|
||
if isModuleSourceLocal(prefix) { | ||
// We're dealing with a local module source here, no need to search the registry | ||
return candidates, nil | ||
} | ||
|
||
if h.AlgoliaClient == nil { | ||
return candidates, nil | ||
} | ||
|
||
modules, err := h.fetchModulesFromAlgolia(ctx, prefix) | ||
if err != nil { | ||
h.Logger.Printf("Error fetching modules from Algolia: %#v", err) | ||
return candidates, err | ||
} | ||
|
||
for _, mod := range modules { | ||
c := decoder.ExpressionCompletionCandidate(decoder.ExpressionCandidate{ | ||
Value: cty.StringVal(mod.FullName), | ||
Detail: "registry", | ||
Description: lang.PlainText(mod.Description), | ||
}) | ||
candidates = append(candidates, c) | ||
} | ||
|
||
return candidates, nil | ||
} | ||
|
||
var moduleSourceLocalPrefixes = []string{ | ||
"./", | ||
"../", | ||
".\\", | ||
"..\\", | ||
} | ||
|
||
func isModuleSourceLocal(raw string) bool { | ||
for _, prefix := range moduleSourceLocalPrefixes { | ||
if strings.HasPrefix(raw, prefix) { | ||
return true | ||
} | ||
} | ||
return false | ||
} |
Oops, something went wrong.