|
9 | 9 | "os/exec" |
10 | 10 | "path" |
11 | 11 | "path/filepath" |
| 12 | + "sort" |
12 | 13 | "strings" |
13 | 14 |
|
14 | 15 | "github.com/stuartleeks/devcontainer-cli/internal/pkg/terminal" |
@@ -68,10 +69,17 @@ func ListDevcontainers() ([]DevcontainerInfo, error) { |
68 | 69 | name = name[index+1:] |
69 | 70 | } |
70 | 71 | } |
| 72 | + localPath := parts[listPartLocalFolder] |
| 73 | + if strings.HasPrefix(localPath, "\\\\wsl$") && wsl.IsWsl() { |
| 74 | + localPath, err = wsl.ConvertWindowsPathToWslPath(localPath) |
| 75 | + if err != nil { |
| 76 | + return []DevcontainerInfo{}, fmt.Errorf("error converting path: %s", err) |
| 77 | + } |
| 78 | + } |
71 | 79 | devcontainer := DevcontainerInfo{ |
72 | 80 | ContainerID: parts[listPartID], |
73 | 81 | ContainerName: parts[listPartContainerName], |
74 | | - LocalFolderPath: parts[listPartLocalFolder], |
| 82 | + LocalFolderPath: localPath, |
75 | 83 | DevcontainerName: name, |
76 | 84 | } |
77 | 85 | devcontainers = append(devcontainers, devcontainer) |
@@ -129,37 +137,41 @@ func GetSourceMountFolderFromDevContainer(containerIDOrName string) (DockerMount |
129 | 137 | return mount, nil |
130 | 138 | } |
131 | 139 |
|
132 | | -// GetContainerIDForPath returns the ID of the running container that matches the path |
133 | | -func GetContainerIDForPath(devcontainerPath string) (string, error) { |
| 140 | +type byLocalPathLength []DevcontainerInfo |
| 141 | + |
| 142 | +func (s byLocalPathLength) Len() int { |
| 143 | + return len(s) |
| 144 | +} |
| 145 | +func (s byLocalPathLength) Swap(i, j int) { |
| 146 | + s[i], s[j] = s[j], s[i] |
| 147 | +} |
| 148 | +func (s byLocalPathLength) Less(i, j int) bool { |
| 149 | + return len(s[i].LocalFolderPath) < len(s[j].LocalFolderPath) |
| 150 | +} |
| 151 | + |
| 152 | +// GetClosestPathMatchForPath returns the dev container with the closes match to the specified path |
| 153 | +func GetClosestPathMatchForPath(devContainers []DevcontainerInfo, devcontainerPath string) (DevcontainerInfo, error) { |
134 | 154 | if devcontainerPath == "" { |
135 | 155 | devcontainerPath = "." |
136 | 156 | } |
137 | 157 | absPath, err := filepath.Abs(devcontainerPath) |
138 | 158 | if err != nil { |
139 | | - return "", fmt.Errorf("Error handling path %q: %s", devcontainerPath, err) |
| 159 | + return DevcontainerInfo{}, fmt.Errorf("Error handling path %q: %s", devcontainerPath, err) |
140 | 160 | } |
141 | 161 |
|
142 | | - windowsPath := absPath |
143 | | - if wsl.IsWsl() { |
144 | | - var err error |
145 | | - windowsPath, err = wsl.ConvertWslPathToWindowsPath(windowsPath) |
146 | | - if err != nil { |
147 | | - return "", err |
| 162 | + matchingPaths := byLocalPathLength{} |
| 163 | + for _, devcontainer := range devContainers { |
| 164 | + // Treat as match if the specified path is within the devcontainer path |
| 165 | + if strings.HasPrefix(absPath, devcontainer.LocalFolderPath) { |
| 166 | + matchingPaths = append(matchingPaths, devcontainer) |
148 | 167 | } |
149 | 168 | } |
150 | | - |
151 | | - devcontainerList, err := ListDevcontainers() |
152 | | - if err != nil { |
153 | | - return "", fmt.Errorf("Error getting container list: %s", err) |
154 | | - } |
155 | | - |
156 | | - for _, devcontainer := range devcontainerList { |
157 | | - if devcontainer.LocalFolderPath == windowsPath { |
158 | | - containerID := devcontainer.ContainerID |
159 | | - return containerID, nil |
160 | | - } |
| 169 | + if len(matchingPaths) == 0 { |
| 170 | + return DevcontainerInfo{}, fmt.Errorf("Could not find running container for path %q", devcontainerPath) |
161 | 171 | } |
162 | | - return "", fmt.Errorf("Could not find running container for path %q", devcontainerPath) |
| 172 | + // return longest prefix match |
| 173 | + sort.Sort(matchingPaths) |
| 174 | + return matchingPaths[len(matchingPaths)-1], nil |
163 | 175 | } |
164 | 176 |
|
165 | 177 | func ExecInDevContainer(containerID string, workDir string, args []string) error { |
|
0 commit comments