Skip to content

Commit 04ddd3d

Browse files
committed
Fixed lint issues
1 parent 040366e commit 04ddd3d

File tree

3 files changed

+67
-35
lines changed

3 files changed

+67
-35
lines changed

engine/engine.go

Lines changed: 42 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
// Package engine provides the implementation of Terragrunt IaC engine interface
12
package engine
23

34
import (
45
"bufio"
56
"context"
7+
"errors"
68
"fmt"
79
"io"
810
"os"
@@ -35,36 +37,41 @@ func (c *TerraformEngine) Init(req *tgengine.InitRequest, stream tgengine.Engine
3537
if err != nil {
3638
return err
3739
}
40+
3841
return nil
3942
}
4043

4144
func (c *TerraformEngine) Run(req *tgengine.RunRequest, stream tgengine.Engine_RunServer) error {
42-
log.Infof("Run Terraform engine %v", req.WorkingDir)
43-
cmd := exec.Command(iacCommand, req.Args...)
44-
cmd.Dir = req.WorkingDir
45-
env := make([]string, 0, len(req.EnvVars))
46-
for key, value := range req.EnvVars {
45+
log.Infof("Run Terraform engine %v", req.GetWorkingDir())
46+
cmd := exec.Command(iacCommand, req.GetArgs()...)
47+
cmd.Dir = req.GetWorkingDir()
48+
49+
env := make([]string, 0, len(req.GetEnvVars()))
50+
for key, value := range req.GetEnvVars() {
4751
env = append(env, fmt.Sprintf("%s=%s", key, value))
4852
}
53+
4954
cmd.Env = append(cmd.Env, env...)
5055

5156
stdoutPipe, err := cmd.StdoutPipe()
5257
if err != nil {
5358
sendError(stream, err)
5459
return err
5560
}
61+
5662
stderrPipe, err := cmd.StderrPipe()
5763
if err != nil {
5864
sendError(stream, err)
5965
return err
6066
}
6167

62-
if req.AllocatePseudoTty {
68+
if req.GetAllocatePseudoTty() {
6369
ptmx, err := pty.Start(cmd)
6470
if err != nil {
6571
log.Errorf("Error allocating pseudo-TTY: %v", err)
6672
return err
6773
}
74+
6875
defer func() { _ = ptmx.Close() }()
6976

7077
go func() {
@@ -87,61 +94,81 @@ func (c *TerraformEngine) Run(req *tgengine.RunRequest, stream tgengine.Engine_R
8794

8895
var wg sync.WaitGroup
8996

90-
// 2 streams to send stdout and stderr
9197
wg.Add(wgSize)
9298

93-
// Stream stdout
9499
go func() {
100+
// Ensure this goroutine signals completion when it returns
95101
defer wg.Done()
102+
103+
// Create a reader that translates data from stdoutPipe into UTF-8 runes
96104
reader := transform.NewReader(stdoutPipe, unicode.UTF8.NewDecoder())
105+
// Wrap the reader in a buffered reader for efficient reading
97106
bufReader := bufio.NewReader(reader)
107+
98108
for {
109+
// Read a single rune from the buffered reader
99110
char, _, err := bufReader.ReadRune()
100111
if err != nil {
101-
if err != io.EOF {
112+
// If there's an error and it's not EOF, log it
113+
if !errors.Is(err, io.EOF) {
102114
log.Errorf("Error reading stdout: %v", err)
103115
}
116+
// Exit the loop on EOF or any other error
104117
break
105118
}
119+
120+
// Stream the read character back to the client
106121
if err = stream.Send(&tgengine.RunResponse{Stdout: string(char)}); err != nil {
122+
// If streaming fails, log the error and exit
107123
log.Errorf("Error sending stdout: %v", err)
108124
return
109125
}
110126
}
111127
}()
112128

113-
// Stream stderr
129+
// Starts a goroutine that captures stderr output character by character,
130+
// applying UTF-8 decoding, and streams each character to the client.
131+
// Handles errors appropriately and signals completion via WaitGroup.
132+
// Terminates on EOF or transmission errors.
114133
go func() {
115134
defer wg.Done()
135+
116136
reader := transform.NewReader(stderrPipe, unicode.UTF8.NewDecoder())
117137
bufReader := bufio.NewReader(reader)
138+
118139
for {
119140
char, _, err := bufReader.ReadRune()
120141
if err != nil {
121-
if err != io.EOF {
142+
if !errors.Is(err, io.EOF) {
122143
log.Errorf("Error reading stderr: %v", err)
123144
}
145+
124146
break
125147
}
148+
126149
if err = stream.Send(&tgengine.RunResponse{Stderr: string(char)}); err != nil {
127150
log.Errorf("Error sending stderr: %v", err)
128151
return
129152
}
130153
}
131154
}()
132155
wg.Wait()
133-
err = cmd.Wait()
156+
134157
resultCode := 0
135-
if err != nil {
136-
if exitError, ok := err.(*exec.ExitError); ok {
158+
159+
if err := cmd.Wait(); err != nil {
160+
var exitError *exec.ExitError
161+
if ok := errors.As(err, &exitError); ok {
137162
resultCode = exitError.ExitCode()
138163
} else {
139164
resultCode = 1
140165
}
141166
}
167+
142168
if err := stream.Send(&tgengine.RunResponse{ResultCode: int32(resultCode)}); err != nil {
143169
return err
144170
}
171+
145172
return nil
146173
}
147174

@@ -158,6 +185,7 @@ func (c *TerraformEngine) Shutdown(req *tgengine.ShutdownRequest, stream tgengin
158185
if err != nil {
159186
return err
160187
}
188+
161189
return nil
162190
}
163191

engine/engine_test.go

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1-
package engine
1+
package engine_test
22

33
import (
44
"context"
55
"testing"
66

7+
"github.com/gruntwork-io/terragrunt-engine-terraform/engine"
8+
79
"github.com/stretchr/testify/require"
810

911
"os"
@@ -118,18 +120,19 @@ func (m *MockShutdownServer) RecvMsg(msg interface{}) error {
118120
}
119121

120122
func TestTerraformEngine_Init(t *testing.T) {
121-
engine := &TerraformEngine{}
123+
t.Parallel()
124+
engine := &engine.TerraformEngine{}
122125
mockStream := &MockInitServer{}
123126

124127
err := engine.Init(&tgengine.InitRequest{}, mockStream)
125128
require.NoError(t, err)
126-
assert.Equal(t, 1, len(mockStream.Responses))
127-
assert.Equal(t, "Terraform Initialization completed\n", mockStream.Responses[0].Stdout)
129+
assert.NotEmpty(t, mockStream.Responses)
130+
assert.Equal(t, "Terraform Initialization completed\n", mockStream.Responses[0].GetStdout())
128131
}
129132

130133
func TestTerraformEngine_Run(t *testing.T) {
131134
t.Parallel()
132-
engine := &TerraformEngine{}
135+
engine := &engine.TerraformEngine{}
133136
mockStream := &MockRunServer{}
134137

135138
cmd := "terraform"
@@ -141,20 +144,20 @@ func TestTerraformEngine_Run(t *testing.T) {
141144
}
142145
err := engine.Run(req, mockStream)
143146
require.NoError(t, err)
144-
assert.True(t, len(mockStream.Responses) > 0)
147+
assert.NotEmpty(t, mockStream.Responses)
145148
// merge stdout from all responses to a string
146149
var output string
147150
for _, response := range mockStream.Responses {
148-
if response.Stdout != "" {
149-
output += response.Stdout
151+
if response.GetStdout() != "" {
152+
output += response.GetStdout()
150153
}
151154
}
152155
assert.Contains(t, output, "Usage: terraform [global options] <subcommand> [args]")
153156
}
154157

155158
func TestTerraformEngineError(t *testing.T) {
156159
t.Parallel()
157-
engine := &TerraformEngine{}
160+
engine := &engine.TerraformEngine{}
158161
mockStream := &MockRunServer{}
159162

160163
cmd := "terraform"
@@ -165,30 +168,30 @@ func TestTerraformEngineError(t *testing.T) {
165168
}
166169
err := engine.Run(req, mockStream)
167170
require.NoError(t, err)
168-
assert.True(t, len(mockStream.Responses) > 0)
171+
assert.NotEmpty(t, mockStream.Responses)
169172
// merge stdout from all responses to a string
170173
var output string
171174

172175
for _, response := range mockStream.Responses {
173-
if response.Stderr != "" {
174-
output += response.Stderr
176+
if response.GetStderr() != "" {
177+
output += response.GetStderr()
175178
}
176179
}
177180
// get status code from last response
178-
code := mockStream.Responses[len(mockStream.Responses)-1].ResultCode
181+
code := mockStream.Responses[len(mockStream.Responses)-1].GetResultCode()
179182
assert.Contains(t, output, "Terraform has no command named \"not-a-valid-command\"")
180183
assert.NotEqual(t, 0, code)
181184
}
182185

183186
func TestTerraformEngine_Shutdown(t *testing.T) {
184187
t.Parallel()
185-
engine := &TerraformEngine{}
188+
engine := &engine.TerraformEngine{}
186189
mockStream := &MockShutdownServer{}
187190

188191
err := engine.Shutdown(&tgengine.ShutdownRequest{}, mockStream)
189192
require.NoError(t, err)
190-
assert.Equal(t, 1, len(mockStream.Responses))
191-
assert.Equal(t, "Terraform Shutdown completed\n", mockStream.Responses[0].Stdout)
193+
assert.Len(t, mockStream.Responses, 1)
194+
assert.Equal(t, "Terraform Shutdown completed\n", mockStream.Responses[0].GetStdout())
192195
}
193196

194197
func TestHelperProcess(*testing.T) {

test/basic_test.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package test
1+
package integration_test
22

33
import (
44
"context"
@@ -65,6 +65,7 @@ func bufDialer(context.Context, string) (net.Conn, error) {
6565
}
6666

6767
func runTerraformCommand(t *testing.T, ctx context.Context, command string, args []string, workingDir string, envVars map[string]string) (string, string, error) {
68+
t.Helper()
6869
// nolint:staticcheck
6970
conn, err := grpc.DialContext(ctx, "", grpc.WithContextDialer(bufDialer), grpc.WithInsecure())
7071
if err != nil {
@@ -95,15 +96,15 @@ func runTerraformCommand(t *testing.T, ctx context.Context, command string, args
9596
break
9697
}
9798

98-
stdout.WriteString(resp.Stdout)
99-
stderr.WriteString(resp.Stderr)
99+
stdout.WriteString(resp.GetStdout())
100+
stderr.WriteString(resp.GetStderr())
100101

101-
_, err = fmt.Fprint(os.Stdout, resp.Stdout)
102+
_, err = fmt.Fprint(os.Stdout, resp.GetStdout())
102103
if err != nil {
103104
return "", "", err
104105
}
105106

106-
_, err = fmt.Fprint(os.Stderr, resp.Stderr)
107+
_, err = fmt.Fprint(os.Stderr, resp.GetStderr())
107108
if err != nil {
108109
return "", "", err
109110
}

0 commit comments

Comments
 (0)