Skip to content

Commit 2281422

Browse files
authored
cmdio: drop AskSelect, migrate caller to RunSelect (#5219)
## Summary - `cmdio.AskSelect` was the only function in `libs/cmdio/compat.go` that mixed template-specific concerns (multi-line label handling) with cmdio. Its single caller in `libs/template/config.go` now calls `cmdio.RunSelect` directly and handles the prefix lines locally, shrinking `cmdio`'s public surface by one. - Added `HideHelp` to `cmdio.SelectOptions` so the template prompt keeps the hidden-help behavior that `AskSelect` previously hardcoded. ## Test plan - [x] Manual: `databricks bundle init default-python` and confirm the enum prompts render their multi-line description and selection list as before.
1 parent 1dd13a4 commit 2281422

4 files changed

Lines changed: 20 additions & 91 deletions

File tree

libs/cmdio/compat.go

Lines changed: 0 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ import (
55
"fmt"
66
"io"
77
"strings"
8-
9-
"github.com/manifoldco/promptui"
108
)
119

1210
/*
@@ -94,43 +92,3 @@ func AskYesOrNo(ctx context.Context, question string) (bool, error) {
9492
ans = strings.ToLower(strings.TrimSpace(ans))
9593
return ans == "y" || ans == "yes", nil
9694
}
97-
98-
func splitAtLastNewLine(s string) (string, string) {
99-
// Split at the newline character
100-
if i := strings.LastIndex(s, "\n"); i != -1 {
101-
return s[:i+1], s[i+1:]
102-
}
103-
// Return the original string if no newline found
104-
return "", s
105-
}
106-
107-
// AskSelect is a compatibility layer for the progress logger interfaces.
108-
// It prompts the user with a question and returns the answer.
109-
func AskSelect(ctx context.Context, question string, choices []string) (string, error) {
110-
c := fromContext(ctx)
111-
112-
// Promptui does not support multiline prompts. So we split the question.
113-
first, last := splitAtLastNewLine(question)
114-
_, err := io.WriteString(c.err, first)
115-
if err != nil {
116-
return "", err
117-
}
118-
119-
prompt := promptui.Select{
120-
Label: last,
121-
Items: choices,
122-
HideHelp: true,
123-
Templates: &promptui.SelectTemplates{
124-
Label: "{{.}}: ",
125-
Selected: last + ": {{.}}",
126-
},
127-
Stdin: c.promptStdin(),
128-
Stdout: nopWriteCloser{c.err},
129-
}
130-
131-
_, ans, err := prompt.Run()
132-
if err != nil {
133-
return "", err
134-
}
135-
return ans, nil
136-
}

libs/cmdio/compat_test.go

Lines changed: 0 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -147,54 +147,6 @@ func (e *errorAfterNReader) Read(p []byte) (n int, err error) {
147147
return 0, e.err
148148
}
149149

150-
func TestCompat_splitAtLastNewLine(t *testing.T) {
151-
tests := []struct {
152-
name string
153-
input string
154-
wantFirst string
155-
wantLast string
156-
}{
157-
{
158-
name: "LF newline in middle",
159-
input: "hello\nworld",
160-
wantFirst: "hello\n",
161-
wantLast: "world",
162-
},
163-
{
164-
name: "CRLF newline in middle",
165-
input: "hello\r\nworld",
166-
wantFirst: "hello\r\n",
167-
wantLast: "world",
168-
},
169-
{
170-
name: "no newline",
171-
input: "hello world",
172-
wantFirst: "",
173-
wantLast: "hello world",
174-
},
175-
{
176-
name: "newline at end",
177-
input: "hello\nworld\n",
178-
wantFirst: "hello\nworld\n",
179-
wantLast: "",
180-
},
181-
{
182-
name: "newline at start",
183-
input: "\nhello world",
184-
wantFirst: "\n",
185-
wantLast: "hello world",
186-
},
187-
}
188-
189-
for _, tt := range tests {
190-
t.Run(tt.name, func(t *testing.T) {
191-
first, last := splitAtLastNewLine(tt.input)
192-
assert.Equal(t, tt.wantFirst, first)
193-
assert.Equal(t, tt.wantLast, last)
194-
})
195-
}
196-
}
197-
198150
func TestCompat_AskYesOrNo(t *testing.T) {
199151
tests := []struct {
200152
name string

libs/cmdio/select.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ type SelectOptions struct {
2323
// StartInSearchMode opens the prompt with the search input focused.
2424
StartInSearchMode bool
2525

26+
// HideHelp hides the navigation help line shown by promptui by default.
27+
HideHelp bool
28+
2629
// LabelTemplate renders Label. Empty uses the default.
2730
LabelTemplate string
2831

@@ -44,6 +47,7 @@ func RunSelect(ctx context.Context, opts SelectOptions) (int, error) {
4447
Items: opts.Items,
4548
Searcher: opts.Searcher,
4649
StartInSearchMode: opts.StartInSearchMode,
50+
HideHelp: opts.HideHelp,
4751
Templates: &promptui.SelectTemplates{
4852
Label: opts.LabelTemplate,
4953
Active: opts.Active,

libs/template/config.go

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"io/fs"
88
"maps"
99
"slices"
10+
"strings"
1011

1112
"github.com/databricks/cli/libs/cmdctx"
1213
"github.com/databricks/cli/libs/cmdio"
@@ -213,10 +214,24 @@ func (c *config) promptOnce(property *jsonschema.Schema, name, defaultVal, descr
213214
if err != nil {
214215
return err
215216
}
216-
userInput, err = cmdio.AskSelect(c.ctx, description, options)
217+
// promptui only supports a single-line label, so render any preceding
218+
// lines of the description separately.
219+
label := description
220+
if i := strings.LastIndex(description, "\n"); i != -1 {
221+
cmdio.LogString(c.ctx, description[:i])
222+
label = description[i+1:]
223+
}
224+
idx, err := cmdio.RunSelect(c.ctx, cmdio.SelectOptions{
225+
Label: label,
226+
Items: options,
227+
HideHelp: true,
228+
LabelTemplate: "{{.}}: ",
229+
Selected: label + ": {{.}}",
230+
})
217231
if err != nil {
218232
return err
219233
}
234+
userInput = options[idx]
220235
} else {
221236
var err error
222237
userInput, err = cmdio.Ask(c.ctx, description, defaultVal)

0 commit comments

Comments
 (0)