From 97872ea57e7a6da494e931054b9d51b9d123a14f Mon Sep 17 00:00:00 2001 From: Radek Simko Date: Tue, 1 Dec 2020 21:25:48 +0000 Subject: [PATCH] Expose terraform.init as a command + implement progress reporting --- go.mod | 1 + go.sum | 2 + internal/context/context.go | 13 ++ internal/langserver/cmd/cmd.go | 6 + internal/langserver/handlers/command/init.go | 56 +++++ .../langserver/handlers/command/progress.go | 54 +++++ internal/langserver/handlers/did_open.go | 58 +++-- .../langserver/handlers/execute_command.go | 9 +- .../handlers/execute_command_init_test.go | 212 ++++++++++++++++++ internal/langserver/handlers/handlers_test.go | 3 +- internal/langserver/handlers/initialize.go | 3 + internal/langserver/handlers/service.go | 3 + internal/lsp/dir_handler.go | 6 + internal/terraform/exec/exec.go | 4 +- internal/terraform/exec/mock/executor.go | 21 +- internal/terraform/exec/types.go | 3 +- 16 files changed, 424 insertions(+), 30 deletions(-) create mode 100644 internal/langserver/handlers/command/init.go create mode 100644 internal/langserver/handlers/command/progress.go create mode 100644 internal/langserver/handlers/execute_command_init_test.go create mode 100644 internal/lsp/dir_handler.go diff --git a/go.mod b/go.mod index 678d5cd33..74909fb3d 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require ( github.com/fsnotify/fsnotify v1.4.9 github.com/gammazero/workerpool v1.0.0 github.com/google/go-cmp v0.5.1 + github.com/google/uuid v1.1.2 github.com/hashicorp/go-multierror v1.1.0 github.com/hashicorp/go-version v1.2.1 github.com/hashicorp/hcl-lang v0.0.0-20201116081236-948e43712a65 diff --git a/go.sum b/go.sum index 5a1a03dfb..284d2ff69 100644 --- a/go.sum +++ b/go.sum @@ -133,6 +133,8 @@ github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXi github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= diff --git a/internal/context/context.go b/internal/context/context.go index 24353b62f..8d6d63686 100644 --- a/internal/context/context.go +++ b/internal/context/context.go @@ -36,6 +36,7 @@ var ( ctxCommandPrefix = &contextKey{"command prefix"} ctxDiags = &contextKey{"diagnostics"} ctxLsVersion = &contextKey{"language server version"} + ctxProgressToken = &contextKey{"progress token"} ) func missingContextErr(ctxKey *contextKey) *MissingContextErr { @@ -249,3 +250,15 @@ func LanguageServerVersion(ctx context.Context) (string, bool) { } return version, true } + +func WithProgressToken(ctx context.Context, pt lsp.ProgressToken) context.Context { + return context.WithValue(ctx, ctxProgressToken, pt) +} + +func ProgressToken(ctx context.Context) (lsp.ProgressToken, bool) { + pt, ok := ctx.Value(ctxProgressToken).(lsp.ProgressToken) + if !ok { + return "", false + } + return pt, true +} diff --git a/internal/langserver/cmd/cmd.go b/internal/langserver/cmd/cmd.go index 12c40d9bf..bbf589e00 100644 --- a/internal/langserver/cmd/cmd.go +++ b/internal/langserver/cmd/cmd.go @@ -2,6 +2,7 @@ package cmd import ( "context" + "sort" "strings" ) @@ -21,6 +22,11 @@ func (h Handlers) Names(commandPrefix string) (names []string) { for name := range h { names = append(names, commandPrefix+name) } + + sort.SliceStable(names, func(i, j int) bool { + return names[i] < names[j] + }) + return names } diff --git a/internal/langserver/handlers/command/init.go b/internal/langserver/handlers/command/init.go new file mode 100644 index 000000000..09233b0b0 --- /dev/null +++ b/internal/langserver/handlers/command/init.go @@ -0,0 +1,56 @@ +package command + +import ( + "context" + "fmt" + + "github.com/creachadair/jrpc2/code" + lsctx "github.com/hashicorp/terraform-ls/internal/context" + "github.com/hashicorp/terraform-ls/internal/langserver/cmd" + ilsp "github.com/hashicorp/terraform-ls/internal/lsp" + lsp "github.com/hashicorp/terraform-ls/internal/protocol" +) + +func TerraformInitHandler(ctx context.Context, args cmd.CommandArgs) (interface{}, error) { + fileUri, ok := args.GetString("uri") + if !ok || fileUri == "" { + return nil, fmt.Errorf("%w: expected uri argument to be set", code.InvalidParams.Err()) + } + + fh := ilsp.FileHandlerFromDocumentURI(lsp.DocumentURI(fileUri)) + + cf, err := lsctx.RootModuleFinder(ctx) + if err != nil { + return nil, err + } + + rm, err := cf.RootModuleByPath(fh.Dir()) + if err != nil { + return nil, err + } + + progressBegin(ctx, "Initializing") + defer func() { + progressEnd(ctx, "Finished") + }() + + progressReport(ctx, "Running terraform init ...") + err = rm.ExecuteTerraformInit(ctx) + if err != nil { + return nil, err + } + + progressReport(ctx, "Detecting paths to watch ...") + paths := rm.PathsToWatch() + + w, err := lsctx.Watcher(ctx) + if err != nil { + return nil, err + } + err = w.AddPaths(paths) + if err != nil { + return nil, fmt.Errorf("failed to add watch for dir (%s): %+v", fh.Dir(), err) + } + + return nil, nil +} diff --git a/internal/langserver/handlers/command/progress.go b/internal/langserver/handlers/command/progress.go new file mode 100644 index 000000000..74868cb74 --- /dev/null +++ b/internal/langserver/handlers/command/progress.go @@ -0,0 +1,54 @@ +package command + +import ( + "context" + + "github.com/creachadair/jrpc2" + lsctx "github.com/hashicorp/terraform-ls/internal/context" + lsp "github.com/hashicorp/terraform-ls/internal/protocol" +) + +func progressBegin(ctx context.Context, title string) error { + token, ok := lsctx.ProgressToken(ctx) + if !ok { + return nil + } + + return jrpc2.PushNotify(ctx, "$/progress", lsp.ProgressParams{ + Token: token, + Value: lsp.WorkDoneProgressBegin{ + Kind: "begin", + Title: title, + }, + }) +} + +func progressReport(ctx context.Context, message string) error { + token, ok := lsctx.ProgressToken(ctx) + if !ok { + return nil + } + + return jrpc2.PushNotify(ctx, "$/progress", lsp.ProgressParams{ + Token: token, + Value: lsp.WorkDoneProgressReport{ + Kind: "report", + Message: message, + }, + }) +} + +func progressEnd(ctx context.Context, message string) error { + token, ok := lsctx.ProgressToken(ctx) + if !ok { + return nil + } + + return jrpc2.PushNotify(ctx, "$/progress", lsp.ProgressParams{ + Token: token, + Value: lsp.WorkDoneProgressEnd{ + Kind: "end", + Message: message, + }, + }) +} diff --git a/internal/langserver/handlers/did_open.go b/internal/langserver/handlers/did_open.go index dacc4b228..b37154ba6 100644 --- a/internal/langserver/handlers/did_open.go +++ b/internal/langserver/handlers/did_open.go @@ -7,11 +7,13 @@ import ( "strings" "github.com/creachadair/jrpc2" + "github.com/google/uuid" lsctx "github.com/hashicorp/terraform-ls/internal/context" + "github.com/hashicorp/terraform-ls/internal/langserver/cmd" + "github.com/hashicorp/terraform-ls/internal/langserver/handlers/command" ilsp "github.com/hashicorp/terraform-ls/internal/lsp" lsp "github.com/hashicorp/terraform-ls/internal/protocol" "github.com/hashicorp/terraform-ls/internal/terraform/rootmodule" - "github.com/hashicorp/terraform-ls/internal/watcher" ) func (lh *logHandler) TextDocumentDidOpen(ctx context.Context, params lsp.DidOpenTextDocumentParams) error { @@ -37,11 +39,6 @@ func (lh *logHandler) TextDocumentDidOpen(ctx context.Context, params lsp.DidOpe return err } - w, err := lsctx.Watcher(ctx) - if err != nil { - return err - } - rootDir, _ := lsctx.RootDirectory(ctx) readableDir := humanReadablePath(rootDir, f.Dir()) @@ -83,7 +80,7 @@ func (lh *logHandler) TextDocumentDidOpen(ctx context.Context, params lsp.DidOpe } else if len(candidates) == 0 { // TODO: Only notify once per f.Dir() per session go func() { - err := askInitForEmptyRootModule(ctx, w, rootDir, f.Dir()) + err := askInitForEmptyRootModule(ctx, rootDir, f) if err != nil { jrpc2.PushNotify(ctx, "window/showMessage", lsp.ShowMessageParams{ Type: lsp.Error, @@ -138,12 +135,12 @@ func humanReadablePath(rootDir, path string) string { return relDir } -func askInitForEmptyRootModule(ctx context.Context, w watcher.Watcher, rootDir, dir string) error { +func askInitForEmptyRootModule(ctx context.Context, rootDir string, dh ilsp.DirHandler) error { msg := fmt.Sprintf("No root module found for %q."+ " Functionality may be limited."+ // Unfortunately we can't be any more specific wrt where // because we don't gather "init-able folders" in any way - " You may need to run terraform init.", humanReadablePath(rootDir, dir)) + " You may need to run terraform init.", humanReadablePath(rootDir, dh.Dir())) title := "terraform init" resp, err := jrpc2.PushCall(ctx, "window/showMessageRequest", lsp.ShowMessageRequestParams{ Type: lsp.Info, @@ -162,21 +159,44 @@ func askInitForEmptyRootModule(ctx context.Context, w watcher.Watcher, rootDir, return fmt.Errorf("unmarshal MessageActionItem: %+v", err) } if action.Title == title { - rmm, err := lsctx.RootModuleManager(ctx) + ctx, err := initiateProgress(ctx) if err != nil { return err } - - rm, err := rmm.InitAndUpdateRootModule(ctx, dir) - if err != nil { - return fmt.Errorf("failed to init root module %+v", err) - } - - paths := rm.PathsToWatch() - err = w.AddPaths(paths) + _, err = command.TerraformInitHandler(ctx, cmd.CommandArgs{ + "uri": dh.URI(), + }) if err != nil { - return fmt.Errorf("failed to add watch for dir (%s): %+v", dir, err) + return fmt.Errorf("Initialization failed: %w", err) } + return nil } return nil } + +func initiateProgress(ctx context.Context) (context.Context, error) { + cc, err := lsctx.ClientCapabilities(ctx) + if err != nil { + return ctx, err + } + + if !cc.Window.WorkDoneProgress { + // server-side reporting not supported + return ctx, nil + } + + id, err := uuid.NewUUID() + if err != nil { + return nil, err + } + token := lsp.ProgressToken(id.String()) + + _, err = jrpc2.PushCall(ctx, "window/workDoneProgress/create", lsp.WorkDoneProgressCreateParams{ + Token: token, + }) + if err == nil { + return lsctx.WithProgressToken(ctx, token), nil + } + + return ctx, err +} diff --git a/internal/langserver/handlers/execute_command.go b/internal/langserver/handlers/execute_command.go index 89beb41c5..a8d9079db 100644 --- a/internal/langserver/handlers/execute_command.go +++ b/internal/langserver/handlers/execute_command.go @@ -12,7 +12,8 @@ import ( ) var handlers = cmd.Handlers{ - cmd.Name("rootmodules"): command.RootModulesHandler, + cmd.Name("rootmodules"): command.RootModulesHandler, + cmd.Name("terraform.init"): command.TerraformInitHandler, } func (lh *logHandler) WorkspaceExecuteCommand(ctx context.Context, params lsp.ExecuteCommandParams) (interface{}, error) { @@ -28,5 +29,11 @@ func (lh *logHandler) WorkspaceExecuteCommand(ctx context.Context, params lsp.Ex if !ok { return nil, fmt.Errorf("%w: command handler not found for %q", code.MethodNotFound.Err(), params.Command) } + + pt, ok := params.WorkDoneToken.(lsp.ProgressToken) + if ok { + ctx = lsctx.WithProgressToken(ctx, pt) + } + return handler(ctx, cmd.ParseCommandArgs(params.Arguments)) } diff --git a/internal/langserver/handlers/execute_command_init_test.go b/internal/langserver/handlers/execute_command_init_test.go new file mode 100644 index 000000000..c35685c37 --- /dev/null +++ b/internal/langserver/handlers/execute_command_init_test.go @@ -0,0 +1,212 @@ +package handlers + +import ( + "errors" + "fmt" + "testing" + + "github.com/creachadair/jrpc2/code" + "github.com/hashicorp/go-version" + "github.com/hashicorp/terraform-ls/internal/langserver" + "github.com/hashicorp/terraform-ls/internal/langserver/cmd" + "github.com/hashicorp/terraform-ls/internal/terraform/exec" + "github.com/hashicorp/terraform-ls/internal/terraform/rootmodule" + "github.com/stretchr/testify/mock" +) + +func TestLangServer_workspaceExecuteCommand_init_argumentError(t *testing.T) { + tmpDir := TempDir(t) + testFileURI := fmt.Sprintf("%s/main.tf", tmpDir.URI()) + + ls := langserver.NewLangServerMock(t, NewMockSession(&MockSessionInput{ + RootModules: map[string]*rootmodule.RootModuleMock{ + tmpDir.Dir(): { + TfExecFactory: validTfMockCalls(), + }, + }, + })) + stop := ls.Start(t) + defer stop() + + ls.Call(t, &langserver.CallRequest{ + Method: "initialize", + ReqParams: fmt.Sprintf(`{ + "capabilities": {}, + "rootUri": %q, + "processId": 12345 + }`, tmpDir.URI())}) + ls.Notify(t, &langserver.CallRequest{ + Method: "initialized", + ReqParams: "{}", + }) + ls.Call(t, &langserver.CallRequest{ + Method: "textDocument/didOpen", + ReqParams: fmt.Sprintf(`{ + "textDocument": { + "version": 0, + "languageId": "terraform", + "text": "provider \"github\" {}", + "uri": %q + } + }`, testFileURI)}) + + ls.CallAndExpectError(t, &langserver.CallRequest{ + Method: "workspace/executeCommand", + ReqParams: fmt.Sprintf(`{ + "command": %q + }`, cmd.Name("terraform.init"))}, code.InvalidParams.Err()) +} + +func TestLangServer_workspaceExecuteCommand_init_basic(t *testing.T) { + tmpDir := TempDir(t) + testFileURI := fmt.Sprintf("%s/main.tf", tmpDir.URI()) + + tfMockCalls := exec.NewMockExecutor([]*mock.Call{ + { + Method: "Version", + Repeatability: 1, + Arguments: []interface{}{ + mock.AnythingOfType(""), + }, + ReturnArguments: []interface{}{ + version.Must(version.NewVersion("0.12.0")), + nil, + }, + }, + { + Method: "GetExecPath", + Repeatability: 1, + ReturnArguments: []interface{}{ + "", + }, + }, + { + Method: "Init", + Repeatability: 1, + Arguments: []interface{}{ + mock.AnythingOfType(""), + }, + ReturnArguments: []interface{}{ + nil, + }, + }, + }) + + ls := langserver.NewLangServerMock(t, NewMockSession(&MockSessionInput{ + RootModules: map[string]*rootmodule.RootModuleMock{ + tmpDir.Dir(): { + TfExecFactory: tfMockCalls, + }, + }, + })) + stop := ls.Start(t) + defer stop() + + ls.Call(t, &langserver.CallRequest{ + Method: "initialize", + ReqParams: fmt.Sprintf(`{ + "capabilities": {}, + "rootUri": %q, + "processId": 12345 + }`, tmpDir.URI())}) + ls.Notify(t, &langserver.CallRequest{ + Method: "initialized", + ReqParams: "{}", + }) + ls.Call(t, &langserver.CallRequest{ + Method: "textDocument/didOpen", + ReqParams: fmt.Sprintf(`{ + "textDocument": { + "version": 0, + "languageId": "terraform", + "text": "provider \"github\" {}", + "uri": %q + } + }`, testFileURI)}) + + ls.CallAndExpectResponse(t, &langserver.CallRequest{ + Method: "workspace/executeCommand", + ReqParams: fmt.Sprintf(`{ + "command": %q, + "arguments": ["uri=%s"] + }`, cmd.Name("terraform.init"), testFileURI)}, `{ + "jsonrpc": "2.0", + "id": 3, + "result": null + }`) +} + +func TestLangServer_workspaceExecuteCommand_init_error(t *testing.T) { + tmpDir := TempDir(t) + testFileURI := fmt.Sprintf("%s/main.tf", tmpDir.URI()) + + tfMockCalls := exec.NewMockExecutor([]*mock.Call{ + { + Method: "Version", + Repeatability: 1, + Arguments: []interface{}{ + mock.AnythingOfType(""), + }, + ReturnArguments: []interface{}{ + version.Must(version.NewVersion("0.12.0")), + nil, + }, + }, + { + Method: "GetExecPath", + Repeatability: 1, + ReturnArguments: []interface{}{ + "", + }, + }, + { + Method: "Init", + Repeatability: 1, + Arguments: []interface{}{ + mock.AnythingOfType(""), + }, + ReturnArguments: []interface{}{ + errors.New("something bad happened"), + }, + }, + }) + + ls := langserver.NewLangServerMock(t, NewMockSession(&MockSessionInput{ + RootModules: map[string]*rootmodule.RootModuleMock{ + tmpDir.Dir(): { + TfExecFactory: tfMockCalls, + }, + }, + })) + stop := ls.Start(t) + defer stop() + + ls.Call(t, &langserver.CallRequest{ + Method: "initialize", + ReqParams: fmt.Sprintf(`{ + "capabilities": {}, + "rootUri": %q, + "processId": 12345 + }`, tmpDir.URI())}) + ls.Notify(t, &langserver.CallRequest{ + Method: "initialized", + ReqParams: "{}", + }) + ls.Call(t, &langserver.CallRequest{ + Method: "textDocument/didOpen", + ReqParams: fmt.Sprintf(`{ + "textDocument": { + "version": 0, + "languageId": "terraform", + "text": "provider \"github\" {}", + "uri": %q + } + }`, testFileURI)}) + + ls.CallAndExpectError(t, &langserver.CallRequest{ + Method: "workspace/executeCommand", + ReqParams: fmt.Sprintf(`{ + "command": %q, + "arguments": ["uri=%s"] + }`, cmd.Name("terraform.init"), testFileURI)}, code.SystemError.Err()) +} diff --git a/internal/langserver/handlers/handlers_test.go b/internal/langserver/handlers/handlers_test.go index f2a7f9ea2..e39bf5c8d 100644 --- a/internal/langserver/handlers/handlers_test.go +++ b/internal/langserver/handlers/handlers_test.go @@ -44,7 +44,8 @@ func initializeResponse(t *testing.T, commandPrefix string) string { "firstTriggerCharacter": "" }, "executeCommandProvider": { - "commands": %s + "commands": %s, + "workDoneProgress":true }, "workspace": { "workspaceFolders": {} diff --git a/internal/langserver/handlers/initialize.go b/internal/langserver/handlers/initialize.go index b6ff4139d..953184d94 100644 --- a/internal/langserver/handlers/initialize.go +++ b/internal/langserver/handlers/initialize.go @@ -85,6 +85,9 @@ func (lh *logHandler) Initialize(ctx context.Context, params lsp.InitializeParam // apply prefix to executeCommand handler names serverCaps.Capabilities.ExecuteCommandProvider = lsp.ExecuteCommandOptions{ Commands: handlers.Names(out.Options.CommandPrefix), + WorkDoneProgressOptions: lsp.WorkDoneProgressOptions{ + WorkDoneProgress: true, + }, } if len(out.UnusedKeys) > 0 { diff --git a/internal/langserver/handlers/service.go b/internal/langserver/handlers/service.go index 0dd4c7214..df099a716 100644 --- a/internal/langserver/handlers/service.go +++ b/internal/langserver/handlers/service.go @@ -196,10 +196,12 @@ func (svc *service) Assigner() (jrpc2.Assigner, error) { if err != nil { return nil, err } + ctx = lsctx.WithClientCapabilities(ctx, cc) ctx = lsctx.WithDiagnostics(ctx, diags) ctx = lsctx.WithDocumentStorage(ctx, svc.fs) ctx = lsctx.WithRootDirectory(ctx, &rootDir) ctx = lsctx.WithRootModuleManager(ctx, svc.modMgr) + ctx = lsctx.WithRootModuleFinder(ctx, svc.modMgr) ctx = lsctx.WithRootModuleWalker(ctx, svc.walker) ctx = lsctx.WithWatcher(ctx, ww) return handle(ctx, req, lh.TextDocumentDidOpen) @@ -267,6 +269,7 @@ func (svc *service) Assigner() (jrpc2.Assigner, error) { ctx = lsctx.WithCommandPrefix(ctx, &commandPrefix) ctx = lsctx.WithRootModuleFinder(ctx, svc.modMgr) ctx = lsctx.WithRootModuleWalker(ctx, svc.walker) + ctx = lsctx.WithWatcher(ctx, ww) return handle(ctx, req, lh.WorkspaceExecuteCommand) }, diff --git a/internal/lsp/dir_handler.go b/internal/lsp/dir_handler.go new file mode 100644 index 000000000..d92f60f9a --- /dev/null +++ b/internal/lsp/dir_handler.go @@ -0,0 +1,6 @@ +package lsp + +type DirHandler interface { + Dir() string + URI() string +} diff --git a/internal/terraform/exec/exec.go b/internal/terraform/exec/exec.go index 7acedc3fd..cc43a06ee 100644 --- a/internal/terraform/exec/exec.go +++ b/internal/terraform/exec/exec.go @@ -87,7 +87,7 @@ func (e *Executor) setLogPath(method string) error { return e.tf.SetLogPath(logPath) } -func (e *Executor) Init(ctx context.Context) error { +func (e *Executor) Init(ctx context.Context, opts ...tfexec.InitOption) error { ctx, cancel := e.withTimeout(ctx) defer cancel() err := e.setLogPath("Init") @@ -95,7 +95,7 @@ func (e *Executor) Init(ctx context.Context) error { return err } - return e.contextfulError(ctx, "Init", e.tf.Init(ctx)) + return e.contextfulError(ctx, "Init", e.tf.Init(ctx, opts...)) } func (e *Executor) Format(ctx context.Context, input []byte) ([]byte, error) { diff --git a/internal/terraform/exec/mock/executor.go b/internal/terraform/exec/mock/executor.go index 5a9b7e7be..65f81b4d7 100644 --- a/internal/terraform/exec/mock/executor.go +++ b/internal/terraform/exec/mock/executor.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.3.0. DO NOT EDIT. +// Code generated by mockery v2.4.0-beta. DO NOT EDIT. package mock @@ -9,6 +9,8 @@ import ( mock "github.com/stretchr/testify/mock" + tfexec "github.com/hashicorp/terraform-exec/tfexec" + tfjson "github.com/hashicorp/terraform-json" time "time" @@ -58,13 +60,20 @@ func (_m *Executor) GetExecPath() string { return r0 } -// Init provides a mock function with given fields: ctx -func (_m *Executor) Init(ctx context.Context) error { - ret := _m.Called(ctx) +// Init provides a mock function with given fields: ctx, opts +func (_m *Executor) Init(ctx context.Context, opts ...tfexec.InitOption) error { + _va := make([]interface{}, len(opts)) + for _i := range opts { + _va[_i] = opts[_i] + } + var _ca []interface{} + _ca = append(_ca, ctx) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) var r0 error - if rf, ok := ret.Get(0).(func(context.Context) error); ok { - r0 = rf(ctx) + if rf, ok := ret.Get(0).(func(context.Context, ...tfexec.InitOption) error); ok { + r0 = rf(ctx, opts...) } else { r0 = ret.Error(0) } diff --git a/internal/terraform/exec/types.go b/internal/terraform/exec/types.go index 061cc4eae..772f51157 100644 --- a/internal/terraform/exec/types.go +++ b/internal/terraform/exec/types.go @@ -6,6 +6,7 @@ import ( "time" "github.com/hashicorp/go-version" + "github.com/hashicorp/terraform-exec/tfexec" tfjson "github.com/hashicorp/terraform-json" ) @@ -22,7 +23,7 @@ type TerraformExecutor interface { SetExecLogPath(path string) error SetTimeout(duration time.Duration) GetExecPath() string - Init(ctx context.Context) error + Init(ctx context.Context, opts ...tfexec.InitOption) error Format(ctx context.Context, input []byte) ([]byte, error) Version(ctx context.Context) (*version.Version, error) ProviderSchemas(ctx context.Context) (*tfjson.ProviderSchemas, error)