From 97a3b70599dcba4aae1c24fc36796362505d39ed Mon Sep 17 00:00:00 2001 From: Andy Feller Date: Sat, 26 Apr 2025 12:57:10 -0400 Subject: [PATCH 1/6] Update to huh@0.7.0, echo mode changes This commit is the initial change around updating to huh@0.7.0; pre-testing changes. --- go.mod | 2 +- go.sum | 12 ++++++++++-- internal/prompter/prompter.go | 9 ++++++--- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 31b07f2cf..3562f24a6 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/briandowns/spinner v1.18.1 github.com/cenkalti/backoff/v4 v4.3.0 github.com/charmbracelet/glamour v0.9.2-0.20250319212134-549f544650e3 - github.com/charmbracelet/huh v0.6.1-0.20250409210615-c5906631cbb5 + github.com/charmbracelet/huh v0.7.0 github.com/charmbracelet/lipgloss v1.1.1-0.20250319133953-166f707985bc github.com/cli/go-gh/v2 v2.12.0 github.com/cli/go-internal v0.0.0-20241025142207-6c48bcd5ce24 diff --git a/go.sum b/go.sum index b312bcf6c..2ac25c2f8 100644 --- a/go.sum +++ b/go.sum @@ -110,20 +110,28 @@ github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc h1:4p github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc/go.mod h1:X4/0JoqgTIPSFcRA/P6INZzIuyqdFY5rm8tb41s9okk= github.com/charmbracelet/glamour v0.9.2-0.20250319212134-549f544650e3 h1:hx6E25SvI2WiZdt/gxINcYBnHD7PE2Vr9auqwg5B05g= github.com/charmbracelet/glamour v0.9.2-0.20250319212134-549f544650e3/go.mod h1:ihVqv4/YOY5Fweu1cxajuQrwJFh3zU4Ukb4mHVNjq3s= -github.com/charmbracelet/huh v0.6.1-0.20250409210615-c5906631cbb5 h1:uOnMxWghHfEYm2DPMeIHHAEirV/TduBVC9ZRXGcX9Q8= -github.com/charmbracelet/huh v0.6.1-0.20250409210615-c5906631cbb5/go.mod h1:xl27E/xNaX3WwdkqpvBwjJcGWhupkU52CWLC5hReBTw= +github.com/charmbracelet/huh v0.7.0 h1:W8S1uyGETgj9Tuda3/JdVkc3x7DBLZYPZc4c+/rnRdc= +github.com/charmbracelet/huh v0.7.0/go.mod h1:UGC3DZHlgOKHvHC07a5vHag41zzhpPFj34U92sOmyuk= github.com/charmbracelet/lipgloss v1.1.1-0.20250319133953-166f707985bc h1:nFRtCfZu/zkltd2lsLUPlVNv3ej/Atod9hcdbRZtlys= github.com/charmbracelet/lipgloss v1.1.1-0.20250319133953-166f707985bc/go.mod h1:aKC/t2arECF6rNOnaKaVU6y4t4ZeHQzqfxedE/VkVhA= github.com/charmbracelet/x/ansi v0.8.0 h1:9GTq3xq9caJW8ZrBTe0LIe2fvfLR/bYXKTx2llXn7xE= github.com/charmbracelet/x/ansi v0.8.0/go.mod h1:wdYl/ONOLHLIVmQaxbIYEC/cRKOQyjTkowiI4blgS9Q= github.com/charmbracelet/x/cellbuf v0.0.13 h1:/KBBKHuVRbq1lYx5BzEHBAFBP8VcQzJejZ/IA3iR28k= github.com/charmbracelet/x/cellbuf v0.0.13/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs= +github.com/charmbracelet/x/conpty v0.1.0 h1:4zc8KaIcbiL4mghEON8D72agYtSeIgq8FSThSPQIb+U= +github.com/charmbracelet/x/conpty v0.1.0/go.mod h1:rMFsDJoDwVmiYM10aD4bH2XiRgwI7NYJtQgl5yskjEQ= +github.com/charmbracelet/x/errors v0.0.0-20240508181413-e8d8b6e2de86 h1:JSt3B+U9iqk37QUU2Rvb6DSBYRLtWqFqfxf8l5hOZUA= +github.com/charmbracelet/x/errors v0.0.0-20240508181413-e8d8b6e2de86/go.mod h1:2P0UgXMEa6TsToMSuFqKFQR+fZTO9CNGUNokkPatT/0= github.com/charmbracelet/x/exp/golden v0.0.0-20241011142426-46044092ad91 h1:payRxjMjKgx2PaCWLZ4p3ro9y97+TVLZNaRZgJwSVDQ= github.com/charmbracelet/x/exp/golden v0.0.0-20241011142426-46044092ad91/go.mod h1:wDlXFlCrmJ8J+swcL/MnGUuYnqgQdW9rhSD61oNMb6U= github.com/charmbracelet/x/exp/strings v0.0.0-20240722160745-212f7b056ed0 h1:qko3AQ4gK1MTS/de7F5hPGx6/k1u0w4TeYmBFwzYVP4= github.com/charmbracelet/x/exp/strings v0.0.0-20240722160745-212f7b056ed0/go.mod h1:pBhA0ybfXv6hDjQUZ7hk1lVxBiUbupdw5R31yPUViVQ= github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ= github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg= +github.com/charmbracelet/x/termios v0.1.1 h1:o3Q2bT8eqzGnGPOYheoYS8eEleT5ZVNYNy8JawjaNZY= +github.com/charmbracelet/x/termios v0.1.1/go.mod h1:rB7fnv1TgOPOyyKRJ9o+AsTU/vK5WHJ2ivHeut/Pcwo= +github.com/charmbracelet/x/xpty v0.1.2 h1:Pqmu4TEJ8KeA9uSkISKMU3f+C1F6OGBn8ABuGlqCbtI= +github.com/charmbracelet/x/xpty v0.1.2/go.mod h1:XK2Z0id5rtLWcpeNiMYBccNNBrP2IJnzHI0Lq13Xzq4= github.com/cli/browser v1.0.0/go.mod h1:IEWkHYbLjkhtjwwWlwTHW2lGxeS5gezEQBMLTwDHf5Q= github.com/cli/browser v1.3.0 h1:LejqCrpWr+1pRqmEPDGnTZOjsMe7sehifLynZJuqJpo= github.com/cli/browser v1.3.0/go.mod h1:HH8s+fOAxjhQoBUAsKuPCbqUuxZDhQ2/aD+SzsEfBTk= diff --git a/internal/prompter/prompter.go b/internal/prompter/prompter.go index 2a4328366..d56374665 100644 --- a/internal/prompter/prompter.go +++ b/internal/prompter/prompter.go @@ -137,10 +137,12 @@ func (p *accessiblePrompter) Input(prompt, defaultValue string) (string, error) func (p *accessiblePrompter) Password(prompt string) (string, error) { var result string - // EchoMode(huh.EchoModePassword) doesn't have any effect in accessible mode. + // EchoModeNone and EchoModePassword both result in disabling echo mode + // as password masking is outside of VT100 spec. form := p.newForm( huh.NewGroup( huh.NewInput(). + EchoMode(huh.EchoModeNone). Title(prompt). Value(&result), ), @@ -171,9 +173,12 @@ func (p *accessiblePrompter) Confirm(prompt string, defaultValue bool) (bool, er func (p *accessiblePrompter) AuthToken() (string, error) { var result string + // EchoModeNone and EchoModePassword both result in disabling echo mode + // as password masking is outside of VT100 spec. form := p.newForm( huh.NewGroup( huh.NewInput(). + EchoMode(huh.EchoModeNone). Title("Paste your authentication token:"). // Note: if this validation fails, the prompt loops. Validate(func(input string) error { @@ -183,8 +188,6 @@ func (p *accessiblePrompter) AuthToken() (string, error) { return nil }). Value(&result), - // This doesn't have any effect in accessible mode. - // EchoMode(huh.EchoModePassword), ), ) From a53b6c074ce66b8df7dd7abddcc713abf15efa1b Mon Sep 17 00:00:00 2001 From: Andy Feller Date: Mon, 28 Apr 2025 08:55:47 -0400 Subject: [PATCH 2/6] Assert password and auth token not displayed This commit expands existing tests (thanks to @babakks) to assert whether the echo mode is actually disabled for password and auth token prompts. --- internal/prompter/accessible_prompter_test.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/internal/prompter/accessible_prompter_test.go b/internal/prompter/accessible_prompter_test.go index 619eb14f1..63f253331 100644 --- a/internal/prompter/accessible_prompter_test.go +++ b/internal/prompter/accessible_prompter_test.go @@ -134,6 +134,11 @@ func TestAccessiblePrompter(t *testing.T) { passwordValue, err := p.Password("Enter password") require.NoError(t, err) require.Equal(t, dummyPassword, passwordValue) + + // Ensure the dummy password is not printed to the screen, + // asserting that echo mode is disabled without OS-level tests. + _, err = console.ExpectString(" \r\n\r\n") + require.NoError(t, err) }) t.Run("Confirm", func(t *testing.T) { @@ -192,6 +197,11 @@ func TestAccessiblePrompter(t *testing.T) { authValue, err := p.AuthToken() require.NoError(t, err) require.Equal(t, dummyAuthToken, authValue) + + // Ensure the dummy password is not printed to the screen, + // asserting that echo mode is disabled without OS-level tests. + _, err = console.ExpectString(" \r\n\r\n") + require.NoError(t, err) }) t.Run("AuthToken - blank input returns error", func(t *testing.T) { @@ -220,6 +230,11 @@ func TestAccessiblePrompter(t *testing.T) { authValue, err := p.AuthToken() require.NoError(t, err) require.Equal(t, dummyAuthTokenForAfterFailure, authValue) + + // Ensure the dummy password is not printed to the screen, + // asserting that echo mode is disabled without OS-level tests. + _, err = console.ExpectString(" \r\n\r\n") + require.NoError(t, err) }) t.Run("ConfirmDeletion", func(t *testing.T) { From 9fa00c350bb4a09dca6ed76d607ed8baef3d9d2e Mon Sep 17 00:00:00 2001 From: Andy Feller Date: Mon, 28 Apr 2025 10:17:23 -0400 Subject: [PATCH 3/6] Update accessible tests based on huh@0.7.0 changes --- internal/prompter/accessible_prompter_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/internal/prompter/accessible_prompter_test.go b/internal/prompter/accessible_prompter_test.go index 63f253331..2211d7720 100644 --- a/internal/prompter/accessible_prompter_test.go +++ b/internal/prompter/accessible_prompter_test.go @@ -38,7 +38,7 @@ func TestAccessiblePrompter(t *testing.T) { go func() { // Wait for prompt to appear - _, err := console.ExpectString("Choose:") + _, err := console.ExpectString("Input a number between 1 and 3:") require.NoError(t, err) // Select option 1 @@ -57,7 +57,7 @@ func TestAccessiblePrompter(t *testing.T) { go func() { // Wait for prompt to appear - _, err := console.ExpectString("Select a number") + _, err := console.ExpectString("Input a number between 0 and 3:") require.NoError(t, err) // Select options 1 and 2 @@ -340,7 +340,7 @@ func TestAccessiblePrompter(t *testing.T) { require.NoError(t, err) // Expect a notice to enter something valid since blank is disallowed. - _, err = console.ExpectString("invalid input. please try again") + _, err = console.ExpectString("Invalid: must be between 1 and 1") require.NoError(t, err) // Send a 1 to select to open the editor. This will immediately exit @@ -367,7 +367,7 @@ func TestAccessiblePrompter(t *testing.T) { require.NoError(t, err) // Expect a notice to enter something valid since blank is disallowed. - _, err = console.ExpectString("invalid input. please try again") + _, err = console.ExpectString("Invalid: must be between 1 and 1") require.NoError(t, err) // Send a 1 to select to open the editor since skip is invalid and From 2d66877d6c447ffb20a602c338e6aab13c916035 Mon Sep 17 00:00:00 2001 From: Andy Feller Date: Mon, 28 Apr 2025 11:15:28 -0400 Subject: [PATCH 4/6] Update internal/prompter/accessible_prompter_test.go --- internal/prompter/accessible_prompter_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/prompter/accessible_prompter_test.go b/internal/prompter/accessible_prompter_test.go index 2211d7720..3c8420cde 100644 --- a/internal/prompter/accessible_prompter_test.go +++ b/internal/prompter/accessible_prompter_test.go @@ -136,7 +136,7 @@ func TestAccessiblePrompter(t *testing.T) { require.Equal(t, dummyPassword, passwordValue) // Ensure the dummy password is not printed to the screen, - // asserting that echo mode is disabled without OS-level tests. + // asserting that echo mode is disabled. _, err = console.ExpectString(" \r\n\r\n") require.NoError(t, err) }) From df0aedbe3c0e5e474f7b5238354cf2ba22eecd3a Mon Sep 17 00:00:00 2001 From: Andy Feller Date: Mon, 28 Apr 2025 11:16:35 -0400 Subject: [PATCH 5/6] Update internal/prompter/prompter.go --- internal/prompter/prompter.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/prompter/prompter.go b/internal/prompter/prompter.go index d56374665..c3281efbf 100644 --- a/internal/prompter/prompter.go +++ b/internal/prompter/prompter.go @@ -137,8 +137,8 @@ func (p *accessiblePrompter) Input(prompt, defaultValue string) (string, error) func (p *accessiblePrompter) Password(prompt string) (string, error) { var result string - // EchoModeNone and EchoModePassword both result in disabling echo mode - // as password masking is outside of VT100 spec. + // EchoModePassword is not used as password masking is unsupported in huh. + // EchoModeNone and EchoModePassword have the same effect of hiding user input. form := p.newForm( huh.NewGroup( huh.NewInput(). From 88d52ebf97bcbfe48a064206709e0adcb0c92922 Mon Sep 17 00:00:00 2001 From: Andy Feller Date: Mon, 28 Apr 2025 11:20:17 -0400 Subject: [PATCH 6/6] Fix other disabled echo mode comments --- internal/prompter/accessible_prompter_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/prompter/accessible_prompter_test.go b/internal/prompter/accessible_prompter_test.go index 3c8420cde..c95d379e3 100644 --- a/internal/prompter/accessible_prompter_test.go +++ b/internal/prompter/accessible_prompter_test.go @@ -199,7 +199,7 @@ func TestAccessiblePrompter(t *testing.T) { require.Equal(t, dummyAuthToken, authValue) // Ensure the dummy password is not printed to the screen, - // asserting that echo mode is disabled without OS-level tests. + // asserting that echo mode is disabled. _, err = console.ExpectString(" \r\n\r\n") require.NoError(t, err) }) @@ -232,7 +232,7 @@ func TestAccessiblePrompter(t *testing.T) { require.Equal(t, dummyAuthTokenForAfterFailure, authValue) // Ensure the dummy password is not printed to the screen, - // asserting that echo mode is disabled without OS-level tests. + // asserting that echo mode is disabled. _, err = console.ExpectString(" \r\n\r\n") require.NoError(t, err) })