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
42 changes: 0 additions & 42 deletions libs/cmdio/compat.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ import (
"fmt"
"io"
"strings"

"github.com/manifoldco/promptui"
)

/*
Expand Down Expand Up @@ -94,43 +92,3 @@ func AskYesOrNo(ctx context.Context, question string) (bool, error) {
ans = strings.ToLower(strings.TrimSpace(ans))
return ans == "y" || ans == "yes", nil
}

func splitAtLastNewLine(s string) (string, string) {
// Split at the newline character
if i := strings.LastIndex(s, "\n"); i != -1 {
return s[:i+1], s[i+1:]
}
// Return the original string if no newline found
return "", s
}

// AskSelect is a compatibility layer for the progress logger interfaces.
// It prompts the user with a question and returns the answer.
func AskSelect(ctx context.Context, question string, choices []string) (string, error) {
c := fromContext(ctx)

// Promptui does not support multiline prompts. So we split the question.
first, last := splitAtLastNewLine(question)
_, err := io.WriteString(c.err, first)
if err != nil {
return "", err
}

prompt := promptui.Select{
Label: last,
Items: choices,
HideHelp: true,
Templates: &promptui.SelectTemplates{
Label: "{{.}}: ",
Selected: last + ": {{.}}",
},
Stdin: c.promptStdin(),
Stdout: nopWriteCloser{c.err},
}

_, ans, err := prompt.Run()
if err != nil {
return "", err
}
return ans, nil
}
48 changes: 0 additions & 48 deletions libs/cmdio/compat_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,54 +147,6 @@ func (e *errorAfterNReader) Read(p []byte) (n int, err error) {
return 0, e.err
}

func TestCompat_splitAtLastNewLine(t *testing.T) {
tests := []struct {
name string
input string
wantFirst string
wantLast string
}{
{
name: "LF newline in middle",
input: "hello\nworld",
wantFirst: "hello\n",
wantLast: "world",
},
{
name: "CRLF newline in middle",
input: "hello\r\nworld",
wantFirst: "hello\r\n",
wantLast: "world",
},
{
name: "no newline",
input: "hello world",
wantFirst: "",
wantLast: "hello world",
},
{
name: "newline at end",
input: "hello\nworld\n",
wantFirst: "hello\nworld\n",
wantLast: "",
},
{
name: "newline at start",
input: "\nhello world",
wantFirst: "\n",
wantLast: "hello world",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
first, last := splitAtLastNewLine(tt.input)
assert.Equal(t, tt.wantFirst, first)
assert.Equal(t, tt.wantLast, last)
})
}
}

func TestCompat_AskYesOrNo(t *testing.T) {
tests := []struct {
name string
Expand Down
4 changes: 4 additions & 0 deletions libs/cmdio/select.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ type SelectOptions struct {
// StartInSearchMode opens the prompt with the search input focused.
StartInSearchMode bool

// HideHelp hides the navigation help line shown by promptui by default.
HideHelp bool

// LabelTemplate renders Label. Empty uses the default.
LabelTemplate string

Expand All @@ -44,6 +47,7 @@ func RunSelect(ctx context.Context, opts SelectOptions) (int, error) {
Items: opts.Items,
Searcher: opts.Searcher,
StartInSearchMode: opts.StartInSearchMode,
HideHelp: opts.HideHelp,
Templates: &promptui.SelectTemplates{
Label: opts.LabelTemplate,
Active: opts.Active,
Expand Down
17 changes: 16 additions & 1 deletion libs/template/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"io/fs"
"maps"
"slices"
"strings"

"github.com/databricks/cli/libs/cmdctx"
"github.com/databricks/cli/libs/cmdio"
Expand Down Expand Up @@ -213,10 +214,24 @@ func (c *config) promptOnce(property *jsonschema.Schema, name, defaultVal, descr
if err != nil {
return err
}
userInput, err = cmdio.AskSelect(c.ctx, description, options)
// promptui only supports a single-line label, so render any preceding
// lines of the description separately.
label := description
if i := strings.LastIndex(description, "\n"); i != -1 {
cmdio.LogString(c.ctx, description[:i])
label = description[i+1:]
}
idx, err := cmdio.RunSelect(c.ctx, cmdio.SelectOptions{
Label: label,
Items: options,
HideHelp: true,
LabelTemplate: "{{.}}: ",
Selected: label + ": {{.}}",
})
if err != nil {
return err
}
userInput = options[idx]
} else {
var err error
userInput, err = cmdio.Ask(c.ctx, description, defaultVal)
Expand Down
Loading