Skip to content

Commit

Permalink
Merge pull request #86 from hashicorp/refactor-context
Browse files Browse the repository at this point in the history
context: Refactor and fix duplicate key
  • Loading branch information
radeksimko authored May 19, 2020
2 parents 906c368 + 85d3384 commit db9a7e6
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 50 deletions.
78 changes: 28 additions & 50 deletions internal/context/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,36 @@ package context

import (
"context"
"fmt"
"log"
"os"
"os/signal"

"github.com/hashicorp/terraform-ls/internal/filesystem"
"github.com/hashicorp/terraform-ls/internal/terraform/exec"
"github.com/hashicorp/terraform-ls/internal/terraform/schema"
"github.com/sourcegraph/go-lsp"
)

func WithSignalCancel(ctx context.Context, l *log.Logger, sigs ...os.Signal) (
context.Context, context.CancelFunc) {
ctx, cancelFunc := context.WithCancel(ctx)

sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, sigs...)

go func() {
select {
case sig := <-sigChan:
l.Printf("Cancellation signal (%s) received", sig)
cancelFunc()
case <-ctx.Done():
}
}()

f := func() {
signal.Stop(sigChan)
cancelFunc()
}
type contextKey struct {
Name string
}

return ctx, f
func (k *contextKey) String() string {
return k.Name
}

const ctxFs = "ctxFilesystem"
var (
ctxFs = &contextKey{"filesystem"}
ctxTerraformExec = &contextKey{"terraform executor"}
ctxClientCapsSetter = &contextKey{"client capabilities setter"}
ctxClientCaps = &contextKey{"client capabilities"}
ctxTfSchemaWriter = &contextKey{"schema writer"}
ctxTfSchemaReader = &contextKey{"schema reader"}
ctxTfVersion = &contextKey{"terraform version"}
ctxTfVersionSetter = &contextKey{"terraform version setter"}
ctxTfExecLogPath = &contextKey{"terraform executor log path"}
)

func missingContextErr(ctxKey *contextKey) *MissingContextErr {
return &MissingContextErr{ctxKey}
}

func WithFilesystem(fs filesystem.Filesystem, ctx context.Context) context.Context {
return context.WithValue(ctx, ctxFs, fs)
Expand All @@ -46,121 +40,105 @@ func WithFilesystem(fs filesystem.Filesystem, ctx context.Context) context.Conte
func Filesystem(ctx context.Context) (filesystem.Filesystem, error) {
fs, ok := ctx.Value(ctxFs).(filesystem.Filesystem)
if !ok {
return nil, fmt.Errorf("no filesystem")
return nil, missingContextErr(ctxFs)
}

return fs, nil
}

const ctxTerraformExec = "ctxTerraformExec"

func WithTerraformExecutor(tf *exec.Executor, ctx context.Context) context.Context {
return context.WithValue(ctx, ctxTerraformExec, tf)
}

func TerraformExecutor(ctx context.Context) (*exec.Executor, error) {
tf, ok := ctx.Value(ctxTerraformExec).(*exec.Executor)
if !ok {
return nil, fmt.Errorf("no terraform executor")
return nil, missingContextErr(ctxTerraformExec)
}

return tf, nil
}

const ctxClientCapsSetter = "ctxClientCapabilitiesSetter"

func WithClientCapabilitiesSetter(caps *lsp.ClientCapabilities, ctx context.Context) context.Context {
return context.WithValue(ctx, ctxClientCapsSetter, caps)
}

func SetClientCapabilities(ctx context.Context, caps *lsp.ClientCapabilities) error {
cc, ok := ctx.Value(ctxClientCapsSetter).(*lsp.ClientCapabilities)
if !ok {
return fmt.Errorf("no client capabilities setter")
return missingContextErr(ctxClientCapsSetter)
}

*cc = *caps
return nil
}

const ctxClientCaps = "ctxClientCapabilities"

func WithClientCapabilities(caps *lsp.ClientCapabilities, ctx context.Context) context.Context {
return context.WithValue(ctx, ctxClientCaps, caps)
}

func ClientCapabilities(ctx context.Context) (lsp.ClientCapabilities, error) {
caps, ok := ctx.Value(ctxClientCaps).(*lsp.ClientCapabilities)
if !ok {
return lsp.ClientCapabilities{}, fmt.Errorf("no client capabilities")
return lsp.ClientCapabilities{}, missingContextErr(ctxClientCaps)
}

return *caps, nil
}

const ctxTfSchemaWriter = "ctxTerraformSchemaWriter"

func WithTerraformSchemaWriter(s schema.Writer, ctx context.Context) context.Context {
return context.WithValue(ctx, ctxTfSchemaWriter, s)
}

func TerraformSchemaWriter(ctx context.Context) (schema.Writer, error) {
ss, ok := ctx.Value(ctxTfSchemaWriter).(schema.Writer)
if !ok {
return nil, fmt.Errorf("no terraform schema writer")
return nil, missingContextErr(ctxTfSchemaWriter)
}

return ss, nil
}

const ctxTfSchemaReader = "ctxTerraformSchemaWriter"

func WithTerraformSchemaReader(s schema.Reader, ctx context.Context) context.Context {
return context.WithValue(ctx, ctxTfSchemaReader, s)
}

func TerraformSchemaReader(ctx context.Context) (schema.Reader, error) {
ss, ok := ctx.Value(ctxTfSchemaReader).(schema.Reader)
if !ok {
return nil, fmt.Errorf("no terraform schema reader")
return nil, missingContextErr(ctxTfSchemaReader)
}

return ss, nil
}

const ctxTfVersion = "ctxTerraformVersion"

func WithTerraformVersion(v string, ctx context.Context) context.Context {
return context.WithValue(ctx, ctxTfVersion, v)
}

func TerraformVersion(ctx context.Context) (string, error) {
tfv, ok := ctx.Value(ctxTfVersion).(string)
if !ok {
return "", fmt.Errorf("no Terraform version")
return "", missingContextErr(ctxTfVersion)
}

return tfv, nil
}

const ctxTfVersionSetter = "ctxTerraformVersionSetter"

func WithTerraformVersionSetter(v *string, ctx context.Context) context.Context {
return context.WithValue(ctx, ctxTfVersionSetter, v)
}

func SetTerraformVersion(ctx context.Context, v string) error {
tfv, ok := ctx.Value(ctxTfVersionSetter).(*string)
if !ok {
return fmt.Errorf("no Terraform version setter")
return missingContextErr(ctxTfVersionSetter)
}
*tfv = v

return nil
}

const ctxTfExecLogPath = "ctxTerraformExecLogPath"

func WithTerraformExecLogPath(path string, ctx context.Context) context.Context {
return context.WithValue(ctx, ctxTfExecLogPath, path)
}
Expand Down
11 changes: 11 additions & 0 deletions internal/context/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package context

import "fmt"

type MissingContextErr struct {
CtxKey *contextKey
}

func (e *MissingContextErr) Error() string {
return fmt.Sprintf("missing context: %s", e.CtxKey)
}
32 changes: 32 additions & 0 deletions internal/context/signal_cancel.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package context

import (
"context"
"log"
"os"
"os/signal"
)

func WithSignalCancel(ctx context.Context, l *log.Logger, sigs ...os.Signal) (
context.Context, context.CancelFunc) {
ctx, cancelFunc := context.WithCancel(ctx)

sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, sigs...)

go func() {
select {
case sig := <-sigChan:
l.Printf("Cancellation signal (%s) received", sig)
cancelFunc()
case <-ctx.Done():
}
}()

f := func() {
signal.Stop(sigChan)
cancelFunc()
}

return ctx, f
}

0 comments on commit db9a7e6

Please sign in to comment.