Skip to content

Commit 1770f59

Browse files
committed
Add git repo handling to default workspace path
1 parent 81c8aa5 commit 1770f59

File tree

2 files changed

+58
-2
lines changed

2 files changed

+58
-2
lines changed

internal/pkg/devcontainers/remoteuri.go

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"regexp"
99
"strings"
1010

11+
"github.com/stuartleeks/devcontainer-cli/internal/pkg/git"
1112
"github.com/stuartleeks/devcontainer-cli/internal/pkg/wsl"
1213
)
1314

@@ -72,8 +73,11 @@ func GetWorkspaceMountPath(folderPath string) (string, error) {
7273
}
7374

7475
// No `workspaceFolder` found in devcontainer.json - use default
75-
_, folderName := filepath.Split(folderPath)
76-
return fmt.Sprintf("/workspaces/%s", folderName), nil
76+
devcontainerPath, err := getDefaultWorkspaceFolderForPath(folderPath)
77+
if err != nil {
78+
return "", fmt.Errorf("Error getting default workspace path: %s", err)
79+
}
80+
return fmt.Sprintf("/workspaces/%s", devcontainerPath), nil
7781
}
7882

7983
// TODO: add tests (and implementation) to handle JSON parsing with comments
@@ -92,3 +96,26 @@ func getWorkspaceMountPathFromDevcontainerDefinition(definition []byte) (string,
9296
}
9397
return "", nil
9498
}
99+
100+
func getDefaultWorkspaceFolderForPath(path string) (string, error) {
101+
102+
// get the git repo-root
103+
rootPath, err := git.GetTopLevelPath(path)
104+
if err != nil {
105+
return "", err
106+
}
107+
if rootPath == "" {
108+
// not a git repo, default to path
109+
rootPath = path
110+
}
111+
112+
// get parent to root
113+
rootParent, _ := filepath.Split(rootPath)
114+
115+
// return path relative to rootParent
116+
relativePath, err := filepath.Rel(rootParent, path)
117+
if err != nil {
118+
return "", err
119+
}
120+
return relativePath, nil
121+
}

internal/pkg/git/git.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package git
2+
3+
import (
4+
"fmt"
5+
"os/exec"
6+
"strings"
7+
"syscall"
8+
)
9+
10+
// GetTopLevelPath returns the top-level folder for the git-repo that contains path, or empty string if not a repo
11+
func GetTopLevelPath(path string) (string, error) {
12+
cmd := exec.Command("git", "rev-parse", "--show-toplevel")
13+
14+
buf, err := cmd.Output()
15+
if err != nil {
16+
if exiterr, ok := err.(*exec.ExitError); ok {
17+
// The program has exited with an exit code != 0
18+
if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
19+
if status.ExitStatus() == 128 {
20+
// exit code 128 indictates not a git repo
21+
return "", nil
22+
}
23+
}
24+
return "", fmt.Errorf("Error git rev-parse --show-toplevel: %s", err)
25+
}
26+
return "", fmt.Errorf("Error git rev-parse --show-toplevel: %s", err)
27+
}
28+
return strings.TrimSpace(string(buf)), nil
29+
}

0 commit comments

Comments
 (0)