fix: shorten dev browser launch socket path
- commit
- ded7322eb9d6be4bd772d3e53c66bfc7e58ff641
- author
- brice · · 2026-06-26 04:29 UTC
- parent
- 8e835cc
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
3 files · +47 -3
M internal/bootstrap/runtime_profile_test.go +5 -1
| @@ -2,6 +2,7 @@ package bootstrap | |||
| 2 | 2 | ||
| 3 | 3 | import ( | |
| 4 | 4 | "path/filepath" | |
| 5 | + | "strings" | |
| 5 | 6 | "testing" | |
| 6 | 7 | ||
| 7 | 8 | "github.com/bnema/dumber/internal/infrastructure/config" | |
| @@ -52,12 +53,15 @@ func TestResolveRuntimeProfile_DevUsesEngineSpecificNamespaces(t *testing.T) { | |||
| 52 | 53 | wd := t.TempDir() | |
| 53 | 54 | t.Chdir(wd) | |
| 54 | 55 | ||
| 56 | + | runtimeDir := t.TempDir() | |
| 55 | 57 | t.Setenv("ENV", "dev") | |
| 58 | + | t.Setenv("XDG_RUNTIME_DIR", runtimeDir) | |
| 56 | 59 | profile, err := ResolveRuntimeProfile(cfg) | |
| 57 | 60 | require.NoError(t, err) | |
| 58 | 61 | require.Equal(t, filepath.Join(wd, ".dev", "dumber", "state"), profile.Shared.StateDir) | |
| 59 | 62 | require.Equal(t, filepath.Join(wd, ".dev", "dumber", "engines", "cef", "data"), profile.CEFUserDataDir()) | |
| 60 | - | require.Equal(t, filepath.Join(wd, ".dev", "dumber", "runtime", "cef", "browser-launch.sock"), profile.IPC.BrowserLaunchSocket) | |
| 63 | + | require.True(t, strings.HasPrefix(profile.IPC.BrowserLaunchSocket, filepath.Join(runtimeDir, "dumber", "dev-"))) | |
| 64 | + | require.Contains(t, profile.IPC.BrowserLaunchSocket, filepath.Join("cef", "browser-launch.sock")) | |
| 61 | 65 | } | |
| 62 | 66 | ||
| 63 | 67 | func TestResolveXDGRuntimeDir_UsesSharedRuntimeRootInDev(t *testing.T) { | |
| @@ -2,6 +2,7 @@ package bootstrap | |||||
| 2 | 2 | ||||
| 3 | import ( | 3 | import ( | ||
| 4 | "path/filepath" | 4 | "path/filepath" | ||
| 5 | + | "strings" | |||
| 5 | "testing" | 6 | "testing" | ||
| 6 | 7 | ||||
| 7 | "github.com/bnema/dumber/internal/infrastructure/config" | 8 | "github.com/bnema/dumber/internal/infrastructure/config" | ||
| @@ -52,12 +53,15 @@ func TestResolveRuntimeProfile_DevUsesEngineSpecificNamespaces(t *testing.T) { | |||||
| 52 | wd := t.TempDir() | 53 | wd := t.TempDir() | ||
| 53 | t.Chdir(wd) | 54 | t.Chdir(wd) | ||
| 54 | 55 | ||||
| 56 | + | runtimeDir := t.TempDir() | |||
| 55 | t.Setenv("ENV", "dev") | 57 | t.Setenv("ENV", "dev") | ||
| 58 | + | t.Setenv("XDG_RUNTIME_DIR", runtimeDir) | |||
| 56 | profile, err := ResolveRuntimeProfile(cfg) | 59 | profile, err := ResolveRuntimeProfile(cfg) | ||
| 57 | require.NoError(t, err) | 60 | require.NoError(t, err) | ||
| 58 | require.Equal(t, filepath.Join(wd, ".dev", "dumber", "state"), profile.Shared.StateDir) | 61 | require.Equal(t, filepath.Join(wd, ".dev", "dumber", "state"), profile.Shared.StateDir) | ||
| 59 | require.Equal(t, filepath.Join(wd, ".dev", "dumber", "engines", "cef", "data"), profile.CEFUserDataDir()) | 62 | require.Equal(t, filepath.Join(wd, ".dev", "dumber", "engines", "cef", "data"), profile.CEFUserDataDir()) | ||
| 60 | - | require.Equal(t, filepath.Join(wd, ".dev", "dumber", "runtime", "cef", "browser-launch.sock"), profile.IPC.BrowserLaunchSocket) | 63 | + | require.True(t, strings.HasPrefix(profile.IPC.BrowserLaunchSocket, filepath.Join(runtimeDir, "dumber", "dev-"))) |
| 64 | + | require.Contains(t, profile.IPC.BrowserLaunchSocket, filepath.Join("cef", "browser-launch.sock")) | |||
| 61 | } | 65 | } | ||
| 62 | 66 | ||||
| 63 | func TestResolveXDGRuntimeDir_UsesSharedRuntimeRootInDev(t *testing.T) { | 67 | func TestResolveXDGRuntimeDir_UsesSharedRuntimeRootInDev(t *testing.T) { | ||
M internal/infrastructure/runtimeprofile/profile.go +15 -1
| @@ -1,6 +1,8 @@ | |||
| 1 | 1 | package runtimeprofile | |
| 2 | 2 | ||
| 3 | 3 | import ( | |
| 4 | + | "crypto/sha256" | |
| 5 | + | "encoding/hex" | |
| 4 | 6 | "fmt" | |
| 5 | 7 | "path/filepath" | |
| 6 | 8 | "strings" | |
| @@ -82,7 +84,7 @@ func Resolve(input ResolveInput) (Profile, error) { | |||
| 82 | 84 | } | |
| 83 | 85 | root := filepath.Join(cwd, ".dev", "dumber") | |
| 84 | 86 | engineRoot := filepath.Join(root, "engines", engine) | |
| 85 | - | ipcRoot := filepath.Join(root, "runtime", engine) | |
| 87 | + | ipcRoot := devIPCRoot(input.Env, root, engine) | |
| 86 | 88 | return Profile{ | |
| 87 | 89 | Mode: ModeDev, | |
| 88 | 90 | Engine: engine, | |
| @@ -133,6 +135,18 @@ func Resolve(input ResolveInput) (Profile, error) { | |||
| 133 | 135 | }, nil | |
| 134 | 136 | } | |
| 135 | 137 | ||
| 138 | + | func devIPCRoot(env func(string) string, root, engine string) string { | |
| 139 | + | base := envValue(env, "XDG_RUNTIME_DIR") | |
| 140 | + | if base == "" { | |
| 141 | + | base = envValue(env, "TMPDIR") | |
| 142 | + | } | |
| 143 | + | if base == "" { | |
| 144 | + | base = "/tmp" | |
| 145 | + | } | |
| 146 | + | sum := sha256.Sum256([]byte(root)) | |
| 147 | + | return filepath.Join(base, "dumber", "dev-"+hex.EncodeToString(sum[:])[:12], engine) | |
| 148 | + | } | |
| 149 | + | ||
| 136 | 150 | // normalizeEngine trims and lowercases the runtime engine name. | |
| 137 | 151 | // Supported engines are "webkit" and "cef"; any other value falls back to | |
| 138 | 152 | // the default "webkit" runtime namespace. | |
| @@ -1,6 +1,8 @@ | |||||
| 1 | package runtimeprofile | 1 | package runtimeprofile | ||
| 2 | 2 | ||||
| 3 | import ( | 3 | import ( | ||
| 4 | + | "crypto/sha256" | |||
| 5 | + | "encoding/hex" | |||
| 4 | "fmt" | 6 | "fmt" | ||
| 5 | "path/filepath" | 7 | "path/filepath" | ||
| 6 | "strings" | 8 | "strings" | ||
| @@ -82,7 +84,7 @@ func Resolve(input ResolveInput) (Profile, error) { | |||||
| 82 | } | 84 | } | ||
| 83 | root := filepath.Join(cwd, ".dev", "dumber") | 85 | root := filepath.Join(cwd, ".dev", "dumber") | ||
| 84 | engineRoot := filepath.Join(root, "engines", engine) | 86 | engineRoot := filepath.Join(root, "engines", engine) | ||
| 85 | - | ipcRoot := filepath.Join(root, "runtime", engine) | 87 | + | ipcRoot := devIPCRoot(input.Env, root, engine) |
| 86 | return Profile{ | 88 | return Profile{ | ||
| 87 | Mode: ModeDev, | 89 | Mode: ModeDev, | ||
| 88 | Engine: engine, | 90 | Engine: engine, | ||
| @@ -133,6 +135,18 @@ func Resolve(input ResolveInput) (Profile, error) { | |||||
| 133 | }, nil | 135 | }, nil | ||
| 134 | } | 136 | } | ||
| 135 | 137 | ||||
| 138 | + | func devIPCRoot(env func(string) string, root, engine string) string { | |||
| 139 | + | base := envValue(env, "XDG_RUNTIME_DIR") | |||
| 140 | + | if base == "" { | |||
| 141 | + | base = envValue(env, "TMPDIR") | |||
| 142 | + | } | |||
| 143 | + | if base == "" { | |||
| 144 | + | base = "/tmp" | |||
| 145 | + | } | |||
| 146 | + | sum := sha256.Sum256([]byte(root)) | |||
| 147 | + | return filepath.Join(base, "dumber", "dev-"+hex.EncodeToString(sum[:])[:12], engine) | |||
| 148 | + | } | |||
| 149 | + | ||||
| 136 | // normalizeEngine trims and lowercases the runtime engine name. | 150 | // normalizeEngine trims and lowercases the runtime engine name. | ||
| 137 | // Supported engines are "webkit" and "cef"; any other value falls back to | 151 | // Supported engines are "webkit" and "cef"; any other value falls back to | ||
| 138 | // the default "webkit" runtime namespace. | 152 | // the default "webkit" runtime namespace. | ||
M internal/infrastructure/runtimeprofile/profile_test.go +27 -1
| @@ -2,6 +2,7 @@ package runtimeprofile | |||
| 2 | 2 | ||
| 3 | 3 | import ( | |
| 4 | 4 | "errors" | |
| 5 | + | "strings" | |
| 5 | 6 | "testing" | |
| 6 | 7 | ||
| 7 | 8 | "github.com/stretchr/testify/require" | |
| @@ -47,7 +48,32 @@ func TestResolve_DevCEF_SeparatesSharedEngineAndIPC(t *testing.T) { | |||
| 47 | 48 | require.Equal(t, "/repo/.dev/dumber/config", profile.Shared.ConfigDir) | |
| 48 | 49 | require.Equal(t, "/repo/.dev/dumber/data", profile.Shared.DataDir) | |
| 49 | 50 | require.Equal(t, "/repo/.dev/dumber/engines/cef/data", profile.CEFUserDataDir()) | |
| 50 | - | require.Equal(t, "/repo/.dev/dumber/runtime/cef/browser-launch.sock", profile.IPC.BrowserLaunchSocket) | |
| 51 | + | require.True(t, strings.HasPrefix(profile.IPC.BrowserLaunchSocket, "/tmp/dumber/dev-")) | |
| 52 | + | require.Contains(t, profile.IPC.BrowserLaunchSocket, "/cef/browser-launch.sock") | |
| 53 | + | } | |
| 54 | + | ||
| 55 | + | func TestResolve_DevIPCPathStaysShortForLongWorktrees(t *testing.T) { | |
| 56 | + | longWorktree := "/tmp/" + strings.Repeat("long-worktree-name-", 5) + "project" | |
| 57 | + | ||
| 58 | + | profile, err := Resolve(ResolveInput{ | |
| 59 | + | Env: func(key string) string { | |
| 60 | + | switch key { | |
| 61 | + | case "ENV": | |
| 62 | + | return "dev" | |
| 63 | + | case "XDG_RUNTIME_DIR": | |
| 64 | + | return "/run/user/1000" | |
| 65 | + | default: | |
| 66 | + | return "" | |
| 67 | + | } | |
| 68 | + | }, | |
| 69 | + | Engine: "cef", | |
| 70 | + | CWD: func() (string, error) { return longWorktree, nil }, | |
| 71 | + | }) | |
| 72 | + | ||
| 73 | + | require.NoError(t, err) | |
| 74 | + | require.Less(t, len(profile.IPC.BrowserLaunchSocket), 108) | |
| 75 | + | require.True(t, strings.HasPrefix(profile.IPC.BrowserLaunchSocket, "/run/user/1000/dumber/dev-")) | |
| 76 | + | require.Contains(t, profile.IPC.BrowserLaunchSocket, "/cef/browser-launch.sock") | |
| 51 | 77 | } | |
| 52 | 78 | ||
| 53 | 79 | func TestResolve_DevWebKitAndCEF_HaveDifferentTechnicalNamespaces(t *testing.T) { | |
| @@ -2,6 +2,7 @@ package runtimeprofile | |||||
| 2 | 2 | ||||
| 3 | import ( | 3 | import ( | ||
| 4 | "errors" | 4 | "errors" | ||
| 5 | + | "strings" | |||
| 5 | "testing" | 6 | "testing" | ||
| 6 | 7 | ||||
| 7 | "github.com/stretchr/testify/require" | 8 | "github.com/stretchr/testify/require" | ||
| @@ -47,7 +48,32 @@ func TestResolve_DevCEF_SeparatesSharedEngineAndIPC(t *testing.T) { | |||||
| 47 | require.Equal(t, "/repo/.dev/dumber/config", profile.Shared.ConfigDir) | 48 | require.Equal(t, "/repo/.dev/dumber/config", profile.Shared.ConfigDir) | ||
| 48 | require.Equal(t, "/repo/.dev/dumber/data", profile.Shared.DataDir) | 49 | require.Equal(t, "/repo/.dev/dumber/data", profile.Shared.DataDir) | ||
| 49 | require.Equal(t, "/repo/.dev/dumber/engines/cef/data", profile.CEFUserDataDir()) | 50 | require.Equal(t, "/repo/.dev/dumber/engines/cef/data", profile.CEFUserDataDir()) | ||
| 50 | - | require.Equal(t, "/repo/.dev/dumber/runtime/cef/browser-launch.sock", profile.IPC.BrowserLaunchSocket) | 51 | + | require.True(t, strings.HasPrefix(profile.IPC.BrowserLaunchSocket, "/tmp/dumber/dev-")) |
| 52 | + | require.Contains(t, profile.IPC.BrowserLaunchSocket, "/cef/browser-launch.sock") | |||
| 53 | + | } | |||
| 54 | + | ||||
| 55 | + | func TestResolve_DevIPCPathStaysShortForLongWorktrees(t *testing.T) { | |||
| 56 | + | longWorktree := "/tmp/" + strings.Repeat("long-worktree-name-", 5) + "project" | |||
| 57 | + | ||||
| 58 | + | profile, err := Resolve(ResolveInput{ | |||
| 59 | + | Env: func(key string) string { | |||
| 60 | + | switch key { | |||
| 61 | + | case "ENV": | |||
| 62 | + | return "dev" | |||
| 63 | + | case "XDG_RUNTIME_DIR": | |||
| 64 | + | return "/run/user/1000" | |||
| 65 | + | default: | |||
| 66 | + | return "" | |||
| 67 | + | } | |||
| 68 | + | }, | |||
| 69 | + | Engine: "cef", | |||
| 70 | + | CWD: func() (string, error) { return longWorktree, nil }, | |||
| 71 | + | }) | |||
| 72 | + | ||||
| 73 | + | require.NoError(t, err) | |||
| 74 | + | require.Less(t, len(profile.IPC.BrowserLaunchSocket), 108) | |||
| 75 | + | require.True(t, strings.HasPrefix(profile.IPC.BrowserLaunchSocket, "/run/user/1000/dumber/dev-")) | |||
| 76 | + | require.Contains(t, profile.IPC.BrowserLaunchSocket, "/cef/browser-launch.sock") | |||
| 51 | } | 77 | } | ||
| 52 | 78 | ||||
| 53 | func TestResolve_DevWebKitAndCEF_HaveDifferentTechnicalNamespaces(t *testing.T) { | 79 | func TestResolve_DevWebKitAndCEF_HaveDifferentTechnicalNamespaces(t *testing.T) { | ||