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 { ChildProcessSpawner } from "effect/unstable/process"; import { GitCommandError, type SourceControlProviderError } from "@t3tools/contracts"; import { ServerConfig } from "../config.ts";import * as GitVcsDriver from "../vcs/GitVcsDriver.ts";import type * as SourceControlProvider from "./SourceControlProvider.ts";import * as SourceControlProviderRegistry from "./SourceControlProviderRegistry.ts";import * as SourceControlRepositoryService from "./SourceControlRepositoryService.ts"; const CLONE_URLS = { nameWithOwner: "octocat/t3code", url: "https://github.com/octocat/t3code", sshUrl: "git@github.com:octocat/t3code.git",}; function makeProvider( overrides: Partial<SourceControlProvider.SourceControlProviderShape> = {},): SourceControlProvider.SourceControlProviderShape { const unsupported = (operation: string) => Effect.die(`unexpected provider operation ${operation}`) as Effect.Effect< never, SourceControlProviderError >; return { kind: "github", listChangeRequests: () => unsupported("listChangeRequests"), getChangeRequest: () => unsupported("getChangeRequest"), createChangeRequest: () => unsupported("createChangeRequest"), getRepositoryCloneUrls: () => Effect.succeed(CLONE_URLS), createRepository: () => Effect.succeed(CLONE_URLS), getDefaultBranch: () => Effect.succeed(null), checkoutChangeRequest: () => unsupported("checkoutChangeRequest"), ...overrides, };} function processOutput(): GitVcsDriver.ExecuteGitResult { return { exitCode: ChildProcessSpawner.ExitCode(0), stdout: "", stderr: "", stdoutTruncated: false, stderrTruncated: false, };} function makeLayer(input: { readonly provider?: SourceControlProvider.SourceControlProviderShape; readonly git?: Partial<GitVcsDriver.GitVcsDriverShape>;}) { return SourceControlRepositoryService.layer.pipe( Layer.provide( Layer.mock(SourceControlProviderRegistry.SourceControlProviderRegistry)({ get: () => Effect.succeed(input.provider ?? makeProvider()), }), ), Layer.provide( Layer.mock(GitVcsDriver.GitVcsDriver)({ execute: () => Effect.succeed(processOutput()), ensureRemote: () => Effect.succeed("origin"), pushCurrentBranch: () => Effect.succeed({ status: "pushed" as const, branch: "feature/remote-v1", upstreamBranch: "origin/feature/remote-v1", setUpstream: true, }), ...input.git, }), ), Layer.provide(ServerConfig.layerTest(process.cwd(), { prefix: "t3-source-control-repos-" })), Layer.provideMerge(NodeServices.layer), );} it.effect("looks up repositories through the requested provider without search", () => { const calls: Array<{ cwd: string; repository: string }> = []; const provider = makeProvider({ getRepositoryCloneUrls: (input) => Effect.sync(() => { calls.push({ cwd: input.cwd, repository: input.repository }); return CLONE_URLS; }), }); return Effect.gen(function* () { const service = yield* SourceControlRepositoryService.SourceControlRepositoryService; const result = yield* service.lookupRepository({ provider: "github", repository: "octocat/t3code", cwd: "/workspace", }); assert.deepStrictEqual(result, { provider: "github", ...CLONE_URLS }); assert.deepStrictEqual(calls, [{ cwd: "/workspace", repository: "octocat/t3code" }]); }).pipe(Effect.provide(makeLayer({ provider })));}); it.effect("clones a looked-up repository into the requested destination", () => Effect.gen(function* () { const fs = yield* FileSystem.FileSystem; const parent = yield* fs.makeTempDirectoryScoped({ prefix: "t3-source-control-clone-parent-", }); const destinationPath = `${parent}/t3code`; const cloneCalls: Array<{ cwd: string; args: ReadonlyArray<string> }> = []; yield* Effect.gen(function* () { const service = yield* SourceControlRepositoryService.SourceControlRepositoryService; const result = yield* service.cloneRepository({ provider: "github", repository: "octocat/t3code", destinationPath, protocol: "https", }); assert.deepStrictEqual(result, { cwd: destinationPath, remoteUrl: CLONE_URLS.url, repository: { provider: "github", ...CLONE_URLS }, }); assert.deepStrictEqual(cloneCalls, [ { cwd: parent, args: ["clone", CLONE_URLS.url, "t3code"], }, ]); }).pipe( Effect.provide( makeLayer({ git: { execute: (input) => Effect.sync(() => { cloneCalls.push({ cwd: input.cwd, args: input.args }); return processOutput(); }), }, }), ), ); }).pipe(Effect.provide(NodeServices.layer)),); it.effect("publishes by creating the repository, adding a remote, and pushing upstream", () => { const createCalls: Array<{ cwd: string; repository: string; visibility: string }> = []; const remoteCalls: Array<{ cwd: string; preferredName: string; url: string }> = []; const pushCalls: Array<{ cwd: string; remoteName: string | null | undefined }> = []; const provider = makeProvider({ createRepository: (input) => Effect.sync(() => { createCalls.push({ cwd: input.cwd, repository: input.repository, visibility: input.visibility, }); return CLONE_URLS; }), }); return Effect.gen(function* () { const service = yield* SourceControlRepositoryService.SourceControlRepositoryService; const result = yield* service.publishRepository({ cwd: "/workspace", provider: "github", repository: "octocat/t3code", visibility: "private", remoteName: "origin", protocol: "ssh", }); assert.deepStrictEqual(result, { repository: { provider: "github", ...CLONE_URLS }, remoteName: "origin", remoteUrl: CLONE_URLS.sshUrl, branch: "feature/remote-v1", upstreamBranch: "origin/feature/remote-v1", status: "pushed", }); assert.deepStrictEqual(createCalls, [ { cwd: "/workspace", repository: "octocat/t3code", visibility: "private" }, ]); assert.deepStrictEqual(remoteCalls, [ { cwd: "/workspace", preferredName: "origin", url: CLONE_URLS.sshUrl }, ]); assert.deepStrictEqual(pushCalls, [{ cwd: "/workspace", remoteName: "origin" }]); }).pipe( Effect.provide( makeLayer({ provider, git: { ensureRemote: (input) => Effect.sync(() => { remoteCalls.push(input); return "origin"; }), pushCurrentBranch: (cwd, _fallbackBranch, options) => Effect.sync(() => { pushCalls.push({ cwd, remoteName: options?.remoteName }); return { status: "pushed" as const, branch: "feature/remote-v1", upstreamBranch: "origin/feature/remote-v1", setUpstream: true, }; }), }, }), ), );}); it.effect("publishes to the remote name returned by ensureRemote", () => { const pushCalls: Array<{ cwd: string; remoteName: string | null | undefined }> = []; return Effect.gen(function* () { const service = yield* SourceControlRepositoryService.SourceControlRepositoryService; const result = yield* service.publishRepository({ cwd: "/workspace", provider: "github", repository: "octocat/t3code", visibility: "private", remoteName: "origin", protocol: "ssh", }); assert.equal(result.remoteName, "origin-1"); assert.deepStrictEqual(pushCalls, [{ cwd: "/workspace", remoteName: "origin-1" }]); }).pipe( Effect.provide( makeLayer({ git: { ensureRemote: () => Effect.succeed("origin-1"), pushCurrentBranch: (cwd, _fallbackBranch, options) => Effect.sync(() => { pushCalls.push({ cwd, remoteName: options?.remoteName }); return { status: "pushed" as const, branch: "feature/remote-v1", upstreamBranch: `${options?.remoteName ?? "missing"}/feature/remote-v1`, setUpstream: true, }; }), }, }), ), );}); it.effect("publish succeeds with status remote_added when the local repo has no commits", () => { let pushCalls = 0; return Effect.gen(function* () { const service = yield* SourceControlRepositoryService.SourceControlRepositoryService; const result = yield* service.publishRepository({ cwd: "/workspace", provider: "github", repository: "octocat/t3code", visibility: "private", remoteName: "origin", protocol: "ssh", }); assert.deepStrictEqual(result, { repository: { provider: "github", ...CLONE_URLS }, remoteName: "origin", remoteUrl: CLONE_URLS.sshUrl, branch: "main", status: "remote_added", }); assert.strictEqual(pushCalls, 0); }).pipe( Effect.provide( makeLayer({ git: { execute: (input) => input.args[0] === "rev-parse" ? Effect.fail( new GitCommandError({ operation: input.operation, command: "git rev-parse --verify HEAD", cwd: input.cwd, detail: "fatal: Needed a single revision", }), ) : Effect.succeed(processOutput()), statusDetails: () => Effect.succeed({ isRepo: true, hasOriginRemote: true, isDefaultBranch: true, branch: "main", upstreamRef: null, hasWorkingTreeChanges: false, workingTree: { files: [], insertions: 0, deletions: 0 }, hasUpstream: false, aheadCount: 0, behindCount: 0, aheadOfDefaultCount: 0, }), pushCurrentBranch: () => Effect.sync(() => { pushCalls += 1; return { status: "pushed" as const, branch: "main", upstreamBranch: "origin/main", setUpstream: true, }; }), }, }), ), );});
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 { ChildProcessSpawner } from "effect/unstable/process";
import { GitCommandError, type SourceControlProviderError } from "@t3tools/contracts";
import { ServerConfig } from "../config.ts";
import * as GitVcsDriver from "../vcs/GitVcsDriver.ts";
import type * as SourceControlProvider from "./SourceControlProvider.ts";
import * as SourceControlProviderRegistry from "./SourceControlProviderRegistry.ts";
import * as SourceControlRepositoryService from "./SourceControlRepositoryService.ts";
const CLONE_URLS = {
nameWithOwner: "octocat/t3code",
url: "https://github.com/octocat/t3code",
sshUrl: "git@github.com:octocat/t3code.git",
};
function makeProvider(
overrides: Partial<SourceControlProvider.SourceControlProviderShape> = {},
): SourceControlProvider.SourceControlProviderShape {
const unsupported = (operation: string) =>
Effect.die(`unexpected provider operation ${operation}`) as Effect.Effect<
never,
SourceControlProviderError
>;
return {
kind: "github",
listChangeRequests: () => unsupported("listChangeRequests"),
getChangeRequest: () => unsupported("getChangeRequest"),
createChangeRequest: () => unsupported("createChangeRequest"),
getRepositoryCloneUrls: () => Effect.succeed(CLONE_URLS),
createRepository: () => Effect.succeed(CLONE_URLS),
getDefaultBranch: () => Effect.succeed(null),
checkoutChangeRequest: () => unsupported("checkoutChangeRequest"),
...overrides,
};
}
function processOutput(): GitVcsDriver.ExecuteGitResult {
return {
exitCode: ChildProcessSpawner.ExitCode(0),
stdout: "",
stderr: "",
stdoutTruncated: false,
stderrTruncated: false,
};
}
function makeLayer(input: {
readonly provider?: SourceControlProvider.SourceControlProviderShape;
readonly git?: Partial<GitVcsDriver.GitVcsDriverShape>;
}) {
return SourceControlRepositoryService.layer.pipe(
Layer.provide(
Layer.mock(SourceControlProviderRegistry.SourceControlProviderRegistry)({
get: () => Effect.succeed(input.provider ?? makeProvider()),
}),
),
Layer.provide(
Layer.mock(GitVcsDriver.GitVcsDriver)({
execute: () => Effect.succeed(processOutput()),
ensureRemote: () => Effect.succeed("origin"),
pushCurrentBranch: () =>
Effect.succeed({
status: "pushed" as const,
branch: "feature/remote-v1",
upstreamBranch: "origin/feature/remote-v1",
setUpstream: true,
}),
...input.git,
}),
),
Layer.provide(ServerConfig.layerTest(process.cwd(), { prefix: "t3-source-control-repos-" })),
Layer.provideMerge(NodeServices.layer),
);
}
it.effect("looks up repositories through the requested provider without search", () => {
const calls: Array<{ cwd: string; repository: string }> = [];
const provider = makeProvider({
getRepositoryCloneUrls: (input) =>
Effect.sync(() => {
calls.push({ cwd: input.cwd, repository: input.repository });
return CLONE_URLS;
}),
});
return Effect.gen(function* () {
const service = yield* SourceControlRepositoryService.SourceControlRepositoryService;
const result = yield* service.lookupRepository({
provider: "github",
repository: "octocat/t3code",
cwd: "/workspace",
});
assert.deepStrictEqual(result, { provider: "github", ...CLONE_URLS });
assert.deepStrictEqual(calls, [{ cwd: "/workspace", repository: "octocat/t3code" }]);
}).pipe(Effect.provide(makeLayer({ provider })));
});
it.effect("clones a looked-up repository into the requested destination", () =>
Effect.gen(function* () {
const fs = yield* FileSystem.FileSystem;
const parent = yield* fs.makeTempDirectoryScoped({
prefix: "t3-source-control-clone-parent-",
});
const destinationPath = `${parent}/t3code`;
const cloneCalls: Array<{ cwd: string; args: ReadonlyArray<string> }> = [];
yield* Effect.gen(function* () {
const service = yield* SourceControlRepositoryService.SourceControlRepositoryService;
const result = yield* service.cloneRepository({
provider: "github",
repository: "octocat/t3code",
destinationPath,
protocol: "https",
});
assert.deepStrictEqual(result, {
cwd: destinationPath,
remoteUrl: CLONE_URLS.url,
repository: { provider: "github", ...CLONE_URLS },
});
assert.deepStrictEqual(cloneCalls, [
{
cwd: parent,
args: ["clone", CLONE_URLS.url, "t3code"],
},
]);
}).pipe(
Effect.provide(
makeLayer({
git: {
execute: (input) =>
Effect.sync(() => {
cloneCalls.push({ cwd: input.cwd, args: input.args });
return processOutput();
}),
},
}),
),
);
}).pipe(Effect.provide(NodeServices.layer)),
);
it.effect("publishes by creating the repository, adding a remote, and pushing upstream", () => {
const createCalls: Array<{ cwd: string; repository: string; visibility: string }> = [];
const remoteCalls: Array<{ cwd: string; preferredName: string; url: string }> = [];
const pushCalls: Array<{ cwd: string; remoteName: string | null | undefined }> = [];
const provider = makeProvider({
createRepository: (input) =>
Effect.sync(() => {
createCalls.push({
cwd: input.cwd,
repository: input.repository,
visibility: input.visibility,
});
return CLONE_URLS;
}),
});
return Effect.gen(function* () {
const service = yield* SourceControlRepositoryService.SourceControlRepositoryService;
const result = yield* service.publishRepository({
cwd: "/workspace",
provider: "github",
repository: "octocat/t3code",
visibility: "private",
remoteName: "origin",
protocol: "ssh",
});
assert.deepStrictEqual(result, {
repository: { provider: "github", ...CLONE_URLS },
remoteName: "origin",
remoteUrl: CLONE_URLS.sshUrl,
branch: "feature/remote-v1",
upstreamBranch: "origin/feature/remote-v1",
status: "pushed",
});
assert.deepStrictEqual(createCalls, [
{ cwd: "/workspace", repository: "octocat/t3code", visibility: "private" },
]);
assert.deepStrictEqual(remoteCalls, [
{ cwd: "/workspace", preferredName: "origin", url: CLONE_URLS.sshUrl },
]);
assert.deepStrictEqual(pushCalls, [{ cwd: "/workspace", remoteName: "origin" }]);
}).pipe(
Effect.provide(
makeLayer({
provider,
git: {
ensureRemote: (input) =>
Effect.sync(() => {
remoteCalls.push(input);
return "origin";
}),
pushCurrentBranch: (cwd, _fallbackBranch, options) =>
Effect.sync(() => {
pushCalls.push({ cwd, remoteName: options?.remoteName });
return {
status: "pushed" as const,
branch: "feature/remote-v1",
upstreamBranch: "origin/feature/remote-v1",
setUpstream: true,
};
}),
},
}),
),
);
});
it.effect("publishes to the remote name returned by ensureRemote", () => {
const pushCalls: Array<{ cwd: string; remoteName: string | null | undefined }> = [];
return Effect.gen(function* () {
const service = yield* SourceControlRepositoryService.SourceControlRepositoryService;
const result = yield* service.publishRepository({
cwd: "/workspace",
provider: "github",
repository: "octocat/t3code",
visibility: "private",
remoteName: "origin",
protocol: "ssh",
});
assert.equal(result.remoteName, "origin-1");
assert.deepStrictEqual(pushCalls, [{ cwd: "/workspace", remoteName: "origin-1" }]);
}).pipe(
Effect.provide(
makeLayer({
git: {
ensureRemote: () => Effect.succeed("origin-1"),
pushCurrentBranch: (cwd, _fallbackBranch, options) =>
Effect.sync(() => {
pushCalls.push({ cwd, remoteName: options?.remoteName });
return {
status: "pushed" as const,
branch: "feature/remote-v1",
upstreamBranch: `${options?.remoteName ?? "missing"}/feature/remote-v1`,
setUpstream: true,
};
}),
},
}),
),
);
});
it.effect("publish succeeds with status remote_added when the local repo has no commits", () => {
let pushCalls = 0;
return Effect.gen(function* () {
const service = yield* SourceControlRepositoryService.SourceControlRepositoryService;
const result = yield* service.publishRepository({
cwd: "/workspace",
provider: "github",
repository: "octocat/t3code",
visibility: "private",
remoteName: "origin",
protocol: "ssh",
});
assert.deepStrictEqual(result, {
repository: { provider: "github", ...CLONE_URLS },
remoteName: "origin",
remoteUrl: CLONE_URLS.sshUrl,
branch: "main",
status: "remote_added",
});
assert.strictEqual(pushCalls, 0);
}).pipe(
Effect.provide(
makeLayer({
git: {
execute: (input) =>
input.args[0] === "rev-parse"
? Effect.fail(
new GitCommandError({
operation: input.operation,
command: "git rev-parse --verify HEAD",
cwd: input.cwd,
detail: "fatal: Needed a single revision",
}),
)
: Effect.succeed(processOutput()),
statusDetails: () =>
Effect.succeed({
isRepo: true,
hasOriginRemote: true,
isDefaultBranch: true,
branch: "main",
upstreamRef: null,
hasWorkingTreeChanges: false,
workingTree: { files: [], insertions: 0, deletions: 0 },
hasUpstream: false,
aheadCount: 0,
behindCount: 0,
aheadOfDefaultCount: 0,
}),
pushCurrentBranch: () =>
Effect.sync(() => {
pushCalls += 1;
return {
status: "pushed" as const,
branch: "main",
upstreamBranch: "origin/main",
setUpstream: true,
};
}),
},
}),
),
);
});