Skip to content

Commit 370b739

Browse files
committed
feat(printer) make PromptForPassword scripting compatible
1 parent 5985f19 commit 370b739

File tree

2 files changed

+59
-3
lines changed

2 files changed

+59
-3
lines changed

internal/pkg/print/print.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -172,11 +172,20 @@ func (p *Printer) PromptForEnter(prompt string) error {
172172
func (p *Printer) PromptForPassword(prompt string) (string, error) {
173173
p.Cmd.PrintErr(prompt)
174174
defer p.Outputln("")
175-
bytePassword, err := term.ReadPassword(int(syscall.Stdin))
175+
if term.IsTerminal(syscall.Stdin) {
176+
bytePassword, err := term.ReadPassword(syscall.Stdin)
177+
if err != nil {
178+
return "", fmt.Errorf("read password: %w", err)
179+
}
180+
return string(bytePassword), nil
181+
}
182+
// Fallback for non-terminal environments
183+
reader := bufio.NewReader(p.Cmd.InOrStdin())
184+
pw, err := reader.ReadString('\n')
176185
if err != nil {
177-
return "", fmt.Errorf("read password: %w", err)
186+
return "", fmt.Errorf("read password from non-terminal: %w", err)
178187
}
179-
return string(bytePassword), nil
188+
return pw[:len(pw)-1], nil // remove trailing newline
180189
}
181190

182191
// Shows the content in the command's stdout using the "less" command

internal/pkg/print/print_test.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"fmt"
77
"io"
88
"log/slog"
9+
"sync"
910
"testing"
1011

1112
"github.com/spf13/cobra"
@@ -936,3 +937,49 @@ func TestOutputResult(t *testing.T) {
936937
})
937938
}
938939
}
940+
941+
func TestPromptForPassword(t *testing.T) {
942+
tests := []struct {
943+
description string
944+
input string
945+
}{
946+
{
947+
description: "password",
948+
input: "mypassword\n",
949+
},
950+
{
951+
description: "empty password",
952+
input: "\n",
953+
},
954+
}
955+
for _, tt := range tests {
956+
t.Run(tt.description, func(t *testing.T) {
957+
cmd := &cobra.Command{}
958+
r, w := io.Pipe()
959+
defer func() {
960+
r.Close()
961+
w.Close()
962+
}()
963+
cmd.SetIn(r)
964+
p := &Printer{
965+
Cmd: cmd,
966+
Verbosity: ErrorLevel,
967+
}
968+
var pw string
969+
var err error
970+
var wg sync.WaitGroup
971+
wg.Go(func() {
972+
pw, err = p.PromptForPassword("Enter password: ")
973+
})
974+
w.Write([]byte(tt.input))
975+
wg.Wait()
976+
if err != nil {
977+
t.Fatalf("unexpected error: %v", err)
978+
}
979+
withoutNewline := tt.input[:len(tt.input)-1]
980+
if pw != withoutNewline {
981+
t.Fatalf("unexpected password: got %q, want %q", pw, withoutNewline)
982+
}
983+
})
984+
}
985+
}

0 commit comments

Comments
 (0)