mirror of https://github.com/coder/coder.git
chore(cli): rename Cmd to Command (#12616)
I think Command is cleaner and my original decision to use "Cmd" a mistake. Plus this creates better parity with cobra.
This commit is contained in:
parent
2a77580ba6
commit
b4c0fa80d8
|
@ -34,7 +34,7 @@ import (
|
||||||
"github.com/coder/serpent"
|
"github.com/coder/serpent"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) workspaceAgent() *serpent.Cmd {
|
func (r *RootCmd) workspaceAgent() *serpent.Command {
|
||||||
var (
|
var (
|
||||||
auth string
|
auth string
|
||||||
logDir string
|
logDir string
|
||||||
|
@ -49,7 +49,7 @@ func (r *RootCmd) workspaceAgent() *serpent.Cmd {
|
||||||
slogJSONPath string
|
slogJSONPath string
|
||||||
slogStackdriverPath string
|
slogStackdriverPath string
|
||||||
)
|
)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "agent",
|
Use: "agent",
|
||||||
Short: `Starts the Coder workspace agent.`,
|
Short: `Starts the Coder workspace agent.`,
|
||||||
// This command isn't useful to manually execute.
|
// This command isn't useful to manually execute.
|
||||||
|
|
|
@ -11,9 +11,9 @@ import (
|
||||||
"github.com/coder/serpent"
|
"github.com/coder/serpent"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) autoupdate() *serpent.Cmd {
|
func (r *RootCmd) autoupdate() *serpent.Command {
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Annotations: workspaceCommand,
|
Annotations: workspaceCommand,
|
||||||
Use: "autoupdate <workspace> <always|never>",
|
Use: "autoupdate <workspace> <always|never>",
|
||||||
Short: "Toggle auto-update policy for a workspace",
|
Short: "Toggle auto-update policy for a workspace",
|
||||||
|
|
|
@ -23,7 +23,7 @@ func TestBuilder(t *testing.T) {
|
||||||
t.Run("NoConfiguration", func(t *testing.T) {
|
t.Run("NoConfiguration", func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "test",
|
Use: "test",
|
||||||
Handler: testHandler(t),
|
Handler: testHandler(t),
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ func TestBuilder(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
tempFile := filepath.Join(t.TempDir(), "test.log")
|
tempFile := filepath.Join(t.TempDir(), "test.log")
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "test",
|
Use: "test",
|
||||||
Handler: testHandler(t,
|
Handler: testHandler(t,
|
||||||
clilog.WithHuman(tempFile),
|
clilog.WithHuman(tempFile),
|
||||||
|
@ -51,7 +51,7 @@ func TestBuilder(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
tempFile := filepath.Join(t.TempDir(), "test.log")
|
tempFile := filepath.Join(t.TempDir(), "test.log")
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "test",
|
Use: "test",
|
||||||
Handler: testHandler(t,
|
Handler: testHandler(t,
|
||||||
clilog.WithHuman(tempFile),
|
clilog.WithHuman(tempFile),
|
||||||
|
@ -68,7 +68,7 @@ func TestBuilder(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
tempFile := filepath.Join(t.TempDir(), "test.log")
|
tempFile := filepath.Join(t.TempDir(), "test.log")
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "test",
|
Use: "test",
|
||||||
Handler: testHandler(t, clilog.WithHuman(tempFile)),
|
Handler: testHandler(t, clilog.WithHuman(tempFile)),
|
||||||
}
|
}
|
||||||
|
@ -81,7 +81,7 @@ func TestBuilder(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
tempFile := filepath.Join(t.TempDir(), "test.log")
|
tempFile := filepath.Join(t.TempDir(), "test.log")
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "test",
|
Use: "test",
|
||||||
Handler: testHandler(t, clilog.WithJSON(tempFile), clilog.WithVerbose()),
|
Handler: testHandler(t, clilog.WithJSON(tempFile), clilog.WithVerbose()),
|
||||||
}
|
}
|
||||||
|
@ -107,7 +107,7 @@ func TestBuilder(t *testing.T) {
|
||||||
|
|
||||||
// Use the default deployment values.
|
// Use the default deployment values.
|
||||||
dv := coderdtest.DeploymentValues(t)
|
dv := coderdtest.DeploymentValues(t)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "test",
|
Use: "test",
|
||||||
Handler: testHandler(t, clilog.FromDeploymentValues(dv)),
|
Handler: testHandler(t, clilog.FromDeploymentValues(dv)),
|
||||||
}
|
}
|
||||||
|
@ -135,7 +135,7 @@ func TestBuilder(t *testing.T) {
|
||||||
Enable: true,
|
Enable: true,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "test",
|
Use: "test",
|
||||||
Handler: testHandler(t, clilog.FromDeploymentValues(dv)),
|
Handler: testHandler(t, clilog.FromDeploymentValues(dv)),
|
||||||
}
|
}
|
||||||
|
@ -150,7 +150,7 @@ func TestBuilder(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
tempFile := filepath.Join(t.TempDir(), "doesnotexist", "test.log")
|
tempFile := filepath.Join(t.TempDir(), "doesnotexist", "test.log")
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "test",
|
Use: "test",
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
logger, closeLog, err := clilog.New(
|
logger, closeLog, err := clilog.New(
|
||||||
|
|
|
@ -56,7 +56,7 @@ func (l *logWriter) Write(p []byte) (n int, err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewWithCommand(
|
func NewWithCommand(
|
||||||
t testing.TB, cmd *serpent.Cmd, args ...string,
|
t testing.TB, cmd *serpent.Command, args ...string,
|
||||||
) (*serpent.Invocation, config.Root) {
|
) (*serpent.Invocation, config.Root) {
|
||||||
configDir := config.Root(t.TempDir())
|
configDir := config.Root(t.TempDir())
|
||||||
// I really would like to fail test on error logs, but realistically, turning on by default
|
// I really would like to fail test on error logs, but realistically, turning on by default
|
||||||
|
|
|
@ -48,7 +48,7 @@ func DefaultCases() []CommandHelpCase {
|
||||||
|
|
||||||
// TestCommandHelp will test the help output of the given commands
|
// TestCommandHelp will test the help output of the given commands
|
||||||
// using golden files.
|
// using golden files.
|
||||||
func TestCommandHelp(t *testing.T, getRoot func(t *testing.T) *serpent.Cmd, cases []CommandHelpCase) {
|
func TestCommandHelp(t *testing.T, getRoot func(t *testing.T) *serpent.Command, cases []CommandHelpCase) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
rootClient, replacements := prepareTestData(t)
|
rootClient, replacements := prepareTestData(t)
|
||||||
|
|
||||||
|
@ -148,7 +148,7 @@ func NormalizeGoldenFile(t *testing.T, byt []byte) []byte {
|
||||||
return byt
|
return byt
|
||||||
}
|
}
|
||||||
|
|
||||||
func extractVisibleCommandPaths(cmdPath []string, cmds []*serpent.Cmd) [][]string {
|
func extractVisibleCommandPaths(cmdPath []string, cmds []*serpent.Command) [][]string {
|
||||||
var cmdPaths [][]string
|
var cmdPaths [][]string
|
||||||
for _, c := range cmds {
|
for _, c := range cmds {
|
||||||
if c.Hidden {
|
if c.Hidden {
|
||||||
|
|
|
@ -11,8 +11,8 @@ import (
|
||||||
// non-root commands (like 'groups' or 'users'), a handler is required.
|
// non-root commands (like 'groups' or 'users'), a handler is required.
|
||||||
// These handlers are likely just the 'help' handler, but this must be
|
// These handlers are likely just the 'help' handler, but this must be
|
||||||
// explicitly set.
|
// explicitly set.
|
||||||
func HandlersOK(t *testing.T, cmd *serpent.Cmd) {
|
func HandlersOK(t *testing.T, cmd *serpent.Command) {
|
||||||
cmd.Walk(func(cmd *serpent.Cmd) {
|
cmd.Walk(func(cmd *serpent.Command) {
|
||||||
if cmd.Handler == nil {
|
if cmd.Handler == nil {
|
||||||
// If you see this error, make the Handler a helper invoker.
|
// If you see this error, make the Handler a helper invoker.
|
||||||
// Handler: func(inv *serpent.Invocation) error {
|
// Handler: func(inv *serpent.Invocation) error {
|
||||||
|
|
|
@ -382,7 +382,7 @@ func TestAgent(t *testing.T) {
|
||||||
output := make(chan string, 100) // Buffered to avoid blocking, overflow is discarded.
|
output := make(chan string, 100) // Buffered to avoid blocking, overflow is discarded.
|
||||||
logs := make(chan []codersdk.WorkspaceAgentLog, 1)
|
logs := make(chan []codersdk.WorkspaceAgentLog, 1)
|
||||||
|
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
tc.opts.Fetch = func(_ context.Context, _ uuid.UUID) (codersdk.WorkspaceAgent, error) {
|
tc.opts.Fetch = func(_ context.Context, _ uuid.UUID) (codersdk.WorkspaceAgent, error) {
|
||||||
t.Log("iter", len(tc.iter))
|
t.Log("iter", len(tc.iter))
|
||||||
|
@ -450,7 +450,7 @@ func TestAgent(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
var fetchCalled uint64
|
var fetchCalled uint64
|
||||||
|
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
buf := bytes.Buffer{}
|
buf := bytes.Buffer{}
|
||||||
err := cliui.Agent(inv.Context(), &buf, uuid.Nil, cliui.AgentOptions{
|
err := cliui.Agent(inv.Context(), &buf, uuid.Nil, cliui.AgentOptions{
|
||||||
|
|
|
@ -22,7 +22,7 @@ func TestExternalAuth(t *testing.T) {
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
ptty := ptytest.New(t)
|
ptty := ptytest.New(t)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
var fetched atomic.Bool
|
var fetched atomic.Bool
|
||||||
return cliui.ExternalAuth(inv.Context(), inv.Stdout, cliui.ExternalAuthOptions{
|
return cliui.ExternalAuth(inv.Context(), inv.Stdout, cliui.ExternalAuthOptions{
|
||||||
|
|
|
@ -11,12 +11,12 @@ var defaultQuery = "owner:me"
|
||||||
// and allows easy integration to a CLI command.
|
// and allows easy integration to a CLI command.
|
||||||
// Example usage:
|
// Example usage:
|
||||||
//
|
//
|
||||||
// func (r *RootCmd) MyCmd() *serpent.Cmd {
|
// func (r *RootCmd) MyCmd() *serpent.Command {
|
||||||
// var (
|
// var (
|
||||||
// filter cliui.WorkspaceFilter
|
// filter cliui.WorkspaceFilter
|
||||||
// ...
|
// ...
|
||||||
// )
|
// )
|
||||||
// cmd := &serpent.Cmd{
|
// cmd := &serpent.Command{
|
||||||
// ...
|
// ...
|
||||||
// }
|
// }
|
||||||
// filter.AttachOptions(&cmd.Options)
|
// filter.AttachOptions(&cmd.Options)
|
||||||
|
|
|
@ -101,7 +101,7 @@ func Test_OutputFormatter(t *testing.T) {
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
cmd := &serpent.Cmd{}
|
cmd := &serpent.Command{}
|
||||||
f.AttachOptions(&cmd.Options)
|
f.AttachOptions(&cmd.Options)
|
||||||
|
|
||||||
fs := cmd.Options.FlagSet()
|
fs := cmd.Options.FlagSet()
|
||||||
|
|
|
@ -147,7 +147,7 @@ func TestPrompt(t *testing.T) {
|
||||||
|
|
||||||
func newPrompt(ptty *ptytest.PTY, opts cliui.PromptOptions, invOpt func(inv *serpent.Invocation)) (string, error) {
|
func newPrompt(ptty *ptytest.PTY, opts cliui.PromptOptions, invOpt func(inv *serpent.Invocation)) (string, error) {
|
||||||
value := ""
|
value := ""
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
var err error
|
var err error
|
||||||
value, err = cliui.Prompt(inv, opts)
|
value, err = cliui.Prompt(inv, opts)
|
||||||
|
@ -210,7 +210,7 @@ func TestPasswordTerminalState(t *testing.T) {
|
||||||
|
|
||||||
// nolint:unused
|
// nolint:unused
|
||||||
func passwordHelper() {
|
func passwordHelper() {
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
cliui.Prompt(inv, cliui.PromptOptions{
|
cliui.Prompt(inv, cliui.PromptOptions{
|
||||||
Text: "Password:",
|
Text: "Password:",
|
||||||
|
|
|
@ -127,7 +127,7 @@ func newProvisionerJob(t *testing.T) provisionerJobTest {
|
||||||
}
|
}
|
||||||
jobLock := sync.Mutex{}
|
jobLock := sync.Mutex{}
|
||||||
logs := make(chan codersdk.ProvisionerJobLog, 1)
|
logs := make(chan codersdk.ProvisionerJobLog, 1)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
return cliui.ProvisionerJob(inv.Context(), inv.Stdout, cliui.ProvisionerJobOptions{
|
return cliui.ProvisionerJob(inv.Context(), inv.Stdout, cliui.ProvisionerJobOptions{
|
||||||
FetchInterval: time.Millisecond,
|
FetchInterval: time.Millisecond,
|
||||||
|
|
|
@ -31,7 +31,7 @@ func TestSelect(t *testing.T) {
|
||||||
|
|
||||||
func newSelect(ptty *ptytest.PTY, opts cliui.SelectOptions) (string, error) {
|
func newSelect(ptty *ptytest.PTY, opts cliui.SelectOptions) (string, error) {
|
||||||
value := ""
|
value := ""
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
var err error
|
var err error
|
||||||
value, err = cliui.Select(inv, opts)
|
value, err = cliui.Select(inv, opts)
|
||||||
|
@ -72,7 +72,7 @@ func TestRichSelect(t *testing.T) {
|
||||||
|
|
||||||
func newRichSelect(ptty *ptytest.PTY, opts cliui.RichSelectOptions) (string, error) {
|
func newRichSelect(ptty *ptytest.PTY, opts cliui.RichSelectOptions) (string, error) {
|
||||||
value := ""
|
value := ""
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
richOption, err := cliui.RichSelect(inv, opts)
|
richOption, err := cliui.RichSelect(inv, opts)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
@ -105,7 +105,7 @@ func TestMultiSelect(t *testing.T) {
|
||||||
|
|
||||||
func newMultiSelect(ptty *ptytest.PTY, items []string) ([]string, error) {
|
func newMultiSelect(ptty *ptytest.PTY, items []string) ([]string, error) {
|
||||||
var values []string
|
var values []string
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
selectedItems, err := cliui.MultiSelect(inv, items)
|
selectedItems, err := cliui.MultiSelect(inv, items)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
|
|
@ -215,7 +215,7 @@ func sshPrepareWorkspaceConfigs(ctx context.Context, client *codersdk.Client) (r
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) configSSH() *serpent.Cmd {
|
func (r *RootCmd) configSSH() *serpent.Command {
|
||||||
var (
|
var (
|
||||||
sshConfigFile string
|
sshConfigFile string
|
||||||
sshConfigOpts sshConfigOptions
|
sshConfigOpts sshConfigOptions
|
||||||
|
@ -226,7 +226,7 @@ func (r *RootCmd) configSSH() *serpent.Cmd {
|
||||||
coderCliPath string
|
coderCliPath string
|
||||||
)
|
)
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Annotations: workspaceCommand,
|
Annotations: workspaceCommand,
|
||||||
Use: "config-ssh",
|
Use: "config-ssh",
|
||||||
Short: "Add an SSH Host entry for your workspaces \"ssh coder.workspace\"",
|
Short: "Add an SSH Host entry for your workspaces \"ssh coder.workspace\"",
|
||||||
|
|
|
@ -19,7 +19,7 @@ import (
|
||||||
"github.com/coder/serpent"
|
"github.com/coder/serpent"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) create() *serpent.Cmd {
|
func (r *RootCmd) create() *serpent.Command {
|
||||||
var (
|
var (
|
||||||
templateName string
|
templateName string
|
||||||
startAt string
|
startAt string
|
||||||
|
@ -31,7 +31,7 @@ func (r *RootCmd) create() *serpent.Cmd {
|
||||||
copyParametersFrom string
|
copyParametersFrom string
|
||||||
)
|
)
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Annotations: workspaceCommand,
|
Annotations: workspaceCommand,
|
||||||
Use: "create [name]",
|
Use: "create [name]",
|
||||||
Short: "Create a workspace",
|
Short: "Create a workspace",
|
||||||
|
|
|
@ -10,10 +10,10 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// nolint
|
// nolint
|
||||||
func (r *RootCmd) deleteWorkspace() *serpent.Cmd {
|
func (r *RootCmd) deleteWorkspace() *serpent.Command {
|
||||||
var orphan bool
|
var orphan bool
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Annotations: workspaceCommand,
|
Annotations: workspaceCommand,
|
||||||
Use: "delete <workspace>",
|
Use: "delete <workspace>",
|
||||||
Short: "Delete a workspace",
|
Short: "Delete a workspace",
|
||||||
|
|
|
@ -19,12 +19,12 @@ import (
|
||||||
"github.com/coder/serpent"
|
"github.com/coder/serpent"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) dotfiles() *serpent.Cmd {
|
func (r *RootCmd) dotfiles() *serpent.Command {
|
||||||
var symlinkDir string
|
var symlinkDir string
|
||||||
var gitbranch string
|
var gitbranch string
|
||||||
var dotfilesRepoDir string
|
var dotfilesRepoDir string
|
||||||
|
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "dotfiles <git_repo_url>",
|
Use: "dotfiles <git_repo_url>",
|
||||||
Middleware: serpent.RequireNArgs(1),
|
Middleware: serpent.RequireNArgs(1),
|
||||||
Short: "Personalize your workspace by applying a canonical dotfiles repository",
|
Short: "Personalize your workspace by applying a canonical dotfiles repository",
|
||||||
|
|
|
@ -13,9 +13,9 @@ import (
|
||||||
"github.com/coder/serpent"
|
"github.com/coder/serpent"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (RootCmd) errorExample() *serpent.Cmd {
|
func (RootCmd) errorExample() *serpent.Command {
|
||||||
errorCmd := func(use string, err error) *serpent.Cmd {
|
errorCmd := func(use string, err error) *serpent.Command {
|
||||||
return &serpent.Cmd{
|
return &serpent.Command{
|
||||||
Use: use,
|
Use: use,
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
return err
|
return err
|
||||||
|
@ -52,7 +52,7 @@ func (RootCmd) errorExample() *serpent.Cmd {
|
||||||
// Some flags
|
// Some flags
|
||||||
var magicWord serpent.String
|
var magicWord serpent.String
|
||||||
|
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "example-error",
|
Use: "example-error",
|
||||||
Short: "Shows what different error messages look like",
|
Short: "Shows what different error messages look like",
|
||||||
Long: "This command is pretty pointless, but without it testing errors is" +
|
Long: "This command is pretty pointless, but without it testing errors is" +
|
||||||
|
@ -61,7 +61,7 @@ func (RootCmd) errorExample() *serpent.Cmd {
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
return inv.Command.HelpHandler(inv)
|
return inv.Command.HelpHandler(inv)
|
||||||
},
|
},
|
||||||
Children: []*serpent.Cmd{
|
Children: []*serpent.Command{
|
||||||
// Typical codersdk api error
|
// Typical codersdk api error
|
||||||
errorCmd("api", apiError),
|
errorCmd("api", apiError),
|
||||||
|
|
||||||
|
|
|
@ -2,15 +2,15 @@ package cli
|
||||||
|
|
||||||
import "github.com/coder/serpent"
|
import "github.com/coder/serpent"
|
||||||
|
|
||||||
func (r *RootCmd) expCmd() *serpent.Cmd {
|
func (r *RootCmd) expCmd() *serpent.Command {
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "exp",
|
Use: "exp",
|
||||||
Short: "Internal commands for testing and experimentation. These are prone to breaking changes with no notice.",
|
Short: "Internal commands for testing and experimentation. These are prone to breaking changes with no notice.",
|
||||||
Handler: func(i *serpent.Invocation) error {
|
Handler: func(i *serpent.Invocation) error {
|
||||||
return i.Command.HelpHandler(i)
|
return i.Command.HelpHandler(i)
|
||||||
},
|
},
|
||||||
Hidden: true,
|
Hidden: true,
|
||||||
Children: []*serpent.Cmd{
|
Children: []*serpent.Command{
|
||||||
r.scaletestCmd(),
|
r.scaletestCmd(),
|
||||||
r.errorExample(),
|
r.errorExample(),
|
||||||
},
|
},
|
||||||
|
|
|
@ -44,14 +44,14 @@ import (
|
||||||
|
|
||||||
const scaletestTracerName = "coder_scaletest"
|
const scaletestTracerName = "coder_scaletest"
|
||||||
|
|
||||||
func (r *RootCmd) scaletestCmd() *serpent.Cmd {
|
func (r *RootCmd) scaletestCmd() *serpent.Command {
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "scaletest",
|
Use: "scaletest",
|
||||||
Short: "Run a scale test against the Coder API",
|
Short: "Run a scale test against the Coder API",
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
return inv.Command.HelpHandler(inv)
|
return inv.Command.HelpHandler(inv)
|
||||||
},
|
},
|
||||||
Children: []*serpent.Cmd{
|
Children: []*serpent.Command{
|
||||||
r.scaletestCleanup(),
|
r.scaletestCleanup(),
|
||||||
r.scaletestDashboard(),
|
r.scaletestDashboard(),
|
||||||
r.scaletestCreateWorkspaces(),
|
r.scaletestCreateWorkspaces(),
|
||||||
|
@ -398,13 +398,13 @@ func (r *userCleanupRunner) Run(ctx context.Context, _ string, _ io.Writer) erro
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) scaletestCleanup() *serpent.Cmd {
|
func (r *RootCmd) scaletestCleanup() *serpent.Command {
|
||||||
var template string
|
var template string
|
||||||
|
|
||||||
cleanupStrategy := &scaletestStrategyFlags{cleanup: true}
|
cleanupStrategy := &scaletestStrategyFlags{cleanup: true}
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
|
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "cleanup",
|
Use: "cleanup",
|
||||||
Short: "Cleanup scaletest workspaces, then cleanup scaletest users.",
|
Short: "Cleanup scaletest workspaces, then cleanup scaletest users.",
|
||||||
Long: "The strategy flags will apply to each stage of the cleanup process.",
|
Long: "The strategy flags will apply to each stage of the cleanup process.",
|
||||||
|
@ -521,7 +521,7 @@ func (r *RootCmd) scaletestCleanup() *serpent.Cmd {
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) scaletestCreateWorkspaces() *serpent.Cmd {
|
func (r *RootCmd) scaletestCreateWorkspaces() *serpent.Command {
|
||||||
var (
|
var (
|
||||||
count int64
|
count int64
|
||||||
retry int64
|
retry int64
|
||||||
|
@ -558,7 +558,7 @@ func (r *RootCmd) scaletestCreateWorkspaces() *serpent.Cmd {
|
||||||
|
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
|
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "create-workspaces",
|
Use: "create-workspaces",
|
||||||
Short: "Creates many users, then creates a workspace for each user and waits for them finish building and fully come online. Optionally runs a command inside each workspace, and connects to the workspace over WireGuard.",
|
Short: "Creates many users, then creates a workspace for each user and waits for them finish building and fully come online. Optionally runs a command inside each workspace, and connects to the workspace over WireGuard.",
|
||||||
Long: `It is recommended that all rate limits are disabled on the server before running this scaletest. This test generates many login events which will be rate limited against the (most likely single) IP.`,
|
Long: `It is recommended that all rate limits are disabled on the server before running this scaletest. This test generates many login events which will be rate limited against the (most likely single) IP.`,
|
||||||
|
@ -864,7 +864,7 @@ func (r *RootCmd) scaletestCreateWorkspaces() *serpent.Cmd {
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) scaletestWorkspaceTraffic() *serpent.Cmd {
|
func (r *RootCmd) scaletestWorkspaceTraffic() *serpent.Command {
|
||||||
var (
|
var (
|
||||||
tickInterval time.Duration
|
tickInterval time.Duration
|
||||||
bytesPerTick int64
|
bytesPerTick int64
|
||||||
|
@ -881,7 +881,7 @@ func (r *RootCmd) scaletestWorkspaceTraffic() *serpent.Cmd {
|
||||||
prometheusFlags = &scaletestPrometheusFlags{}
|
prometheusFlags = &scaletestPrometheusFlags{}
|
||||||
)
|
)
|
||||||
|
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "workspace-traffic",
|
Use: "workspace-traffic",
|
||||||
Short: "Generate traffic to scaletest workspaces through coderd",
|
Short: "Generate traffic to scaletest workspaces through coderd",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
|
@ -1109,7 +1109,7 @@ func (r *RootCmd) scaletestWorkspaceTraffic() *serpent.Cmd {
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) scaletestDashboard() *serpent.Cmd {
|
func (r *RootCmd) scaletestDashboard() *serpent.Command {
|
||||||
var (
|
var (
|
||||||
interval time.Duration
|
interval time.Duration
|
||||||
jitter time.Duration
|
jitter time.Duration
|
||||||
|
@ -1125,7 +1125,7 @@ func (r *RootCmd) scaletestDashboard() *serpent.Cmd {
|
||||||
prometheusFlags = &scaletestPrometheusFlags{}
|
prometheusFlags = &scaletestPrometheusFlags{}
|
||||||
)
|
)
|
||||||
|
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "dashboard",
|
Use: "dashboard",
|
||||||
Short: "Generate traffic to the HTTP API to simulate use of the dashboard.",
|
Short: "Generate traffic to the HTTP API to simulate use of the dashboard.",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
|
|
|
@ -4,8 +4,8 @@ package cli
|
||||||
|
|
||||||
import "github.com/coder/serpent"
|
import "github.com/coder/serpent"
|
||||||
|
|
||||||
func (r *RootCmd) scaletestCmd() *serpent.Cmd {
|
func (r *RootCmd) scaletestCmd() *serpent.Command {
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "scaletest",
|
Use: "scaletest",
|
||||||
Short: "Run a scale test against the Coder API",
|
Short: "Run a scale test against the Coder API",
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
|
|
@ -12,23 +12,23 @@ import (
|
||||||
"github.com/coder/serpent"
|
"github.com/coder/serpent"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) externalAuth() *serpent.Cmd {
|
func (r *RootCmd) externalAuth() *serpent.Command {
|
||||||
return &serpent.Cmd{
|
return &serpent.Command{
|
||||||
Use: "external-auth",
|
Use: "external-auth",
|
||||||
Short: "Manage external authentication",
|
Short: "Manage external authentication",
|
||||||
Long: "Authenticate with external services inside of a workspace.",
|
Long: "Authenticate with external services inside of a workspace.",
|
||||||
Handler: func(i *serpent.Invocation) error {
|
Handler: func(i *serpent.Invocation) error {
|
||||||
return i.Command.HelpHandler(i)
|
return i.Command.HelpHandler(i)
|
||||||
},
|
},
|
||||||
Children: []*serpent.Cmd{
|
Children: []*serpent.Command{
|
||||||
r.externalAuthAccessToken(),
|
r.externalAuthAccessToken(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) externalAuthAccessToken() *serpent.Cmd {
|
func (r *RootCmd) externalAuthAccessToken() *serpent.Command {
|
||||||
var extra string
|
var extra string
|
||||||
return &serpent.Cmd{
|
return &serpent.Command{
|
||||||
Use: "access-token <provider>",
|
Use: "access-token <provider>",
|
||||||
Short: "Print auth for an external provider",
|
Short: "Print auth for an external provider",
|
||||||
Long: "Print an access-token for an external auth provider. " +
|
Long: "Print an access-token for an external auth provider. " +
|
||||||
|
|
|
@ -9,9 +9,9 @@ import (
|
||||||
"github.com/coder/serpent"
|
"github.com/coder/serpent"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) favorite() *serpent.Cmd {
|
func (r *RootCmd) favorite() *serpent.Command {
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Aliases: []string{"fav", "favou" + "rite"},
|
Aliases: []string{"fav", "favou" + "rite"},
|
||||||
Annotations: workspaceCommand,
|
Annotations: workspaceCommand,
|
||||||
Use: "favorite <workspace>",
|
Use: "favorite <workspace>",
|
||||||
|
@ -36,9 +36,9 @@ func (r *RootCmd) favorite() *serpent.Cmd {
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) unfavorite() *serpent.Cmd {
|
func (r *RootCmd) unfavorite() *serpent.Command {
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Aliases: []string{"unfav", "unfavou" + "rite"},
|
Aliases: []string{"unfav", "unfavou" + "rite"},
|
||||||
Annotations: workspaceCommand,
|
Annotations: workspaceCommand,
|
||||||
Use: "unfavorite <workspace>",
|
Use: "unfavorite <workspace>",
|
||||||
|
|
|
@ -18,8 +18,8 @@ import (
|
||||||
|
|
||||||
// gitAskpass is used by the Coder agent to automatically authenticate
|
// gitAskpass is used by the Coder agent to automatically authenticate
|
||||||
// with Git providers based on a hostname.
|
// with Git providers based on a hostname.
|
||||||
func (r *RootCmd) gitAskpass() *serpent.Cmd {
|
func (r *RootCmd) gitAskpass() *serpent.Command {
|
||||||
return &serpent.Cmd{
|
return &serpent.Command{
|
||||||
Use: "gitaskpass",
|
Use: "gitaskpass",
|
||||||
Hidden: true,
|
Hidden: true,
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
|
|
@ -18,8 +18,8 @@ import (
|
||||||
"github.com/coder/serpent"
|
"github.com/coder/serpent"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) gitssh() *serpent.Cmd {
|
func (r *RootCmd) gitssh() *serpent.Command {
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "gitssh",
|
Use: "gitssh",
|
||||||
Hidden: true,
|
Hidden: true,
|
||||||
Short: `Wraps the "ssh" command and uses the coder gitssh key for authentication`,
|
Short: `Wraps the "ssh" command and uses the coder gitssh key for authentication`,
|
||||||
|
|
|
@ -107,7 +107,7 @@ var usageTemplate = func() *template.Template {
|
||||||
}
|
}
|
||||||
return sb.String()
|
return sb.String()
|
||||||
},
|
},
|
||||||
"formatSubcommand": func(cmd *serpent.Cmd) string {
|
"formatSubcommand": func(cmd *serpent.Command) string {
|
||||||
// Minimize padding by finding the longest neighboring name.
|
// Minimize padding by finding the longest neighboring name.
|
||||||
maxNameLength := len(cmd.Name())
|
maxNameLength := len(cmd.Name())
|
||||||
if parent := cmd.Parent; parent != nil {
|
if parent := cmd.Parent; parent != nil {
|
||||||
|
@ -189,12 +189,12 @@ var usageTemplate = func() *template.Template {
|
||||||
s = wrapTTY(s)
|
s = wrapTTY(s)
|
||||||
return s
|
return s
|
||||||
},
|
},
|
||||||
"visibleChildren": func(cmd *serpent.Cmd) []*serpent.Cmd {
|
"visibleChildren": func(cmd *serpent.Command) []*serpent.Command {
|
||||||
return filterSlice(cmd.Children, func(c *serpent.Cmd) bool {
|
return filterSlice(cmd.Children, func(c *serpent.Command) bool {
|
||||||
return !c.Hidden
|
return !c.Hidden
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
"optionGroups": func(cmd *serpent.Cmd) []optionGroup {
|
"optionGroups": func(cmd *serpent.Command) []optionGroup {
|
||||||
groups := []optionGroup{{
|
groups := []optionGroup{{
|
||||||
// Default group.
|
// Default group.
|
||||||
Name: "",
|
Name: "",
|
||||||
|
|
|
@ -70,7 +70,7 @@ func workspaceListRowFromWorkspace(now time.Time, workspace codersdk.Workspace)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) list() *serpent.Cmd {
|
func (r *RootCmd) list() *serpent.Command {
|
||||||
var (
|
var (
|
||||||
filter cliui.WorkspaceFilter
|
filter cliui.WorkspaceFilter
|
||||||
formatter = cliui.NewOutputFormatter(
|
formatter = cliui.NewOutputFormatter(
|
||||||
|
@ -92,7 +92,7 @@ func (r *RootCmd) list() *serpent.Cmd {
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Annotations: workspaceCommand,
|
Annotations: workspaceCommand,
|
||||||
Use: "list",
|
Use: "list",
|
||||||
Short: "List workspaces",
|
Short: "List workspaces",
|
||||||
|
|
|
@ -125,7 +125,7 @@ func (r *RootCmd) loginWithPassword(
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) login() *serpent.Cmd {
|
func (r *RootCmd) login() *serpent.Command {
|
||||||
const firstUserTrialEnv = "CODER_FIRST_USER_TRIAL"
|
const firstUserTrialEnv = "CODER_FIRST_USER_TRIAL"
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -135,7 +135,7 @@ func (r *RootCmd) login() *serpent.Cmd {
|
||||||
trial bool
|
trial bool
|
||||||
useTokenForSession bool
|
useTokenForSession bool
|
||||||
)
|
)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "login [<url>]",
|
Use: "login [<url>]",
|
||||||
Short: "Authenticate with Coder deployment",
|
Short: "Authenticate with Coder deployment",
|
||||||
Middleware: serpent.RequireRangeArgs(0, 1),
|
Middleware: serpent.RequireRangeArgs(0, 1),
|
||||||
|
|
|
@ -12,9 +12,9 @@ import (
|
||||||
"github.com/coder/serpent"
|
"github.com/coder/serpent"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) logout() *serpent.Cmd {
|
func (r *RootCmd) logout() *serpent.Command {
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "logout",
|
Use: "logout",
|
||||||
Short: "Unauthenticate your local session",
|
Short: "Unauthenticate your local session",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
|
|
|
@ -13,10 +13,10 @@ import (
|
||||||
"github.com/coder/serpent"
|
"github.com/coder/serpent"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) netcheck() *serpent.Cmd {
|
func (r *RootCmd) netcheck() *serpent.Command {
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
|
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "netcheck",
|
Use: "netcheck",
|
||||||
Short: "Print network debug information for DERP and STUN",
|
Short: "Print network debug information for DERP and STUN",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
|
|
10
cli/open.go
10
cli/open.go
|
@ -17,14 +17,14 @@ import (
|
||||||
"github.com/coder/serpent"
|
"github.com/coder/serpent"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) open() *serpent.Cmd {
|
func (r *RootCmd) open() *serpent.Command {
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "open",
|
Use: "open",
|
||||||
Short: "Open a workspace",
|
Short: "Open a workspace",
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
return inv.Command.HelpHandler(inv)
|
return inv.Command.HelpHandler(inv)
|
||||||
},
|
},
|
||||||
Children: []*serpent.Cmd{
|
Children: []*serpent.Command{
|
||||||
r.openVSCode(),
|
r.openVSCode(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -33,14 +33,14 @@ func (r *RootCmd) open() *serpent.Cmd {
|
||||||
|
|
||||||
const vscodeDesktopName = "VS Code Desktop"
|
const vscodeDesktopName = "VS Code Desktop"
|
||||||
|
|
||||||
func (r *RootCmd) openVSCode() *serpent.Cmd {
|
func (r *RootCmd) openVSCode() *serpent.Command {
|
||||||
var (
|
var (
|
||||||
generateToken bool
|
generateToken bool
|
||||||
testOpenError bool
|
testOpenError bool
|
||||||
)
|
)
|
||||||
|
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Annotations: workspaceCommand,
|
Annotations: workspaceCommand,
|
||||||
Use: "vscode <workspace> [<directory in workspace>]",
|
Use: "vscode <workspace> [<directory in workspace>]",
|
||||||
Short: fmt.Sprintf("Open a workspace in %s", vscodeDesktopName),
|
Short: fmt.Sprintf("Open a workspace in %s", vscodeDesktopName),
|
||||||
|
|
|
@ -16,8 +16,8 @@ import (
|
||||||
"github.com/coder/serpent"
|
"github.com/coder/serpent"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) organizations() *serpent.Cmd {
|
func (r *RootCmd) organizations() *serpent.Command {
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Annotations: workspaceCommand,
|
Annotations: workspaceCommand,
|
||||||
Use: "organizations [subcommand]",
|
Use: "organizations [subcommand]",
|
||||||
Short: "Organization related commands",
|
Short: "Organization related commands",
|
||||||
|
@ -26,7 +26,7 @@ func (r *RootCmd) organizations() *serpent.Cmd {
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
return inv.Command.HelpHandler(inv)
|
return inv.Command.HelpHandler(inv)
|
||||||
},
|
},
|
||||||
Children: []*serpent.Cmd{
|
Children: []*serpent.Command{
|
||||||
r.currentOrganization(),
|
r.currentOrganization(),
|
||||||
r.switchOrganization(),
|
r.switchOrganization(),
|
||||||
r.createOrganization(),
|
r.createOrganization(),
|
||||||
|
@ -37,10 +37,10 @@ func (r *RootCmd) organizations() *serpent.Cmd {
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) switchOrganization() *serpent.Cmd {
|
func (r *RootCmd) switchOrganization() *serpent.Command {
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
|
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "set <organization name | ID>",
|
Use: "set <organization name | ID>",
|
||||||
Short: "set the organization used by the CLI. Pass an empty string to reset to the default organization.",
|
Short: "set the organization used by the CLI. Pass an empty string to reset to the default organization.",
|
||||||
Long: "set the organization used by the CLI. Pass an empty string to reset to the default organization.\n" + formatExamples(
|
Long: "set the organization used by the CLI. Pass an empty string to reset to the default organization.\n" + formatExamples(
|
||||||
|
@ -206,7 +206,7 @@ func orgNames(orgs []codersdk.Organization) []string {
|
||||||
return names
|
return names
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) currentOrganization() *serpent.Cmd {
|
func (r *RootCmd) currentOrganization() *serpent.Command {
|
||||||
var (
|
var (
|
||||||
stringFormat func(orgs []codersdk.Organization) (string, error)
|
stringFormat func(orgs []codersdk.Organization) (string, error)
|
||||||
client = new(codersdk.Client)
|
client = new(codersdk.Client)
|
||||||
|
@ -224,7 +224,7 @@ func (r *RootCmd) currentOrganization() *serpent.Cmd {
|
||||||
)
|
)
|
||||||
onlyID = false
|
onlyID = false
|
||||||
)
|
)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "show [current|me|uuid]",
|
Use: "show [current|me|uuid]",
|
||||||
Short: "Show the organization, if no argument is given, the organization currently in use will be shown.",
|
Short: "Show the organization, if no argument is given, the organization currently in use will be shown.",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
|
|
|
@ -12,10 +12,10 @@ import (
|
||||||
"github.com/coder/serpent"
|
"github.com/coder/serpent"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) createOrganization() *serpent.Cmd {
|
func (r *RootCmd) createOrganization() *serpent.Command {
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
|
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "create <organization name>",
|
Use: "create <organization name>",
|
||||||
Short: "Create a new organization.",
|
Short: "Create a new organization.",
|
||||||
// This action is currently irreversible, so it's hidden until we have a way to delete organizations.
|
// This action is currently irreversible, so it's hidden until we have a way to delete organizations.
|
||||||
|
|
|
@ -17,7 +17,7 @@ import (
|
||||||
"github.com/coder/serpent"
|
"github.com/coder/serpent"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) ping() *serpent.Cmd {
|
func (r *RootCmd) ping() *serpent.Command {
|
||||||
var (
|
var (
|
||||||
pingNum int64
|
pingNum int64
|
||||||
pingTimeout time.Duration
|
pingTimeout time.Duration
|
||||||
|
@ -25,7 +25,7 @@ func (r *RootCmd) ping() *serpent.Cmd {
|
||||||
)
|
)
|
||||||
|
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Annotations: workspaceCommand,
|
Annotations: workspaceCommand,
|
||||||
Use: "ping <workspace>",
|
Use: "ping <workspace>",
|
||||||
Short: "Ping a workspace",
|
Short: "Ping a workspace",
|
||||||
|
|
|
@ -23,14 +23,14 @@ import (
|
||||||
"github.com/coder/serpent"
|
"github.com/coder/serpent"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) portForward() *serpent.Cmd {
|
func (r *RootCmd) portForward() *serpent.Command {
|
||||||
var (
|
var (
|
||||||
tcpForwards []string // <port>:<port>
|
tcpForwards []string // <port>:<port>
|
||||||
udpForwards []string // <port>:<port>
|
udpForwards []string // <port>:<port>
|
||||||
disableAutostart bool
|
disableAutostart bool
|
||||||
)
|
)
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "port-forward <workspace>",
|
Use: "port-forward <workspace>",
|
||||||
Short: `Forward ports from a workspace to the local machine. For reverse port forwarding, use "coder ssh -R".`,
|
Short: `Forward ports from a workspace to the local machine. For reverse port forwarding, use "coder ssh -R".`,
|
||||||
Aliases: []string{"tunnel"},
|
Aliases: []string{"tunnel"},
|
||||||
|
|
|
@ -12,10 +12,10 @@ import (
|
||||||
"github.com/coder/coder/v2/codersdk"
|
"github.com/coder/coder/v2/codersdk"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) publickey() *serpent.Cmd {
|
func (r *RootCmd) publickey() *serpent.Command {
|
||||||
var reset bool
|
var reset bool
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "publickey",
|
Use: "publickey",
|
||||||
Aliases: []string{"pubkey"},
|
Aliases: []string{"pubkey"},
|
||||||
Short: "Output your Coder public key used for Git operations",
|
Short: "Output your Coder public key used for Git operations",
|
||||||
|
|
|
@ -12,9 +12,9 @@ import (
|
||||||
"github.com/coder/coder/v2/codersdk"
|
"github.com/coder/coder/v2/codersdk"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) rename() *serpent.Cmd {
|
func (r *RootCmd) rename() *serpent.Command {
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Annotations: workspaceCommand,
|
Annotations: workspaceCommand,
|
||||||
Use: "rename <workspace> <new name>",
|
Use: "rename <workspace> <new name>",
|
||||||
Short: "Rename a workspace",
|
Short: "Rename a workspace",
|
||||||
|
|
|
@ -17,10 +17,10 @@ import (
|
||||||
"github.com/coder/coder/v2/coderd/userpassword"
|
"github.com/coder/coder/v2/coderd/userpassword"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (*RootCmd) resetPassword() *serpent.Cmd {
|
func (*RootCmd) resetPassword() *serpent.Command {
|
||||||
var postgresURL string
|
var postgresURL string
|
||||||
|
|
||||||
root := &serpent.Cmd{
|
root := &serpent.Command{
|
||||||
Use: "reset-password <username>",
|
Use: "reset-password <username>",
|
||||||
Short: "Directly connect to the database to reset a user's password",
|
Short: "Directly connect to the database to reset a user's password",
|
||||||
Middleware: serpent.RequireNArgs(1),
|
Middleware: serpent.RequireNArgs(1),
|
||||||
|
|
|
@ -4,8 +4,8 @@ package cli
|
||||||
|
|
||||||
import "github.com/coder/serpent"
|
import "github.com/coder/serpent"
|
||||||
|
|
||||||
func (*RootCmd) resetPassword() *serpent.Cmd {
|
func (*RootCmd) resetPassword() *serpent.Command {
|
||||||
root := &serpent.Cmd{
|
root := &serpent.Command{
|
||||||
Use: "reset-password <username>",
|
Use: "reset-password <username>",
|
||||||
Short: "Directly connect to the database to reset a user's password",
|
Short: "Directly connect to the database to reset a user's password",
|
||||||
// We accept RawArgs so all commands and flags are accepted.
|
// We accept RawArgs so all commands and flags are accepted.
|
||||||
|
|
|
@ -13,11 +13,11 @@ import (
|
||||||
"github.com/coder/serpent"
|
"github.com/coder/serpent"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) restart() *serpent.Cmd {
|
func (r *RootCmd) restart() *serpent.Command {
|
||||||
var parameterFlags workspaceParameterFlags
|
var parameterFlags workspaceParameterFlags
|
||||||
|
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Annotations: workspaceCommand,
|
Annotations: workspaceCommand,
|
||||||
Use: "restart <workspace>",
|
Use: "restart <workspace>",
|
||||||
Short: "Restart a workspace",
|
Short: "Restart a workspace",
|
||||||
|
|
22
cli/root.go
22
cli/root.go
|
@ -84,9 +84,9 @@ var (
|
||||||
errUnauthenticatedURLSaved = xerrors.New(notLoggedInURLSavedMessage)
|
errUnauthenticatedURLSaved = xerrors.New(notLoggedInURLSavedMessage)
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) Core() []*serpent.Cmd {
|
func (r *RootCmd) Core() []*serpent.Command {
|
||||||
// Please re-sort this list alphabetically if you change it!
|
// Please re-sort this list alphabetically if you change it!
|
||||||
return []*serpent.Cmd{
|
return []*serpent.Command{
|
||||||
r.dotfiles(),
|
r.dotfiles(),
|
||||||
r.externalAuth(),
|
r.externalAuth(),
|
||||||
r.login(),
|
r.login(),
|
||||||
|
@ -132,13 +132,13 @@ func (r *RootCmd) Core() []*serpent.Cmd {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) AGPL() []*serpent.Cmd {
|
func (r *RootCmd) AGPL() []*serpent.Command {
|
||||||
all := append(r.Core(), r.Server( /* Do not import coderd here. */ nil))
|
all := append(r.Core(), r.Server( /* Do not import coderd here. */ nil))
|
||||||
return all
|
return all
|
||||||
}
|
}
|
||||||
|
|
||||||
// Main is the entrypoint for the Coder CLI.
|
// Main is the entrypoint for the Coder CLI.
|
||||||
func (r *RootCmd) RunMain(subcommands []*serpent.Cmd) {
|
func (r *RootCmd) RunMain(subcommands []*serpent.Command) {
|
||||||
rand.Seed(time.Now().UnixMicro())
|
rand.Seed(time.Now().UnixMicro())
|
||||||
|
|
||||||
cmd, err := r.Command(subcommands)
|
cmd, err := r.Command(subcommands)
|
||||||
|
@ -166,10 +166,10 @@ func (r *RootCmd) RunMain(subcommands []*serpent.Cmd) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) Command(subcommands []*serpent.Cmd) (*serpent.Cmd, error) {
|
func (r *RootCmd) Command(subcommands []*serpent.Command) (*serpent.Command, error) {
|
||||||
fmtLong := `Coder %s — A tool for provisioning self-hosted development environments with Terraform.
|
fmtLong := `Coder %s — A tool for provisioning self-hosted development environments with Terraform.
|
||||||
`
|
`
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "coder [global-flags] <subcommand>",
|
Use: "coder [global-flags] <subcommand>",
|
||||||
Long: fmt.Sprintf(fmtLong, buildinfo.Version()) + formatExamples(
|
Long: fmt.Sprintf(fmtLong, buildinfo.Version()) + formatExamples(
|
||||||
example{
|
example{
|
||||||
|
@ -200,7 +200,7 @@ func (r *RootCmd) Command(subcommands []*serpent.Cmd) (*serpent.Cmd, error) {
|
||||||
cmd.AddSubcommands(subcommands...)
|
cmd.AddSubcommands(subcommands...)
|
||||||
|
|
||||||
// Set default help handler for all commands.
|
// Set default help handler for all commands.
|
||||||
cmd.Walk(func(c *serpent.Cmd) {
|
cmd.Walk(func(c *serpent.Command) {
|
||||||
if c.HelpHandler == nil {
|
if c.HelpHandler == nil {
|
||||||
c.HelpHandler = helpFn()
|
c.HelpHandler = helpFn()
|
||||||
}
|
}
|
||||||
|
@ -208,7 +208,7 @@ func (r *RootCmd) Command(subcommands []*serpent.Cmd) (*serpent.Cmd, error) {
|
||||||
|
|
||||||
var merr error
|
var merr error
|
||||||
// Add [flags] to usage when appropriate.
|
// Add [flags] to usage when appropriate.
|
||||||
cmd.Walk(func(cmd *serpent.Cmd) {
|
cmd.Walk(func(cmd *serpent.Command) {
|
||||||
const flags = "[flags]"
|
const flags = "[flags]"
|
||||||
if strings.Contains(cmd.Use, flags) {
|
if strings.Contains(cmd.Use, flags) {
|
||||||
merr = errors.Join(
|
merr = errors.Join(
|
||||||
|
@ -244,7 +244,7 @@ func (r *RootCmd) Command(subcommands []*serpent.Cmd) (*serpent.Cmd, error) {
|
||||||
})
|
})
|
||||||
|
|
||||||
// Add alises when appropriate.
|
// Add alises when appropriate.
|
||||||
cmd.Walk(func(cmd *serpent.Cmd) {
|
cmd.Walk(func(cmd *serpent.Command) {
|
||||||
// TODO: we should really be consistent about naming.
|
// TODO: we should really be consistent about naming.
|
||||||
if cmd.Name() == "delete" || cmd.Name() == "remove" {
|
if cmd.Name() == "delete" || cmd.Name() == "remove" {
|
||||||
if slices.Contains(cmd.Aliases, "rm") {
|
if slices.Contains(cmd.Aliases, "rm") {
|
||||||
|
@ -259,7 +259,7 @@ func (r *RootCmd) Command(subcommands []*serpent.Cmd) (*serpent.Cmd, error) {
|
||||||
})
|
})
|
||||||
|
|
||||||
// Sanity-check command options.
|
// Sanity-check command options.
|
||||||
cmd.Walk(func(cmd *serpent.Cmd) {
|
cmd.Walk(func(cmd *serpent.Command) {
|
||||||
for _, opt := range cmd.Options {
|
for _, opt := range cmd.Options {
|
||||||
// Verify that every option is configurable.
|
// Verify that every option is configurable.
|
||||||
if opt.Flag == "" && opt.Env == "" {
|
if opt.Flag == "" && opt.Env == "" {
|
||||||
|
@ -282,7 +282,7 @@ func (r *RootCmd) Command(subcommands []*serpent.Cmd) (*serpent.Cmd, error) {
|
||||||
var debugOptions bool
|
var debugOptions bool
|
||||||
|
|
||||||
// Add a wrapper to every command to enable debugging options.
|
// Add a wrapper to every command to enable debugging options.
|
||||||
cmd.Walk(func(cmd *serpent.Cmd) {
|
cmd.Walk(func(cmd *serpent.Command) {
|
||||||
h := cmd.Handler
|
h := cmd.Handler
|
||||||
if h == nil {
|
if h == nil {
|
||||||
// We should never have a nil handler, but if we do, do not
|
// We should never have a nil handler, but if we do, do not
|
||||||
|
|
|
@ -28,7 +28,7 @@ import (
|
||||||
//nolint:tparallel,paralleltest
|
//nolint:tparallel,paralleltest
|
||||||
func TestCommandHelp(t *testing.T) {
|
func TestCommandHelp(t *testing.T) {
|
||||||
// Test with AGPL commands
|
// Test with AGPL commands
|
||||||
getCmds := func(t *testing.T) *serpent.Cmd {
|
getCmds := func(t *testing.T) *serpent.Command {
|
||||||
// Must return a fresh instance of cmds each time.
|
// Must return a fresh instance of cmds each time.
|
||||||
|
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
|
@ -53,15 +53,15 @@ When enabling scheduled stop, enter a duration in one of the following formats:
|
||||||
`
|
`
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) schedules() *serpent.Cmd {
|
func (r *RootCmd) schedules() *serpent.Command {
|
||||||
scheduleCmd := &serpent.Cmd{
|
scheduleCmd := &serpent.Command{
|
||||||
Annotations: workspaceCommand,
|
Annotations: workspaceCommand,
|
||||||
Use: "schedule { show | start | stop | override } <workspace>",
|
Use: "schedule { show | start | stop | override } <workspace>",
|
||||||
Short: "Schedule automated start and stop times for workspaces",
|
Short: "Schedule automated start and stop times for workspaces",
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
return inv.Command.HelpHandler(inv)
|
return inv.Command.HelpHandler(inv)
|
||||||
},
|
},
|
||||||
Children: []*serpent.Cmd{
|
Children: []*serpent.Command{
|
||||||
r.scheduleShow(),
|
r.scheduleShow(),
|
||||||
r.scheduleStart(),
|
r.scheduleStart(),
|
||||||
r.scheduleStop(),
|
r.scheduleStop(),
|
||||||
|
@ -73,7 +73,7 @@ func (r *RootCmd) schedules() *serpent.Cmd {
|
||||||
}
|
}
|
||||||
|
|
||||||
// scheduleShow() is just a wrapper for list() with some different defaults.
|
// scheduleShow() is just a wrapper for list() with some different defaults.
|
||||||
func (r *RootCmd) scheduleShow() *serpent.Cmd {
|
func (r *RootCmd) scheduleShow() *serpent.Command {
|
||||||
var (
|
var (
|
||||||
filter cliui.WorkspaceFilter
|
filter cliui.WorkspaceFilter
|
||||||
formatter = cliui.NewOutputFormatter(
|
formatter = cliui.NewOutputFormatter(
|
||||||
|
@ -91,7 +91,7 @@ func (r *RootCmd) scheduleShow() *serpent.Cmd {
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
showCmd := &serpent.Cmd{
|
showCmd := &serpent.Command{
|
||||||
Use: "show <workspace | --search <query> | --all>",
|
Use: "show <workspace | --search <query> | --all>",
|
||||||
Short: "Show workspace schedules",
|
Short: "Show workspace schedules",
|
||||||
Long: scheduleShowDescriptionLong,
|
Long: scheduleShowDescriptionLong,
|
||||||
|
@ -136,9 +136,9 @@ func (r *RootCmd) scheduleShow() *serpent.Cmd {
|
||||||
return showCmd
|
return showCmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) scheduleStart() *serpent.Cmd {
|
func (r *RootCmd) scheduleStart() *serpent.Command {
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "start <workspace-name> { <start-time> [day-of-week] [location] | manual }",
|
Use: "start <workspace-name> { <start-time> [day-of-week] [location] | manual }",
|
||||||
Long: scheduleStartDescriptionLong + "\n" + formatExamples(
|
Long: scheduleStartDescriptionLong + "\n" + formatExamples(
|
||||||
example{
|
example{
|
||||||
|
@ -185,9 +185,9 @@ func (r *RootCmd) scheduleStart() *serpent.Cmd {
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) scheduleStop() *serpent.Cmd {
|
func (r *RootCmd) scheduleStop() *serpent.Command {
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
return &serpent.Cmd{
|
return &serpent.Command{
|
||||||
Use: "stop <workspace-name> { <duration> | manual }",
|
Use: "stop <workspace-name> { <duration> | manual }",
|
||||||
Long: scheduleStopDescriptionLong + "\n" + formatExamples(
|
Long: scheduleStopDescriptionLong + "\n" + formatExamples(
|
||||||
example{
|
example{
|
||||||
|
@ -229,9 +229,9 @@ func (r *RootCmd) scheduleStop() *serpent.Cmd {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) scheduleOverride() *serpent.Cmd {
|
func (r *RootCmd) scheduleOverride() *serpent.Command {
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
overrideCmd := &serpent.Cmd{
|
overrideCmd := &serpent.Command{
|
||||||
Use: "override-stop <workspace-name> <duration from now>",
|
Use: "override-stop <workspace-name> <duration from now>",
|
||||||
Short: "Override the stop time of a currently running workspace instance.",
|
Short: "Override the stop time of a currently running workspace instance.",
|
||||||
Long: scheduleOverrideDescriptionLong + "\n" + formatExamples(
|
Long: scheduleOverrideDescriptionLong + "\n" + formatExamples(
|
||||||
|
|
|
@ -258,7 +258,7 @@ func enablePrometheus(
|
||||||
), nil
|
), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd.API, io.Closer, error)) *serpent.Cmd {
|
func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd.API, io.Closer, error)) *serpent.Command {
|
||||||
if newAPI == nil {
|
if newAPI == nil {
|
||||||
newAPI = func(_ context.Context, o *coderd.Options) (*coderd.API, io.Closer, error) {
|
newAPI = func(_ context.Context, o *coderd.Options) (*coderd.API, io.Closer, error) {
|
||||||
api := coderd.New(o)
|
api := coderd.New(o)
|
||||||
|
@ -270,7 +270,7 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd.
|
||||||
vals = new(codersdk.DeploymentValues)
|
vals = new(codersdk.DeploymentValues)
|
||||||
opts = vals.Options()
|
opts = vals.Options()
|
||||||
)
|
)
|
||||||
serverCmd := &serpent.Cmd{
|
serverCmd := &serpent.Command{
|
||||||
Use: "server",
|
Use: "server",
|
||||||
Short: "Start a Coder server",
|
Short: "Start a Coder server",
|
||||||
Options: opts,
|
Options: opts,
|
||||||
|
@ -1148,7 +1148,7 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd.
|
||||||
|
|
||||||
var pgRawURL bool
|
var pgRawURL bool
|
||||||
|
|
||||||
postgresBuiltinURLCmd := &serpent.Cmd{
|
postgresBuiltinURLCmd := &serpent.Command{
|
||||||
Use: "postgres-builtin-url",
|
Use: "postgres-builtin-url",
|
||||||
Short: "Output the connection URL for the built-in PostgreSQL deployment.",
|
Short: "Output the connection URL for the built-in PostgreSQL deployment.",
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
@ -1165,7 +1165,7 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd.
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
postgresBuiltinServeCmd := &serpent.Cmd{
|
postgresBuiltinServeCmd := &serpent.Command{
|
||||||
Use: "postgres-builtin-serve",
|
Use: "postgres-builtin-serve",
|
||||||
Short: "Run the built-in PostgreSQL deployment.",
|
Short: "Run the built-in PostgreSQL deployment.",
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
|
|
@ -22,7 +22,7 @@ import (
|
||||||
"github.com/coder/serpent"
|
"github.com/coder/serpent"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) newCreateAdminUserCommand() *serpent.Cmd {
|
func (r *RootCmd) newCreateAdminUserCommand() *serpent.Command {
|
||||||
var (
|
var (
|
||||||
newUserDBURL string
|
newUserDBURL string
|
||||||
newUserSSHKeygenAlgorithm string
|
newUserSSHKeygenAlgorithm string
|
||||||
|
@ -30,7 +30,7 @@ func (r *RootCmd) newCreateAdminUserCommand() *serpent.Cmd {
|
||||||
newUserEmail string
|
newUserEmail string
|
||||||
newUserPassword string
|
newUserPassword string
|
||||||
)
|
)
|
||||||
createAdminUserCommand := &serpent.Cmd{
|
createAdminUserCommand := &serpent.Command{
|
||||||
Use: "create-admin-user",
|
Use: "create-admin-user",
|
||||||
Short: "Create a new admin user with the given username, email and password and adds it to every organization.",
|
Short: "Create a new admin user with the given username, email and password and adds it to every organization.",
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
|
|
@ -4,8 +4,8 @@ package cli
|
||||||
|
|
||||||
import "github.com/coder/serpent"
|
import "github.com/coder/serpent"
|
||||||
|
|
||||||
func (r *RootCmd) Server(_ func()) *serpent.Cmd {
|
func (r *RootCmd) Server(_ func()) *serpent.Command {
|
||||||
root := &serpent.Cmd{
|
root := &serpent.Command{
|
||||||
Use: "server",
|
Use: "server",
|
||||||
Short: "Start a Coder server",
|
Short: "Start a Coder server",
|
||||||
// We accept RawArgs so all commands and flags are accepted.
|
// We accept RawArgs so all commands and flags are accepted.
|
||||||
|
|
|
@ -8,9 +8,9 @@ import (
|
||||||
"github.com/coder/serpent"
|
"github.com/coder/serpent"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) show() *serpent.Cmd {
|
func (r *RootCmd) show() *serpent.Command {
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
return &serpent.Cmd{
|
return &serpent.Command{
|
||||||
Use: "show <workspace>",
|
Use: "show <workspace>",
|
||||||
Short: "Display details of a workspace's resources and agents",
|
Short: "Display details of a workspace's resources and agents",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
|
|
|
@ -18,7 +18,7 @@ import (
|
||||||
"github.com/coder/serpent"
|
"github.com/coder/serpent"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) speedtest() *serpent.Cmd {
|
func (r *RootCmd) speedtest() *serpent.Command {
|
||||||
var (
|
var (
|
||||||
direct bool
|
direct bool
|
||||||
duration time.Duration
|
duration time.Duration
|
||||||
|
@ -26,7 +26,7 @@ func (r *RootCmd) speedtest() *serpent.Cmd {
|
||||||
pcapFile string
|
pcapFile string
|
||||||
)
|
)
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Annotations: workspaceCommand,
|
Annotations: workspaceCommand,
|
||||||
Use: "speedtest <workspace>",
|
Use: "speedtest <workspace>",
|
||||||
Short: "Run upload and download tests from your machine to a workspace",
|
Short: "Run upload and download tests from your machine to a workspace",
|
||||||
|
|
|
@ -44,7 +44,7 @@ var (
|
||||||
autostopNotifyCountdown = []time.Duration{30 * time.Minute}
|
autostopNotifyCountdown = []time.Duration{30 * time.Minute}
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) ssh() *serpent.Cmd {
|
func (r *RootCmd) ssh() *serpent.Command {
|
||||||
var (
|
var (
|
||||||
stdio bool
|
stdio bool
|
||||||
forwardAgent bool
|
forwardAgent bool
|
||||||
|
@ -58,7 +58,7 @@ func (r *RootCmd) ssh() *serpent.Cmd {
|
||||||
disableAutostart bool
|
disableAutostart bool
|
||||||
)
|
)
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Annotations: workspaceCommand,
|
Annotations: workspaceCommand,
|
||||||
Use: "ssh <workspace>",
|
Use: "ssh <workspace>",
|
||||||
Short: "Start a shell into a workspace",
|
Short: "Start a shell into a workspace",
|
||||||
|
|
|
@ -12,11 +12,11 @@ import (
|
||||||
"github.com/coder/serpent"
|
"github.com/coder/serpent"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) start() *serpent.Cmd {
|
func (r *RootCmd) start() *serpent.Command {
|
||||||
var parameterFlags workspaceParameterFlags
|
var parameterFlags workspaceParameterFlags
|
||||||
|
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Annotations: workspaceCommand,
|
Annotations: workspaceCommand,
|
||||||
Use: "start <workspace>",
|
Use: "start <workspace>",
|
||||||
Short: "Start a workspace",
|
Short: "Start a workspace",
|
||||||
|
|
18
cli/stat.go
18
cli/stat.go
|
@ -26,7 +26,7 @@ func initStatterMW(tgt **clistat.Statter, fs afero.Fs) serpent.MiddlewareFunc {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) stat() *serpent.Cmd {
|
func (r *RootCmd) stat() *serpent.Command {
|
||||||
var (
|
var (
|
||||||
st *clistat.Statter
|
st *clistat.Statter
|
||||||
fs = afero.NewReadOnlyFs(afero.NewOsFs())
|
fs = afero.NewReadOnlyFs(afero.NewOsFs())
|
||||||
|
@ -41,11 +41,11 @@ func (r *RootCmd) stat() *serpent.Cmd {
|
||||||
cliui.JSONFormat(),
|
cliui.JSONFormat(),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "stat",
|
Use: "stat",
|
||||||
Short: "Show resource usage for the current workspace.",
|
Short: "Show resource usage for the current workspace.",
|
||||||
Middleware: initStatterMW(&st, fs),
|
Middleware: initStatterMW(&st, fs),
|
||||||
Children: []*serpent.Cmd{
|
Children: []*serpent.Command{
|
||||||
r.statCPU(fs),
|
r.statCPU(fs),
|
||||||
r.statMem(fs),
|
r.statMem(fs),
|
||||||
r.statDisk(fs),
|
r.statDisk(fs),
|
||||||
|
@ -130,13 +130,13 @@ func (r *RootCmd) stat() *serpent.Cmd {
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*RootCmd) statCPU(fs afero.Fs) *serpent.Cmd {
|
func (*RootCmd) statCPU(fs afero.Fs) *serpent.Command {
|
||||||
var (
|
var (
|
||||||
hostArg bool
|
hostArg bool
|
||||||
st *clistat.Statter
|
st *clistat.Statter
|
||||||
formatter = cliui.NewOutputFormatter(cliui.TextFormat(), cliui.JSONFormat())
|
formatter = cliui.NewOutputFormatter(cliui.TextFormat(), cliui.JSONFormat())
|
||||||
)
|
)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "cpu",
|
Use: "cpu",
|
||||||
Short: "Show CPU usage, in cores.",
|
Short: "Show CPU usage, in cores.",
|
||||||
Middleware: initStatterMW(&st, fs),
|
Middleware: initStatterMW(&st, fs),
|
||||||
|
@ -171,14 +171,14 @@ func (*RootCmd) statCPU(fs afero.Fs) *serpent.Cmd {
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*RootCmd) statMem(fs afero.Fs) *serpent.Cmd {
|
func (*RootCmd) statMem(fs afero.Fs) *serpent.Command {
|
||||||
var (
|
var (
|
||||||
hostArg bool
|
hostArg bool
|
||||||
prefixArg string
|
prefixArg string
|
||||||
st *clistat.Statter
|
st *clistat.Statter
|
||||||
formatter = cliui.NewOutputFormatter(cliui.TextFormat(), cliui.JSONFormat())
|
formatter = cliui.NewOutputFormatter(cliui.TextFormat(), cliui.JSONFormat())
|
||||||
)
|
)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "mem",
|
Use: "mem",
|
||||||
Short: "Show memory usage, in gigabytes.",
|
Short: "Show memory usage, in gigabytes.",
|
||||||
Middleware: initStatterMW(&st, fs),
|
Middleware: initStatterMW(&st, fs),
|
||||||
|
@ -225,14 +225,14 @@ func (*RootCmd) statMem(fs afero.Fs) *serpent.Cmd {
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*RootCmd) statDisk(fs afero.Fs) *serpent.Cmd {
|
func (*RootCmd) statDisk(fs afero.Fs) *serpent.Command {
|
||||||
var (
|
var (
|
||||||
pathArg string
|
pathArg string
|
||||||
prefixArg string
|
prefixArg string
|
||||||
st *clistat.Statter
|
st *clistat.Statter
|
||||||
formatter = cliui.NewOutputFormatter(cliui.TextFormat(), cliui.JSONFormat())
|
formatter = cliui.NewOutputFormatter(cliui.TextFormat(), cliui.JSONFormat())
|
||||||
)
|
)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "disk",
|
Use: "disk",
|
||||||
Short: "Show disk usage, in gigabytes.",
|
Short: "Show disk usage, in gigabytes.",
|
||||||
Middleware: initStatterMW(&st, fs),
|
Middleware: initStatterMW(&st, fs),
|
||||||
|
|
14
cli/state.go
14
cli/state.go
|
@ -11,14 +11,14 @@ import (
|
||||||
"github.com/coder/serpent"
|
"github.com/coder/serpent"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) state() *serpent.Cmd {
|
func (r *RootCmd) state() *serpent.Command {
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "state",
|
Use: "state",
|
||||||
Short: "Manually manage Terraform state to fix broken workspaces",
|
Short: "Manually manage Terraform state to fix broken workspaces",
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
return inv.Command.HelpHandler(inv)
|
return inv.Command.HelpHandler(inv)
|
||||||
},
|
},
|
||||||
Children: []*serpent.Cmd{
|
Children: []*serpent.Command{
|
||||||
r.statePull(),
|
r.statePull(),
|
||||||
r.statePush(),
|
r.statePush(),
|
||||||
},
|
},
|
||||||
|
@ -26,10 +26,10 @@ func (r *RootCmd) state() *serpent.Cmd {
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) statePull() *serpent.Cmd {
|
func (r *RootCmd) statePull() *serpent.Command {
|
||||||
var buildNumber int64
|
var buildNumber int64
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "pull <workspace> [file]",
|
Use: "pull <workspace> [file]",
|
||||||
Short: "Pull a Terraform state file from a workspace.",
|
Short: "Pull a Terraform state file from a workspace.",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
|
@ -84,10 +84,10 @@ func buildNumberOption(n *int64) serpent.Option {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) statePush() *serpent.Cmd {
|
func (r *RootCmd) statePush() *serpent.Command {
|
||||||
var buildNumber int64
|
var buildNumber int64
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "push <workspace> <file>",
|
Use: "push <workspace> <file>",
|
||||||
Short: "Push a Terraform state file to a workspace.",
|
Short: "Push a Terraform state file to a workspace.",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
|
|
|
@ -9,9 +9,9 @@ import (
|
||||||
"github.com/coder/serpent"
|
"github.com/coder/serpent"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) stop() *serpent.Cmd {
|
func (r *RootCmd) stop() *serpent.Command {
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Annotations: workspaceCommand,
|
Annotations: workspaceCommand,
|
||||||
Use: "stop <workspace>",
|
Use: "stop <workspace>",
|
||||||
Short: "Stop a workspace",
|
Short: "Stop a workspace",
|
||||||
|
|
|
@ -21,25 +21,25 @@ import (
|
||||||
"github.com/coder/serpent"
|
"github.com/coder/serpent"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) support() *serpent.Cmd {
|
func (r *RootCmd) support() *serpent.Command {
|
||||||
supportCmd := &serpent.Cmd{
|
supportCmd := &serpent.Command{
|
||||||
Use: "support",
|
Use: "support",
|
||||||
Short: "Commands for troubleshooting issues with a Coder deployment.",
|
Short: "Commands for troubleshooting issues with a Coder deployment.",
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
return inv.Command.HelpHandler(inv)
|
return inv.Command.HelpHandler(inv)
|
||||||
},
|
},
|
||||||
Hidden: true, // TODO: un-hide once the must-haves from #12160 are completed.
|
Hidden: true, // TODO: un-hide once the must-haves from #12160 are completed.
|
||||||
Children: []*serpent.Cmd{
|
Children: []*serpent.Command{
|
||||||
r.supportBundle(),
|
r.supportBundle(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
return supportCmd
|
return supportCmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) supportBundle() *serpent.Cmd {
|
func (r *RootCmd) supportBundle() *serpent.Command {
|
||||||
var outputPath string
|
var outputPath string
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "bundle <workspace> [<agent>]",
|
Use: "bundle <workspace> [<agent>]",
|
||||||
Short: "Generate a support bundle to troubleshoot issues connecting to a workspace.",
|
Short: "Generate a support bundle to troubleshoot issues connecting to a workspace.",
|
||||||
Long: `This command generates a file containing detailed troubleshooting information about the Coder deployment and workspace connections. You must specify a single workspace (and optionally an agent name).`,
|
Long: `This command generates a file containing detailed troubleshooting information about the Coder deployment and workspace connections. You must specify a single workspace (and optionally an agent name).`,
|
||||||
|
|
|
@ -16,7 +16,7 @@ import (
|
||||||
"github.com/coder/coder/v2/codersdk"
|
"github.com/coder/coder/v2/codersdk"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) templateCreate() *serpent.Cmd {
|
func (r *RootCmd) templateCreate() *serpent.Command {
|
||||||
var (
|
var (
|
||||||
provisioner string
|
provisioner string
|
||||||
provisionerTags []string
|
provisionerTags []string
|
||||||
|
@ -34,7 +34,7 @@ func (r *RootCmd) templateCreate() *serpent.Cmd {
|
||||||
uploadFlags templateUploadFlags
|
uploadFlags templateUploadFlags
|
||||||
)
|
)
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "create [name]",
|
Use: "create [name]",
|
||||||
Short: "DEPRECATED: Create a template from the current directory or as specified by flag",
|
Short: "DEPRECATED: Create a template from the current directory or as specified by flag",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
|
|
|
@ -14,9 +14,9 @@ import (
|
||||||
"github.com/coder/serpent"
|
"github.com/coder/serpent"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) templateDelete() *serpent.Cmd {
|
func (r *RootCmd) templateDelete() *serpent.Command {
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "delete [name...]",
|
Use: "delete [name...]",
|
||||||
Short: "Delete templates",
|
Short: "Delete templates",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
|
|
|
@ -15,7 +15,7 @@ import (
|
||||||
"github.com/coder/coder/v2/codersdk"
|
"github.com/coder/coder/v2/codersdk"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) templateEdit() *serpent.Cmd {
|
func (r *RootCmd) templateEdit() *serpent.Command {
|
||||||
const deprecatedFlagName = "deprecated"
|
const deprecatedFlagName = "deprecated"
|
||||||
var (
|
var (
|
||||||
name string
|
name string
|
||||||
|
@ -40,7 +40,7 @@ func (r *RootCmd) templateEdit() *serpent.Cmd {
|
||||||
)
|
)
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
|
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "edit <template>",
|
Use: "edit <template>",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(1),
|
serpent.RequireNArgs(1),
|
||||||
|
|
|
@ -20,7 +20,7 @@ import (
|
||||||
"github.com/coder/serpent"
|
"github.com/coder/serpent"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (*RootCmd) templateInit() *serpent.Cmd {
|
func (*RootCmd) templateInit() *serpent.Command {
|
||||||
var templateID string
|
var templateID string
|
||||||
exampleList, err := examples.List()
|
exampleList, err := examples.List()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -32,7 +32,7 @@ func (*RootCmd) templateInit() *serpent.Cmd {
|
||||||
templateIDs = append(templateIDs, ex.ID)
|
templateIDs = append(templateIDs, ex.ID)
|
||||||
}
|
}
|
||||||
sort.Strings(templateIDs)
|
sort.Strings(templateIDs)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "init [directory]",
|
Use: "init [directory]",
|
||||||
Short: "Get started with a templated template.",
|
Short: "Get started with a templated template.",
|
||||||
Middleware: serpent.RequireRangeArgs(0, 1),
|
Middleware: serpent.RequireRangeArgs(0, 1),
|
||||||
|
|
|
@ -10,14 +10,14 @@ import (
|
||||||
"github.com/coder/serpent"
|
"github.com/coder/serpent"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) templateList() *serpent.Cmd {
|
func (r *RootCmd) templateList() *serpent.Command {
|
||||||
formatter := cliui.NewOutputFormatter(
|
formatter := cliui.NewOutputFormatter(
|
||||||
cliui.TableFormat([]templateTableRow{}, []string{"name", "last updated", "used by"}),
|
cliui.TableFormat([]templateTableRow{}, []string{"name", "last updated", "used by"}),
|
||||||
cliui.JSONFormat(),
|
cliui.JSONFormat(),
|
||||||
)
|
)
|
||||||
|
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "list",
|
Use: "list",
|
||||||
Short: "List all the templates available for the organization",
|
Short: "List all the templates available for the organization",
|
||||||
Aliases: []string{"ls"},
|
Aliases: []string{"ls"},
|
||||||
|
|
|
@ -15,7 +15,7 @@ import (
|
||||||
"github.com/coder/serpent"
|
"github.com/coder/serpent"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) templatePull() *serpent.Cmd {
|
func (r *RootCmd) templatePull() *serpent.Command {
|
||||||
var (
|
var (
|
||||||
tarMode bool
|
tarMode bool
|
||||||
zipMode bool
|
zipMode bool
|
||||||
|
@ -23,7 +23,7 @@ func (r *RootCmd) templatePull() *serpent.Cmd {
|
||||||
)
|
)
|
||||||
|
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "pull <name> [destination]",
|
Use: "pull <name> [destination]",
|
||||||
Short: "Download the active, latest, or specified version of a template to a path.",
|
Short: "Download the active, latest, or specified version of a template to a path.",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
|
|
|
@ -23,7 +23,7 @@ import (
|
||||||
"github.com/coder/serpent"
|
"github.com/coder/serpent"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) templatePush() *serpent.Cmd {
|
func (r *RootCmd) templatePush() *serpent.Command {
|
||||||
var (
|
var (
|
||||||
versionName string
|
versionName string
|
||||||
provisioner string
|
provisioner string
|
||||||
|
@ -36,7 +36,7 @@ func (r *RootCmd) templatePush() *serpent.Cmd {
|
||||||
activate bool
|
activate bool
|
||||||
)
|
)
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "push [template]",
|
Use: "push [template]",
|
||||||
Short: "Create or update a template from the current directory or as specified by flag",
|
Short: "Create or update a template from the current directory or as specified by flag",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
|
|
|
@ -12,8 +12,8 @@ import (
|
||||||
"github.com/coder/serpent"
|
"github.com/coder/serpent"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) templates() *serpent.Cmd {
|
func (r *RootCmd) templates() *serpent.Command {
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "templates",
|
Use: "templates",
|
||||||
Short: "Manage templates",
|
Short: "Manage templates",
|
||||||
Long: "Templates are written in standard Terraform and describe the infrastructure for workspaces\n" + formatExamples(
|
Long: "Templates are written in standard Terraform and describe the infrastructure for workspaces\n" + formatExamples(
|
||||||
|
@ -30,7 +30,7 @@ func (r *RootCmd) templates() *serpent.Cmd {
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
return inv.Command.HelpHandler(inv)
|
return inv.Command.HelpHandler(inv)
|
||||||
},
|
},
|
||||||
Children: []*serpent.Cmd{
|
Children: []*serpent.Command{
|
||||||
r.templateCreate(),
|
r.templateCreate(),
|
||||||
r.templateEdit(),
|
r.templateEdit(),
|
||||||
r.templateInit(),
|
r.templateInit(),
|
||||||
|
|
|
@ -14,16 +14,16 @@ import (
|
||||||
"github.com/coder/serpent"
|
"github.com/coder/serpent"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) unarchiveTemplateVersion() *serpent.Cmd {
|
func (r *RootCmd) unarchiveTemplateVersion() *serpent.Command {
|
||||||
return r.setArchiveTemplateVersion(false)
|
return r.setArchiveTemplateVersion(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) archiveTemplateVersion() *serpent.Cmd {
|
func (r *RootCmd) archiveTemplateVersion() *serpent.Command {
|
||||||
return r.setArchiveTemplateVersion(true)
|
return r.setArchiveTemplateVersion(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
//nolint:revive
|
//nolint:revive
|
||||||
func (r *RootCmd) setArchiveTemplateVersion(archive bool) *serpent.Cmd {
|
func (r *RootCmd) setArchiveTemplateVersion(archive bool) *serpent.Command {
|
||||||
presentVerb := "archive"
|
presentVerb := "archive"
|
||||||
pastVerb := "archived"
|
pastVerb := "archived"
|
||||||
if !archive {
|
if !archive {
|
||||||
|
@ -32,7 +32,7 @@ func (r *RootCmd) setArchiveTemplateVersion(archive bool) *serpent.Cmd {
|
||||||
}
|
}
|
||||||
|
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: presentVerb + " <template-name> [template-version-names...] ",
|
Use: presentVerb + " <template-name> [template-version-names...] ",
|
||||||
Short: strings.ToUpper(string(presentVerb[0])) + presentVerb[1:] + " a template version(s).",
|
Short: strings.ToUpper(string(presentVerb[0])) + presentVerb[1:] + " a template version(s).",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
|
@ -96,10 +96,10 @@ func (r *RootCmd) setArchiveTemplateVersion(archive bool) *serpent.Cmd {
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) archiveTemplateVersions() *serpent.Cmd {
|
func (r *RootCmd) archiveTemplateVersions() *serpent.Command {
|
||||||
var all serpent.Bool
|
var all serpent.Bool
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "archive [template-name...] ",
|
Use: "archive [template-name...] ",
|
||||||
Short: "Archive unused or failed template versions from a given template(s)",
|
Short: "Archive unused or failed template versions from a given template(s)",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
|
|
|
@ -14,8 +14,8 @@ import (
|
||||||
"github.com/coder/serpent"
|
"github.com/coder/serpent"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) templateVersions() *serpent.Cmd {
|
func (r *RootCmd) templateVersions() *serpent.Command {
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "versions",
|
Use: "versions",
|
||||||
Short: "Manage different versions of the specified template",
|
Short: "Manage different versions of the specified template",
|
||||||
Aliases: []string{"version"},
|
Aliases: []string{"version"},
|
||||||
|
@ -28,7 +28,7 @@ func (r *RootCmd) templateVersions() *serpent.Cmd {
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
return inv.Command.HelpHandler(inv)
|
return inv.Command.HelpHandler(inv)
|
||||||
},
|
},
|
||||||
Children: []*serpent.Cmd{
|
Children: []*serpent.Command{
|
||||||
r.templateVersionsList(),
|
r.templateVersionsList(),
|
||||||
r.archiveTemplateVersion(),
|
r.archiveTemplateVersion(),
|
||||||
r.unarchiveTemplateVersion(),
|
r.unarchiveTemplateVersion(),
|
||||||
|
@ -38,7 +38,7 @@ func (r *RootCmd) templateVersions() *serpent.Cmd {
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) templateVersionsList() *serpent.Cmd {
|
func (r *RootCmd) templateVersionsList() *serpent.Command {
|
||||||
defaultColumns := []string{
|
defaultColumns := []string{
|
||||||
"Name",
|
"Name",
|
||||||
"Created At",
|
"Created At",
|
||||||
|
@ -54,7 +54,7 @@ func (r *RootCmd) templateVersionsList() *serpent.Cmd {
|
||||||
|
|
||||||
var includeArchived serpent.Bool
|
var includeArchived serpent.Bool
|
||||||
|
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "list <template>",
|
Use: "list <template>",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(1),
|
serpent.RequireNArgs(1),
|
||||||
|
|
|
@ -13,8 +13,8 @@ import (
|
||||||
"github.com/coder/serpent"
|
"github.com/coder/serpent"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) tokens() *serpent.Cmd {
|
func (r *RootCmd) tokens() *serpent.Command {
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "tokens",
|
Use: "tokens",
|
||||||
Short: "Manage personal access tokens",
|
Short: "Manage personal access tokens",
|
||||||
Long: "Tokens are used to authenticate automated clients to Coder.\n" + formatExamples(
|
Long: "Tokens are used to authenticate automated clients to Coder.\n" + formatExamples(
|
||||||
|
@ -35,7 +35,7 @@ func (r *RootCmd) tokens() *serpent.Cmd {
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
return inv.Command.HelpHandler(inv)
|
return inv.Command.HelpHandler(inv)
|
||||||
},
|
},
|
||||||
Children: []*serpent.Cmd{
|
Children: []*serpent.Command{
|
||||||
r.createToken(),
|
r.createToken(),
|
||||||
r.listTokens(),
|
r.listTokens(),
|
||||||
r.removeToken(),
|
r.removeToken(),
|
||||||
|
@ -44,13 +44,13 @@ func (r *RootCmd) tokens() *serpent.Cmd {
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) createToken() *serpent.Cmd {
|
func (r *RootCmd) createToken() *serpent.Command {
|
||||||
var (
|
var (
|
||||||
tokenLifetime time.Duration
|
tokenLifetime time.Duration
|
||||||
name string
|
name string
|
||||||
)
|
)
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "create",
|
Use: "create",
|
||||||
Short: "Create a token",
|
Short: "Create a token",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
|
@ -118,7 +118,7 @@ func tokenListRowFromToken(token codersdk.APIKeyWithOwner) tokenListRow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) listTokens() *serpent.Cmd {
|
func (r *RootCmd) listTokens() *serpent.Command {
|
||||||
// we only display the 'owner' column if the --all argument is passed in
|
// we only display the 'owner' column if the --all argument is passed in
|
||||||
defaultCols := []string{"id", "name", "last used", "expires at", "created at"}
|
defaultCols := []string{"id", "name", "last used", "expires at", "created at"}
|
||||||
if slices.Contains(os.Args, "-a") || slices.Contains(os.Args, "--all") {
|
if slices.Contains(os.Args, "-a") || slices.Contains(os.Args, "--all") {
|
||||||
|
@ -135,7 +135,7 @@ func (r *RootCmd) listTokens() *serpent.Cmd {
|
||||||
)
|
)
|
||||||
|
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "list",
|
Use: "list",
|
||||||
Aliases: []string{"ls"},
|
Aliases: []string{"ls"},
|
||||||
Short: "List tokens",
|
Short: "List tokens",
|
||||||
|
@ -187,9 +187,9 @@ func (r *RootCmd) listTokens() *serpent.Cmd {
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) removeToken() *serpent.Cmd {
|
func (r *RootCmd) removeToken() *serpent.Command {
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "remove <name>",
|
Use: "remove <name>",
|
||||||
Aliases: []string{"delete"},
|
Aliases: []string{"delete"},
|
||||||
Short: "Delete a token",
|
Short: "Delete a token",
|
||||||
|
|
|
@ -9,11 +9,11 @@ import (
|
||||||
"github.com/coder/serpent"
|
"github.com/coder/serpent"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) update() *serpent.Cmd {
|
func (r *RootCmd) update() *serpent.Command {
|
||||||
var parameterFlags workspaceParameterFlags
|
var parameterFlags workspaceParameterFlags
|
||||||
|
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Annotations: workspaceCommand,
|
Annotations: workspaceCommand,
|
||||||
Use: "update <workspace>",
|
Use: "update <workspace>",
|
||||||
Short: "Will update and start a given workspace if it is out of date",
|
Short: "Will update and start a given workspace if it is out of date",
|
||||||
|
|
|
@ -15,7 +15,7 @@ import (
|
||||||
"github.com/coder/serpent"
|
"github.com/coder/serpent"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) userCreate() *serpent.Cmd {
|
func (r *RootCmd) userCreate() *serpent.Command {
|
||||||
var (
|
var (
|
||||||
email string
|
email string
|
||||||
username string
|
username string
|
||||||
|
@ -24,7 +24,7 @@ func (r *RootCmd) userCreate() *serpent.Cmd {
|
||||||
loginType string
|
loginType string
|
||||||
)
|
)
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "create",
|
Use: "create",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(0),
|
serpent.RequireNArgs(0),
|
||||||
|
|
|
@ -11,9 +11,9 @@ import (
|
||||||
"github.com/coder/serpent"
|
"github.com/coder/serpent"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) userDelete() *serpent.Cmd {
|
func (r *RootCmd) userDelete() *serpent.Command {
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "delete <username|user_id>",
|
Use: "delete <username|user_id>",
|
||||||
Short: "Delete a user by username or user_id.",
|
Short: "Delete a user by username or user_id.",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
|
|
|
@ -13,14 +13,14 @@ import (
|
||||||
"github.com/coder/serpent"
|
"github.com/coder/serpent"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) userList() *serpent.Cmd {
|
func (r *RootCmd) userList() *serpent.Command {
|
||||||
formatter := cliui.NewOutputFormatter(
|
formatter := cliui.NewOutputFormatter(
|
||||||
cliui.TableFormat([]codersdk.User{}, []string{"username", "email", "created_at", "status"}),
|
cliui.TableFormat([]codersdk.User{}, []string{"username", "email", "created_at", "status"}),
|
||||||
cliui.JSONFormat(),
|
cliui.JSONFormat(),
|
||||||
)
|
)
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
|
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "list",
|
Use: "list",
|
||||||
Aliases: []string{"ls"},
|
Aliases: []string{"ls"},
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
|
@ -47,14 +47,14 @@ func (r *RootCmd) userList() *serpent.Cmd {
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) userSingle() *serpent.Cmd {
|
func (r *RootCmd) userSingle() *serpent.Command {
|
||||||
formatter := cliui.NewOutputFormatter(
|
formatter := cliui.NewOutputFormatter(
|
||||||
&userShowFormat{},
|
&userShowFormat{},
|
||||||
cliui.JSONFormat(),
|
cliui.JSONFormat(),
|
||||||
)
|
)
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
|
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "show <username|user_id|'me'>",
|
Use: "show <username|user_id|'me'>",
|
||||||
Short: "Show a single user. Use 'me' to indicate the currently authenticated user.",
|
Short: "Show a single user. Use 'me' to indicate the currently authenticated user.",
|
||||||
Long: formatExamples(
|
Long: formatExamples(
|
||||||
|
|
|
@ -5,15 +5,15 @@ import (
|
||||||
"github.com/coder/serpent"
|
"github.com/coder/serpent"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) users() *serpent.Cmd {
|
func (r *RootCmd) users() *serpent.Command {
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Short: "Manage users",
|
Short: "Manage users",
|
||||||
Use: "users [subcommand]",
|
Use: "users [subcommand]",
|
||||||
Aliases: []string{"user"},
|
Aliases: []string{"user"},
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
return inv.Command.HelpHandler(inv)
|
return inv.Command.HelpHandler(inv)
|
||||||
},
|
},
|
||||||
Children: []*serpent.Cmd{
|
Children: []*serpent.Command{
|
||||||
r.userCreate(),
|
r.userCreate(),
|
||||||
r.userList(),
|
r.userList(),
|
||||||
r.userSingle(),
|
r.userSingle(),
|
||||||
|
|
|
@ -14,7 +14,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// createUserStatusCommand sets a user status.
|
// createUserStatusCommand sets a user status.
|
||||||
func (r *RootCmd) createUserStatusCommand(sdkStatus codersdk.UserStatus) *serpent.Cmd {
|
func (r *RootCmd) createUserStatusCommand(sdkStatus codersdk.UserStatus) *serpent.Command {
|
||||||
var verb string
|
var verb string
|
||||||
var pastVerb string
|
var pastVerb string
|
||||||
var aliases []string
|
var aliases []string
|
||||||
|
@ -36,7 +36,7 @@ func (r *RootCmd) createUserStatusCommand(sdkStatus codersdk.UserStatus) *serpen
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
|
|
||||||
var columns []string
|
var columns []string
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: fmt.Sprintf("%s <username|user_id>", verb),
|
Use: fmt.Sprintf("%s <username|user_id>", verb),
|
||||||
Short: short,
|
Short: short,
|
||||||
Aliases: aliases,
|
Aliases: aliases,
|
||||||
|
|
|
@ -61,7 +61,7 @@ func defaultVersionInfo() *versionInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
// version prints the coder version
|
// version prints the coder version
|
||||||
func (*RootCmd) version(versionInfo func() *versionInfo) *serpent.Cmd {
|
func (*RootCmd) version(versionInfo func() *versionInfo) *serpent.Command {
|
||||||
var (
|
var (
|
||||||
formatter = cliui.NewOutputFormatter(
|
formatter = cliui.NewOutputFormatter(
|
||||||
cliui.TextFormat(),
|
cliui.TextFormat(),
|
||||||
|
@ -70,7 +70,7 @@ func (*RootCmd) version(versionInfo func() *versionInfo) *serpent.Cmd {
|
||||||
vi = versionInfo()
|
vi = versionInfo()
|
||||||
)
|
)
|
||||||
|
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "version",
|
Use: "version",
|
||||||
Short: "Show coder version",
|
Short: "Show coder version",
|
||||||
Options: serpent.OptionSet{},
|
Options: serpent.OptionSet{},
|
||||||
|
|
|
@ -32,7 +32,7 @@ import (
|
||||||
// This command needs to remain stable for compatibility with
|
// This command needs to remain stable for compatibility with
|
||||||
// various VS Code versions, so it's kept separate from our
|
// various VS Code versions, so it's kept separate from our
|
||||||
// standard SSH command.
|
// standard SSH command.
|
||||||
func (r *RootCmd) vscodeSSH() *serpent.Cmd {
|
func (r *RootCmd) vscodeSSH() *serpent.Command {
|
||||||
var (
|
var (
|
||||||
sessionTokenFile string
|
sessionTokenFile string
|
||||||
urlFile string
|
urlFile string
|
||||||
|
@ -41,7 +41,7 @@ func (r *RootCmd) vscodeSSH() *serpent.Cmd {
|
||||||
networkInfoInterval time.Duration
|
networkInfoInterval time.Duration
|
||||||
waitEnum string
|
waitEnum string
|
||||||
)
|
)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
// A SSH config entry is added by the VS Code extension that
|
// A SSH config entry is added by the VS Code extension that
|
||||||
// passes %h to ProxyCommand. The prefix of `coder-vscode--`
|
// passes %h to ProxyCommand. The prefix of `coder-vscode--`
|
||||||
// is a magical string represented in our VS Code extension.
|
// is a magical string represented in our VS Code extension.
|
||||||
|
|
|
@ -22,8 +22,8 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
var root *serpent.Cmd
|
var root *serpent.Command
|
||||||
root = &serpent.Cmd{
|
root = &serpent.Command{
|
||||||
Use: "cliui",
|
Use: "cliui",
|
||||||
Short: "Used for visually testing UI components for the CLI.",
|
Short: "Used for visually testing UI components for the CLI.",
|
||||||
HelpHandler: func(inv *serpent.Invocation) error {
|
HelpHandler: func(inv *serpent.Invocation) error {
|
||||||
|
@ -37,7 +37,7 @@ func main() {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
root.Children = append(root.Children, &serpent.Cmd{
|
root.Children = append(root.Children, &serpent.Command{
|
||||||
Use: "prompt",
|
Use: "prompt",
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
_, err := cliui.Prompt(inv, cliui.PromptOptions{
|
_, err := cliui.Prompt(inv, cliui.PromptOptions{
|
||||||
|
@ -75,7 +75,7 @@ func main() {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
root.Children = append(root.Children, &serpent.Cmd{
|
root.Children = append(root.Children, &serpent.Command{
|
||||||
Use: "select",
|
Use: "select",
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
value, err := cliui.Select(inv, cliui.SelectOptions{
|
value, err := cliui.Select(inv, cliui.SelectOptions{
|
||||||
|
@ -87,7 +87,7 @@ func main() {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
root.Children = append(root.Children, &serpent.Cmd{
|
root.Children = append(root.Children, &serpent.Command{
|
||||||
Use: "job",
|
Use: "job",
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
job := codersdk.ProvisionerJob{
|
job := codersdk.ProvisionerJob{
|
||||||
|
@ -173,7 +173,7 @@ func main() {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
root.Children = append(root.Children, &serpent.Cmd{
|
root.Children = append(root.Children, &serpent.Command{
|
||||||
Use: "agent",
|
Use: "agent",
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
var agent codersdk.WorkspaceAgent
|
var agent codersdk.WorkspaceAgent
|
||||||
|
@ -265,7 +265,7 @@ func main() {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
root.Children = append(root.Children, &serpent.Cmd{
|
root.Children = append(root.Children, &serpent.Command{
|
||||||
Use: "resources",
|
Use: "resources",
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
disconnected := dbtime.Now().Add(-4 * time.Second)
|
disconnected := dbtime.Now().Add(-4 * time.Second)
|
||||||
|
@ -315,7 +315,7 @@ func main() {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
root.Children = append(root.Children, &serpent.Cmd{
|
root.Children = append(root.Children, &serpent.Command{
|
||||||
Use: "git-auth",
|
Use: "git-auth",
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
var count atomic.Int32
|
var count atomic.Int32
|
||||||
|
|
|
@ -15,22 +15,22 @@ import (
|
||||||
"github.com/coder/serpent"
|
"github.com/coder/serpent"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) features() *serpent.Cmd {
|
func (r *RootCmd) features() *serpent.Command {
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Short: "List Enterprise features",
|
Short: "List Enterprise features",
|
||||||
Use: "features",
|
Use: "features",
|
||||||
Aliases: []string{"feature"},
|
Aliases: []string{"feature"},
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
return inv.Command.HelpHandler(inv)
|
return inv.Command.HelpHandler(inv)
|
||||||
},
|
},
|
||||||
Children: []*serpent.Cmd{
|
Children: []*serpent.Command{
|
||||||
r.featuresList(),
|
r.featuresList(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) featuresList() *serpent.Cmd {
|
func (r *RootCmd) featuresList() *serpent.Command {
|
||||||
var (
|
var (
|
||||||
featureColumns = []string{"Name", "Entitlement", "Enabled", "Limit", "Actual"}
|
featureColumns = []string{"Name", "Entitlement", "Enabled", "Limit", "Actual"}
|
||||||
columns []string
|
columns []string
|
||||||
|
@ -38,7 +38,7 @@ func (r *RootCmd) featuresList() *serpent.Cmd {
|
||||||
)
|
)
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
|
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "list",
|
Use: "list",
|
||||||
Aliases: []string{"ls"},
|
Aliases: []string{"ls"},
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
|
|
|
@ -12,14 +12,14 @@ import (
|
||||||
"github.com/coder/serpent"
|
"github.com/coder/serpent"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) groupCreate() *serpent.Cmd {
|
func (r *RootCmd) groupCreate() *serpent.Command {
|
||||||
var (
|
var (
|
||||||
avatarURL string
|
avatarURL string
|
||||||
displayName string
|
displayName string
|
||||||
)
|
)
|
||||||
|
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "create <name>",
|
Use: "create <name>",
|
||||||
Short: "Create a user group",
|
Short: "Create a user group",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
|
|
|
@ -12,9 +12,9 @@ import (
|
||||||
"github.com/coder/serpent"
|
"github.com/coder/serpent"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) groupDelete() *serpent.Cmd {
|
func (r *RootCmd) groupDelete() *serpent.Command {
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "delete <name>",
|
Use: "delete <name>",
|
||||||
Short: "Delete a user group",
|
Short: "Delete a user group",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
|
|
|
@ -15,7 +15,7 @@ import (
|
||||||
"github.com/coder/serpent"
|
"github.com/coder/serpent"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) groupEdit() *serpent.Cmd {
|
func (r *RootCmd) groupEdit() *serpent.Command {
|
||||||
var (
|
var (
|
||||||
avatarURL string
|
avatarURL string
|
||||||
name string
|
name string
|
||||||
|
@ -24,7 +24,7 @@ func (r *RootCmd) groupEdit() *serpent.Cmd {
|
||||||
rmUsers []string
|
rmUsers []string
|
||||||
)
|
)
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "edit <name>",
|
Use: "edit <name>",
|
||||||
Short: "Edit a user group",
|
Short: "Edit a user group",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
|
|
|
@ -13,14 +13,14 @@ import (
|
||||||
"github.com/coder/serpent"
|
"github.com/coder/serpent"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) groupList() *serpent.Cmd {
|
func (r *RootCmd) groupList() *serpent.Command {
|
||||||
formatter := cliui.NewOutputFormatter(
|
formatter := cliui.NewOutputFormatter(
|
||||||
cliui.TableFormat([]groupTableRow{}, nil),
|
cliui.TableFormat([]groupTableRow{}, nil),
|
||||||
cliui.JSONFormat(),
|
cliui.JSONFormat(),
|
||||||
)
|
)
|
||||||
|
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "list",
|
Use: "list",
|
||||||
Short: "List user groups",
|
Short: "List user groups",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
|
|
|
@ -2,15 +2,15 @@ package cli
|
||||||
|
|
||||||
import "github.com/coder/serpent"
|
import "github.com/coder/serpent"
|
||||||
|
|
||||||
func (r *RootCmd) groups() *serpent.Cmd {
|
func (r *RootCmd) groups() *serpent.Command {
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "groups",
|
Use: "groups",
|
||||||
Short: "Manage groups",
|
Short: "Manage groups",
|
||||||
Aliases: []string{"group"},
|
Aliases: []string{"group"},
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
return inv.Command.HelpHandler(inv)
|
return inv.Command.HelpHandler(inv)
|
||||||
},
|
},
|
||||||
Children: []*serpent.Cmd{
|
Children: []*serpent.Command{
|
||||||
r.groupCreate(),
|
r.groupCreate(),
|
||||||
r.groupList(),
|
r.groupList(),
|
||||||
r.groupEdit(),
|
r.groupEdit(),
|
||||||
|
|
|
@ -20,15 +20,15 @@ import (
|
||||||
|
|
||||||
var jwtRegexp = regexp.MustCompile(`^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$`)
|
var jwtRegexp = regexp.MustCompile(`^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$`)
|
||||||
|
|
||||||
func (r *RootCmd) licenses() *serpent.Cmd {
|
func (r *RootCmd) licenses() *serpent.Command {
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Short: "Add, delete, and list licenses",
|
Short: "Add, delete, and list licenses",
|
||||||
Use: "licenses",
|
Use: "licenses",
|
||||||
Aliases: []string{"license"},
|
Aliases: []string{"license"},
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
return inv.Command.HelpHandler(inv)
|
return inv.Command.HelpHandler(inv)
|
||||||
},
|
},
|
||||||
Children: []*serpent.Cmd{
|
Children: []*serpent.Command{
|
||||||
r.licenseAdd(),
|
r.licenseAdd(),
|
||||||
r.licensesList(),
|
r.licensesList(),
|
||||||
r.licenseDelete(),
|
r.licenseDelete(),
|
||||||
|
@ -37,14 +37,14 @@ func (r *RootCmd) licenses() *serpent.Cmd {
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) licenseAdd() *serpent.Cmd {
|
func (r *RootCmd) licenseAdd() *serpent.Command {
|
||||||
var (
|
var (
|
||||||
filename string
|
filename string
|
||||||
license string
|
license string
|
||||||
debug bool
|
debug bool
|
||||||
)
|
)
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "add [-f file | -l license]",
|
Use: "add [-f file | -l license]",
|
||||||
Short: "Add license to Coder deployment",
|
Short: "Add license to Coder deployment",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
|
@ -136,7 +136,7 @@ func validJWT(s string) error {
|
||||||
return xerrors.New("Invalid license")
|
return xerrors.New("Invalid license")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) licensesList() *serpent.Cmd {
|
func (r *RootCmd) licensesList() *serpent.Command {
|
||||||
type tableLicense struct {
|
type tableLicense struct {
|
||||||
ID int32 `table:"id,default_sort"`
|
ID int32 `table:"id,default_sort"`
|
||||||
UUID uuid.UUID `table:"uuid" format:"uuid"`
|
UUID uuid.UUID `table:"uuid" format:"uuid"`
|
||||||
|
@ -208,7 +208,7 @@ func (r *RootCmd) licensesList() *serpent.Cmd {
|
||||||
)
|
)
|
||||||
|
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "list",
|
Use: "list",
|
||||||
Short: "List licenses (including expired)",
|
Short: "List licenses (including expired)",
|
||||||
Aliases: []string{"ls"},
|
Aliases: []string{"ls"},
|
||||||
|
@ -239,9 +239,9 @@ func (r *RootCmd) licensesList() *serpent.Cmd {
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) licenseDelete() *serpent.Cmd {
|
func (r *RootCmd) licenseDelete() *serpent.Command {
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "delete <id>",
|
Use: "delete <id>",
|
||||||
Short: "Delete license by ID",
|
Short: "Delete license by ID",
|
||||||
Aliases: []string{"del"},
|
Aliases: []string{"del"},
|
||||||
|
|
|
@ -32,14 +32,14 @@ import (
|
||||||
"github.com/coder/serpent"
|
"github.com/coder/serpent"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) provisionerDaemons() *serpent.Cmd {
|
func (r *RootCmd) provisionerDaemons() *serpent.Command {
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "provisionerd",
|
Use: "provisionerd",
|
||||||
Short: "Manage provisioner daemons",
|
Short: "Manage provisioner daemons",
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
return inv.Command.HelpHandler(inv)
|
return inv.Command.HelpHandler(inv)
|
||||||
},
|
},
|
||||||
Children: []*serpent.Cmd{
|
Children: []*serpent.Command{
|
||||||
r.provisionerDaemonStart(),
|
r.provisionerDaemonStart(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,7 @@ func validateProvisionerDaemonName(name string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) provisionerDaemonStart() *serpent.Cmd {
|
func (r *RootCmd) provisionerDaemonStart() *serpent.Command {
|
||||||
var (
|
var (
|
||||||
cacheDir string
|
cacheDir string
|
||||||
logHuman string
|
logHuman string
|
||||||
|
@ -75,7 +75,7 @@ func (r *RootCmd) provisionerDaemonStart() *serpent.Cmd {
|
||||||
prometheusAddress string
|
prometheusAddress string
|
||||||
)
|
)
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "start",
|
Use: "start",
|
||||||
Short: "Run a provisioner daemon",
|
Short: "Run a provisioner daemon",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
|
|
|
@ -7,8 +7,8 @@ import (
|
||||||
"github.com/coder/serpent"
|
"github.com/coder/serpent"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) provisionerDaemons() *serpent.Cmd {
|
func (r *RootCmd) provisionerDaemons() *serpent.Command {
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "provisionerd",
|
Use: "provisionerd",
|
||||||
Short: "Manage provisioner daemons",
|
Short: "Manage provisioner daemons",
|
||||||
// We accept RawArgs so all commands and flags are accepted.
|
// We accept RawArgs so all commands and flags are accepted.
|
||||||
|
|
|
@ -44,7 +44,7 @@ func (c *closers) Add(f func()) {
|
||||||
*c = append(*c, f)
|
*c = append(*c, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) proxyServer() *serpent.Cmd {
|
func (r *RootCmd) proxyServer() *serpent.Command {
|
||||||
var (
|
var (
|
||||||
cfg = new(codersdk.DeploymentValues)
|
cfg = new(codersdk.DeploymentValues)
|
||||||
// Filter options for only relevant ones.
|
// Filter options for only relevant ones.
|
||||||
|
@ -102,7 +102,7 @@ func (r *RootCmd) proxyServer() *serpent.Cmd {
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "server",
|
Use: "server",
|
||||||
Short: "Start a workspace proxy server",
|
Short: "Start a workspace proxy server",
|
||||||
Options: opts,
|
Options: opts,
|
||||||
|
|
|
@ -7,8 +7,8 @@ import (
|
||||||
"github.com/coder/serpent"
|
"github.com/coder/serpent"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) proxyServer() *serpent.Cmd {
|
func (r *RootCmd) proxyServer() *serpent.Command {
|
||||||
root := &serpent.Cmd{
|
root := &serpent.Command{
|
||||||
Use: "server",
|
Use: "server",
|
||||||
Short: "Start a workspace proxy server",
|
Short: "Start a workspace proxy server",
|
||||||
Aliases: []string{},
|
Aliases: []string{},
|
||||||
|
|
|
@ -9,8 +9,8 @@ type RootCmd struct {
|
||||||
cli.RootCmd
|
cli.RootCmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) enterpriseOnly() []*serpent.Cmd {
|
func (r *RootCmd) enterpriseOnly() []*serpent.Command {
|
||||||
return []*serpent.Cmd{
|
return []*serpent.Command{
|
||||||
r.Server(nil),
|
r.Server(nil),
|
||||||
r.workspaceProxy(),
|
r.workspaceProxy(),
|
||||||
r.features(),
|
r.features(),
|
||||||
|
@ -20,7 +20,7 @@ func (r *RootCmd) enterpriseOnly() []*serpent.Cmd {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) EnterpriseSubcommands() []*serpent.Cmd {
|
func (r *RootCmd) EnterpriseSubcommands() []*serpent.Command {
|
||||||
all := append(r.Core(), r.enterpriseOnly()...)
|
all := append(r.Core(), r.enterpriseOnly()...)
|
||||||
return all
|
return all
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ import (
|
||||||
//nolint:tparallel,paralleltest
|
//nolint:tparallel,paralleltest
|
||||||
func TestEnterpriseCommandHelp(t *testing.T) {
|
func TestEnterpriseCommandHelp(t *testing.T) {
|
||||||
// Only test the enterprise commands
|
// Only test the enterprise commands
|
||||||
getCmds := func(t *testing.T) *serpent.Cmd {
|
getCmds := func(t *testing.T) *serpent.Command {
|
||||||
// Must return a fresh instance of cmds each time.
|
// Must return a fresh instance of cmds each time.
|
||||||
t.Helper()
|
t.Helper()
|
||||||
var root cli.RootCmd
|
var root cli.RootCmd
|
||||||
|
|
|
@ -28,7 +28,7 @@ import (
|
||||||
agplcoderd "github.com/coder/coder/v2/coderd"
|
agplcoderd "github.com/coder/coder/v2/coderd"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) Server(_ func()) *serpent.Cmd {
|
func (r *RootCmd) Server(_ func()) *serpent.Command {
|
||||||
cmd := r.RootCmd.Server(func(ctx context.Context, options *agplcoderd.Options) (*agplcoderd.API, io.Closer, error) {
|
cmd := r.RootCmd.Server(func(ctx context.Context, options *agplcoderd.Options) (*agplcoderd.API, io.Closer, error) {
|
||||||
if options.DeploymentValues.DERP.Server.RelayURL.String() != "" {
|
if options.DeploymentValues.DERP.Server.RelayURL.String() != "" {
|
||||||
_, err := url.Parse(options.DeploymentValues.DERP.Server.RelayURL.String())
|
_, err := url.Parse(options.DeploymentValues.DERP.Server.RelayURL.String())
|
||||||
|
|
|
@ -18,8 +18,8 @@ import (
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) dbcryptCmd() *serpent.Cmd {
|
func (r *RootCmd) dbcryptCmd() *serpent.Command {
|
||||||
dbcryptCmd := &serpent.Cmd{
|
dbcryptCmd := &serpent.Command{
|
||||||
Use: "dbcrypt",
|
Use: "dbcrypt",
|
||||||
Short: "Manage database encryption.",
|
Short: "Manage database encryption.",
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
@ -34,9 +34,9 @@ func (r *RootCmd) dbcryptCmd() *serpent.Cmd {
|
||||||
return dbcryptCmd
|
return dbcryptCmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*RootCmd) dbcryptRotateCmd() *serpent.Cmd {
|
func (*RootCmd) dbcryptRotateCmd() *serpent.Command {
|
||||||
var flags rotateFlags
|
var flags rotateFlags
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "rotate",
|
Use: "rotate",
|
||||||
Short: "Rotate database encryption keys.",
|
Short: "Rotate database encryption keys.",
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
@ -107,9 +107,9 @@ func (*RootCmd) dbcryptRotateCmd() *serpent.Cmd {
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*RootCmd) dbcryptDecryptCmd() *serpent.Cmd {
|
func (*RootCmd) dbcryptDecryptCmd() *serpent.Command {
|
||||||
var flags decryptFlags
|
var flags decryptFlags
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "decrypt",
|
Use: "decrypt",
|
||||||
Short: "Decrypt a previously encrypted database.",
|
Short: "Decrypt a previously encrypted database.",
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
@ -164,9 +164,9 @@ func (*RootCmd) dbcryptDecryptCmd() *serpent.Cmd {
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*RootCmd) dbcryptDeleteCmd() *serpent.Cmd {
|
func (*RootCmd) dbcryptDeleteCmd() *serpent.Command {
|
||||||
var flags deleteFlags
|
var flags deleteFlags
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "delete",
|
Use: "delete",
|
||||||
Short: "Delete all encrypted data from the database. THIS IS A DESTRUCTIVE OPERATION.",
|
Short: "Delete all encrypted data from the database. THIS IS A DESTRUCTIVE OPERATION.",
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
|
|
@ -15,8 +15,8 @@ import (
|
||||||
"github.com/coder/serpent"
|
"github.com/coder/serpent"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) workspaceProxy() *serpent.Cmd {
|
func (r *RootCmd) workspaceProxy() *serpent.Command {
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "workspace-proxy",
|
Use: "workspace-proxy",
|
||||||
Short: "Workspace proxies provide low-latency experiences for geo-distributed teams.",
|
Short: "Workspace proxies provide low-latency experiences for geo-distributed teams.",
|
||||||
Long: "Workspace proxies provide low-latency experiences for geo-distributed teams. " +
|
Long: "Workspace proxies provide low-latency experiences for geo-distributed teams. " +
|
||||||
|
@ -27,7 +27,7 @@ func (r *RootCmd) workspaceProxy() *serpent.Cmd {
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
return inv.Command.HelpHandler(inv)
|
return inv.Command.HelpHandler(inv)
|
||||||
},
|
},
|
||||||
Children: []*serpent.Cmd{
|
Children: []*serpent.Command{
|
||||||
r.proxyServer(),
|
r.proxyServer(),
|
||||||
r.createProxy(),
|
r.createProxy(),
|
||||||
r.deleteProxy(),
|
r.deleteProxy(),
|
||||||
|
@ -40,10 +40,10 @@ func (r *RootCmd) workspaceProxy() *serpent.Cmd {
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) regenerateProxyToken() *serpent.Cmd {
|
func (r *RootCmd) regenerateProxyToken() *serpent.Command {
|
||||||
formatter := newUpdateProxyResponseFormatter()
|
formatter := newUpdateProxyResponseFormatter()
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "regenerate-token <name|id>",
|
Use: "regenerate-token <name|id>",
|
||||||
Short: "Regenerate a workspace proxy authentication token. " +
|
Short: "Regenerate a workspace proxy authentication token. " +
|
||||||
"This will invalidate the existing authentication token.",
|
"This will invalidate the existing authentication token.",
|
||||||
|
@ -86,7 +86,7 @@ func (r *RootCmd) regenerateProxyToken() *serpent.Cmd {
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) patchProxy() *serpent.Cmd {
|
func (r *RootCmd) patchProxy() *serpent.Command {
|
||||||
var (
|
var (
|
||||||
proxyName string
|
proxyName string
|
||||||
displayName string
|
displayName string
|
||||||
|
@ -113,7 +113,7 @@ func (r *RootCmd) patchProxy() *serpent.Cmd {
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "edit <name|id>",
|
Use: "edit <name|id>",
|
||||||
Short: "Edit a workspace proxy",
|
Short: "Edit a workspace proxy",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
|
@ -186,9 +186,9 @@ func (r *RootCmd) patchProxy() *serpent.Cmd {
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) deleteProxy() *serpent.Cmd {
|
func (r *RootCmd) deleteProxy() *serpent.Command {
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "delete <name|id>",
|
Use: "delete <name|id>",
|
||||||
Short: "Delete a workspace proxy",
|
Short: "Delete a workspace proxy",
|
||||||
Options: serpent.OptionSet{
|
Options: serpent.OptionSet{
|
||||||
|
@ -229,7 +229,7 @@ func (r *RootCmd) deleteProxy() *serpent.Cmd {
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) createProxy() *serpent.Cmd {
|
func (r *RootCmd) createProxy() *serpent.Command {
|
||||||
var (
|
var (
|
||||||
proxyName string
|
proxyName string
|
||||||
displayName string
|
displayName string
|
||||||
|
@ -245,7 +245,7 @@ func (r *RootCmd) createProxy() *serpent.Cmd {
|
||||||
}
|
}
|
||||||
|
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "create",
|
Use: "create",
|
||||||
Short: "Create a workspace proxy",
|
Short: "Create a workspace proxy",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
|
@ -335,7 +335,7 @@ func (r *RootCmd) createProxy() *serpent.Cmd {
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) listProxies() *serpent.Cmd {
|
func (r *RootCmd) listProxies() *serpent.Command {
|
||||||
formatter := cliui.NewOutputFormatter(
|
formatter := cliui.NewOutputFormatter(
|
||||||
cliui.TableFormat([]codersdk.WorkspaceProxy{}, []string{"name", "url", "proxy status"}),
|
cliui.TableFormat([]codersdk.WorkspaceProxy{}, []string{"name", "url", "proxy status"}),
|
||||||
cliui.JSONFormat(),
|
cliui.JSONFormat(),
|
||||||
|
@ -363,7 +363,7 @@ func (r *RootCmd) listProxies() *serpent.Cmd {
|
||||||
)
|
)
|
||||||
|
|
||||||
client := new(codersdk.Client)
|
client := new(codersdk.Client)
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "ls",
|
Use: "ls",
|
||||||
Aliases: []string{"list"},
|
Aliases: []string{"list"},
|
||||||
Short: "List all workspace proxies",
|
Short: "List all workspace proxies",
|
||||||
|
|
2
go.mod
2
go.mod
|
@ -208,7 +208,7 @@ require go.uber.org/mock v0.4.0
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/benbjohnson/clock v1.3.5
|
github.com/benbjohnson/clock v1.3.5
|
||||||
github.com/coder/serpent v0.4.0
|
github.com/coder/serpent v0.4.1-0.20240315163851-a0148c87ea3f
|
||||||
github.com/gomarkdown/markdown v0.0.0-20231222211730-1d6d20845b47
|
github.com/gomarkdown/markdown v0.0.0-20231222211730-1d6d20845b47
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
2
go.sum
2
go.sum
|
@ -216,6 +216,8 @@ github.com/coder/retry v1.5.1 h1:iWu8YnD8YqHs3XwqrqsjoBTAVqT9ml6z9ViJ2wlMiqc=
|
||||||
github.com/coder/retry v1.5.1/go.mod h1:blHMk9vs6LkoRT9ZHyuZo360cufXEhrxqvEzeMtRGoY=
|
github.com/coder/retry v1.5.1/go.mod h1:blHMk9vs6LkoRT9ZHyuZo360cufXEhrxqvEzeMtRGoY=
|
||||||
github.com/coder/serpent v0.4.0 h1:L/itwnCxfhLutxQ2mScP3tH1ro8z8+Kc/iKKyZZxEMk=
|
github.com/coder/serpent v0.4.0 h1:L/itwnCxfhLutxQ2mScP3tH1ro8z8+Kc/iKKyZZxEMk=
|
||||||
github.com/coder/serpent v0.4.0/go.mod h1:Wud83ikZF/ulbdMcEMAwqvkEIQx7+l47+ef69M/arAA=
|
github.com/coder/serpent v0.4.0/go.mod h1:Wud83ikZF/ulbdMcEMAwqvkEIQx7+l47+ef69M/arAA=
|
||||||
|
github.com/coder/serpent v0.4.1-0.20240315163851-a0148c87ea3f h1:nqJ/Mvm+nLI22n5BIYhvSmTZ6CD+MRo/aGVZwVQgr1k=
|
||||||
|
github.com/coder/serpent v0.4.1-0.20240315163851-a0148c87ea3f/go.mod h1:REkJ5ZFHQUWFTPLExhXYZ1CaHFjxvGNRlLXLdsI08YA=
|
||||||
github.com/coder/ssh v0.0.0-20231128192721-70855dedb788 h1:YoUSJ19E8AtuUFVYBpXuOD6a/zVP3rcxezNsoDseTUw=
|
github.com/coder/ssh v0.0.0-20231128192721-70855dedb788 h1:YoUSJ19E8AtuUFVYBpXuOD6a/zVP3rcxezNsoDseTUw=
|
||||||
github.com/coder/ssh v0.0.0-20231128192721-70855dedb788/go.mod h1:aGQbuCLyhRLMzZF067xc84Lh7JDs1FKwCmF1Crl9dxQ=
|
github.com/coder/ssh v0.0.0-20231128192721-70855dedb788/go.mod h1:aGQbuCLyhRLMzZF067xc84Lh7JDs1FKwCmF1Crl9dxQ=
|
||||||
github.com/coder/tailscale v1.1.1-0.20240214140224-3788ab894ba1 h1:A7dZHNidAVH6Kxn5D3hTEH+iRO8slnM0aRer6/cxlyE=
|
github.com/coder/tailscale v1.1.1-0.20240214140224-3788ab894ba1 h1:A7dZHNidAVH6Kxn5D3hTEH+iRO8slnM0aRer6/cxlyE=
|
||||||
|
|
|
@ -59,7 +59,7 @@ func TestPtytest(t *testing.T) {
|
||||||
tt := tt
|
tt := tt
|
||||||
// nolint:paralleltest // Avoid parallel test to more easily identify the issue.
|
// nolint:paralleltest // Avoid parallel test to more easily identify the issue.
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
cmd := &serpent.Cmd{
|
cmd := &serpent.Command{
|
||||||
Use: "test",
|
Use: "test",
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
fmt.Fprint(inv.Stdout, tt.output)
|
fmt.Fprint(inv.Stdout, tt.output)
|
||||||
|
|
|
@ -25,8 +25,8 @@ var commandTemplate *template.Template
|
||||||
func init() {
|
func init() {
|
||||||
commandTemplate = template.Must(
|
commandTemplate = template.Must(
|
||||||
template.New("command.tpl").Funcs(template.FuncMap{
|
template.New("command.tpl").Funcs(template.FuncMap{
|
||||||
"visibleSubcommands": func(cmd *serpent.Cmd) []*serpent.Cmd {
|
"visibleSubcommands": func(cmd *serpent.Command) []*serpent.Command {
|
||||||
var visible []*serpent.Cmd
|
var visible []*serpent.Command
|
||||||
for _, sub := range cmd.Children {
|
for _, sub := range cmd.Children {
|
||||||
if sub.Hidden {
|
if sub.Hidden {
|
||||||
continue
|
continue
|
||||||
|
@ -35,7 +35,7 @@ func init() {
|
||||||
}
|
}
|
||||||
return visible
|
return visible
|
||||||
},
|
},
|
||||||
"visibleOptions": func(cmd *serpent.Cmd) []serpent.Option {
|
"visibleOptions": func(cmd *serpent.Command) []serpent.Option {
|
||||||
var visible []serpent.Option
|
var visible []serpent.Option
|
||||||
for _, opt := range cmd.Options {
|
for _, opt := range cmd.Options {
|
||||||
if opt.Hidden {
|
if opt.Hidden {
|
||||||
|
@ -45,7 +45,7 @@ func init() {
|
||||||
}
|
}
|
||||||
return visible
|
return visible
|
||||||
},
|
},
|
||||||
"atRoot": func(cmd *serpent.Cmd) bool {
|
"atRoot": func(cmd *serpent.Command) bool {
|
||||||
return cmd.FullName() == "coder"
|
return cmd.FullName() == "coder"
|
||||||
},
|
},
|
||||||
"newLinesToBr": func(s string) string {
|
"newLinesToBr": func(s string) string {
|
||||||
|
@ -54,7 +54,7 @@ func init() {
|
||||||
"wrapCode": func(s string) string {
|
"wrapCode": func(s string) string {
|
||||||
return fmt.Sprintf("<code>%s</code>", s)
|
return fmt.Sprintf("<code>%s</code>", s)
|
||||||
},
|
},
|
||||||
"commandURI": func(cmd *serpent.Cmd) string {
|
"commandURI": func(cmd *serpent.Command) string {
|
||||||
return fmtDocFilename(cmd)
|
return fmtDocFilename(cmd)
|
||||||
},
|
},
|
||||||
"fullName": fullName,
|
"fullName": fullName,
|
||||||
|
@ -67,14 +67,14 @@ func init() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func fullName(cmd *serpent.Cmd) string {
|
func fullName(cmd *serpent.Command) string {
|
||||||
if cmd.FullName() == "coder" {
|
if cmd.FullName() == "coder" {
|
||||||
return "coder"
|
return "coder"
|
||||||
}
|
}
|
||||||
return strings.TrimPrefix(cmd.FullName(), "coder ")
|
return strings.TrimPrefix(cmd.FullName(), "coder ")
|
||||||
}
|
}
|
||||||
|
|
||||||
func fmtDocFilename(cmd *serpent.Cmd) string {
|
func fmtDocFilename(cmd *serpent.Command) string {
|
||||||
if cmd.FullName() == "coder" {
|
if cmd.FullName() == "coder" {
|
||||||
// Special case for index.
|
// Special case for index.
|
||||||
return "../cli.md"
|
return "../cli.md"
|
||||||
|
@ -83,7 +83,7 @@ func fmtDocFilename(cmd *serpent.Cmd) string {
|
||||||
return fmt.Sprintf("%s.md", name)
|
return fmt.Sprintf("%s.md", name)
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeCommand(w io.Writer, cmd *serpent.Cmd) error {
|
func writeCommand(w io.Writer, cmd *serpent.Command) error {
|
||||||
var b strings.Builder
|
var b strings.Builder
|
||||||
err := commandTemplate.Execute(&b, cmd)
|
err := commandTemplate.Execute(&b, cmd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -112,7 +112,7 @@ func writeCommand(w io.Writer, cmd *serpent.Cmd) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func genTree(dir string, cmd *serpent.Cmd, wroteLog map[string]*serpent.Cmd) error {
|
func genTree(dir string, cmd *serpent.Command, wroteLog map[string]*serpent.Command) error {
|
||||||
if cmd.Hidden {
|
if cmd.Hidden {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,7 +83,7 @@ func main() {
|
||||||
root := (&cli.RootCmd{})
|
root := (&cli.RootCmd{})
|
||||||
|
|
||||||
// wroteMap indexes file paths to commands.
|
// wroteMap indexes file paths to commands.
|
||||||
wroteMap := make(map[string]*serpent.Cmd)
|
wroteMap := make(map[string]*serpent.Command)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
docsDir = filepath.Join(workdir, "docs")
|
docsDir = filepath.Join(workdir, "docs")
|
||||||
|
|
Loading…
Reference in New Issue