Skip to content

Commit 22f2c6d

Browse files
authored
chore: add command to render all existing cli prompts (#13689)
Adds a command to render all the existing cli prompts we use. This is to validate a change to how our cli ui prompts look.
1 parent ce7f13c commit 22f2c6d

File tree

2 files changed

+148
-0
lines changed

2 files changed

+148
-0
lines changed

cli/exp.go

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ func (r *RootCmd) expCmd() *serpent.Command {
1313
Children: []*serpent.Command{
1414
r.scaletestCmd(),
1515
r.errorExample(),
16+
r.promptExample(),
1617
},
1718
}
1819
return cmd

cli/prompts.go

+147
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
package cli
2+
3+
import (
4+
"fmt"
5+
"strings"
6+
7+
"golang.org/x/xerrors"
8+
9+
"github.com/coder/coder/v2/cli/cliui"
10+
"github.com/coder/coder/v2/codersdk"
11+
"github.com/coder/serpent"
12+
)
13+
14+
func (RootCmd) promptExample() *serpent.Command {
15+
promptCmd := func(use string, prompt func(inv *serpent.Invocation) error, options ...serpent.Option) *serpent.Command {
16+
return &serpent.Command{
17+
Use: use,
18+
Options: options,
19+
Handler: func(inv *serpent.Invocation) error {
20+
return prompt(inv)
21+
},
22+
}
23+
}
24+
25+
var useSearch bool
26+
useSearchOption := serpent.Option{
27+
Name: "search",
28+
Description: "Show the search.",
29+
Required: false,
30+
Flag: "search",
31+
Value: serpent.BoolOf(&useSearch),
32+
}
33+
cmd := &serpent.Command{
34+
Use: "prompt-example",
35+
Short: "Example of various prompt types used within coder cli.",
36+
Long: "Example of various prompt types used within coder cli. " +
37+
"This command exists to aid in adjusting visuals of command prompts.",
38+
Handler: func(inv *serpent.Invocation) error {
39+
return inv.Command.HelpHandler(inv)
40+
},
41+
Children: []*serpent.Command{
42+
promptCmd("confirm", func(inv *serpent.Invocation) error {
43+
value, err := cliui.Prompt(inv, cliui.PromptOptions{
44+
Text: "Basic confirmation prompt.",
45+
Default: "yes",
46+
IsConfirm: true,
47+
})
48+
_, _ = fmt.Fprintf(inv.Stdout, "%s\n", value)
49+
return err
50+
}),
51+
promptCmd("validation", func(inv *serpent.Invocation) error {
52+
value, err := cliui.Prompt(inv, cliui.PromptOptions{
53+
Text: "Input a string that starts with a capital letter.",
54+
Default: "",
55+
Secret: false,
56+
IsConfirm: false,
57+
Validate: func(s string) error {
58+
if len(s) == 0 {
59+
return xerrors.Errorf("an input string is required")
60+
}
61+
if strings.ToUpper(string(s[0])) != string(s[0]) {
62+
return xerrors.Errorf("input string must start with a capital letter")
63+
}
64+
return nil
65+
},
66+
})
67+
_, _ = fmt.Fprintf(inv.Stdout, "%s\n", value)
68+
return err
69+
}),
70+
promptCmd("secret", func(inv *serpent.Invocation) error {
71+
value, err := cliui.Prompt(inv, cliui.PromptOptions{
72+
Text: "Input a secret",
73+
Default: "",
74+
Secret: true,
75+
IsConfirm: false,
76+
Validate: func(s string) error {
77+
if len(s) == 0 {
78+
return xerrors.Errorf("an input string is required")
79+
}
80+
return nil
81+
},
82+
})
83+
_, _ = fmt.Fprintf(inv.Stdout, "Your secret of length %d is safe with me\n", len(value))
84+
return err
85+
}),
86+
promptCmd("select", func(inv *serpent.Invocation) error {
87+
value, err := cliui.Select(inv, cliui.SelectOptions{
88+
Options: []string{
89+
"Blue", "Green", "Yellow", "Red", "Something else",
90+
},
91+
Default: "",
92+
Message: "Select your favorite color:",
93+
Size: 5,
94+
HideSearch: !useSearch,
95+
})
96+
if value == "Something else" {
97+
_, _ = fmt.Fprint(inv.Stdout, "I would have picked blue.\n")
98+
} else {
99+
_, _ = fmt.Fprintf(inv.Stdout, "%s is a nice color.\n", value)
100+
}
101+
return err
102+
}, useSearchOption),
103+
promptCmd("multi-select", func(inv *serpent.Invocation) error {
104+
values, err := cliui.MultiSelect(inv, cliui.MultiSelectOptions{
105+
Message: "Select some things:",
106+
Options: []string{
107+
"Code", "Chair", "Whale", "Diamond", "Carrot",
108+
},
109+
Defaults: []string{"Code"},
110+
})
111+
_, _ = fmt.Fprintf(inv.Stdout, "%q are nice choices.\n", strings.Join(values, ", "))
112+
return err
113+
}),
114+
promptCmd("rich-parameter", func(inv *serpent.Invocation) error {
115+
value, err := cliui.RichSelect(inv, cliui.RichSelectOptions{
116+
Options: []codersdk.TemplateVersionParameterOption{
117+
{
118+
Name: "Blue",
119+
Description: "Like the ocean.",
120+
Value: "blue",
121+
Icon: "/logo/blue.png",
122+
},
123+
{
124+
Name: "Red",
125+
Description: "Like a clown's nose.",
126+
Value: "red",
127+
Icon: "/logo/red.png",
128+
},
129+
{
130+
Name: "Yellow",
131+
Description: "Like a bumblebee. ",
132+
Value: "yellow",
133+
Icon: "/logo/yellow.png",
134+
},
135+
},
136+
Default: "blue",
137+
Size: 5,
138+
HideSearch: useSearch,
139+
})
140+
_, _ = fmt.Fprintf(inv.Stdout, "%s is a good choice.\n", value.Name)
141+
return err
142+
}, useSearchOption),
143+
},
144+
}
145+
146+
return cmd
147+
}

0 commit comments

Comments
 (0)