Skip to content

Commit ae5434d

Browse files
authored
[virtenv] Create symlinks for support dirs, move wrappers to a subdir. (#852)
## Summary This creates symlinks for all dirs in profile dir except `bin` (because that has wrappers). Also moved bin dir from `.devbox/virtenv/bin` to `.devbox/virtenv/.wrappers/bin` and all support symlinks are in `.devbox/virtenv/.wrappers`. This ensures we can't have collisions with plugin data which is stored in `.devbox/virtenv/[plugin-name]` This fixes #851 ## How was it tested? ``` devbox shell ls -al .devbox/virtenv ls -al .devbox/virtenv/.wrappers which go ``` Also tested mariadb example
1 parent b9fcb19 commit ae5434d

File tree

5 files changed

+48
-13
lines changed

5 files changed

+48
-13
lines changed

internal/impl/devbox.go

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -573,7 +573,7 @@ func (d *Devbox) computeNixEnv(ctx context.Context) (map[string]string, error) {
573573

574574
// Prepend virtenv bin path first so user can override it if needed. Virtenv
575575
// is where the bin wrappers live
576-
env["PATH"] = JoinPathLists(d.virtenvBinPath(), env["PATH"])
576+
env["PATH"] = JoinPathLists(filepath.Join(d.projectDir, plugin.WrapperBinPath), env["PATH"])
577577

578578
// Include env variables in devbox.json
579579
configEnv := d.configEnvs(env)
@@ -801,10 +801,6 @@ func (d *Devbox) setCommonHelperEnvVars(env map[string]string) {
801801
env["LIBRARY_PATH"] = filepath.Join(d.projectDir, nix.ProfilePath, "lib") + ":" + env["LIBRARY_PATH"]
802802
}
803803

804-
func (d *Devbox) virtenvBinPath() string {
805-
return filepath.Join(d.projectDir, plugin.VirtenvBinPath)
806-
}
807-
808804
// nix bins returns the paths to all the nix binaries that are installed by
809805
// the flake. If there are conflicts, it returns the first one it finds of a
810806
// give name. This matches how nix flakes behaves if there are conflicts in

internal/plugin/plugin.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,12 @@ import (
1919
const (
2020
devboxDirName = "devbox.d"
2121
devboxHiddenDirName = ".devbox"
22-
VirtenvBinPath = ".devbox/virtenv/bin"
2322
VirtenvPath = ".devbox/virtenv"
2423
)
2524

25+
var WrapperPath = filepath.Join(VirtenvPath, ".wrappers")
26+
var WrapperBinPath = filepath.Join(WrapperPath, "bin")
27+
2628
type config struct {
2729
Name string `json:"name"`
2830
Version string `json:"version"`

internal/plugin/rm.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ func Remove(projectDir string, pkgs []string) error {
1717
}
1818

1919
func RemoveInvalidSymlinks(projectDir string) error {
20-
binPath := filepath.Join(projectDir, VirtenvBinPath)
20+
binPath := filepath.Join(projectDir, VirtenvPath, "bin")
2121
if _, err := os.Stat(binPath); errors.Is(err, os.ErrNotExist) {
2222
return nil
2323
}

internal/services/services.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ func toggleServices(
5353

5454
serviceBinPath := filepath.Join(
5555
projectDir,
56-
plugin.VirtenvBinPath,
56+
plugin.WrapperBinPath,
5757
fmt.Sprintf("%s-service-%s", name, lo.Ternary(action == startService, "start", "stop")),
5858
)
5959
cmd := exec.Command(serviceBinPath)

internal/wrapnix/wrapper.go

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"text/template"
1010

1111
"github.com/pkg/errors"
12+
"go.jetpack.io/devbox/internal/nix"
1213
"go.jetpack.io/devbox/internal/plugin"
1314
)
1415

@@ -35,8 +36,11 @@ func CreateWrappers(ctx context.Context, devbox devboxer) error {
3536
return err
3637
}
3738

38-
destPath := virtenvBinPath(devbox.ProjectDir())
39-
_ = os.RemoveAll(destPath)
39+
// Remove all old wrappers
40+
_ = os.RemoveAll(filepath.Join(devbox.ProjectDir(), plugin.WrapperPath))
41+
42+
// Recreate the bin wrapper directory
43+
destPath := filepath.Join(devbox.ProjectDir(), plugin.WrapperBinPath)
4044
_ = os.MkdirAll(destPath, 0755)
4145

4246
for _, service := range services {
@@ -73,7 +77,7 @@ func CreateWrappers(ctx context.Context, devbox devboxer) error {
7377
}
7478
}
7579

76-
return nil
80+
return createSymlinksForSupportDirs(devbox.ProjectDir())
7781
}
7882

7983
type createWrapperArgs struct {
@@ -94,6 +98,39 @@ func createWrapper(args *createWrapperArgs) error {
9498

9599
}
96100

97-
func virtenvBinPath(projectDir string) string {
98-
return filepath.Join(projectDir, plugin.VirtenvBinPath)
101+
// createSymlinksForSupportDirs creates symlinks for the support dirs
102+
// (etc, lib, share) in the virtenv. Some tools (like mariadb) expect
103+
// these to be in a dir relative to the bin.
104+
//
105+
// TODO: this is not perfect. using the profile path will not take into account
106+
// any special stuff we do in flake.nix. We should use the nix store directly,
107+
// but that is a bit more complicated. Nix merges any support directories
108+
// recursively, so we need to do the same.
109+
// e.g. if go_1_19 and go_1_20 are installed, .devbox/nix/profile/default/share/go/api
110+
// will contain the union of both. We need to do the same.
111+
func createSymlinksForSupportDirs(projectDir string) error {
112+
profilePath := filepath.Join(projectDir, nix.ProfilePath)
113+
if _, err := os.Stat(profilePath); errors.Is(err, os.ErrNotExist) {
114+
return nil
115+
}
116+
117+
supportDirs, err := os.ReadDir(profilePath)
118+
if err != nil {
119+
return err
120+
}
121+
122+
for _, dir := range supportDirs {
123+
// bin has wrappers and is not a symlink
124+
if dir.Name() == "bin" {
125+
continue
126+
}
127+
128+
oldname := filepath.Join(projectDir, nix.ProfilePath, dir.Name())
129+
newname := filepath.Join(projectDir, plugin.WrapperPath, dir.Name())
130+
131+
if err := os.Symlink(oldname, newname); err != nil {
132+
return err
133+
}
134+
}
135+
return nil
99136
}

0 commit comments

Comments
 (0)