Skip to content

Commit 4050d12

Browse files
committed
Move functional code for exec into internal/pkg
1 parent fa92c27 commit 4050d12

File tree

2 files changed

+112
-85
lines changed

2 files changed

+112
-85
lines changed

cmd/devcontainer/devcontainer.go

Lines changed: 5 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,11 @@ package main
33
import (
44
"fmt"
55
"os"
6-
"os/exec"
7-
"path"
8-
"path/filepath"
96
"sort"
10-
"strings"
117
"text/tabwriter"
128

139
"github.com/spf13/cobra"
1410
"github.com/stuartleeks/devcontainer-cli/internal/pkg/devcontainers"
15-
"github.com/stuartleeks/devcontainer-cli/internal/pkg/wsl"
1611
)
1712

1813
func createListCommand() *cobra.Command {
@@ -103,19 +98,13 @@ func createExecCommand() *cobra.Command {
10398
return cmd.Usage()
10499
}
105100

106-
containerID := ""
101+
containerIDOrName := ""
107102
devcontainerList, err := devcontainers.ListDevcontainers()
108103
if err != nil {
109104
return err
110105
}
111106
if argDevcontainerName != "" {
112-
devcontainerName := argDevcontainerName
113-
for _, devcontainer := range devcontainerList {
114-
if devcontainer.ContainerName == devcontainerName || devcontainer.DevcontainerName == devcontainerName {
115-
containerID = devcontainer.ContainerID
116-
break
117-
}
118-
}
107+
containerIDOrName = argDevcontainerName
119108
} else if argPromptForDevcontainer {
120109
// prompt user
121110
fmt.Println("Specify the devcontainer to use:")
@@ -127,85 +116,16 @@ func createExecCommand() *cobra.Command {
127116
if selection < 0 || selection >= len(devcontainerList) {
128117
return fmt.Errorf("Invalid option")
129118
}
130-
containerID = devcontainerList[selection].ContainerID
119+
containerIDOrName = devcontainerList[selection].ContainerID
131120
} else {
132121
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-
}
149-
for _, devcontainer := range devcontainerList {
150-
if devcontainer.LocalFolderPath == windowsPath {
151-
containerID = devcontainer.ContainerID
152-
break
153-
}
154-
}
155-
}
156-
157-
if containerID == "" {
158-
fmt.Println("Failed to find a matching (running) dev container")
159-
return cmd.Usage()
160-
}
161-
162-
localPath, err := devcontainers.GetLocalFolderFromDevContainer(containerID)
163-
if err != nil {
164-
return err
165-
}
166-
167-
mountPath := argWorkDir
168-
if mountPath == "" {
169-
mountPath, err = devcontainers.GetWorkspaceMountPath(localPath)
122+
containerIDOrName, err = devcontainers.GetContainerIDForPath(devcontainerPath)
170123
if err != nil {
171124
return err
172125
}
173126
}
174127

175-
wslPath := localPath
176-
if strings.HasPrefix(wslPath, "\\\\wsl$") && wsl.IsWsl() {
177-
wslPath, err = wsl.ConvertWindowsPathToWslPath(wslPath)
178-
if err != nil {
179-
return fmt.Errorf("error converting path: %s", err)
180-
}
181-
}
182-
183-
devcontainerJSONPath := path.Join(wslPath, ".devcontainer/devcontainer.json")
184-
userName, err := devcontainers.GetDevContainerUserName(devcontainerJSONPath)
185-
if err != nil {
186-
return err
187-
}
188-
189-
dockerArgs := []string{"exec", "-it", "--workdir", mountPath}
190-
if userName != "" {
191-
dockerArgs = append(dockerArgs, "--user", userName)
192-
}
193-
dockerArgs = append(dockerArgs, containerID)
194-
dockerArgs = append(dockerArgs, args...)
195-
196-
dockerCmd := exec.Command("docker", dockerArgs...)
197-
dockerCmd.Stdin = os.Stdin
198-
dockerCmd.Stdout = os.Stdout
199-
200-
err = dockerCmd.Start()
201-
if err != nil {
202-
return fmt.Errorf("Exec: start error: %s", err)
203-
}
204-
err = dockerCmd.Wait()
205-
if err != nil {
206-
return fmt.Errorf("Exec: wait error: %s", err)
207-
}
208-
return nil
128+
return devcontainers.ExecInDevContainer(containerIDOrName, argWorkDir, args)
209129
},
210130
Args: cobra.ArbitraryArgs,
211131
DisableFlagsInUseLine: true,

internal/pkg/devcontainers/dockerutils.go

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,13 @@ import (
44
"bufio"
55
"bytes"
66
"fmt"
7+
"os"
78
"os/exec"
9+
"path"
10+
"path/filepath"
811
"strings"
12+
13+
"github.com/stuartleeks/devcontainer-cli/internal/pkg/wsl"
914
)
1015

1116
// Devcontainer names are a derived property.
@@ -85,3 +90,105 @@ func GetLocalFolderFromDevContainer(containerIDOrName string) (string, error) {
8590

8691
return strings.TrimSpace(string(output)), nil
8792
}
93+
94+
// GetContainerIDForPath returns the ID of the running container that matches the path
95+
func GetContainerIDForPath(devcontainerPath string) (string, error) {
96+
if devcontainerPath == "" {
97+
devcontainerPath = "."
98+
}
99+
absPath, err := filepath.Abs(devcontainerPath)
100+
if err != nil {
101+
return "", fmt.Errorf("Error handling path %q: %s", devcontainerPath, err)
102+
}
103+
104+
windowsPath := absPath
105+
if wsl.IsWsl() {
106+
var err error
107+
windowsPath, err = wsl.ConvertWslPathToWindowsPath(windowsPath)
108+
if err != nil {
109+
return "", err
110+
}
111+
}
112+
113+
devcontainerList, err := ListDevcontainers()
114+
if err != nil {
115+
return "", fmt.Errorf("Error getting container list: %s", err)
116+
}
117+
118+
for _, devcontainer := range devcontainerList {
119+
if devcontainer.LocalFolderPath == windowsPath {
120+
containerID := devcontainer.ContainerID
121+
return containerID, nil
122+
}
123+
}
124+
return "", fmt.Errorf("Could not find running container for path %q", devcontainerPath)
125+
}
126+
127+
func ExecInDevContainer(containerIDOrName string, workDir string, args []string) error {
128+
129+
containerID := ""
130+
devcontainerList, err := ListDevcontainers()
131+
if err != nil {
132+
return err
133+
}
134+
135+
for _, devcontainer := range devcontainerList {
136+
if devcontainer.ContainerName == containerIDOrName ||
137+
devcontainer.DevcontainerName == containerIDOrName ||
138+
devcontainer.ContainerID == containerIDOrName {
139+
containerID = devcontainer.ContainerID
140+
break
141+
}
142+
}
143+
144+
if containerID == "" {
145+
return fmt.Errorf("Failed to find a matching (running) dev container for %q", containerIDOrName)
146+
}
147+
148+
localPath, err := GetLocalFolderFromDevContainer(containerID)
149+
if err != nil {
150+
return err
151+
}
152+
153+
if workDir == "" {
154+
workDir, err = GetWorkspaceMountPath(localPath)
155+
if err != nil {
156+
return err
157+
}
158+
}
159+
160+
wslPath := localPath
161+
if strings.HasPrefix(wslPath, "\\\\wsl$") && wsl.IsWsl() {
162+
wslPath, err = wsl.ConvertWindowsPathToWslPath(wslPath)
163+
if err != nil {
164+
return fmt.Errorf("error converting path: %s", err)
165+
}
166+
}
167+
168+
devcontainerJSONPath := path.Join(wslPath, ".devcontainer/devcontainer.json")
169+
userName, err := GetDevContainerUserName(devcontainerJSONPath)
170+
if err != nil {
171+
return err
172+
}
173+
174+
dockerArgs := []string{"exec", "-it", "--workdir", workDir}
175+
if userName != "" {
176+
dockerArgs = append(dockerArgs, "--user", userName)
177+
}
178+
dockerArgs = append(dockerArgs, containerID)
179+
dockerArgs = append(dockerArgs, args...)
180+
181+
dockerCmd := exec.Command("docker", dockerArgs...)
182+
dockerCmd.Stdin = os.Stdin
183+
dockerCmd.Stdout = os.Stdout
184+
185+
err = dockerCmd.Start()
186+
if err != nil {
187+
return fmt.Errorf("Exec: start error: %s", err)
188+
}
189+
err = dockerCmd.Wait()
190+
if err != nil {
191+
return fmt.Errorf("Exec: wait error: %s", err)
192+
}
193+
return nil
194+
}

0 commit comments

Comments
 (0)