fix: render interactive prompts once on Windows by using ux components#8649
Conversation
azd used the archived AlecAivazis/survey library for interactive input, which has an unfixed Windows-specific bug that re-renders a prompt and its answer above the next prompt. Route the terminal path of Prompt, Select, Confirm, and MultiSelect through the in-repo pkg/ux components, which render prompts themselves and do not exhibit the double-render. Non-terminal, no-prompt, and external prompt-client paths are unchanged. Fixes Azure#435 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR addresses a Windows-specific double-render issue in interactive prompts by routing terminal-based prompt rendering away from the archived survey library and through azd’s in-repo pkg/ux components, while preserving the existing non-terminal and external prompt-client behaviors.
Changes:
- Added terminal-only UX implementations for Prompt/Select/Confirm/MultiSelect in a new
console_ux.gohelper file. - Updated
AskerConsoleprompt methods to dispatch to UX implementations when running in a terminal. - Documented the fix in the CLI changelog.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 7 comments.
| File | Description |
|---|---|
cli/azd/pkg/input/console.go |
Routes terminal interactive prompt methods to UX helpers. |
cli/azd/pkg/input/console_ux.go |
Implements UX-backed Prompt/Select/Confirm/MultiSelect and cancellation mapping. |
cli/azd/CHANGELOG.md |
Adds a bug-fix entry describing the Windows prompt double-render fix. |
- Guard the ux terminal dispatch with !c.noPrompt so --no-prompt continues to short-circuit through the Asker no-prompt implementation instead of prompting. - Preserve survey's empty-selection behavior by setting AllowEmptySelection on the ux MultiSelect (callers that require a choice already enforce it). - Use new(val) pointer construction per repo Go conventions. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Extract pure transformation helpers (selectChoices, multiSelectChoices, multiSelectValues) from the ux prompt wrappers and add table-driven tests covering them plus mapUxCancel and optionLabel. Restores the pkg/input coverage that dropped when console_ux.go was introduced. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Refactor the ux prompt wrappers to delegate to a generic runComponent helper and extract option-builder and result-transform helpers. This collapses the duplicated spinner/cancel/bookkeeping logic into one testable function and makes the per-type wiring unit-testable. Adds tests for runComponent (success, cancel, error, pointer results), the option builders, and the result transforms, raising pkg/input coverage back above its pre-change level. Only the four thin TTY-bound *Ux wrappers remain uncovered (they require a real terminal). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Azure Dev CLI Install InstructionsInstall scriptsMacOS/Linux
bash: pwsh: WindowsPowerShell install MSI install Standalone Binary
MSI
Documentationlearn.microsoft.com documentationtitle: Azure Developer CLI reference
|
Summary
Fixes #435.
On Windows terminals (PowerShell 7, Windows Terminal, VS Code terminal), azd's interactive prompts render twice -- after the user submits a value, the prompt and its answer are redrawn above the next prompt. Originally reported for the
azd initenvironment-name prompt, later confirmed for Select/Confirm prompts as well.Root cause
azd uses the archived AlecAivazis/survey library for interactive input. survey has a long-standing Windows-specific double-render bug (survey#368, #406, #479) that was never fixed upstream; the project was archived in April 2024.
Fix
Per maintainer guidance on the issue, route the terminal rendering path of
Prompt,Select,Confirm, andMultiSelectthrough the in-repopkg/uxcomponents (ux.NewPrompt,ux.NewSelect,ux.NewConfirm,ux.NewMultiSelect). These components render prompts themselves and do not exhibit the double-render.The non-terminal,
--no-prompt, and external prompt-client (promptClient) paths are left untouched, so machine-friendly behavior used by tests, CI, and piped stdin is unchanged.Changes
cli/azd/pkg/input/console_ux.go:promptUx,selectUx,confirmUx,multiSelectUxhelpers, plus:mapUxCancel-- mapsux.ErrCancelledtosurveyterm.InterruptErrso existing Ctrl+C / interrupt handling continues to work.optionLabel-- preserves the gray(detail)suffix previously rendered for select option details.cli/azd/pkg/input/console.go: each of the four methods now dispatches to itsuxhelper whenc.isTerminal.Testing
go build ./...-- cleango test ./pkg/input/...-- passgolangci-lint run ./...-- 0 issuesmage preflight-- gofmt, go fix, copyright, cspell, cspell-misc, build, and test all pass.Manual Windows verification recommended on each prompt type to confirm single-render output.