Skip to content

Commit bb570fa

Browse files
committed
Convert exec arguments
1 parent da4fbad commit bb570fa

File tree

4 files changed

+81
-25
lines changed

4 files changed

+81
-25
lines changed

Makefile

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ help: ## show this help
55
| column -t -s '|'
66

77

8-
build: ## Build devcontainer cli
8+
build: fmt ## Build devcontainer cli
99
go build ./cmd/devcontainer
1010

1111
lint: build ## Build and lint
@@ -31,4 +31,8 @@ endif
3131

3232

3333
test:
34-
go test -v ./...
34+
go test -v ./...
35+
36+
37+
fmt:
38+
find . -name '*.go' | grep -v vendor | xargs gofmt -s -w

cmd/devcontainer/devcontainer.go

Lines changed: 72 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"os"
66
"os/exec"
77
"path"
8+
"path/filepath"
89
"sort"
910
"strings"
1011
"text/tabwriter"
@@ -65,30 +66,57 @@ func createListCommand() *cobra.Command {
6566
return cmdList
6667
}
6768

69+
func countBooleans(values ...bool) int {
70+
count := 0
71+
for _, v := range values {
72+
if v {
73+
count++
74+
}
75+
}
76+
return count
77+
}
78+
6879
func createExecCommand() *cobra.Command {
80+
var argDevcontainerName string
81+
var argDevcontainerPath string
82+
var argPromptForDevcontainer bool
83+
6984
cmd := &cobra.Command{
70-
Use: "exec DEVCONTAINER_NAME COMMAND [args...] (args will default to /bin/bash if none provided)",
85+
Use: "exec [--name <name>| --path <path> | --prompt ] [<command> [<args...>]] (command will default to /bin/bash if none provided)",
7186
Short: "Execute a command in a devcontainer",
72-
Long: "Execute a command in a devcontainer, similar to `docker exec`. Pass `?` as DEVCONTAINER_NAME to be prompted.",
87+
Long: "Execute a command in a devcontainer, similar to `docker exec`",
7388
RunE: func(cmd *cobra.Command, args []string) error {
7489

75-
if len(args) < 1 {
76-
return cmd.Usage()
90+
// Default to executing /bin/bash
91+
if len(args) == 0 {
92+
args = []string{"/bin/bash"}
7793
}
7894

79-
// Default to executing /bin/bash
80-
if (len(args) == 1) {
81-
args = append(args, "/bin/bash")
95+
sourceCount := countBooleans(
96+
argDevcontainerName != "",
97+
argDevcontainerPath != "",
98+
argPromptForDevcontainer,
99+
)
100+
if sourceCount > 0 {
101+
fmt.Println("Can specify at most one of --name/--path/--prompt")
102+
return cmd.Usage()
82103
}
83104

84-
devcontainerName := args[0]
105+
containerID := ""
85106
devcontainerList, err := devcontainers.ListDevcontainers()
86107
if err != nil {
87108
return err
88109
}
89-
90-
containerID := ""
91-
if devcontainerName == "?" {
110+
if argDevcontainerName != "" {
111+
var devcontainerName string
112+
devcontainerName = argDevcontainerName
113+
for _, devcontainer := range devcontainerList {
114+
if devcontainer.ContainerName == devcontainerName || devcontainer.DevcontainerName == devcontainerName {
115+
containerID = devcontainer.ContainerID
116+
break
117+
}
118+
}
119+
} else if argPromptForDevcontainer {
92120
// prompt user
93121
fmt.Println("Specify the devcontainer to use:")
94122
for index, devcontainer := range devcontainerList {
@@ -101,15 +129,34 @@ func createExecCommand() *cobra.Command {
101129
}
102130
containerID = devcontainerList[selection].ContainerID
103131
} else {
132+
devcontainerPath := argDevcontainerPath
133+
if devcontainerPath == "" {
134+
devcontainerPath = "."
135+
}
136+
absPath, err := filepath.Abs(devcontainerPath)
137+
if err != nil {
138+
return fmt.Errorf("Error handling path %q: %s", devcontainerPath, err)
139+
}
140+
141+
windowsPath := absPath
142+
if wsl.IsWsl() {
143+
var err error
144+
windowsPath, err = wsl.ConvertWslPathToWindowsPath(windowsPath)
145+
if err != nil {
146+
return err
147+
}
148+
}
104149
for _, devcontainer := range devcontainerList {
105-
if devcontainer.ContainerName == devcontainerName || devcontainer.DevcontainerName == devcontainerName {
150+
if devcontainer.LocalFolderPath == windowsPath {
106151
containerID = devcontainer.ContainerID
107152
break
108153
}
109154
}
110-
if containerID == "" {
111-
return cmd.Usage()
112-
}
155+
}
156+
157+
if containerID == "" {
158+
fmt.Println("Failed to find dev container")
159+
return cmd.Usage()
113160
}
114161

115162
localPath, err := devcontainers.GetLocalFolderFromDevContainer(containerID)
@@ -130,8 +177,8 @@ func createExecCommand() *cobra.Command {
130177
}
131178
}
132179

133-
devcontainerJsonPath := path.Join(wslPath, ".devcontainer/devcontainer.json")
134-
userName, err := devcontainers.GetDevContainerUserName(devcontainerJsonPath)
180+
devcontainerJSONPath := path.Join(wslPath, ".devcontainer/devcontainer.json")
181+
userName, err := devcontainers.GetDevContainerUserName(devcontainerJSONPath)
135182
if err != nil {
136183
return err
137184
}
@@ -141,24 +188,24 @@ func createExecCommand() *cobra.Command {
141188
dockerArgs = append(dockerArgs, "--user", userName)
142189
}
143190
dockerArgs = append(dockerArgs, containerID)
144-
dockerArgs = append(dockerArgs, args[1:]...)
191+
dockerArgs = append(dockerArgs, args...)
145192

146193
dockerCmd := exec.Command("docker", dockerArgs...)
147194
dockerCmd.Stdin = os.Stdin
148195
dockerCmd.Stdout = os.Stdout
149196

150197
err = dockerCmd.Start()
151198
if err != nil {
152-
return fmt.Errorf("Exec: start error: %s\n", err)
199+
return fmt.Errorf("Exec: start error: %s", err)
153200
}
154201
err = dockerCmd.Wait()
155202
if err != nil {
156-
return fmt.Errorf("Exec: wait error: %s\n", err)
203+
return fmt.Errorf("Exec: wait error: %s", err)
157204
}
158205
return nil
159206
},
160-
Args: cobra.ArbitraryArgs,
161-
DisableFlagParsing: true,
207+
Args: cobra.ArbitraryArgs,
208+
// DisableFlagParsing: true,
162209
DisableFlagsInUseLine: true,
163210
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
164211
// only completing the first arg (devcontainer name)
@@ -177,5 +224,8 @@ func createExecCommand() *cobra.Command {
177224
return names, cobra.ShellCompDirectiveNoFileComp
178225
},
179226
}
227+
cmd.Flags().StringVarP(&argDevcontainerName, "name", "n", "", "name of dev container to exec into")
228+
cmd.Flags().StringVarP(&argDevcontainerPath, "path", "", "", "path containing the dev container to exec into")
229+
cmd.Flags().BoolVarP(&argPromptForDevcontainer, "prompt", "", false, "prompt for the dev container to exec into")
180230
return cmd
181231
}

internal/pkg/config/config.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,6 @@ func SaveConfig() error {
6868
if err := os.MkdirAll(configPath, 0755); err != nil {
6969
return err
7070
}
71-
configFilePath:=filepath.Join(configPath, "devcontainer-cli.json")
71+
configFilePath := filepath.Join(configPath, "devcontainer-cli.json")
7272
return viper.WriteConfigAs(configFilePath)
7373
}

internal/pkg/devcontainers/dockerutils.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ type DevcontainerInfo struct {
1919
ContainerID string
2020
ContainerName string
2121
DevcontainerName string
22+
LocalFolderPath string
2223
}
2324

2425
const (
@@ -63,6 +64,7 @@ func ListDevcontainers() ([]DevcontainerInfo, error) {
6364
devcontainer := DevcontainerInfo{
6465
ContainerID: parts[listPartID],
6566
ContainerName: parts[listPartContainerName],
67+
LocalFolderPath: parts[listPartLocalFolder],
6668
DevcontainerName: name,
6769
}
6870
devcontainers = append(devcontainers, devcontainer)

0 commit comments

Comments
 (0)