mirror of
https://github.com/coder/coder.git
synced 2025-07-03 16:13:58 +00:00
Relates to https://github.com/coder/coder/issues/16419 Builds upon https://github.com/coder/coder/pull/16638 and adds a command `exp rpty` that allows you to open a ReconnectingPTY session to an agent. This ultimately allows us to add an integration-style CLI test to verify the functionality added in #16638 .
211 lines
6.1 KiB
Go
211 lines
6.1 KiB
Go
package cli
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
"golang.org/x/xerrors"
|
|
|
|
"github.com/coder/coder/v2/cli/cliui"
|
|
"github.com/coder/coder/v2/codersdk"
|
|
"github.com/coder/serpent"
|
|
)
|
|
|
|
func (RootCmd) promptExample() *serpent.Command {
|
|
promptCmd := func(use string, prompt func(inv *serpent.Invocation) error, options ...serpent.Option) *serpent.Command {
|
|
return &serpent.Command{
|
|
Use: use,
|
|
Options: options,
|
|
Handler: func(inv *serpent.Invocation) error {
|
|
return prompt(inv)
|
|
},
|
|
}
|
|
}
|
|
|
|
var (
|
|
useSearch bool
|
|
useSearchOption = serpent.Option{
|
|
Name: "search",
|
|
Description: "Show the search.",
|
|
Required: false,
|
|
Flag: "search",
|
|
Value: serpent.BoolOf(&useSearch),
|
|
}
|
|
|
|
multiSelectValues []string
|
|
multiSelectError error
|
|
useThingsOption = serpent.Option{
|
|
Name: "things",
|
|
Description: "Tell me what things you want.",
|
|
Flag: "things",
|
|
Default: "",
|
|
Value: serpent.StringArrayOf(&multiSelectValues),
|
|
}
|
|
|
|
enableCustomInput bool
|
|
enableCustomInputOption = serpent.Option{
|
|
Name: "enable-custom-input",
|
|
Description: "Enable custom input option in multi-select.",
|
|
Required: false,
|
|
Flag: "enable-custom-input",
|
|
Value: serpent.BoolOf(&enableCustomInput),
|
|
}
|
|
)
|
|
cmd := &serpent.Command{
|
|
Use: "prompt-example",
|
|
Short: "Example of various prompt types used within coder cli.",
|
|
Long: "Example of various prompt types used within coder cli. " +
|
|
"This command exists to aid in adjusting visuals of command prompts.",
|
|
Handler: func(inv *serpent.Invocation) error {
|
|
return inv.Command.HelpHandler(inv)
|
|
},
|
|
Children: []*serpent.Command{
|
|
promptCmd("confirm", func(inv *serpent.Invocation) error {
|
|
value, err := cliui.Prompt(inv, cliui.PromptOptions{
|
|
Text: "Basic confirmation prompt.",
|
|
Default: "yes",
|
|
IsConfirm: true,
|
|
})
|
|
_, _ = fmt.Fprintf(inv.Stdout, "%s\n", value)
|
|
return err
|
|
}),
|
|
promptCmd("validation", func(inv *serpent.Invocation) error {
|
|
value, err := cliui.Prompt(inv, cliui.PromptOptions{
|
|
Text: "Input a string that starts with a capital letter.",
|
|
Default: "",
|
|
Secret: false,
|
|
IsConfirm: false,
|
|
Validate: func(s string) error {
|
|
if len(s) == 0 {
|
|
return xerrors.Errorf("an input string is required")
|
|
}
|
|
if strings.ToUpper(string(s[0])) != string(s[0]) {
|
|
return xerrors.Errorf("input string must start with a capital letter")
|
|
}
|
|
return nil
|
|
},
|
|
})
|
|
_, _ = fmt.Fprintf(inv.Stdout, "%s\n", value)
|
|
return err
|
|
}),
|
|
promptCmd("secret", func(inv *serpent.Invocation) error {
|
|
value, err := cliui.Prompt(inv, cliui.PromptOptions{
|
|
Text: "Input a secret",
|
|
Default: "",
|
|
Secret: true,
|
|
IsConfirm: false,
|
|
Validate: func(s string) error {
|
|
if len(s) == 0 {
|
|
return xerrors.Errorf("an input string is required")
|
|
}
|
|
return nil
|
|
},
|
|
})
|
|
_, _ = fmt.Fprintf(inv.Stdout, "Your secret of length %d is safe with me\n", len(value))
|
|
return err
|
|
}),
|
|
promptCmd("select", func(inv *serpent.Invocation) error {
|
|
value, err := cliui.Select(inv, cliui.SelectOptions{
|
|
Options: []string{
|
|
"Blue", "Green", "Yellow", "Red", "Something else",
|
|
},
|
|
Default: "",
|
|
Message: "Select your favorite color:",
|
|
Size: 5,
|
|
HideSearch: !useSearch,
|
|
})
|
|
if value == "Something else" {
|
|
_, _ = fmt.Fprint(inv.Stdout, "I would have picked blue.\n")
|
|
} else {
|
|
_, _ = fmt.Fprintf(inv.Stdout, "%s is a nice color.\n", value)
|
|
}
|
|
return err
|
|
}, useSearchOption),
|
|
promptCmd("multiple", func(inv *serpent.Invocation) error {
|
|
_, _ = fmt.Fprintf(inv.Stdout, "This command exists to test the behavior of multiple prompts. The survey library does not erase the original message prompt after.")
|
|
thing, err := cliui.Select(inv, cliui.SelectOptions{
|
|
Message: "Select a thing",
|
|
Options: []string{
|
|
"Car", "Bike", "Plane", "Boat", "Train",
|
|
},
|
|
Default: "Car",
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
color, err := cliui.Select(inv, cliui.SelectOptions{
|
|
Message: "Select a color",
|
|
Options: []string{
|
|
"Blue", "Green", "Yellow", "Red",
|
|
},
|
|
Default: "Blue",
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
properties, err := cliui.MultiSelect(inv, cliui.MultiSelectOptions{
|
|
Message: "Select properties",
|
|
Options: []string{
|
|
"Fast", "Cool", "Expensive", "New",
|
|
},
|
|
Defaults: []string{"Fast"},
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
_, _ = fmt.Fprintf(inv.Stdout, "Your %s %s is awesome! Did you paint it %s?\n",
|
|
strings.Join(properties, " "),
|
|
thing,
|
|
color,
|
|
)
|
|
return err
|
|
}),
|
|
promptCmd("multi-select", func(inv *serpent.Invocation) error {
|
|
if len(multiSelectValues) == 0 {
|
|
multiSelectValues, multiSelectError = cliui.MultiSelect(inv, cliui.MultiSelectOptions{
|
|
Message: "Select some things:",
|
|
Options: []string{
|
|
"Code", "Chairs", "Whale", "Diamond", "Carrot",
|
|
},
|
|
Defaults: []string{"Code"},
|
|
EnableCustomInput: enableCustomInput,
|
|
})
|
|
}
|
|
_, _ = fmt.Fprintf(inv.Stdout, "%q are nice choices.\n", strings.Join(multiSelectValues, ", "))
|
|
return multiSelectError
|
|
}, useThingsOption, enableCustomInputOption),
|
|
promptCmd("rich-parameter", func(inv *serpent.Invocation) error {
|
|
value, err := cliui.RichSelect(inv, cliui.RichSelectOptions{
|
|
Options: []codersdk.TemplateVersionParameterOption{
|
|
{
|
|
Name: "Blue",
|
|
Description: "Like the ocean.",
|
|
Value: "blue",
|
|
Icon: "/logo/blue.png",
|
|
},
|
|
{
|
|
Name: "Red",
|
|
Description: "Like a clown's nose.",
|
|
Value: "red",
|
|
Icon: "/logo/red.png",
|
|
},
|
|
{
|
|
Name: "Yellow",
|
|
Description: "Like a bumblebee. ",
|
|
Value: "yellow",
|
|
Icon: "/logo/yellow.png",
|
|
},
|
|
},
|
|
Default: "blue",
|
|
Size: 5,
|
|
HideSearch: useSearch,
|
|
})
|
|
_, _ = fmt.Fprintf(inv.Stdout, "%s is a good choice.\n", value.Name)
|
|
return err
|
|
}, useSearchOption),
|
|
},
|
|
}
|
|
|
|
return cmd
|
|
}
|