| author | |
| committer | |
| log | edc503a7a8ea5284a2711981c1a10a6b9999f5e4 |
| tree | 1951be148923aa6e03f5ed88d0bbff3e266ab53a |
| parent | 323dc321a2f8bec2160e6e35f94d07c5bb949084 |
| signature | Signed by PGP key B5690EEEBB952194 |
2 files changed, 59 insertions(+), 0 deletions(-)
apps/server/src/os-jank.test.ts created+40| ... | ... | @@ -0,0 +1,40 @@ |
| 1 | import * as NodeOS from "node:os"; | |
| 2 | import { assert, it } from "vite-plus/test"; | |
| 3 | ||
| 4 | import { hydratePosixHome } from "./os-jank.ts"; | |
| 5 | ||
| 6 | it("hydrates HOME for minimal service environments from the user account", () => { | |
| 7 | const env: NodeJS.ProcessEnv = {}; | |
| 8 | ||
| 9 | hydratePosixHome(env); | |
| 10 | ||
| 11 | assert.equal(env.HOME, NodeOS.userInfo().homedir); | |
| 12 | }); | |
| 13 | ||
| 14 | it("hydrates HOME independently of a blank process HOME", () => { | |
| 15 | const originalHome = process.env.HOME; | |
| 16 | const env: NodeJS.ProcessEnv = { HOME: " " }; | |
| 17 | ||
| 18 | try { | |
| 19 | process.env.HOME = " "; | |
| 20 | hydratePosixHome(env); | |
| 21 | } finally { | |
| 22 | if (originalHome === undefined) { | |
| 23 | delete process.env.HOME; | |
| 24 | } else { | |
| 25 | process.env.HOME = originalHome; | |
| 26 | } | |
| 27 | } | |
| 28 | ||
| 29 | assert.equal(env.HOME, NodeOS.userInfo().homedir); | |
| 30 | }); | |
| 31 | ||
| 32 | it("preserves an explicitly configured HOME", () => { | |
| 33 | const env: NodeJS.ProcessEnv = { HOME: "/custom/home" }; | |
| 34 | ||
| 35 | hydratePosixHome(env, () => { | |
| 36 | throw new Error("HOME lookup should not run"); | |
| 37 | }); | |
| 38 | ||
| 39 | assert.equal(env.HOME, "/custom/home"); | |
| 40 | }); |
apps/server/src/os-jank.ts+19| ... | ... | @@ -36,6 +36,18 @@ function hydratePosixPath(env: NodeJS.ProcessEnv, platform: NodeJS.Platform): vo |
| 36 | 36 | } |
| 37 | 37 | } |
| 38 | 38 | |
| 39 | export function hydratePosixHome( | |
| 40 | env: NodeJS.ProcessEnv, | |
| 41 | resolveHomeDir = () => NodeOS.userInfo().homedir, | |
| 42 | ): void { | |
| 43 | if ((env.HOME?.trim() ?? "").length > 0) return; | |
| 44 | ||
| 45 | const homeDir = resolveHomeDir(); | |
| 46 | if (homeDir.length > 0) { | |
| 47 | env.HOME = homeDir; | |
| 48 | } | |
| 49 | } | |
| 50 | ||
| 39 | 51 | export const fixPath = Effect.fn("fixPath")(function* (): Effect.fn.Return< |
| 40 | 52 | void, |
| 41 | 53 | never, |
| ... | ... | @@ -63,6 +75,13 @@ export const fixPath = Effect.fn("fixPath")(function* (): Effect.fn.Return< |
| 63 | 75 | |
| 64 | 76 | if (platform !== "darwin" && platform !== "linux") return; |
| 65 | 77 | |
| 78 | yield* Effect.sync(() => hydratePosixHome(env)).pipe( | |
| 79 | Effect.catchDefect((defect) => | |
| 80 | Effect.sync(() => { | |
| 81 | logPathHydrationWarning("Failed to hydrate HOME from the user account.", defect); | |
| 82 | }), | |
| 83 | ), | |
| 84 | ); | |
| 66 | 85 | yield* Effect.sync(() => hydratePosixPath(env, platform)).pipe( |
| 67 | 86 | Effect.catchDefect((defect) => |
| 68 | 87 | Effect.sync(() => { |