import * as NodeServices from "@effect/platform-node/NodeServices";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 PlatformError from "effect/PlatformError";import { ChildProcessSpawner } from "effect/unstable/process";import { assert, it } from "@effect/vitest"; import { GitCommandError } from "@t3tools/contracts";import * as ServerConfig from "../config.ts";import * as GitVcsDriver from "./GitVcsDriver.ts";import * as VcsProcess from "./VcsProcess.ts";import { runVcsDriverContractSuite } from "./testing/VcsDriverContractHarness.ts"; const ServerConfigLayer = ServerConfig.layerTest(process.cwd(), { prefix: "t3-git-vcs-contract-",});const GitContractLayer = Layer.mergeAll(GitVcsDriver.vcsLayer, GitVcsDriver.layer).pipe( Layer.provide(ServerConfigLayer), Layer.provideMerge(VcsProcess.layer), Layer.provideMerge(NodeServices.layer),); const runGit = (cwd: string, args: ReadonlyArray<string>) => Effect.gen(function* () { const driver = yield* GitVcsDriver.GitVcsDriver; yield* driver.execute({ operation: "GitVcsDriver.contract.git", cwd, args, timeoutMs: 10_000, }); }); type GitContractError = GitCommandError | PlatformError.PlatformError; runVcsDriverContractSuite<GitVcsDriver.GitVcsDriver, GitContractError>({ name: "Git", kind: "git", layer: GitContractLayer, fixture: { createRepo: (cwd) => Effect.gen(function* () { yield* runGit(cwd, ["init"]); yield* runGit(cwd, ["config", "user.email", "test@test.com"]); yield* runGit(cwd, ["config", "user.name", "Test"]); }), writeFile: (cwd, relativePath, contents) => Effect.gen(function* () { const fileSystem = yield* FileSystem.FileSystem; const path = yield* Path.Path; const absolutePath = path.join(cwd, relativePath); yield* fileSystem.makeDirectory(path.dirname(absolutePath), { recursive: true }); yield* fileSystem.writeFileString(absolutePath, contents); }), trackFile: (cwd, relativePath) => runGit(cwd, ["add", relativePath]), commit: (cwd, message) => runGit(cwd, ["commit", "-m", message]), ignorePath: (cwd, pattern) => Effect.gen(function* () { const fileSystem = yield* FileSystem.FileSystem; const path = yield* Path.Path; yield* fileSystem.writeFileString(path.join(cwd, ".gitignore"), `${pattern}\n`); }), },}); it.effect("GitVcsDriver forwards execute env to the VCS process", () => { let observedEnv: NodeJS.ProcessEnv | undefined; let observedAppendTruncationMarker: boolean | undefined; let observedOutputMode: VcsProcess.VcsProcessInput["outputMode"]; return Effect.gen(function* () { const driver = yield* GitVcsDriver.makeVcsDriverShape(); yield* driver.execute({ operation: "GitVcsDriver.test.env", cwd: "/repo", args: ["status"], env: { GIT_INDEX_FILE: "/tmp/t3-index", }, appendTruncationMarker: true, outputMode: "error", }); assert.deepStrictEqual(observedEnv, { GIT_INDEX_FILE: "/tmp/t3-index", }); assert.strictEqual(observedAppendTruncationMarker, true); assert.strictEqual(observedOutputMode, "error"); }).pipe( Effect.provide( Layer.mergeAll( NodeServices.layer, Layer.mock(VcsProcess.VcsProcess)({ run: (input) => Effect.sync(() => { observedEnv = input.env; observedAppendTruncationMarker = input.appendTruncationMarker; observedOutputMode = input.outputMode; return { exitCode: ChildProcessSpawner.ExitCode(0), stdout: "", stderr: "", stdoutTruncated: false, stderrTruncated: false, }; }), }), ), ), );});
import * as NodeServices from "@effect/platform-node/NodeServices";
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 PlatformError from "effect/PlatformError";
import { ChildProcessSpawner } from "effect/unstable/process";
import { assert, it } from "@effect/vitest";
import { GitCommandError } from "@t3tools/contracts";
import * as ServerConfig from "../config.ts";
import * as GitVcsDriver from "./GitVcsDriver.ts";
import * as VcsProcess from "./VcsProcess.ts";
import { runVcsDriverContractSuite } from "./testing/VcsDriverContractHarness.ts";
const ServerConfigLayer = ServerConfig.layerTest(process.cwd(), {
prefix: "t3-git-vcs-contract-",
});
const GitContractLayer = Layer.mergeAll(GitVcsDriver.vcsLayer, GitVcsDriver.layer).pipe(
Layer.provide(ServerConfigLayer),
Layer.provideMerge(VcsProcess.layer),
Layer.provideMerge(NodeServices.layer),
);
const runGit = (cwd: string, args: ReadonlyArray<string>) =>
Effect.gen(function* () {
const driver = yield* GitVcsDriver.GitVcsDriver;
yield* driver.execute({
operation: "GitVcsDriver.contract.git",
cwd,
args,
timeoutMs: 10_000,
});
});
type GitContractError = GitCommandError | PlatformError.PlatformError;
runVcsDriverContractSuite<GitVcsDriver.GitVcsDriver, GitContractError>({
name: "Git",
kind: "git",
layer: GitContractLayer,
fixture: {
createRepo: (cwd) =>
Effect.gen(function* () {
yield* runGit(cwd, ["init"]);
yield* runGit(cwd, ["config", "user.email", "test@test.com"]);
yield* runGit(cwd, ["config", "user.name", "Test"]);
}),
writeFile: (cwd, relativePath, contents) =>
Effect.gen(function* () {
const fileSystem = yield* FileSystem.FileSystem;
const path = yield* Path.Path;
const absolutePath = path.join(cwd, relativePath);
yield* fileSystem.makeDirectory(path.dirname(absolutePath), { recursive: true });
yield* fileSystem.writeFileString(absolutePath, contents);
}),
trackFile: (cwd, relativePath) => runGit(cwd, ["add", relativePath]),
commit: (cwd, message) => runGit(cwd, ["commit", "-m", message]),
ignorePath: (cwd, pattern) =>
Effect.gen(function* () {
const fileSystem = yield* FileSystem.FileSystem;
const path = yield* Path.Path;
yield* fileSystem.writeFileString(path.join(cwd, ".gitignore"), `${pattern}\n`);
}),
},
});
it.effect("GitVcsDriver forwards execute env to the VCS process", () => {
let observedEnv: NodeJS.ProcessEnv | undefined;
let observedAppendTruncationMarker: boolean | undefined;
let observedOutputMode: VcsProcess.VcsProcessInput["outputMode"];
return Effect.gen(function* () {
const driver = yield* GitVcsDriver.makeVcsDriverShape();
yield* driver.execute({
operation: "GitVcsDriver.test.env",
cwd: "/repo",
args: ["status"],
env: {
GIT_INDEX_FILE: "/tmp/t3-index",
},
appendTruncationMarker: true,
outputMode: "error",
});
assert.deepStrictEqual(observedEnv, {
GIT_INDEX_FILE: "/tmp/t3-index",
});
assert.strictEqual(observedAppendTruncationMarker, true);
assert.strictEqual(observedOutputMode, "error");
}).pipe(
Effect.provide(
Layer.mergeAll(
NodeServices.layer,
Layer.mock(VcsProcess.VcsProcess)({
run: (input) =>
Effect.sync(() => {
observedEnv = input.env;
observedAppendTruncationMarker = input.appendTruncationMarker;
observedOutputMode = input.outputMode;
return {
exitCode: ChildProcessSpawner.ExitCode(0),
stdout: "",
stderr: "",
stdoutTruncated: false,
stderrTruncated: false,
};
}),
}),
),
),
);
});