Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability to specify path to TF binary #109

Merged
merged 3 commits into from
May 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions commands/completion_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func (c *CompletionCommand) flags() *flag.FlagSet {
func (c *CompletionCommand) Run(args []string) int {
f := c.flags()
if err := f.Parse(args); err != nil {
c.Ui.Error(fmt.Sprintf("Error parsing command-line flags: %s\n", err.Error()))
c.Ui.Error(fmt.Sprintf("Error parsing command-line flags: %s", err))
return 1
}

Expand All @@ -59,17 +59,17 @@ func (c *CompletionCommand) Run(args []string) int {
lspUri := ilsp.FileHandlerFromPath(path).DocumentURI()
parts := strings.Split(c.atPos, ":")
if len(parts) != 2 {
c.Ui.Error(fmt.Sprintf("Error parsing at-pos argument: %q (expected line:col format)\n", c.atPos))
c.Ui.Error(fmt.Sprintf("Error parsing at-pos argument: %q (expected line:col format)", c.atPos))
return 1
}
line, err := strconv.Atoi(parts[0])
if err != nil {
c.Ui.Error(fmt.Sprintf("Error parsing line: %s (expected number)\n", err))
c.Ui.Error(fmt.Sprintf("Error parsing line: %s (expected number)", err))
return 1
}
col, err := strconv.Atoi(parts[1])
if err != nil {
c.Ui.Error(fmt.Sprintf("Error parsing column: %s (expected number)\n", err))
c.Ui.Error(fmt.Sprintf("Error parsing column: %s (expected number)", err))
return 1
}
lspPos := lsp.Position{Line: line, Character: col}
Expand Down
38 changes: 33 additions & 5 deletions commands/serve_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"fmt"
"log"
"os"
"path/filepath"
"strings"
"syscall"

Expand All @@ -22,6 +23,7 @@ type ServeCommand struct {
// flags
port int
logFilePath string
tfExecPath string
tfExecLogPath string
}

Expand All @@ -31,6 +33,7 @@ func (c *ServeCommand) flags() *flag.FlagSet {
fs.IntVar(&c.port, "port", 0, "port number to listen on (turns server into TCP mode)")
fs.StringVar(&c.logFilePath, "log-file", "", "path to a file to log into with support "+
"for variables (e.g. Timestamp, Pid, Ppid) via Go template syntax {{.VarName}}")
fs.StringVar(&c.tfExecPath, "tf-exec", "", "path to Terraform binary")
fs.StringVar(&c.tfExecLogPath, "tf-log-file", "", "path to a file for Terraform executions"+
" to be logged into with support for variables (e.g. Timestamp, Pid, Ppid) via Go template"+
" syntax {{.VarName}}")
Expand All @@ -43,15 +46,15 @@ func (c *ServeCommand) flags() *flag.FlagSet {
func (c *ServeCommand) Run(args []string) int {
f := c.flags()
if err := f.Parse(args); err != nil {
c.Ui.Error(fmt.Sprintf("Error parsing command-line flags: %s\n", err.Error()))
c.Ui.Error(fmt.Sprintf("Error parsing command-line flags: %s", err))
return 1
}

var logger *log.Logger
if c.logFilePath != "" {
fl, err := logging.NewFileLogger(c.logFilePath)
if err != nil {
c.Ui.Error(fmt.Sprintf("Failed to setup file logging: %s\n", err.Error()))
c.Ui.Error(fmt.Sprintf("Failed to setup file logging: %s", err))
return 1
}
defer fl.Close()
Expand All @@ -68,7 +71,7 @@ func (c *ServeCommand) Run(args []string) int {
if c.tfExecLogPath != "" {
err := logging.ValidateExecLogPath(c.tfExecLogPath)
if err != nil {
c.Ui.Error(fmt.Sprintf("Failed to setup logging for Terraform: %s\n", err.Error()))
c.Ui.Error(fmt.Sprintf("Failed to setup logging for Terraform: %s", err))
return 1
}
ctx = lsctx.WithTerraformExecLogPath(c.tfExecLogPath, ctx)
Expand All @@ -79,18 +82,43 @@ func (c *ServeCommand) Run(args []string) int {
srv := langserver.NewLangServer(ctx, handlers.NewSession)
srv.SetLogger(logger)

if c.tfExecPath != "" {
path := c.tfExecPath

logger.Printf("Setting Terraform exec path to %q", path)

// just some sanity checking here, no need to get too specific otherwise will be complex cross-OS
if !filepath.IsAbs(path) {
c.Ui.Error(fmt.Sprintf("Expected absolute path for Terraform binary, got %q", path))
return 1
}
stat, err := os.Stat(path)
if err != nil {
c.Ui.Error(fmt.Sprintf("Unable to find Terraform binary: %s", err))
return 1
}
if stat.IsDir() {
c.Ui.Error(fmt.Sprintf("Expected a Terraform binary, got a directory: %q", path))
return 1
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Total nitpick, but I assume the above lines could make a validateTfExecPath(string) error function.


srv.SetDiscoveryFunc(func() (string, error) {
return path, nil
})
}

if c.port != 0 {
err := srv.StartTCP(fmt.Sprintf("localhost:%d", c.port))
if err != nil {
c.Ui.Error(fmt.Sprintf("Failed to start TCP server: %s\n", err))
c.Ui.Error(fmt.Sprintf("Failed to start TCP server: %s", err))
return 1
}
return 0
}

err := srv.StartAndWait(os.Stdin, os.Stdout)
if err != nil {
c.Ui.Error(fmt.Sprintf("Failed to start server: %s\n", err))
c.Ui.Error(fmt.Sprintf("Failed to start server: %s", err))
return 1
}

Expand Down
6 changes: 3 additions & 3 deletions internal/terraform/schema/schema_storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ func (s *Storage) Providers() ([]string, error) {
}

providers := make([]string, 0)
for name, _ := range ps.Schemas {
for name := range ps.Schemas {
providers = append(providers, name)
}

Expand Down Expand Up @@ -214,7 +214,7 @@ func (s *Storage) Resources() ([]Resource, error) {

resources := make([]Resource, 0)
for provider, schema := range ps.Schemas {
for name, _ := range schema.ResourceSchemas {
for name := range schema.ResourceSchemas {
resources = append(resources, Resource{
Provider: provider,
Name: name,
Expand Down Expand Up @@ -254,7 +254,7 @@ func (s *Storage) DataSources() ([]DataSource, error) {

dataSources := make([]DataSource, 0)
for provider, schema := range ps.Schemas {
for name, _ := range schema.DataSourceSchemas {
for name := range schema.DataSourceSchemas {
dataSources = append(dataSources, DataSource{
Provider: provider,
Name: name,
Expand Down
12 changes: 8 additions & 4 deletions langserver/handlers/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ type service struct {
sessCtx context.Context
stopSession context.CancelFunc

tfPath discovery.DiscoveryFunc
tfDiscoFunc discovery.DiscoveryFunc
ss *schema.Storage
executorFunc func(ctx context.Context, execPath string) *exec.Executor
}
Expand All @@ -44,7 +44,7 @@ func NewSession(srvCtx context.Context) session.Session {
sessCtx: sessCtx,
stopSession: stopSession,
executorFunc: exec.NewExecutor,
tfPath: d.LookPath,
tfDiscoFunc: d.LookPath,
ss: schema.NewStorage(),
}
}
Expand All @@ -53,6 +53,10 @@ func (svc *service) SetLogger(logger *log.Logger) {
svc.logger = logger
}

func (svc *service) SetDiscoveryFunc(f discovery.DiscoveryFunc) {
svc.tfDiscoFunc = f
}

// Assigner builds out the jrpc2.Map according to the LSP protocol
// and passes related dependencies to handlers via context
func (svc *service) Assigner() (jrpc2.Assigner, error) {
Expand Down Expand Up @@ -81,7 +85,7 @@ func (svc *service) Assigner() (jrpc2.Assigner, error) {
ctx = lsctx.WithFilesystem(fs, ctx)
ctx = lsctx.WithClientCapabilitiesSetter(cc, ctx)

tfPath, err := svc.tfPath()
tfPath, err := svc.tfDiscoFunc()
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -157,7 +161,7 @@ func (svc *service) Assigner() (jrpc2.Assigner, error) {

ctx = lsctx.WithFilesystem(fs, ctx)

tfPath, err := svc.tfPath()
tfPath, err := svc.tfDiscoFunc()
if err != nil {
return nil, err
}
Expand Down
4 changes: 2 additions & 2 deletions langserver/handlers/service_mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ func (ms *mockSession) new(srvCtx context.Context) session.Session {
executorFunc: func(context.Context, string) *exec.Executor {
return exec.MockExecutor(ms.mid)
},
tfPath: d.LookPath,
ss: schema.MockStorage(nil),
tfDiscoFunc: d.LookPath,
ss: schema.MockStorage(nil),
}

return svc
Expand Down
18 changes: 14 additions & 4 deletions langserver/langserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,17 @@ import (
"github.com/creachadair/jrpc2"
"github.com/creachadair/jrpc2/channel"
"github.com/creachadair/jrpc2/server"

"github.com/hashicorp/terraform-ls/internal/terraform/discovery"
"github.com/hashicorp/terraform-ls/langserver/session"
)

type langServer struct {
srvCtx context.Context
logger *log.Logger
srvOptions *jrpc2.ServerOptions
newSession session.SessionFactory
srvCtx context.Context
logger *log.Logger
tfDiscoFunc discovery.DiscoveryFunc
srvOptions *jrpc2.ServerOptions
newSession session.SessionFactory
}

func NewLangServer(srvCtx context.Context, sf session.SessionFactory) *langServer {
Expand All @@ -41,9 +44,16 @@ func (ls *langServer) SetLogger(logger *log.Logger) {
ls.logger = logger
}

func (ls *langServer) SetDiscoveryFunc(f discovery.DiscoveryFunc) {
ls.tfDiscoFunc = f
}

func (ls *langServer) newService() server.Service {
svc := ls.newSession(ls.srvCtx)
svc.SetLogger(ls.logger)
if ls.tfDiscoFunc != nil {
svc.SetDiscoveryFunc(ls.tfDiscoFunc)
}
return svc
}

Expand Down
3 changes: 3 additions & 0 deletions langserver/session/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@ import (
"log"

"github.com/creachadair/jrpc2"

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

type Session interface {
Assigner() (jrpc2.Assigner, error)
Finish(jrpc2.ServerStatus)
SetLogger(*log.Logger)
SetDiscoveryFunc(discovery.DiscoveryFunc)
}

type SessionFactory func(context.Context) Session
2 changes: 1 addition & 1 deletion version/version.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package version

import (
"fmt"
"errors"
"fmt"

version "github.com/hashicorp/go-version"
)
Expand Down