t3-code-android-nightly/scripts/sync-reference-repos.test.ts
Julius Marminge 194c73f3f9
chore(deps): upgrade Effect to stable 4.0.1 (#16138)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-05 13:15:14 -07:00

302 lines
11 KiB
TypeScript

import * as NodeServices from "@effect/platform-node/NodeServices";
import { assert, it } from "@effect/vitest";
import * as Effect from "effect/Effect";
import * as FileSystem from "effect/FileSystem";
import * as Layer from "effect/Layer";
import * as Path from "effect/Path";
import * as Sink from "effect/Sink";
import * as Stream from "effect/Stream";
import { ChildProcessSpawner } from "effect/process";
import { referenceRepos } from "./lib/reference-repos.ts";
import {
planReferenceRepoSync,
resolveReferenceRepoRef,
syncReferenceRepos,
} from "./sync-reference-repos.ts";
const encoder = new TextEncoder();
const effectSmol = referenceRepos[0]!;
const alchemyEffect = referenceRepos[1]!;
function mockHandle(
options: {
readonly exitCode?: number;
readonly stdout?: string;
readonly stderr?: string;
} = {},
) {
return ChildProcessSpawner.makeHandle({
pid: ChildProcessSpawner.ProcessId(1),
exitCode: Effect.succeed(ChildProcessSpawner.ExitCode(options.exitCode ?? 0)),
isRunning: Effect.succeed(false),
kill: () => Effect.void,
unref: Effect.succeed(Effect.void),
stdin: Sink.drain,
stdout: Stream.make(encoder.encode(options.stdout ?? "done\n")),
stderr: Stream.make(encoder.encode(options.stderr ?? "")),
all: Stream.empty,
getInputFd: () => Sink.drain,
getOutputFd: () => Stream.empty,
});
}
function mockSpawnerLayer(
commands: Array<{ readonly command: string; readonly args: ReadonlyArray<string> }>,
handle = mockHandle(),
) {
return Layer.succeed(
ChildProcessSpawner.ChildProcessSpawner,
ChildProcessSpawner.make((command) => {
const childProcess = command as unknown as {
readonly command: string;
readonly args: ReadonlyArray<string>;
};
commands.push({
command: childProcess.command,
args: childProcess.args,
});
return Effect.succeed(handle);
}),
);
}
it.layer(NodeServices.layer)("sync-reference-repos", (it) => {
it.effect("resolves the effect-smol tag from the root catalog", () =>
Effect.gen(function* () {
const fs = yield* FileSystem.FileSystem;
const path = yield* Path.Path;
const rootDir = yield* fs.makeTempDirectoryScoped({
prefix: "sync-reference-repos-version-",
});
yield* fs.writeFileString(
path.join(rootDir, "pnpm-workspace.yaml"),
"catalog:\n effect: 4.0.0-beta.73\n",
);
assert.equal(
yield* resolveReferenceRepoRef(effectSmol, rootDir, false),
"effect@4.0.0-beta.73",
);
}),
);
it.effect("uses the latest branch without reading package versions", () =>
Effect.gen(function* () {
const fs = yield* FileSystem.FileSystem;
const rootDir = yield* fs.makeTempDirectoryScoped({
prefix: "sync-reference-repos-latest-",
});
assert.equal(yield* resolveReferenceRepoRef(effectSmol, rootDir, true), "main");
}),
);
it.effect("preserves version source read context and the filesystem cause", () =>
Effect.gen(function* () {
const fs = yield* FileSystem.FileSystem;
const path = yield* Path.Path;
const rootDir = yield* fs.makeTempDirectoryScoped({
prefix: "sync-reference-repos-read-error-",
});
const sourcePath = path.join(rootDir, effectSmol.versionSourcePath);
const error = yield* resolveReferenceRepoRef(effectSmol, rootDir, false).pipe(Effect.flip);
if (error._tag !== "ReferenceRepoVersionSourceError") {
assert.fail(`Unexpected error: ${error._tag}`);
}
assert.equal(error.operation, "read");
assert.equal(error.repoId, effectSmol.id);
assert.equal(error.sourcePath, sourcePath);
assert.ok(error.cause !== undefined);
assert.ok(!error.message.includes(String((error.cause as Error).message)));
}),
);
it.effect("preserves version source parse context and the schema cause", () =>
Effect.gen(function* () {
const fs = yield* FileSystem.FileSystem;
const path = yield* Path.Path;
const rootDir = yield* fs.makeTempDirectoryScoped({
prefix: "sync-reference-repos-parse-error-",
});
const sourcePath = path.join(rootDir, alchemyEffect.versionSourcePath);
yield* fs.makeDirectory(path.dirname(sourcePath), { recursive: true });
yield* fs.writeFileString(sourcePath, "{");
const error = yield* resolveReferenceRepoRef(alchemyEffect, rootDir, false).pipe(Effect.flip);
if (error._tag !== "ReferenceRepoVersionSourceError") {
assert.fail(`Unexpected error: ${error._tag}`);
}
assert.equal(error.operation, "parse");
assert.equal(error.repoId, alchemyEffect.id);
assert.equal(error.sourcePath, sourcePath);
assert.ok(error.cause !== undefined);
assert.ok(!error.message.includes(String((error.cause as Error).message)));
}),
);
it.effect("reports the unresolved package path without inventing a cause", () =>
Effect.gen(function* () {
const fs = yield* FileSystem.FileSystem;
const path = yield* Path.Path;
const rootDir = yield* fs.makeTempDirectoryScoped({
prefix: "sync-reference-repos-resolution-error-",
});
const sourcePath = path.join(rootDir, alchemyEffect.versionSourcePath);
yield* fs.makeDirectory(path.dirname(sourcePath), { recursive: true });
yield* fs.writeFileString(sourcePath, '{"dependencies":{}}');
const error = yield* resolveReferenceRepoRef(alchemyEffect, rootDir, false).pipe(Effect.flip);
if (error._tag !== "ReferenceRepoVersionResolutionError") {
assert.fail(`Unexpected error: ${error._tag}`);
}
assert.equal(error.repoId, alchemyEffect.id);
assert.equal(error.sourcePath, sourcePath);
assert.deepStrictEqual(error.packageVersionPath, ["dependencies", "alchemy"]);
assert.ok(!("cause" in error));
}),
);
it.effect("resolves the alchemy-effect tag from the relay package", () =>
Effect.gen(function* () {
const fs = yield* FileSystem.FileSystem;
const path = yield* Path.Path;
const rootDir = yield* fs.makeTempDirectoryScoped({
prefix: "sync-reference-repos-alchemy-version-",
});
yield* fs.makeDirectory(path.join(rootDir, "infra", "relay"), { recursive: true });
yield* fs.writeFileString(
path.join(rootDir, "infra", "relay", "package.json"),
'{"dependencies":{"alchemy":"2.0.0-beta.49"}}',
);
assert.equal(yield* resolveReferenceRepoRef(alchemyEffect, rootDir, false), "v2.0.0-beta.49");
}),
);
it.effect("plans an add for a missing subtree and a pull for an existing subtree", () =>
Effect.gen(function* () {
const fs = yield* FileSystem.FileSystem;
const path = yield* Path.Path;
const rootDir = yield* fs.makeTempDirectoryScoped({
prefix: "sync-reference-repos-plan-",
});
yield* fs.writeFileString(
path.join(rootDir, "pnpm-workspace.yaml"),
"catalog:\n effect: 4.0.0-beta.73\n",
);
const addPlan = yield* planReferenceRepoSync(effectSmol, rootDir, false);
assert.equal(addPlan.action, "add");
assert.deepStrictEqual(addPlan.args, [
"subtree",
"add",
"--prefix=.repos/effect-smol",
"https://github.com/Effect-TS/effect.git",
"effect@4.0.0-beta.73",
"--squash",
]);
yield* fs.makeDirectory(path.join(rootDir, effectSmol.prefix), { recursive: true });
assert.equal((yield* planReferenceRepoSync(effectSmol, rootDir, false)).action, "pull");
}),
);
it.effect("runs the planned git subtree command through the process service", () => {
const commands: Array<{ readonly command: string; readonly args: ReadonlyArray<string> }> = [];
return Effect.gen(function* () {
const fs = yield* FileSystem.FileSystem;
const path = yield* Path.Path;
const rootDir = yield* fs.makeTempDirectoryScoped({
prefix: "sync-reference-repos-run-",
});
yield* fs.writeFileString(
path.join(rootDir, "pnpm-workspace.yaml"),
"catalog:\n effect: 4.0.0-beta.73\n",
);
yield* syncReferenceRepos({ rootDir, repoId: "effect-smol" }).pipe(
Effect.provide(mockSpawnerLayer(commands)),
);
assert.deepStrictEqual(commands, [
{
command: "git",
args: [
"subtree",
"add",
"--prefix=.repos/effect-smol",
"https://github.com/Effect-TS/effect.git",
"effect@4.0.0-beta.73",
"--squash",
],
},
]);
});
});
it.effect("rejects unknown repo selectors", () =>
Effect.gen(function* () {
const error = yield* syncReferenceRepos({
repoId: "missing",
dryRun: true,
}).pipe(Effect.flip);
if (error._tag !== "ReferenceRepoSelectionError") {
assert.fail(`Unexpected error: ${error._tag}`);
}
assert.equal(error.repoId, "missing");
assert.deepStrictEqual(error.expectedRepoIds, ["effect-smol", "alchemy-effect"]);
assert.ok(!("cause" in error));
}),
);
it.effect("reports non-zero git exits without retaining process output", () => {
const commands: Array<{ readonly command: string; readonly args: ReadonlyArray<string> }> = [];
return Effect.gen(function* () {
const fs = yield* FileSystem.FileSystem;
const path = yield* Path.Path;
const rootDir = yield* fs.makeTempDirectoryScoped({
prefix: "sync-reference-repos-exit-error-",
});
yield* fs.writeFileString(
path.join(rootDir, "pnpm-workspace.yaml"),
"catalog:\n effect: 4.0.0-beta.73\n",
);
const error = yield* syncReferenceRepos({ rootDir, repoId: "effect-smol" }).pipe(
Effect.provide(
mockSpawnerLayer(
commands,
mockHandle({ exitCode: 23, stderr: "subtree failed secret-token-value\n" }),
),
),
Effect.flip,
);
if (error._tag !== "ReferenceRepoGitSubtreeError") {
assert.fail(`Unexpected error: ${error._tag}`);
}
assert.equal(error.operation, "exit");
assert.equal(error.repoId, effectSmol.id);
assert.equal(error.action, "add");
assert.equal(error.repository, effectSmol.repository);
assert.equal(error.ref, "effect@4.0.0-beta.73");
assert.equal(error.rootDir, rootDir);
assert.equal(error.argumentCount, commands[0]?.args.length);
assert.equal(error.exitCode, 23);
assert.equal(error.stdoutLength, 5);
assert.equal(error.stderrLength, 34);
assert.notProperty(error, "args");
assert.notProperty(error, "stderr");
assert.notInclude(error.message, "secret-token-value");
assert.ok(!("cause" in error));
});
});
});