Skip to content
This repository was archived by the owner on May 31, 2024. It is now read-only.

Commit 2b73987

Browse files
authored
Merge branch 'main' into lcloudy_CacheFilesExcluded
2 parents d44be29 + fa2f6df commit 2b73987

11 files changed

Lines changed: 589 additions & 2272 deletions

File tree

packages/cdk/npm-shrinkwrap.json

Lines changed: 373 additions & 2230 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/cli/go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ require (
88
github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de
99
github.com/aws/aws-sdk-go-v2 v1.8.1
1010
github.com/aws/aws-sdk-go-v2/config v1.6.1
11+
github.com/aws/aws-sdk-go-v2/credentials v1.3.3
1112
github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue v1.1.4
1213
github.com/aws/aws-sdk-go-v2/feature/dynamodb/expression v1.2.0
1314
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.3.2

packages/cli/go.sum

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ github.com/aws/aws-sdk-go-v2 v1.7.1/go.mod h1:L5LuPC1ZgDr2xQS7AmIec/Jlc7O/Y1u2Kx
5959
github.com/aws/aws-sdk-go-v2 v1.8.0/go.mod h1:xEFuWz+3TYdlPRuo+CqATbeDWIWyaT5uAPwPaWtgse0=
6060
github.com/aws/aws-sdk-go-v2 v1.8.1 h1:GcFgQl7MsBygmeeqXyV1ivrTEmsVz/rdFJaTcltG9ag=
6161
github.com/aws/aws-sdk-go-v2 v1.8.1/go.mod h1:xEFuWz+3TYdlPRuo+CqATbeDWIWyaT5uAPwPaWtgse0=
62+
github.com/aws/aws-sdk-go-v2 v1.11.2 h1:SDiCYqxdIYi6HgQfAWRhgdZrdnOuGyLDJVRSWLeHWvs=
6263
github.com/aws/aws-sdk-go-v2/config v1.5.0/go.mod h1:RWlPOAW3E3tbtNAqTwvSW54Of/yP3oiZXMI0xfUdjyA=
6364
github.com/aws/aws-sdk-go-v2/config v1.6.1 h1:qrZINaORyr78syO1zfD4l7r4tZjy0Z1l0sy4jiysyOM=
6465
github.com/aws/aws-sdk-go-v2/config v1.6.1/go.mod h1:t/y3UPu0XEDy0cEw6mvygaBQaPzWiYAxfP2SzgtvclA=
@@ -416,6 +417,8 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
416417
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
417418
golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo=
418419
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
420+
golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38=
421+
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
419422
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 h1:kQgndtyPBW/JIYERgdxfwMYh3AVStj88WQTlNDi2a+o=
420423
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
421424
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -526,6 +529,9 @@ golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7w
526529
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
527530
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
528531
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
532+
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
533+
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf h1:2ucpDCmfkl8Bd/FsLtiD653Wf96cW37s+iGx93zsu4k=
534+
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
529535
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654 h1:id054HUawV2/6IGm2IV8KZQjqtwAOo2CYlOToYqa0d0=
530536
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
531537
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
@@ -598,6 +604,12 @@ golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
598604
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
599605
golang.org/x/tools v0.1.2 h1:kRBLX7v7Af8W7Gdbbc908OJcdgtK8bOz9Uaj8/F1ACA=
600606
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
607+
golang.org/x/tools v0.1.7 h1:6j8CgantCy3yc8JGBqkDLMKWqZ0RDU2g1HVgacojGWQ=
608+
golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
609+
golang.org/x/tools v0.1.8 h1:P1HhGGuLW4aAclzjtmJdf0mJOjVUZUzOTqkAkWL+l6w=
610+
golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
611+
golang.org/x/tools v0.1.9 h1:j9KsMiaP1c3B0OTQGth0/k+miLGTgLsAFUCrF2vLcF8=
612+
golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
601613
golang.org/x/tools v0.1.10 h1:QjFRCZxdOhBJ/UNgnBZLbNV13DlbnK0quyivTnXJM20=
602614
golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
603615
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

packages/cli/internal/pkg/aws/cdk/execute_cdk.go

Lines changed: 68 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package cdk
33
import (
44
"bufio"
55
"fmt"
6+
"io"
67
"os"
78
"os/exec"
89
"regexp"
@@ -18,7 +19,10 @@ var ExecuteCdkCommand = executeCdkCommand
1819
var execCommand = exec.Command
1920
var progressRegex = regexp.MustCompile(`^.*\|\s*([0-9]+/[0-9]+)\s*\|(.*)`)
2021

22+
// These can be swapped out to use fake versions during tests
2123
var osRemoveAll = os.RemoveAll
24+
var mfaInput io.Reader = os.Stdin // Stream to get MFA codes from the user
25+
var mfaOutput io.Writer = os.Stdout // Stream to ask the user for MFA codes
2226

2327
func executeCdkCommand(appDir string, commandArgs []string, executionName string) (ProgressStream, error) {
2428
return executeCdkCommandAndCleanupDirectory(appDir, commandArgs, "", executionName)
@@ -30,7 +34,13 @@ func executeCdkCommandAndCleanupDirectory(appDir string, commandArgs []string, t
3034
cmd := execCommand("npm", cmdArgs...)
3135
cmd.Dir = appDir
3236

33-
progressChan, wait, err := processCommandOutputs(cmd, executionName)
37+
// Note that cmd won't have any access to stdin, stdout, or stderr that go
38+
// anywhere by default. It does not inherit our streams. This is a problem
39+
// because sometimes the CDK needs to dialog interactively with the user to
40+
// e.g. get MFA codes. So we make sure to forward along important output
41+
// and do our own prompting in processCommandIO.
42+
43+
progressChan, wait, err := processCommandIO(cmd, executionName)
3444
if err != nil {
3545
deleteCDKOutputDir(tmpDir)
3646
return nil, err
@@ -48,20 +58,24 @@ func executeCdkCommandAndCleanupDirectory(appDir string, commandArgs []string, t
4858
return progressChan, nil
4959
}
5060

51-
func processCommandOutputs(cmd *exec.Cmd, executionName string) (chan ProgressEvent, *sync.WaitGroup, error) {
61+
func processCommandIO(cmd *exec.Cmd, executionName string) (chan ProgressEvent, *sync.WaitGroup, error) {
5262
stderr, err := cmd.StderrPipe()
5363
if err != nil {
5464
return nil, nil, actionableerror.FindSuggestionForError(err, actionableerror.AwsErrorMessageToSuggestedActionMap)
5565
}
5666
stdout, err := cmd.StdoutPipe()
5767

68+
if err != nil {
69+
return nil, nil, actionableerror.FindSuggestionForError(err, actionableerror.AwsErrorMessageToSuggestedActionMap)
70+
}
71+
stdin, err := cmd.StdinPipe()
5872
if err != nil {
5973
return nil, nil, actionableerror.FindSuggestionForError(err, actionableerror.AwsErrorMessageToSuggestedActionMap)
6074
}
6175
if err := cmd.Start(); err != nil {
6276
return nil, nil, fmt.Errorf("couldn't execute CDK deploy command: %w", err)
6377
}
64-
progressChan, wait := processOutputs(bufio.NewScanner(stdout), bufio.NewScanner(stderr), executionName)
78+
progressChan, wait := processOutputs(bufio.NewScanner(stdout), bufio.NewScanner(stderr), stdin, executionName)
6579
return progressChan, wait, nil
6680
}
6781

@@ -74,7 +88,7 @@ func deleteCDKOutputDir(cdkOutputDir string) {
7488
}
7589
}
7690

77-
func processOutputs(stdout *bufio.Scanner, stderr *bufio.Scanner, executionName string) (chan ProgressEvent, *sync.WaitGroup) {
91+
func processOutputs(stdout *bufio.Scanner, stderr *bufio.Scanner, stdin io.WriteCloser, executionName string) (chan ProgressEvent, *sync.WaitGroup) {
7892
var wait sync.WaitGroup
7993
wait.Add(2)
8094
progressChan := make(chan ProgressEvent)
@@ -83,12 +97,59 @@ func processOutputs(stdout *bufio.Scanner, stderr *bufio.Scanner, executionName
8397
}
8498
go func() {
8599
defer wait.Done()
100+
// We can't just scan through lines, because the MFA prompt is a
101+
// partial line and we need to see it. So scan runes instead and do our
102+
// own line buffering.
103+
stdout.Split(bufio.ScanRunes)
104+
line := ""
86105
for stdout.Scan() {
87-
log.Debug().Msg(stdout.Text())
106+
line += stdout.Text()
107+
if strings.HasSuffix(line, "\n") {
108+
// We got a whole line at this character
109+
log.Debug().Msg(line[:len(line)-1])
110+
line = ""
111+
}
112+
if strings.HasSuffix(line, ": ") && strings.HasPrefix(line, "MFA token for") {
113+
// CDK may make MFA prompts here, so we need to forward them to the user.
114+
// We also need to make sure to drop down a couple lines
115+
// because if there's a progress spinner going it will just
116+
// immediately clobber our prompt.
117+
fmt.Fprintf(mfaOutput, "\n%s\n\n", line)
118+
line = ""
119+
120+
oldStepDescription := currentEvent.StepDescription
121+
currentEvent.StepDescription = "Waiting for MFA..."
122+
progressChan <- *currentEvent
123+
124+
// And we need to read and pass along a code.
125+
var reply string
126+
fmt.Fscanln(mfaInput, &reply)
127+
128+
currentEvent.StepDescription = oldStepDescription
129+
progressChan <- *currentEvent
130+
131+
_, err := stdin.Write([]byte(reply + "\n"))
132+
if err != nil {
133+
log.Error().Msgf("error encountered while forwarding MFA code: %v", err)
134+
} else {
135+
log.Debug().Msg("Sent MFA code")
136+
}
137+
// We only need to send at most one MFA code, and if we don't
138+
// close its standard input we get stuck when the CDK is done
139+
// with its work.
140+
err = stdin.Close()
141+
if err != nil {
142+
log.Error().Msgf("error encountered while closing CDK input stream: %v", err)
143+
}
144+
}
145+
}
146+
if line != "" {
147+
// Handle any last unterminated line
148+
log.Debug().Msg(line)
88149
}
89150
err := stdout.Err()
90151
if err != nil {
91-
log.Debug().Msgf("error encountered while scanning stdout: %v", err)
152+
log.Error().Msgf("error encountered while scanning stdout: %v", err)
92153
}
93154
}()
94155
go func() {
@@ -99,7 +160,7 @@ func processOutputs(stdout *bufio.Scanner, stderr *bufio.Scanner, executionName
99160
}
100161
err := stderr.Err()
101162
if err != nil {
102-
log.Debug().Msgf("error encountered while scanning stderr: %v", err)
163+
log.Error().Msgf("error encountered while scanning stderr: %v", err)
103164
}
104165
}()
105166
return progressChan, &wait

packages/cli/internal/pkg/aws/cdk/execute_cdk_test.go

Lines changed: 91 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
package cdk
22

33
import (
4+
"bytes"
45
"fmt"
6+
"io"
57
"os"
68
"os/exec"
9+
"strings"
710
"testing"
811

912
iomocks "github.com/aws/amazon-genomics-cli/internal/pkg/mocks/io"
@@ -14,10 +17,15 @@ import (
1417
)
1518

1619
const (
17-
testExecuteCommandSuccessArg = "test-execute-command-success-arg"
18-
testExecuteCommandFailureArg = "test-execute-command-failure-arg"
19-
testExecuteExecutioName = "test-key"
20-
testExecuteCommandProgressLine = "Agc-Context-Demo-yy110HKO4J-ctx1 | 3/10 | 3:22:16 PM | REVIEW_IN_PROGRESS | AWS::CloudFormation::Stack | Agc-Context-Demo-yy110HKO4J-ctx1 User Initiated"
20+
testExecuteCommandSuccessArg = "test-execute-command-success-arg"
21+
testExecuteCommandMultilineArg = "test-execute-command-multiline-arg"
22+
testExecuteCommandPromptArg = "test-execute-command-prompt-arg"
23+
testExecuteCommandFailureArg = "test-execute-command-failure-arg"
24+
testExecuteExecutioName = "test-key"
25+
testExecuteCommandProgressLine = "Agc-Context-Demo-yy110HKO4J-ctx1 | 3/10 | 3:22:16 PM | REVIEW_IN_PROGRESS | AWS::CloudFormation::Stack | Agc-Context-Demo-yy110HKO4J-ctx1 User Initiated"
26+
testExecuteCommandProgressLine2 = "Agc-Context-Demo-yy110HKO4J-ctx1 | 4/10 | 3:23:16 PM | REVIEW_IN_PROGRESS | AWS::CloudFormation::Stack | Agc-Context-Demo-yy110HKO4J-ctx1 User Initiated"
27+
testExecuteCodePrompt = "\nMFA token for arn:something-or-other: \n\n"
28+
testExecuteCode = "31337"
2129
)
2230

2331
func fakeExecCommand(command string, args ...string) *exec.Cmd {
@@ -33,6 +41,8 @@ type ExecuteCdkCommandTestSuite struct {
3341

3442
osRemoveAllOrig func(string) error
3543
execCommandOrig func(command string, args ...string) *exec.Cmd
44+
mfaInputOrig io.Reader
45+
mfaOutputOrig io.Writer
3646

3747
ctrl *gomock.Controller
3848
mockOs *iomocks.MockOS
@@ -49,9 +59,14 @@ func (s *ExecuteCdkCommandTestSuite) SetupTest() {
4959
s.mockOs = iomocks.NewMockOS(s.ctrl)
5060
s.osRemoveAllOrig = osRemoveAll
5161
s.execCommandOrig = execCommand
62+
s.mfaInputOrig = mfaInput
63+
s.mfaOutputOrig = mfaOutput
5264

5365
osRemoveAll = s.mockOs.RemoveAll
5466
execCommand = fakeExecCommand
67+
// mfaInput and mfaOutput will be overwritten by the tests that need them.
68+
// If we use real pipes here it's too easy for us to deadlock when the code
69+
// under test misbehaves.
5570

5671
s.appDir = s.T().TempDir()
5772
s.tmpDir = "/test/tmp/dir"
@@ -64,6 +79,8 @@ func (s *ExecuteCdkCommandTestSuite) AfterTest(_, _ string) {
6479
func (s *ExecuteCdkCommandTestSuite) TearDownTest() {
6580
osRemoveAll = s.osRemoveAllOrig
6681
execCommand = s.execCommandOrig
82+
mfaInput = s.mfaInputOrig
83+
mfaOutput = s.mfaOutputOrig
6784
}
6885

6986
func (s *ExecuteCdkCommandTestSuite) TestExecuteCdkCommand_Success() {
@@ -81,6 +98,51 @@ func (s *ExecuteCdkCommandTestSuite) TestExecuteCdkCommand_Success() {
8198
waitForChanToClose(progressStream)
8299
}
83100

101+
func (s *ExecuteCdkCommandTestSuite) TestExecuteCdkCommand_Multiline() {
102+
s.mockOs.EXPECT().RemoveAll(gomock.Any()).Return(nil).Times(0)
103+
104+
progressStream, err := executeCdkCommand(s.appDir, []string{testExecuteCommandMultilineArg}, testExecuteExecutioName)
105+
s.Require().NoError(err)
106+
event1 := <-progressStream
107+
s.Assert().Equal(3, event1.CurrentStep)
108+
s.Assert().Equal(10, event1.TotalSteps)
109+
s.Assert().Equal(testExecuteCommandProgressLine, event1.Outputs[0])
110+
s.Assert().Equal(testExecuteExecutioName, event1.ExecutionName)
111+
event2 := <-progressStream
112+
s.Assert().Equal(4, event2.CurrentStep)
113+
s.Assert().Equal(10, event2.TotalSteps)
114+
// Lines should accumulate into Outputs
115+
s.Assert().Equal(testExecuteCommandProgressLine, event2.Outputs[0])
116+
s.Assert().Equal(testExecuteCommandProgressLine2, event2.Outputs[1])
117+
s.Assert().Equal(testExecuteExecutioName, event2.ExecutionName)
118+
event3 := <-progressStream
119+
s.Assert().NoError(event3.Err)
120+
waitForChanToClose(progressStream)
121+
}
122+
123+
func (s *ExecuteCdkCommandTestSuite) TestExecuteCdkCommand_Prompt() {
124+
s.mockOs.EXPECT().RemoveAll(gomock.Any()).Return(nil).Times(0)
125+
126+
// Prepare the input the test expects to see typed
127+
toType := testExecuteCode + "\n"
128+
mfaInput = strings.NewReader(toType)
129+
// And somewhere to put the prompt
130+
var promptBuffer bytes.Buffer
131+
mfaOutput = &promptBuffer
132+
133+
progressStream, err := executeCdkCommand(s.appDir, []string{testExecuteCommandPromptArg}, testExecuteExecutioName)
134+
s.Require().NoError(err)
135+
event1 := <-progressStream
136+
s.Assert().Equal("Waiting for MFA...", event1.StepDescription)
137+
// Prompt goes into the pipe before the event. So check it.
138+
s.Assert().Equal(testExecuteCodePrompt, promptBuffer.String())
139+
// Code is already waiting to be read when we start.
140+
// It shold continue.
141+
event2 := <-progressStream
142+
s.Assert().NoError(event2.Err)
143+
waitForChanToClose(progressStream)
144+
}
145+
84146
func (s *ExecuteCdkCommandTestSuite) TestExecuteCdkCommandAndCleanupDirectory_Success() {
85147
s.mockOs.EXPECT().RemoveAll(s.tmpDir).Return(nil).Times(1)
86148

@@ -153,15 +215,35 @@ func TestHelperProcess(t *testing.T) {
153215
testArg := args[4]
154216
switch testArg {
155217
case testExecuteCommandSuccessArg:
156-
fmt.Fprint(os.Stdout, "some line")
157-
fmt.Fprint(os.Stderr, testExecuteCommandProgressLine)
218+
fmt.Fprintln(os.Stdout, "some line")
219+
fmt.Fprintln(os.Stderr, testExecuteCommandProgressLine)
220+
os.Exit(0)
221+
case testExecuteCommandMultilineArg:
222+
fmt.Fprintln(os.Stdout, "some line")
223+
fmt.Fprintln(os.Stderr, testExecuteCommandProgressLine)
224+
fmt.Fprintln(os.Stdout, "another line")
225+
fmt.Fprintln(os.Stderr, testExecuteCommandProgressLine2)
226+
os.Exit(0)
227+
case testExecuteCommandPromptArg:
228+
// Because the stdout and stderr streams are different, the order in
229+
// which they feed into the event-generation logic is nondeterministic,
230+
// so we make sure to only do the MFA prompt here (and not any progress
231+
// likes to stderr), because otherwise the test wouldn't be able to
232+
// predict what order it would see events in, and would then be hard to
233+
// write.
234+
fmt.Fprint(os.Stdout, testExecuteCodePrompt)
235+
var reply string
236+
fmt.Scanln(&reply)
237+
if reply != testExecuteCode {
238+
os.Exit(1)
239+
}
158240
os.Exit(0)
159241
case testExecuteCommandFailureArg:
160-
fmt.Fprint(os.Stdout, "some line")
161-
fmt.Fprint(os.Stderr, testExecuteCommandFailureArg)
242+
fmt.Fprintln(os.Stdout, "some line")
243+
fmt.Fprintln(os.Stderr, testExecuteCommandFailureArg)
162244
os.Exit(1)
163245
default:
164-
fmt.Fprint(os.Stderr, "Unknown failure")
246+
fmt.Fprintln(os.Stderr, "Unknown failure")
165247
os.Exit(1)
166248
}
167249
}

packages/cli/internal/pkg/aws/cdk/progress.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,12 @@ func runProgressBar(ctx context.Context, description string, numberOfChannels in
194194
if len(keyWithSteps) == numberOfChannels {
195195
bar.SetCurrent(int64(currentStep))
196196
}
197+
198+
if progressEvent.StepDescription != "" {
199+
bar.Set("description", progressEvent.StepDescription)
200+
} else {
201+
bar.Set("description", description)
202+
}
197203
case <-ctx.Done():
198204
close(receiver)
199205
bar.SetCurrent(bar.Total()).Finish()

0 commit comments

Comments
 (0)