Thanks to visit codestin.com
Credit goes to github.com

Skip to content
This repository was archived by the owner on Aug 30, 2024. It is now read-only.

Commit 721fe62

Browse files
committed
Add open command
1 parent 9477995 commit 721fe62

File tree

5 files changed

+145
-1
lines changed

5 files changed

+145
-1
lines changed

docs/coder.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ coder provides a CLI for working with an existing Coder Enterprise installation
1616
* [coder envs](coder_envs.md) - Interact with Coder environments
1717
* [coder login](coder_login.md) - Authenticate this client for future operations
1818
* [coder logout](coder_logout.md) - Remove local authentication credentials if any exist
19+
* [coder open](coder_open.md) - launch your IDE and connect to a Coder environment
1920
* [coder secrets](coder_secrets.md) - Interact with Coder Secrets
2021
* [coder sh](coder_sh.md) - Open a shell and execute commands in a Coder environment
2122
* [coder sync](coder_sync.md) - Establish a one way directory sync to a Coder environment

docs/coder_open.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
## coder open
2+
3+
launch your IDE and connect to a Coder environment
4+
5+
```
6+
coder open [environment_name]:[remote_workspace_path] [flags]
7+
```
8+
9+
### Examples
10+
11+
```
12+
coder open backend-dev:/home/coder
13+
coder open backend-dev:/home/coder/backend-project
14+
```
15+
16+
### Options
17+
18+
```
19+
-h, --help help for open
20+
```
21+
22+
### Options inherited from parent commands
23+
24+
```
25+
-v, --verbose show verbose output
26+
```
27+
28+
### SEE ALSO
29+
30+
* [coder](coder.md) - coder provides a CLI for working with an existing Coder Enterprise installation
31+

internal/cmd/cmd.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ func Make() *cobra.Command {
2424
loginCmd(),
2525
logoutCmd(),
2626
shCmd(),
27+
openCmd(),
2728
usersCmd(),
2829
configSSHCmd(),
2930
secretsCmd(),

internal/cmd/open.go

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
package cmd
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"os/exec"
7+
"os/user"
8+
"path/filepath"
9+
"strings"
10+
11+
"cdr.dev/coder-cli/coder-sdk"
12+
"cdr.dev/coder-cli/pkg/clog"
13+
"github.com/spf13/cobra"
14+
)
15+
16+
func openCmd() *cobra.Command {
17+
return &cobra.Command{
18+
Use: "open [environment_name]:[remote_workspace_path]",
19+
Args: cobra.ExactArgs(1),
20+
Short: "launch your IDE and connect to a Coder environment",
21+
ValidArgsFunction: getEnvsForCompletion(coder.Me),
22+
Example: `coder open backend-dev:/home/coder
23+
coder open backend-dev:/home/coder/backend-project`,
24+
RunE: func(cmd *cobra.Command, args []string) error {
25+
ctx := cmd.Context()
26+
client, err := newClient(ctx)
27+
if err != nil {
28+
return err
29+
}
30+
parts := strings.Split(args[0], ":")
31+
if len(parts) < 2 {
32+
return cmd.Usage()
33+
}
34+
35+
envName, workspacePath := parts[0], parts[1]
36+
env, err := findEnv(ctx, client, envName, coder.Me)
37+
if err != nil {
38+
return err
39+
}
40+
warnIfAliasMissing(env.Name)
41+
42+
if _, err := exec.LookPath("code"); err != nil {
43+
return clog.Error(
44+
`"code" command line tool not found`, clog.BlankLine,
45+
clog.Tipf(`read about "code" here: https://code.visualstudio.com/docs/editor/command-line`),
46+
)
47+
}
48+
49+
// TODO(@cmoog) maybe check if it's not installed first, although it does seem to check internally
50+
if err = installRemoteSSH(ctx); err != nil {
51+
return clog.Error(
52+
"failed to install VSCode Remote SSH extension", clog.BlankLine,
53+
clog.Causef(err.Error()),
54+
)
55+
}
56+
57+
if err = openVSCodeRemote(ctx, env.Name, workspacePath); err != nil {
58+
return err
59+
}
60+
61+
return nil
62+
},
63+
}
64+
}
65+
66+
func warnIfAliasMissing(envName string) {
67+
usr, err := user.Current()
68+
if err != nil {
69+
return
70+
}
71+
72+
// TODO(@cmoog) might be a better way of finding the path of the SSH config / whether an alias is valid or not
73+
config, err := readStr(filepath.Join(usr.HomeDir, ".ssh", "config"))
74+
if err != nil {
75+
clog.LogWarn(
76+
"failed to check that SSH target exists", clog.BlankLine,
77+
clog.Causef(err.Error()),
78+
clog.Tipf(`run "coder config-ssh" to add SSH targets for each environment`),
79+
)
80+
return
81+
}
82+
83+
if !strings.Contains(config, fmt.Sprintf("coder.%s", envName)) {
84+
clog.LogWarn(
85+
"SSH alias not found for environment", clog.BlankLine,
86+
clog.Tipf(`run "coder config-ssh" to add SSH targets for each environment`),
87+
)
88+
return
89+
}
90+
}
91+
92+
func installRemoteSSH(ctx context.Context) error {
93+
cmd := exec.CommandContext(ctx,
94+
"code", "--install-extension", "ms-vscode-remote.remote-ssh",
95+
)
96+
if _, err := cmd.CombinedOutput(); err != nil {
97+
return err
98+
}
99+
return nil
100+
}
101+
102+
func openVSCodeRemote(ctx context.Context, envName, dirPath string) error {
103+
cmd := exec.CommandContext(ctx,
104+
"code", "--remote", "ssh-remote+coder."+envName, dirPath,
105+
)
106+
_, err := cmd.CombinedOutput()
107+
if err != nil {
108+
return err
109+
}
110+
return nil
111+
}

pkg/clog/doc.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22
//
33
// clog encourages returning error types rather than
44
// logging them and failing with os.Exit as they happen.
5-
// Error, Fatal, and Warn allow downstream functions to return errors with rich formatting information
5+
// Error and Fatal allow downstream functions to return errors with rich formatting information
66
// while preserving the original, single-line error chain.
77
package clog

0 commit comments

Comments
 (0)