Skip to content
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
21 changes: 20 additions & 1 deletion cmd/aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ Examples:
DisableFlagParsing: true,
PreRunE: initConfig(nil),
RunE: func(cmd *cobra.Command, args []string) error {
args, nonInteractive := stripNonInteractiveFlag(args)

rt, err := runtime.NewDockerRuntime(cfg.DockerHost)
if err != nil {
return err
Expand Down Expand Up @@ -85,7 +87,7 @@ Examples:
}

stdout, stderr := io.Writer(os.Stdout), io.Writer(os.Stderr)
if terminal.IsTerminal(os.Stderr) {
if !nonInteractive && terminal.IsTerminal(os.Stderr) {
s := terminal.NewSpinner(os.Stderr, "Loading service...", 4*time.Second)
s.Start()
defer s.Stop()
Expand All @@ -97,3 +99,20 @@ Examples:
},
}
}

// stripNonInteractiveFlag pulls lstk's --non-interactive flag out of the AWS CLI
// passthrough args and reports whether it was set. The aws command uses
// DisableFlagParsing, so Cobra never parses the flag here — left in place it would
// be forwarded to the aws binary and rejected as an unknown option.
func stripNonInteractiveFlag(args []string) ([]string, bool) {
out := make([]string, 0, len(args))
nonInteractive := false
for _, a := range args {
if a == "--non-interactive" {
nonInteractive = true
continue
}
out = append(out, a)
}
return out, nonInteractive
}
52 changes: 52 additions & 0 deletions cmd/aws_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package cmd

import (
"reflect"
"testing"
)

func TestStripNonInteractiveFlag(t *testing.T) {
tests := []struct {
name string
args []string
wantArgs []string
wantNonInteract bool
}{
{
name: "absent",
args: []string{"s3", "ls"},
wantArgs: []string{"s3", "ls"},
wantNonInteract: false,
},
{
name: "bare flag is stripped and enables non-interactive",
args: []string{"--non-interactive", "s3", "ls"},
wantArgs: []string{"s3", "ls"},
wantNonInteract: true,
},
{
name: "flag among aws args is stripped",
args: []string{"s3", "ls", "--non-interactive", "--recursive"},
wantArgs: []string{"s3", "ls", "--recursive"},
wantNonInteract: true,
},
{
name: "does not strip a similarly named aws flag",
args: []string{"s3", "ls", "--non-interactive-mode"},
wantArgs: []string{"s3", "ls", "--non-interactive-mode"},
wantNonInteract: false,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gotArgs, gotNonInteract := stripNonInteractiveFlag(tt.args)
if gotNonInteract != tt.wantNonInteract {
t.Errorf("nonInteractive = %v, want %v", gotNonInteract, tt.wantNonInteract)
}
if !reflect.DeepEqual(gotArgs, tt.wantArgs) {
t.Errorf("args = %v, want %v", gotArgs, tt.wantArgs)
}
})
}
}
22 changes: 22 additions & 0 deletions test/integration/aws_cmd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,28 @@ func TestAWSCommandShowsSpinnerForSlowOperation(t *testing.T) {
assert.Contains(t, out, "ARGS:--profile localstack s3 ls")
}

func TestAWSCommandSuppressesSpinnerInNonInteractiveMode(t *testing.T) {
requireDocker(t)
cleanup()
t.Cleanup(cleanup)
ctx := testContext(t)
// A running emulator is required: without it, `lstk aws` exits before reaching the spinner.
startTestContainer(t, ctx)

// A slow operation would normally render the spinner in a PTY; --non-interactive
// must suppress it so captured streams carry no ANSI control codes.
fakeDir := writeSlowFakeAWS(t, 5)
homeDir := t.TempDir()
writeAWSProfile(t, homeDir)
e := env.With(env.DisableEvents, "1").With("PATH", fakeDir+":/bin:/usr/bin").With(env.Home, homeDir)

out, err := runLstkInPTY(t, ctx, e, "--non-interactive", "aws", "s3", "ls")
require.NoError(t, err, "lstk aws failed: %s", out)

assert.NotContains(t, out, "Loading service")
assert.Contains(t, out, "ARGS:--profile localstack s3 ls")
}

func TestAWSCommandSuppressesSpinnerForFastOperation(t *testing.T) {
requireDocker(t)
cleanup()
Expand Down
Loading