mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
chore(cli): replace clibase with external coder/serpent (#12252)
This commit is contained in:
@@ -18,13 +18,13 @@ import (
|
||||
"golang.org/x/xerrors"
|
||||
"tailscale.com/tailcfg"
|
||||
|
||||
"github.com/coder/coder/v2/cli/clibase"
|
||||
"github.com/coder/coder/v2/cli/clitest"
|
||||
"github.com/coder/coder/v2/cli/cliui"
|
||||
"github.com/coder/coder/v2/coderd/util/ptr"
|
||||
"github.com/coder/coder/v2/codersdk"
|
||||
"github.com/coder/coder/v2/tailnet"
|
||||
"github.com/coder/coder/v2/testutil"
|
||||
"github.com/coder/serpent"
|
||||
)
|
||||
|
||||
func TestAgent(t *testing.T) {
|
||||
@@ -382,8 +382,8 @@ func TestAgent(t *testing.T) {
|
||||
output := make(chan string, 100) // Buffered to avoid blocking, overflow is discarded.
|
||||
logs := make(chan []codersdk.WorkspaceAgentLog, 1)
|
||||
|
||||
cmd := &clibase.Cmd{
|
||||
Handler: func(inv *clibase.Invocation) error {
|
||||
cmd := &serpent.Cmd{
|
||||
Handler: func(inv *serpent.Invocation) error {
|
||||
tc.opts.Fetch = func(_ context.Context, _ uuid.UUID) (codersdk.WorkspaceAgent, error) {
|
||||
t.Log("iter", len(tc.iter))
|
||||
var err error
|
||||
@@ -450,8 +450,8 @@ func TestAgent(t *testing.T) {
|
||||
t.Parallel()
|
||||
var fetchCalled uint64
|
||||
|
||||
cmd := &clibase.Cmd{
|
||||
Handler: func(inv *clibase.Invocation) error {
|
||||
cmd := &serpent.Cmd{
|
||||
Handler: func(inv *serpent.Invocation) error {
|
||||
buf := bytes.Buffer{}
|
||||
err := cliui.Agent(inv.Context(), &buf, uuid.Nil, cliui.AgentOptions{
|
||||
FetchInterval: 10 * time.Millisecond,
|
||||
|
||||
@@ -3,13 +3,13 @@ package cliui
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/coder/coder/v2/cli/clibase"
|
||||
"github.com/coder/pretty"
|
||||
"github.com/coder/serpent"
|
||||
)
|
||||
|
||||
func DeprecationWarning(message string) clibase.MiddlewareFunc {
|
||||
return func(next clibase.HandlerFunc) clibase.HandlerFunc {
|
||||
return func(i *clibase.Invocation) error {
|
||||
func DeprecationWarning(message string) serpent.MiddlewareFunc {
|
||||
return func(next serpent.HandlerFunc) serpent.HandlerFunc {
|
||||
return func(i *serpent.Invocation) error {
|
||||
_, _ = fmt.Fprintln(i.Stdout, "\n"+pretty.Sprint(DefaultStyles.Wrap,
|
||||
pretty.Sprint(
|
||||
DefaultStyles.Warn,
|
||||
|
||||
@@ -8,11 +8,11 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/coder/coder/v2/cli/clibase"
|
||||
"github.com/coder/coder/v2/cli/cliui"
|
||||
"github.com/coder/coder/v2/codersdk"
|
||||
"github.com/coder/coder/v2/pty/ptytest"
|
||||
"github.com/coder/coder/v2/testutil"
|
||||
"github.com/coder/serpent"
|
||||
)
|
||||
|
||||
func TestExternalAuth(t *testing.T) {
|
||||
@@ -22,8 +22,8 @@ func TestExternalAuth(t *testing.T) {
|
||||
defer cancel()
|
||||
|
||||
ptty := ptytest.New(t)
|
||||
cmd := &clibase.Cmd{
|
||||
Handler: func(inv *clibase.Invocation) error {
|
||||
cmd := &serpent.Cmd{
|
||||
Handler: func(inv *serpent.Invocation) error {
|
||||
var fetched atomic.Bool
|
||||
return cliui.ExternalAuth(inv.Context(), inv.Stdout, cliui.ExternalAuthOptions{
|
||||
Fetch: func(ctx context.Context) ([]codersdk.TemplateVersionExternalAuth, error) {
|
||||
|
||||
+8
-8
@@ -1,8 +1,8 @@
|
||||
package cliui
|
||||
|
||||
import (
|
||||
"github.com/coder/coder/v2/cli/clibase"
|
||||
"github.com/coder/coder/v2/codersdk"
|
||||
"github.com/coder/serpent"
|
||||
)
|
||||
|
||||
var defaultQuery = "owner:me"
|
||||
@@ -11,12 +11,12 @@ var defaultQuery = "owner:me"
|
||||
// and allows easy integration to a CLI command.
|
||||
// Example usage:
|
||||
//
|
||||
// func (r *RootCmd) MyCmd() *clibase.Cmd {
|
||||
// func (r *RootCmd) MyCmd() *serpent.Cmd {
|
||||
// var (
|
||||
// filter cliui.WorkspaceFilter
|
||||
// ...
|
||||
// )
|
||||
// cmd := &clibase.Cmd{
|
||||
// cmd := &serpent.Cmd{
|
||||
// ...
|
||||
// }
|
||||
// filter.AttachOptions(&cmd.Options)
|
||||
@@ -44,20 +44,20 @@ func (w *WorkspaceFilter) Filter() codersdk.WorkspaceFilter {
|
||||
return f
|
||||
}
|
||||
|
||||
func (w *WorkspaceFilter) AttachOptions(opts *clibase.OptionSet) {
|
||||
func (w *WorkspaceFilter) AttachOptions(opts *serpent.OptionSet) {
|
||||
*opts = append(*opts,
|
||||
clibase.Option{
|
||||
serpent.Option{
|
||||
Flag: "all",
|
||||
FlagShorthand: "a",
|
||||
Description: "Specifies whether all workspaces will be listed or not.",
|
||||
|
||||
Value: clibase.BoolOf(&w.all),
|
||||
Value: serpent.BoolOf(&w.all),
|
||||
},
|
||||
clibase.Option{
|
||||
serpent.Option{
|
||||
Flag: "search",
|
||||
Description: "Search for a workspace with a query.",
|
||||
Default: defaultQuery,
|
||||
Value: clibase.StringOf(&w.searchQuery),
|
||||
Value: serpent.StringOf(&w.searchQuery),
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
+11
-11
@@ -9,12 +9,12 @@ import (
|
||||
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/coder/coder/v2/cli/clibase"
|
||||
"github.com/coder/serpent"
|
||||
)
|
||||
|
||||
type OutputFormat interface {
|
||||
ID() string
|
||||
AttachOptions(opts *clibase.OptionSet)
|
||||
AttachOptions(opts *serpent.OptionSet)
|
||||
Format(ctx context.Context, data any) (string, error)
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ func NewOutputFormatter(formats ...OutputFormat) *OutputFormatter {
|
||||
|
||||
// AttachOptions attaches the --output flag to the given command, and any
|
||||
// additional flags required by the output formatters.
|
||||
func (f *OutputFormatter) AttachOptions(opts *clibase.OptionSet) {
|
||||
func (f *OutputFormatter) AttachOptions(opts *serpent.OptionSet) {
|
||||
for _, format := range f.formats {
|
||||
format.AttachOptions(opts)
|
||||
}
|
||||
@@ -60,11 +60,11 @@ func (f *OutputFormatter) AttachOptions(opts *clibase.OptionSet) {
|
||||
}
|
||||
|
||||
*opts = append(*opts,
|
||||
clibase.Option{
|
||||
serpent.Option{
|
||||
Flag: "output",
|
||||
FlagShorthand: "o",
|
||||
Default: f.formats[0].ID(),
|
||||
Value: clibase.StringOf(&f.formatID),
|
||||
Value: serpent.StringOf(&f.formatID),
|
||||
Description: "Output format. Available formats: " + strings.Join(formatNames, ", ") + ".",
|
||||
},
|
||||
)
|
||||
@@ -129,13 +129,13 @@ func (*tableFormat) ID() string {
|
||||
}
|
||||
|
||||
// AttachOptions implements OutputFormat.
|
||||
func (f *tableFormat) AttachOptions(opts *clibase.OptionSet) {
|
||||
func (f *tableFormat) AttachOptions(opts *serpent.OptionSet) {
|
||||
*opts = append(*opts,
|
||||
clibase.Option{
|
||||
serpent.Option{
|
||||
Flag: "column",
|
||||
FlagShorthand: "c",
|
||||
Default: strings.Join(f.defaultColumns, ","),
|
||||
Value: clibase.StringArrayOf(&f.columns),
|
||||
Value: serpent.StringArrayOf(&f.columns),
|
||||
Description: "Columns to display in table output. Available columns: " + strings.Join(f.allColumns, ", ") + ".",
|
||||
},
|
||||
)
|
||||
@@ -161,7 +161,7 @@ func (jsonFormat) ID() string {
|
||||
}
|
||||
|
||||
// AttachOptions implements OutputFormat.
|
||||
func (jsonFormat) AttachOptions(_ *clibase.OptionSet) {}
|
||||
func (jsonFormat) AttachOptions(_ *serpent.OptionSet) {}
|
||||
|
||||
// Format implements OutputFormat.
|
||||
func (jsonFormat) Format(_ context.Context, data any) (string, error) {
|
||||
@@ -187,7 +187,7 @@ func (textFormat) ID() string {
|
||||
return "text"
|
||||
}
|
||||
|
||||
func (textFormat) AttachOptions(_ *clibase.OptionSet) {}
|
||||
func (textFormat) AttachOptions(_ *serpent.OptionSet) {}
|
||||
|
||||
func (textFormat) Format(_ context.Context, data any) (string, error) {
|
||||
return fmt.Sprintf("%s", data), nil
|
||||
@@ -213,7 +213,7 @@ func (d *DataChangeFormat) ID() string {
|
||||
return d.format.ID()
|
||||
}
|
||||
|
||||
func (d *DataChangeFormat) AttachOptions(opts *clibase.OptionSet) {
|
||||
func (d *DataChangeFormat) AttachOptions(opts *serpent.OptionSet) {
|
||||
d.format.AttachOptions(opts)
|
||||
}
|
||||
|
||||
|
||||
@@ -8,13 +8,13 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/coder/coder/v2/cli/clibase"
|
||||
"github.com/coder/coder/v2/cli/cliui"
|
||||
"github.com/coder/serpent"
|
||||
)
|
||||
|
||||
type format struct {
|
||||
id string
|
||||
attachOptionsFn func(opts *clibase.OptionSet)
|
||||
attachOptionsFn func(opts *serpent.OptionSet)
|
||||
formatFn func(ctx context.Context, data any) (string, error)
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ func (f *format) ID() string {
|
||||
return f.id
|
||||
}
|
||||
|
||||
func (f *format) AttachOptions(opts *clibase.OptionSet) {
|
||||
func (f *format) AttachOptions(opts *serpent.OptionSet) {
|
||||
if f.attachOptionsFn != nil {
|
||||
f.attachOptionsFn(opts)
|
||||
}
|
||||
@@ -85,12 +85,12 @@ func Test_OutputFormatter(t *testing.T) {
|
||||
cliui.JSONFormat(),
|
||||
&format{
|
||||
id: "foo",
|
||||
attachOptionsFn: func(opts *clibase.OptionSet) {
|
||||
opts.Add(clibase.Option{
|
||||
attachOptionsFn: func(opts *serpent.OptionSet) {
|
||||
opts.Add(serpent.Option{
|
||||
Name: "foo",
|
||||
Flag: "foo",
|
||||
FlagShorthand: "f",
|
||||
Value: clibase.DiscardValue,
|
||||
Value: serpent.DiscardValue,
|
||||
Description: "foo flag 1234",
|
||||
})
|
||||
},
|
||||
@@ -101,7 +101,7 @@ func Test_OutputFormatter(t *testing.T) {
|
||||
},
|
||||
)
|
||||
|
||||
cmd := &clibase.Cmd{}
|
||||
cmd := &serpent.Cmd{}
|
||||
f.AttachOptions(&cmd.Options)
|
||||
|
||||
fs := cmd.Options.FlagSet()
|
||||
|
||||
@@ -5,12 +5,12 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/coder/coder/v2/cli/clibase"
|
||||
"github.com/coder/coder/v2/codersdk"
|
||||
"github.com/coder/pretty"
|
||||
"github.com/coder/serpent"
|
||||
)
|
||||
|
||||
func RichParameter(inv *clibase.Invocation, templateVersionParameter codersdk.TemplateVersionParameter) (string, error) {
|
||||
func RichParameter(inv *serpent.Invocation, templateVersionParameter codersdk.TemplateVersionParameter) (string, error) {
|
||||
label := templateVersionParameter.Name
|
||||
if templateVersionParameter.DisplayName != "" {
|
||||
label = templateVersionParameter.DisplayName
|
||||
|
||||
+5
-5
@@ -13,8 +13,8 @@ import (
|
||||
"github.com/mattn/go-isatty"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/coder/coder/v2/cli/clibase"
|
||||
"github.com/coder/pretty"
|
||||
"github.com/coder/serpent"
|
||||
)
|
||||
|
||||
// PromptOptions supply a set of options to the prompt.
|
||||
@@ -30,13 +30,13 @@ const skipPromptFlag = "yes"
|
||||
|
||||
// SkipPromptOption adds a "--yes/-y" flag to the cmd that can be used to skip
|
||||
// prompts.
|
||||
func SkipPromptOption() clibase.Option {
|
||||
return clibase.Option{
|
||||
func SkipPromptOption() serpent.Option {
|
||||
return serpent.Option{
|
||||
Flag: skipPromptFlag,
|
||||
FlagShorthand: "y",
|
||||
Description: "Bypass prompts.",
|
||||
// Discard
|
||||
Value: clibase.BoolOf(new(bool)),
|
||||
Value: serpent.BoolOf(new(bool)),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ const (
|
||||
)
|
||||
|
||||
// Prompt asks the user for input.
|
||||
func Prompt(inv *clibase.Invocation, opts PromptOptions) (string, error) {
|
||||
func Prompt(inv *serpent.Invocation, opts PromptOptions) (string, error) {
|
||||
// If the cmd has a "yes" flag for skipping confirm prompts, honor it.
|
||||
// If it's not a "Confirm" prompt, then don't skip. As the default value of
|
||||
// "yes" makes no sense.
|
||||
|
||||
@@ -11,11 +11,11 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/coder/coder/v2/cli/clibase"
|
||||
"github.com/coder/coder/v2/cli/cliui"
|
||||
"github.com/coder/coder/v2/pty"
|
||||
"github.com/coder/coder/v2/pty/ptytest"
|
||||
"github.com/coder/coder/v2/testutil"
|
||||
"github.com/coder/serpent"
|
||||
)
|
||||
|
||||
func TestPrompt(t *testing.T) {
|
||||
@@ -77,7 +77,7 @@ func TestPrompt(t *testing.T) {
|
||||
resp, err := newPrompt(ptty, cliui.PromptOptions{
|
||||
Text: "ShouldNotSeeThis",
|
||||
IsConfirm: true,
|
||||
}, func(inv *clibase.Invocation) {
|
||||
}, func(inv *serpent.Invocation) {
|
||||
inv.Command.Options = append(inv.Command.Options, cliui.SkipPromptOption())
|
||||
inv.Args = []string{"-y"}
|
||||
})
|
||||
@@ -145,10 +145,10 @@ func TestPrompt(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func newPrompt(ptty *ptytest.PTY, opts cliui.PromptOptions, invOpt func(inv *clibase.Invocation)) (string, error) {
|
||||
func newPrompt(ptty *ptytest.PTY, opts cliui.PromptOptions, invOpt func(inv *serpent.Invocation)) (string, error) {
|
||||
value := ""
|
||||
cmd := &clibase.Cmd{
|
||||
Handler: func(inv *clibase.Invocation) error {
|
||||
cmd := &serpent.Cmd{
|
||||
Handler: func(inv *serpent.Invocation) error {
|
||||
var err error
|
||||
value, err = cliui.Prompt(inv, opts)
|
||||
return err
|
||||
@@ -210,8 +210,8 @@ func TestPasswordTerminalState(t *testing.T) {
|
||||
|
||||
// nolint:unused
|
||||
func passwordHelper() {
|
||||
cmd := &clibase.Cmd{
|
||||
Handler: func(inv *clibase.Invocation) error {
|
||||
cmd := &serpent.Cmd{
|
||||
Handler: func(inv *serpent.Invocation) error {
|
||||
cliui.Prompt(inv, cliui.PromptOptions{
|
||||
Text: "Password:",
|
||||
Secret: true,
|
||||
|
||||
@@ -11,11 +11,11 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/coder/coder/v2/cli/clibase"
|
||||
"github.com/coder/coder/v2/cli/cliui"
|
||||
"github.com/coder/coder/v2/coderd/database/dbtime"
|
||||
"github.com/coder/coder/v2/codersdk"
|
||||
"github.com/coder/coder/v2/pty/ptytest"
|
||||
"github.com/coder/serpent"
|
||||
)
|
||||
|
||||
// This cannot be ran in parallel because it uses a signal.
|
||||
@@ -127,8 +127,8 @@ func newProvisionerJob(t *testing.T) provisionerJobTest {
|
||||
}
|
||||
jobLock := sync.Mutex{}
|
||||
logs := make(chan codersdk.ProvisionerJobLog, 1)
|
||||
cmd := &clibase.Cmd{
|
||||
Handler: func(inv *clibase.Invocation) error {
|
||||
cmd := &serpent.Cmd{
|
||||
Handler: func(inv *serpent.Invocation) error {
|
||||
return cliui.ProvisionerJob(inv.Context(), inv.Stdout, cliui.ProvisionerJobOptions{
|
||||
FetchInterval: time.Millisecond,
|
||||
Fetch: func() (codersdk.ProvisionerJob, error) {
|
||||
|
||||
+4
-4
@@ -10,8 +10,8 @@ import (
|
||||
"github.com/AlecAivazis/survey/v2/terminal"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/coder/coder/v2/cli/clibase"
|
||||
"github.com/coder/coder/v2/codersdk"
|
||||
"github.com/coder/serpent"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -68,7 +68,7 @@ type RichSelectOptions struct {
|
||||
}
|
||||
|
||||
// RichSelect displays a list of user options including name and description.
|
||||
func RichSelect(inv *clibase.Invocation, richOptions RichSelectOptions) (*codersdk.TemplateVersionParameterOption, error) {
|
||||
func RichSelect(inv *serpent.Invocation, richOptions RichSelectOptions) (*codersdk.TemplateVersionParameterOption, error) {
|
||||
opts := make([]string, len(richOptions.Options))
|
||||
var defaultOpt string
|
||||
for i, option := range richOptions.Options {
|
||||
@@ -102,7 +102,7 @@ func RichSelect(inv *clibase.Invocation, richOptions RichSelectOptions) (*coders
|
||||
}
|
||||
|
||||
// Select displays a list of user options.
|
||||
func Select(inv *clibase.Invocation, opts SelectOptions) (string, error) {
|
||||
func Select(inv *serpent.Invocation, opts SelectOptions) (string, error) {
|
||||
// The survey library used *always* fails when testing on Windows,
|
||||
// as it requires a live TTY (can't be a conpty). We should fork
|
||||
// this library to add a dummy fallback, that simply reads/writes
|
||||
@@ -138,7 +138,7 @@ func Select(inv *clibase.Invocation, opts SelectOptions) (string, error) {
|
||||
return value, err
|
||||
}
|
||||
|
||||
func MultiSelect(inv *clibase.Invocation, items []string) ([]string, error) {
|
||||
func MultiSelect(inv *serpent.Invocation, items []string) ([]string, error) {
|
||||
// Similar hack is applied to Select()
|
||||
if flag.Lookup("test.v") != nil {
|
||||
return items, nil
|
||||
|
||||
@@ -6,10 +6,10 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/coder/coder/v2/cli/clibase"
|
||||
"github.com/coder/coder/v2/cli/cliui"
|
||||
"github.com/coder/coder/v2/codersdk"
|
||||
"github.com/coder/coder/v2/pty/ptytest"
|
||||
"github.com/coder/serpent"
|
||||
)
|
||||
|
||||
func TestSelect(t *testing.T) {
|
||||
@@ -31,8 +31,8 @@ func TestSelect(t *testing.T) {
|
||||
|
||||
func newSelect(ptty *ptytest.PTY, opts cliui.SelectOptions) (string, error) {
|
||||
value := ""
|
||||
cmd := &clibase.Cmd{
|
||||
Handler: func(inv *clibase.Invocation) error {
|
||||
cmd := &serpent.Cmd{
|
||||
Handler: func(inv *serpent.Invocation) error {
|
||||
var err error
|
||||
value, err = cliui.Select(inv, opts)
|
||||
return err
|
||||
@@ -72,8 +72,8 @@ func TestRichSelect(t *testing.T) {
|
||||
|
||||
func newRichSelect(ptty *ptytest.PTY, opts cliui.RichSelectOptions) (string, error) {
|
||||
value := ""
|
||||
cmd := &clibase.Cmd{
|
||||
Handler: func(inv *clibase.Invocation) error {
|
||||
cmd := &serpent.Cmd{
|
||||
Handler: func(inv *serpent.Invocation) error {
|
||||
richOption, err := cliui.RichSelect(inv, opts)
|
||||
if err == nil {
|
||||
value = richOption.Value
|
||||
@@ -105,8 +105,8 @@ func TestMultiSelect(t *testing.T) {
|
||||
|
||||
func newMultiSelect(ptty *ptytest.PTY, items []string) ([]string, error) {
|
||||
var values []string
|
||||
cmd := &clibase.Cmd{
|
||||
Handler: func(inv *clibase.Invocation) error {
|
||||
cmd := &serpent.Cmd{
|
||||
Handler: func(inv *serpent.Invocation) error {
|
||||
selectedItems, err := cliui.MultiSelect(inv, items)
|
||||
if err == nil {
|
||||
values = selectedItems
|
||||
|
||||
Reference in New Issue
Block a user