History

test(server): pin git config for fixtures and compare native realpaths (#9570)

Julius Marminge committed 2 months ago

Commit 12b6d021 parent f083f524 files · +61 −29Browse files

Unified · Split

4 files
  1. apps/server/src/project/RepositoryIdentityResolver.test.ts +8 −4
  2. apps/server/src/testUtils/gitConfig.setup.ts +21 −0
  3. apps/server/src/vcs/GitVcsDriverCore.test.ts +31 −25
  4. apps/server/vite.config.ts +1 −0
apps/server/src/project/RepositoryIdentityResolver.test.ts+8−4
@@ -1,3 +1,5 @@
1+// @effect-diagnostics nodeBuiltinImport:off - realpathSync.native resolves Windows 8.3 short names, which the Effect realPath does not.
2+import * as NodeFS from "node:fs";
13 import * as NodeServices from "@effect/platform-node/NodeServices";
24 import { expect, it } from "@effect/vitest";
35 import * as Duration from "effect/Duration";
@@ -131,9 +133,11 @@ it.layer(NodeServices.layer)("RepositoryIdentityResolverLive", (it) => { · 127 unmodified lines
131133
132134 const resolver = yield* RepositoryIdentityResolver.RepositoryIdentityResolver;
133135 const identity = yield* resolver.resolve(cwd);
136+ // Native realpath, since git reports the long form of a directory the
137+ // temp dir may name by its 8.3 short form on Windows.
134138 const resolvedIdentityRoot =
135− identity?.rootPath === undefined ? "" : yield* fileSystem.realPath(identity.rootPath);
136− const resolvedCwd = yield* fileSystem.realPath(cwd);
139+ identity?.rootPath === undefined ? "" : NodeFS.realpathSync.native(identity.rootPath);
140+ const resolvedCwd = NodeFS.realpathSync.native(cwd);
137141
138142 expect(identity).not.toBeNull();
139143 expect(identity?.canonicalKey).toBe("github.com/t3tools/t3code");
@@ -161,8 +165,8 @@ it.layer(NodeServices.layer)("RepositoryIdentityResolverLive", (it) => { · 21 unmodified lines
161165 const resolver = yield* RepositoryIdentityResolver.RepositoryIdentityResolver;
162166 const identity = yield* resolver.resolve(nestedWorkspace);
163167 const resolvedIdentityRoot =
164− identity?.rootPath === undefined ? "" : yield* fileSystem.realPath(identity.rootPath);
165− const resolvedRepoRoot = yield* fileSystem.realPath(repoRoot);
168+ identity?.rootPath === undefined ? "" : NodeFS.realpathSync.native(identity.rootPath);
169+ const resolvedRepoRoot = NodeFS.realpathSync.native(repoRoot);
166170
167171 expect(identity).not.toBeNull();
168172 expect(identity?.canonicalKey).toBe("github.com/t3tools/t3code");
apps/server/src/testUtils/gitConfig.setup.ts+21−0
@@ -0,0 +1,21 @@
1+// Pins git behaviour for every repository the suite creates, ahead of the
2+// host's ~/.gitconfig. Git for Windows installs with core.autocrlf=true,
3+// which checks committed LF files out as CRLF and breaks every byte-exact
4+// content assertion; a signing key or a non-default init branch on the
5+// developer's machine breaks fixtures the same way. Set as environment so
6+// each git child the driver spawns sees it without touching the fixtures.
7+const entries: ReadonlyArray<readonly [key: string, value: string]> = [
8+ ["core.autocrlf", "false"],
9+ ["core.filemode", "false"],
10+ ["core.longpaths", "true"],
11+ ["commit.gpgsign", "false"],
12+ ["tag.gpgsign", "false"],
13+ ["init.defaultBranch", "main"],
14+];
15+
16+const existing = Number(process.env.GIT_CONFIG_COUNT ?? "0");
17+process.env.GIT_CONFIG_COUNT = String(existing + entries.length);
18+entries.forEach(([key, value], index) => {
19+ process.env[`GIT_CONFIG_KEY_${existing + index}`] = key;
20+ process.env[`GIT_CONFIG_VALUE_${existing + index}`] = value;
21+});
apps/server/src/vcs/GitVcsDriverCore.test.ts+31−25
@@ -1,4 +1,7 @@
1+// @effect-diagnostics nodeBuiltinImport:off - realpathSync.native resolves Windows 8.3 short names, which the Effect realPath does not.
2+import * as NodeFS from "node:fs";
13 import * as NodeServices from "@effect/platform-node/NodeServices";
4+import { HostProcessPlatform } from "@t3tools/shared/hostProcess";
25 import { assert, it, describe } from "@effect/vitest";
36 import * as Deferred from "effect/Deferred";
47 import * as Effect from "effect/Effect";
@@ -570,7 +573,6 @@ it.effect("backs off failed upstream refreshes across linked worktrees", () => · 565 unmodified lines
570573 const driver = yield* makeGitVcsDriverCore().pipe(
571574 Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, failingFetchSpawner),
572575 );
573− const fileSystem = yield* FileSystem.FileSystem;
574576 const cwd = yield* makeTmpDir();
575577 const remote = yield* makeTmpDir("git-vcs-driver-remote-");
576578 const worktreesRoot = yield* makeTmpDir("git-vcs-driver-worktrees-");
@@ -606,9 +608,11 @@ it.effect("backs off failed upstream refreshes across linked worktrees", () => · 29 unmodified lines
606608 "rev-parse",
607609 "--git-common-dir",
608610 ])).stdout.trim();
611+ // Native realpath, since git reports the long form of a directory the
612+ // temp dir may name by its 8.3 short form on Windows.
609613 assert.equal(
610− yield* fileSystem.realPath(pathService.resolve(cwd, rootCommonDir)),
611− yield* fileSystem.realPath(pathService.resolve(worktreePath, linkedCommonDir)),
614+ NodeFS.realpathSync.native(pathService.resolve(cwd, rootCommonDir)),
615+ NodeFS.realpathSync.native(pathService.resolve(worktreePath, linkedCommonDir)),
612616 );
613617 yield* Ref.set(fetchAttempts, 0);
614618
@@ -1376,31 +1380,33 @@ it.layer(TestLayer)("GitVcsDriver core integration", (it) => { · 761 unmodified lines
13761380 });
13771381
13781382 describe("worktree operations", () => {
1379− it.effect("preserves newline characters in worktree paths when listing refs", () =>
1380− Effect.gen(function* () {
1381− const cwd = yield* makeTmpDir();
1382− yield* initRepoWithCommit(cwd);
1383− const worktreesRoot = yield* makeTmpDir("git-vcs-driver-worktrees-");
1384− const fileSystem = yield* FileSystem.FileSystem;
1385− const pathService = yield* Path.Path;
1386− const worktreePath = pathService.join(worktreesRoot, "linked\nworktree");
1387− const driver = yield* GitVcsDriver.GitVcsDriver;
1383+ // NTFS rejects a newline in a file name, so there is nothing to preserve there.
1384+ it.effect.skipIf(HostProcessPlatform.defaultValue() === "win32")(
1385+ "preserves newline characters in worktree paths when listing refs",
1386+ () =>
1387+ Effect.gen(function* () {
1388+ const cwd = yield* makeTmpDir();
1389+ yield* initRepoWithCommit(cwd);
1390+ const worktreesRoot = yield* makeTmpDir("git-vcs-driver-worktrees-");
1391+ const pathService = yield* Path.Path;
1392+ const worktreePath = pathService.join(worktreesRoot, "linked\nworktree");
1393+ const driver = yield* GitVcsDriver.GitVcsDriver;
13881394
1389− yield* git(cwd, ["worktree", "add", "-b", "feature/newline-path", worktreePath]);
1395+ yield* git(cwd, ["worktree", "add", "-b", "feature/newline-path", worktreePath]);
13901396
1391− const refs = yield* driver.listRefs({ cwd, refresh: true });
1392− const listedPath = refs.refs.find(
1393− (ref) => ref.name === "feature/newline-path",
1394− )?.worktreePath;
1397+ const refs = yield* driver.listRefs({ cwd, refresh: true });
1398+ const listedPath = refs.refs.find(
1399+ (ref) => ref.name === "feature/newline-path",
1400+ )?.worktreePath;
13951401
1396− if (typeof listedPath !== "string") {
1397− return assert.fail("expected the linked branch to include its worktree path");
1398− }
1399− assert.equal(
1400− yield* fileSystem.realPath(listedPath),
1401− yield* fileSystem.realPath(worktreePath),
1402− );
1403− }),
1402+ if (typeof listedPath !== "string") {
1403+ return assert.fail("expected the linked branch to include its worktree path");
1404+ }
1405+ assert.equal(
1406+ NodeFS.realpathSync.native(listedPath),
1407+ NodeFS.realpathSync.native(worktreePath),
1408+ );
1409+ }),
14041410 );
14051411
14061412 it.effect("checks out submodules in a new worktree", () =>
apps/server/vite.config.ts+1−0
@@ -78,6 +78,7 @@ export default mergeConfig( · 77 unmodified lines
7878 // The server suite exercises sqlite, git, temp worktrees, and orchestration
7979 // runtimes heavily. Running files in parallel introduces load-sensitive flakes.
8080 fileParallelism: false,
81+ setupFiles: ["./src/testUtils/gitConfig.setup.ts"],
8182 // Server integration tests exercise sqlite, git, and orchestration together.
8283 // Under package-wide runs they can exceed the default budget on loaded CI hosts.
8384 hookTimeout: 120_000,

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t