diff --git a/coder-sdk/env.go b/coder-sdk/env.go index 2eced5f1..a95ed4bf 100644 --- a/coder-sdk/env.go +++ b/coder-sdk/env.go @@ -39,10 +39,6 @@ type RebuildMessage struct { Text string `json:"text"` Required bool `json:"required"` AutoOffThreshold xjson.MSDuration `json:"auto_off_threshold" tab:"-"` - RebuildMessages []struct { - Text string `json:"text"` - Required bool `json:"required"` - } `json:"rebuild_messages" tab:"-"` } // EnvironmentStat represents the state of an environment diff --git a/docs/coder_sh.md b/docs/coder_sh.md index 8bd80ac6..72270e8f 100644 --- a/docs/coder_sh.md +++ b/docs/coder_sh.md @@ -14,6 +14,7 @@ coder sh [environment_name] [] [flags] ``` coder sh backend-env +coder sh front-end-dev cat ~/config.json ``` ### Options diff --git a/internal/cmd/cmd.go b/internal/cmd/cmd.go index d00796cd..c629beb3 100644 --- a/internal/cmd/cmd.go +++ b/internal/cmd/cmd.go @@ -21,24 +21,24 @@ func Make() *cobra.Command { } app.AddCommand( - makeLoginCmd(), - makeLogoutCmd(), - makeShellCmd(), - makeUsersCmd(), - makeConfigSSHCmd(), - makeSecretsCmd(), - envsCommand(), - makeSyncCmd(), - makeURLCmd(), + loginCmd(), + logoutCmd(), + shCmd(), + usersCmd(), + configSSHCmd(), + secretsCmd(), + envsCmd(), + syncCmd(), + urlCmd(), resourceCmd(), - completionCmd, - genDocs(app), + completionCmd(), + genDocsCmd(app), ) app.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "show verbose output") return app } -func genDocs(rootCmd *cobra.Command) *cobra.Command { +func genDocsCmd(rootCmd *cobra.Command) *cobra.Command { return &cobra.Command{ Use: "gen-docs [dir_path]", Short: "Generate a markdown documentation tree for the root command.", @@ -52,17 +52,18 @@ func genDocs(rootCmd *cobra.Command) *cobra.Command { } // reference: https://github.com/spf13/cobra/blob/master/shell_completions.md -var completionCmd = &cobra.Command{ - Use: "completion [bash|zsh|fish|powershell]", - Short: "Generate completion script", - Example: `coder completion fish > ~/.config/fish/completions/coder.fish +func completionCmd() *cobra.Command { + return &cobra.Command{ + Use: "completion [bash|zsh|fish|powershell]", + Short: "Generate completion script", + Example: `coder completion fish > ~/.config/fish/completions/coder.fish coder completion zsh > "${fpath[1]}/_coder" Linux: $ coder completion bash > /etc/bash_completion.d/coder MacOS: $ coder completion bash > /usr/local/etc/bash_completion.d/coder`, - Long: `To load completions: + Long: `To load completions: Bash: @@ -93,19 +94,20 @@ $ coder completion fish | source To load completions for each session, execute once: $ coder completion fish > ~/.config/fish/completions/coder.fish `, - DisableFlagsInUseLine: true, - ValidArgs: []string{"bash", "zsh", "fish", "powershell"}, - Args: cobra.ExactValidArgs(1), - Run: func(cmd *cobra.Command, args []string) { - switch args[0] { - case "bash": - _ = cmd.Root().GenBashCompletion(os.Stdout) // Best effort. - case "zsh": - _ = cmd.Root().GenZshCompletion(os.Stdout) // Best effort. - case "fish": - _ = cmd.Root().GenFishCompletion(os.Stdout, true) // Best effort. - case "powershell": - _ = cmd.Root().GenPowerShellCompletion(os.Stdout) // Best effort. - } - }, + DisableFlagsInUseLine: true, + ValidArgs: []string{"bash", "zsh", "fish", "powershell"}, + Args: cobra.ExactValidArgs(1), + Run: func(cmd *cobra.Command, args []string) { + switch args[0] { + case "bash": + _ = cmd.Root().GenBashCompletion(os.Stdout) // Best effort. + case "zsh": + _ = cmd.Root().GenZshCompletion(os.Stdout) // Best effort. + case "fish": + _ = cmd.Root().GenFishCompletion(os.Stdout, true) // Best effort. + case "powershell": + _ = cmd.Root().GenPowerShellCompletion(os.Stdout) // Best effort. + } + }, + } } diff --git a/internal/cmd/configssh.go b/internal/cmd/configssh.go index db76b71e..38d20fdf 100644 --- a/internal/cmd/configssh.go +++ b/internal/cmd/configssh.go @@ -18,7 +18,7 @@ import ( "golang.org/x/xerrors" ) -func makeConfigSSHCmd() *cobra.Command { +func configSSHCmd() *cobra.Command { var ( configpath string remove = false diff --git a/internal/cmd/envs.go b/internal/cmd/envs.go index 67c6b50e..1ddf9309 100644 --- a/internal/cmd/envs.go +++ b/internal/cmd/envs.go @@ -17,7 +17,7 @@ import ( const defaultImgTag = "latest" -func envsCommand() *cobra.Command { +func envsCmd() *cobra.Command { var user string cmd := &cobra.Command{ Use: "envs", @@ -28,12 +28,12 @@ func envsCommand() *cobra.Command { cmd.AddCommand( lsEnvsCommand(&user), - stopEnvsCommand(&user), - rmEnvsCommand(&user), + stopEnvsCmd(&user), + rmEnvsCmd(&user), watchBuildLogCommand(&user), rebuildEnvCommand(&user), - createEnvCommand(&user), - editEnvCommand(&user), + createEnvCmd(&user), + editEnvCmd(&user), ) return cmd } @@ -84,7 +84,7 @@ func lsEnvsCommand(user *string) *cobra.Command { return cmd } -func stopEnvsCommand(user *string) *cobra.Command { +func stopEnvsCmd(user *string) *cobra.Command { return &cobra.Command{ Use: "stop [...environment_names]", Short: "stop Coder environments by name", @@ -131,7 +131,7 @@ coder envs --user charlie@coder.com ls -o json \ } } -func createEnvCommand(user *string) *cobra.Command { +func createEnvCmd(user *string) *cobra.Command { var ( org string img string @@ -239,7 +239,7 @@ coder envs create --cpu 4 --disk 100 --memory 8 --image 5f443b16-30652892427b955 return cmd } -func editEnvCommand(user *string) *cobra.Command { +func editEnvCmd(user *string) *cobra.Command { var ( org string img string @@ -336,7 +336,7 @@ coder envs edit back-end-env --disk 20`, return cmd } -func rmEnvsCommand(user *string) *cobra.Command { +func rmEnvsCmd(user *string) *cobra.Command { var force bool cmd := &cobra.Command{ Use: "rm [...environment_names]", diff --git a/internal/cmd/login.go b/internal/cmd/login.go index 2984822b..d6a8db11 100644 --- a/internal/cmd/login.go +++ b/internal/cmd/login.go @@ -18,7 +18,7 @@ import ( "golang.org/x/xerrors" ) -func makeLoginCmd() *cobra.Command { +func loginCmd() *cobra.Command { return &cobra.Command{ Use: "login [Coder Enterprise URL eg. https://my.coder.domain/]", Short: "Authenticate this client for future operations", diff --git a/internal/cmd/logout.go b/internal/cmd/logout.go index b653d68f..dde3d758 100644 --- a/internal/cmd/logout.go +++ b/internal/cmd/logout.go @@ -9,7 +9,7 @@ import ( "golang.org/x/xerrors" ) -func makeLogoutCmd() *cobra.Command { +func logoutCmd() *cobra.Command { return &cobra.Command{ Use: "logout", Short: "Remove local authentication credentials if any exist", diff --git a/internal/cmd/secrets.go b/internal/cmd/secrets.go index 879d6bde..baa8ad25 100644 --- a/internal/cmd/secrets.go +++ b/internal/cmd/secrets.go @@ -14,7 +14,7 @@ import ( "cdr.dev/coder-cli/internal/x/xtabwriter" ) -func makeSecretsCmd() *cobra.Command { +func secretsCmd() *cobra.Command { var user string cmd := &cobra.Command{ Use: "secrets", @@ -26,28 +26,28 @@ func makeSecretsCmd() *cobra.Command { &cobra.Command{ Use: "ls", Short: "List all secrets owned by the active user", - RunE: listSecrets(&user), + RunE: listSecretsCmd(&user), }, - makeCreateSecret(&user), + createSecretCmd(&user), &cobra.Command{ Use: "rm [...secret_name]", Short: "Remove one or more secrets by name", Args: cobra.MinimumNArgs(1), - RunE: makeRemoveSecrets(&user), + RunE: removeSecretsCmd(&user), Example: "coder secrets rm mysql-password mysql-user", }, &cobra.Command{ Use: "view [secret_name]", Short: "View a secret by name", Args: cobra.ExactArgs(1), - RunE: makeViewSecret(&user), + RunE: viewSecretCmd(&user), Example: "coder secrets view mysql-password", }, ) return cmd } -func makeCreateSecret(userEmail *string) *cobra.Command { +func createSecretCmd(userEmail *string) *cobra.Command { var ( fromFile string fromLiteral string @@ -136,7 +136,7 @@ coder secrets create aws-credentials --from-file ./credentials.json`, return cmd } -func listSecrets(userEmail *string) func(cmd *cobra.Command, _ []string) error { +func listSecretsCmd(userEmail *string) func(cmd *cobra.Command, _ []string) error { return func(cmd *cobra.Command, _ []string) error { client, err := newClient() if err != nil { @@ -169,7 +169,7 @@ func listSecrets(userEmail *string) func(cmd *cobra.Command, _ []string) error { } } -func makeViewSecret(userEmail *string) func(cmd *cobra.Command, args []string) error { +func viewSecretCmd(userEmail *string) func(cmd *cobra.Command, args []string) error { return func(cmd *cobra.Command, args []string) error { var ( name = args[0] @@ -196,7 +196,7 @@ func makeViewSecret(userEmail *string) func(cmd *cobra.Command, args []string) e } } -func makeRemoveSecrets(userEmail *string) func(c *cobra.Command, args []string) error { +func removeSecretsCmd(userEmail *string) func(c *cobra.Command, args []string) error { return func(cmd *cobra.Command, args []string) error { client, err := newClient() if err != nil { diff --git a/internal/cmd/shell.go b/internal/cmd/shell.go index 18197570..9d4b9b10 100644 --- a/internal/cmd/shell.go +++ b/internal/cmd/shell.go @@ -23,11 +23,12 @@ import ( func getEnvsForCompletion(user string) func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + ctx := cmd.Context() client, err := newClient() if err != nil { return nil, cobra.ShellCompDirectiveDefault } - envs, err := getEnvs(context.TODO(), client, user) + envs, err := getEnvs(ctx, client, user) if err != nil { return nil, cobra.ShellCompDirectiveDefault } @@ -40,7 +41,7 @@ func getEnvsForCompletion(user string) func(cmd *cobra.Command, args []string, t } } -func makeShellCmd() *cobra.Command { +func shCmd() *cobra.Command { return &cobra.Command{ Use: "sh [environment_name] []", Short: "Open a shell and execute commands in a Coder environment", @@ -49,13 +50,13 @@ func makeShellCmd() *cobra.Command { DisableFlagParsing: true, ValidArgsFunction: getEnvsForCompletion(coder.Me), RunE: shell, - Example: "coder sh backend-env", + Example: `coder sh backend-env +coder sh front-end-dev cat ~/config.json`, } } -func shell(_ *cobra.Command, cmdArgs []string) error { - ctx := context.Background() - +func shell(cmd *cobra.Command, cmdArgs []string) error { + ctx := cmd.Context() command := "sh" args := []string{"-c"} if len(cmdArgs) > 1 { @@ -106,6 +107,18 @@ func runCommand(ctx context.Context, envName, command string, args []string) err return xerrors.Errorf("find environment: %w", err) } + // check if a rebuild is required before attempting to open a shell + for _, r := range env.RebuildMessages { + // use the first rebuild message that is required + if r.Required { + return clog.Error( + fmt.Sprintf(`environment "%s" requires a rebuild`, env.Name), + clog.Causef(r.Text), clog.BlankLine, + clog.Tipf(`run "coder envs rebuild %s" to rebuild`, env.Name), + ) + } + } + termFD := os.Stdout.Fd() isInteractive := terminal.IsTerminal(int(termFD)) diff --git a/internal/cmd/sync.go b/internal/cmd/sync.go index 4ff3f4ec..7247d883 100644 --- a/internal/cmd/sync.go +++ b/internal/cmd/sync.go @@ -15,7 +15,7 @@ import ( "golang.org/x/xerrors" ) -func makeSyncCmd() *cobra.Command { +func syncCmd() *cobra.Command { var init bool cmd := &cobra.Command{ Use: "sync [local directory] [:]", diff --git a/internal/cmd/urls.go b/internal/cmd/urls.go index c91427da..1faa1328 100644 --- a/internal/cmd/urls.go +++ b/internal/cmd/urls.go @@ -18,7 +18,7 @@ import ( "cdr.dev/coder-cli/internal/x/xtabwriter" ) -func makeURLCmd() *cobra.Command { +func urlCmd() *cobra.Command { var outputFmt string cmd := &cobra.Command{ Use: "urls", @@ -29,7 +29,7 @@ func makeURLCmd() *cobra.Command { Short: "List all DevURLs for an environment", Args: cobra.ExactArgs(1), ValidArgsFunction: getEnvsForCompletion(coder.Me), - RunE: makeListDevURLs(&outputFmt), + RunE: listDevURLsCmd(&outputFmt), } lsCmd.Flags().StringVarP(&outputFmt, "output", "o", "human", "human|json") @@ -43,7 +43,7 @@ func makeURLCmd() *cobra.Command { cmd.AddCommand( lsCmd, rmCmd, - makeCreateDevURL(), + createDevURLCmd(), ) return cmd @@ -89,7 +89,7 @@ func accessLevelIsValid(level string) bool { // Run gets the list of active devURLs from the cemanager for the // specified environment and outputs info to stdout. -func makeListDevURLs(outputFmt *string) func(cmd *cobra.Command, args []string) error { +func listDevURLsCmd(outputFmt *string) func(cmd *cobra.Command, args []string) error { return func(cmd *cobra.Command, args []string) error { envName := args[0] devURLs, err := urlList(cmd.Context(), envName) @@ -120,7 +120,7 @@ func makeListDevURLs(outputFmt *string) func(cmd *cobra.Command, args []string) } } -func makeCreateDevURL() *cobra.Command { +func createDevURLCmd() *cobra.Command { var ( access string urlname string diff --git a/internal/cmd/users.go b/internal/cmd/users.go index b74b1758..15dfbf78 100644 --- a/internal/cmd/users.go +++ b/internal/cmd/users.go @@ -10,7 +10,7 @@ import ( "cdr.dev/coder-cli/internal/x/xtabwriter" ) -func makeUsersCmd() *cobra.Command { +func usersCmd() *cobra.Command { cmd := &cobra.Command{ Use: "users", Short: "Interact with Coder user accounts", pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy