Skip to content

Commit

Permalink
Add utm parameters to module.* commands (#923)
Browse files Browse the repository at this point in the history
* Add utm parameters to module.* commands

* update test data

* log error instead of returning it
  • Loading branch information
radeksimko authored May 31, 2022
1 parent dd6733a commit ba5501c
Show file tree
Hide file tree
Showing 10 changed files with 104 additions and 23 deletions.
8 changes: 3 additions & 5 deletions internal/decoder/decoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
lsp "github.com/hashicorp/terraform-ls/internal/protocol"
"github.com/hashicorp/terraform-ls/internal/state"
"github.com/hashicorp/terraform-ls/internal/terraform/ast"
"github.com/hashicorp/terraform-ls/internal/utm"
tfschema "github.com/hashicorp/terraform-schema/schema"
)

Expand Down Expand Up @@ -80,7 +81,8 @@ func varsPathContext(mod *state.Module) (*decoder.PathContext, error) {

func decoderContext(ctx context.Context) decoder.DecoderContext {
dCtx := decoder.DecoderContext{
UtmSource: "terraform-ls",
UtmSource: utm.UtmSource,
UtmMedium: utm.UtmMedium(ctx),
UseUtmContent: true,
}

Expand All @@ -92,9 +94,5 @@ func decoderContext(ctx context.Context) decoder.DecoderContext {
}
}

clientName, ok := ilsp.ClientName(ctx)
if ok {
dCtx.UtmMedium = clientName
}
return dCtx
}
29 changes: 29 additions & 0 deletions internal/langserver/handlers/command/docs_url.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package command

import (
"context"
"net/url"

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

func docsURL(ctx context.Context, rawURL, utmContent string) (*url.URL, error) {
u, err := url.Parse(rawURL)
if err != nil {
return nil, err
}

q := u.Query()
q.Set("utm_source", utm.UtmSource)
if medium := utm.UtmMedium(ctx); medium != "" {
q.Set("utm_medium", medium)
}

if utmContent != "" {
q.Set("utm_content", utmContent)
}

u.RawQuery = q.Encode()

return u, nil
}
7 changes: 6 additions & 1 deletion internal/langserver/handlers/command/handler.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
package command

import "github.com/hashicorp/terraform-ls/internal/state"
import (
"log"

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

type CmdHandler struct {
StateStore *state.StateStore
Logger *log.Logger
}
25 changes: 19 additions & 6 deletions internal/langserver/handlers/command/module_calls.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,12 @@ func (h *CmdHandler) ModuleCallsHandler(ctx context.Context, args cmd.CommandArg
return response, nil
}

response.ModuleCalls = parseModuleRecords(found.ModManifest.Records)
response.ModuleCalls = h.parseModuleRecords(ctx, found.ModManifest.Records)

return response, nil
}

func parseModuleRecords(records []datadir.ModuleRecord) []moduleCall {
func (h *CmdHandler) parseModuleRecords(ctx context.Context, records []datadir.ModuleRecord) []moduleCall {
// sort all records by key so that dependent modules are found
// after primary modules
sort.SliceStable(records, func(i, j int) bool {
Expand All @@ -89,11 +89,16 @@ func parseModuleRecords(records []datadir.ModuleRecord) []moduleCall {
subModuleName = v[1]
}

docsLink, err := getModuleDocumentationLink(ctx, manifest)
if err != nil {
h.Logger.Printf("failed to get module docs link: %s", err)
}

// build what we know
moduleInfo := moduleCall{
Name: moduleName,
SourceAddr: manifest.SourceAddr,
DocsLink: getModuleDocumentationLink(manifest),
DocsLink: docsLink,
Version: manifest.VersionStr,
SourceType: manifest.GetModuleType(),
DependentModules: make([]moduleCall, 0),
Expand Down Expand Up @@ -124,11 +129,19 @@ func parseModuleRecords(records []datadir.ModuleRecord) []moduleCall {
return list
}

func getModuleDocumentationLink(record datadir.ModuleRecord) string {
func getModuleDocumentationLink(ctx context.Context, record datadir.ModuleRecord) (string, error) {
if record.GetModuleType() != datadir.TFREGISTRY {
return ""
return "", nil
}

shortName := strings.TrimPrefix(record.SourceAddr, "registry.terraform.io/")
return fmt.Sprintf(`https://registry.terraform.io/modules/%s/%s`, shortName, record.VersionStr)

rawURL := fmt.Sprintf(`https://registry.terraform.io/modules/%s/%s`, shortName, record.VersionStr)

u, err := docsURL(ctx, rawURL, "workspace/executeCommand/module.calls")
if err != nil {
return "", err
}

return u.String(), nil
}
15 changes: 10 additions & 5 deletions internal/langserver/handlers/command/module_calls_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package command

import (
"context"
"testing"

"github.com/google/go-cmp/cmp"
Expand Down Expand Up @@ -47,15 +48,15 @@ func Test_parseModuleRecords(t *testing.T) {
SourceAddr: "terraform-aws-modules/ec2-instance/aws",
Version: "2.12.0",
SourceType: "tfregistry",
DocsLink: "https://registry.terraform.io/modules/terraform-aws-modules/ec2-instance/aws/2.12.0",
DocsLink: "https://registry.terraform.io/modules/terraform-aws-modules/ec2-instance/aws/2.12.0?utm_content=workspace%2FexecuteCommand%2Fmodule.calls&utm_source=terraform-ls",
DependentModules: []moduleCall{},
},
{
Name: "eks",
SourceAddr: "terraform-aws-modules/eks/aws",
Version: "17.20.0",
SourceType: "tfregistry",
DocsLink: "https://registry.terraform.io/modules/terraform-aws-modules/eks/aws/17.20.0",
DocsLink: "https://registry.terraform.io/modules/terraform-aws-modules/eks/aws/17.20.0?utm_content=workspace%2FexecuteCommand%2Fmodule.calls&utm_source=terraform-ls",
DependentModules: []moduleCall{
{
Name: "fargate",
Expand All @@ -80,7 +81,9 @@ func Test_parseModuleRecords(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := parseModuleRecords(tt.records)
ctx := context.Background()
h := &CmdHandler{}
got := h.parseModuleRecords(ctx, tt.records)
if diff := cmp.Diff(tt.want, got); diff != "" {
t.Fatalf("module mismatch: %s", diff)
}
Expand Down Expand Up @@ -111,15 +114,17 @@ func Test_parseModuleRecords_v1_1(t *testing.T) {
SourceAddr: "registry.terraform.io/terraform-aws-modules/ec2-instance/aws",
Version: "2.12.0",
SourceType: "tfregistry",
DocsLink: "https://registry.terraform.io/modules/terraform-aws-modules/ec2-instance/aws/2.12.0",
DocsLink: "https://registry.terraform.io/modules/terraform-aws-modules/ec2-instance/aws/2.12.0?utm_content=workspace%2FexecuteCommand%2Fmodule.calls&utm_source=terraform-ls",
DependentModules: []moduleCall{},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := parseModuleRecords(tt.records)
ctx := context.Background()
h := &CmdHandler{}
got := h.parseModuleRecords(ctx, tt.records)
if diff := cmp.Diff(tt.want, got); diff != "" {
t.Fatalf("module mismatch: %s", diff)
}
Expand Down
19 changes: 15 additions & 4 deletions internal/langserver/handlers/command/module_providers.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,14 @@ func (h *CmdHandler) ModuleProvidersHandler(ctx context.Context, args cmd.Comman
}

for provider, version := range mod.Meta.ProviderRequirements {
docsLink, err := getProviderDocumentationLink(ctx, provider)
if err != nil {
return response, err
}
response.ProviderRequirements[provider.String()] = providerRequirement{
DisplayName: provider.ForDisplay(),
VersionConstraint: version.String(),
DocsLink: getProviderDocumentationLink(provider),
DocsLink: docsLink,
}
}

Expand All @@ -70,10 +74,17 @@ func (h *CmdHandler) ModuleProvidersHandler(ctx context.Context, args cmd.Comman
return response, nil
}

func getProviderDocumentationLink(provider tfaddr.Provider) string {
func getProviderDocumentationLink(ctx context.Context, provider tfaddr.Provider) (string, error) {
if provider.IsLegacy() || provider.IsBuiltIn() || provider.Hostname != "registry.terraform.io" {
return ""
return "", nil
}

rawURL := fmt.Sprintf(`https://registry.terraform.io/providers/%s/latest`, provider.ForDisplay())

u, err := docsURL(ctx, rawURL, "workspace/executeCommand/module.providers")
if err != nil {
return "", err
}

return fmt.Sprintf(`https://registry.terraform.io/providers/%s/latest`, provider.ForDisplay())
return u.String(), nil
}
1 change: 1 addition & 0 deletions internal/langserver/handlers/execute_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
func cmdHandlers(svc *service) cmd.Handlers {
cmdHandler := &command.CmdHandler{
StateStore: svc.stateStore,
Logger: svc.logger,
}
return cmd.Handlers{
cmd.Name("rootmodules"): removedHandler("use module.callers instead"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,12 +143,12 @@ func TestLangServer_workspaceExecuteCommand_moduleProviders_basic(t *testing.T)
"registry.terraform.io/hashicorp/aws": {
"display_name": "hashicorp/aws",
"version_constraint":"1.2.3",
"docs_link": "https://registry.terraform.io/providers/hashicorp/aws/latest"
"docs_link": "https://registry.terraform.io/providers/hashicorp/aws/latest?utm_content=workspace%2FexecuteCommand%2Fmodule.providers\u0026utm_source=terraform-ls"
},
"registry.terraform.io/hashicorp/google": {
"display_name": "hashicorp/google",
"version_constraint": "\u003e= 2.0.0",
"docs_link": "https://registry.terraform.io/providers/hashicorp/google/latest"
"docs_link": "https://registry.terraform.io/providers/hashicorp/google/latest?utm_content=workspace%2FexecuteCommand%2Fmodule.providers\u0026utm_source=terraform-ls"
}
},
"installed_providers":{
Expand Down
1 change: 1 addition & 0 deletions internal/langserver/handlers/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,7 @@ func (svc *service) Assigner() (jrpc2.Assigner, error) {
ctx = lsctx.WithWatcher(ctx, svc.watcher)
ctx = lsctx.WithRootDirectory(ctx, &rootDir)
ctx = lsctx.WithDiagnosticsNotifier(ctx, svc.diagsNotifier)
ctx = ilsp.ContextWithClientName(ctx, &clientName)
ctx = exec.WithExecutorOpts(ctx, svc.tfExecOpts)
ctx = exec.WithExecutorFactory(ctx, svc.tfExecFactory)

Expand Down
18 changes: 18 additions & 0 deletions internal/utm/utm.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package utm

import (
"context"

ilsp "github.com/hashicorp/terraform-ls/internal/lsp"
)

const UtmSource = "terraform-ls"

func UtmMedium(ctx context.Context) string {
clientName, ok := ilsp.ClientName(ctx)
if ok {
return clientName
}

return ""
}

0 comments on commit ba5501c

Please sign in to comment.