Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 78 additions & 1 deletion apps/server/src/environment/ServerEnvironmentLabel.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import * as PlatformError from "effect/PlatformError";
import * as References from "effect/References";
import * as Schema from "effect/Schema";
import * as ChildProcessSpawner from "effect/unstable/process/ChildProcessSpawner";
import { HostProcessHostname, HostProcessPlatform } from "@t3tools/shared/hostProcess";
import { HostProcessEnvironment, HostProcessHostname, HostProcessPlatform } from "@t3tools/shared/hostProcess";
import { vi } from "vite-plus/test";

import * as ProcessRunner from "../processRunner.ts";
Expand Down Expand Up @@ -49,11 +49,13 @@ const withHostPlatform = <ROut, E, RIn>(
layer: Layer.Layer<ROut, E, RIn>,
platform: NodeJS.Platform,
hostname: string,
env: NodeJS.ProcessEnv = {},
) =>
Layer.mergeAll(
layer,
Layer.succeed(HostProcessPlatform, platform),
Layer.succeed(HostProcessHostname, hostname),
Layer.succeed(HostProcessEnvironment, env),
);

afterEach(() => {
Expand Down Expand Up @@ -282,4 +284,79 @@ describe("resolveServerEnvironmentLabel", () => {
expect(result).toBe("t3code");
}),
);
it.effect("appends WSL distro name when WSL_DISTRO_NAME is present", () =>
Effect.gen(function* () {
runMock.mockReturnValueOnce(
Effect.succeed({
stdout: "",
stderr: "",
code: ChildProcessSpawner.ExitCode(1),
timedOut: false,
stdoutTruncated: false,
stderrTruncated: false,
stdoutInvalidUtf8: false,
stderrInvalidUtf8: false,
}),
);

const WslLayer = Layer.merge(
ProcessRunnerTest,
FileSystem.layerNoop({
exists: (path) => Effect.succeed(path === "/proc/sys/kernel/osrelease"),
readFileString: (path) =>
path === "/proc/sys/kernel/osrelease"
? Effect.succeed("5.15.90.1-microsoft-standard-WSL2")
: Effect.succeed(""),
}),
);

const result = yield* ServerEnvironmentLabel.resolveServerEnvironmentLabel({
cwdBaseName: "t3code",
}).pipe(
Effect.provide(
withHostPlatform(WslLayer, "linux", "WINDOWS-HOST", { WSL_DISTRO_NAME: "Ubuntu-22.04" })
)
);

expect(result).toBe("WINDOWS-HOST (WSL: Ubuntu-22.04)");
}),
);

it.effect("appends generic WSL label when WSL_DISTRO_NAME is absent", () =>
Effect.gen(function* () {
runMock.mockReturnValueOnce(
Effect.succeed({
stdout: "",
stderr: "",
code: ChildProcessSpawner.ExitCode(1),
timedOut: false,
stdoutTruncated: false,
stderrTruncated: false,
stdoutInvalidUtf8: false,
stderrInvalidUtf8: false,
}),
);

const WslLayer = Layer.merge(
ProcessRunnerTest,
FileSystem.layerNoop({
exists: (path) => Effect.succeed(path === "/proc/sys/kernel/osrelease"),
readFileString: (path) =>
path === "/proc/sys/kernel/osrelease"
? Effect.succeed("5.15.90.1-microsoft-standard-WSL2")
: Effect.succeed(""),
}),
);

const result = yield* ServerEnvironmentLabel.resolveServerEnvironmentLabel({
cwdBaseName: "t3code",
}).pipe(
Effect.provide(
withHostPlatform(WslLayer, "linux", "WINDOWS-HOST", {})
)
);

expect(result).toBe("WINDOWS-HOST (WSL)");
}),
);
Comment thread
cursor[bot] marked this conversation as resolved.
});
60 changes: 59 additions & 1 deletion apps/server/src/environment/ServerEnvironmentLabel.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { HostProcessHostname, HostProcessPlatform } from "@t3tools/shared/hostProcess";
import { HostProcessEnvironment, HostProcessHostname, HostProcessPlatform } from "@t3tools/shared/hostProcess";
import * as Effect from "effect/Effect";
import * as FileSystem from "effect/FileSystem";
import * as Option from "effect/Option";
Expand Down Expand Up @@ -179,6 +179,55 @@ const resolveFriendlyHostLabel = Effect.fn("resolveFriendlyHostLabel")(function*
return null;
});

const isWslEnvironment = Effect.fn("isWslEnvironment")(function* () {
const platform = yield* HostProcessPlatform;
if (platform !== "linux") {
return false;
}

const fileSystem = yield* FileSystem.FileSystem;
const osReleasePath = "/proc/sys/kernel/osrelease";

const content = yield* fileSystem.exists(osReleasePath).pipe(
Effect.mapError(
(cause) =>
new ServerEnvironmentLabelFileError({
operation: "inspect",
path: osReleasePath,
cause,
}),
),
Effect.flatMap((exists) =>
exists
? fileSystem.readFileString(osReleasePath).pipe(
Effect.mapError(
(cause) =>
new ServerEnvironmentLabelFileError({
operation: "read",
path: osReleasePath,
cause,
}),
),
)
: Effect.succeed("")
),
Effect.catchTags({
ServerEnvironmentLabelFileError: (error) =>
Effect.logDebug(error.message).pipe(
Effect.annotateLogs({
operation: error.operation,
path: error.path,
cause: error,
}),
Effect.as(""),
),
}),
);
Comment thread
macroscopeapp[bot] marked this conversation as resolved.

const lowerContent = content.toLowerCase();
return lowerContent.includes("microsoft") || lowerContent.includes("wsl");
});

export const resolveServerEnvironmentLabel = Effect.fn("resolveServerEnvironmentLabel")(function* (
input: ResolveServerEnvironmentLabelInput,
) {
Expand All @@ -189,6 +238,15 @@ export const resolveServerEnvironmentLabel = Effect.fn("resolveServerEnvironment

const hostname = normalizeLabel(yield* HostProcessHostname);
if (hostname) {
const isWsl = yield* isWslEnvironment();
if (isWsl) {
const env = yield* HostProcessEnvironment;
const distroName = env["WSL_DISTRO_NAME"];
if (distroName && distroName.trim().length > 0) {
return `${hostname} (WSL: ${distroName.trim()})`;
}
return `${hostname} (WSL)`;
}
Comment on lines +241 to +249

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This changes the resolved server environment label (a backend behavior change) but ServerEnvironmentLabel.test.ts is untouched. Consider adding focused cases there using the existing FileSystem.layerNoop seam plus Layer.succeed(HostProcessEnvironment, { WSL_DISTRO_NAME: "Ubuntu" }): WSL with a distro name, WSL without one, and a non-WSL Linux host that still returns the plain hostname.

Posted via Macroscope — Effect Service Conventions

return hostname;
}

Expand Down
Loading