import * as NodePath from "@effect/platform-node/NodePath";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 PlatformError from "effect/PlatformError";import { ChildProcessSpawner } from "effect/unstable/process"; import { GitCommandError, SourceControlProviderError } from "@t3tools/contracts"; import * as 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.SourceControlProvider["Service"]> = {},): SourceControlProvider.SourceControlProvider["Service"] { 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.SourceControlProvider["Service"]; readonly git?: Partial<GitVcsDriver.GitVcsDriver["Service"]>; readonly fileSystem?: FileSystem.FileSystem;}) { const serviceLayer = 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(), input.fileSystem ? "/tmp/t3-source-control-repos" : { prefix: "t3-source-control-repos-" }, ), ), ); return input.fileSystem ? serviceLayer.pipe( Layer.provide(Layer.succeed(FileSystem.FileSystem, input.fileSystem)), Layer.provideMerge(NodePath.layer), ) : serviceLayer.pipe(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("preserves provider failures without deriving the repository message from them", () => { const providerCause = new SourceControlProviderError({ provider: "github", operation: "getRepositoryCloneUrls", cwd: "/workspace", repository: "octocat/t3code", detail: "credential token abc123 was rejected", }); const provider = makeProvider({ getRepositoryCloneUrls: () => Effect.fail(providerCause), }); return Effect.gen(function* () { const service = yield* SourceControlRepositoryService.SourceControlRepositoryService; const error = yield* Effect.flip( service.lookupRepository({ provider: "github", repository: "octocat/t3code", cwd: "/workspace", }), ); assert.strictEqual(error.provider, "github"); assert.strictEqual(error.operation, "lookupRepository"); assert.strictEqual(error.detail, "The source control operation could not be completed."); assert.strictEqual( error.message, "Source control repository operation lookupRepository failed for github: The source control operation could not be completed.", ); assert.strictEqual(error.cause, providerCause); }).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("preserves destination probe failures instead of treating them as missing paths", () => { const fileSystemCause = PlatformError.systemError({ _tag: "PermissionDenied", module: "FileSystem", method: "exists", pathOrDescriptor: "/restricted/t3code", }); return Effect.gen(function* () { const service = yield* SourceControlRepositoryService.SourceControlRepositoryService; const error = yield* Effect.flip( service.cloneRepository({ remoteUrl: CLONE_URLS.sshUrl, destinationPath: "/restricted/t3code", }), ); assert.strictEqual(error.provider, "unknown"); assert.strictEqual(error.operation, "cloneRepository"); assert.strictEqual(error.cause, fileSystemCause); }).pipe( Effect.provide( makeLayer({ fileSystem: FileSystem.makeNoop({ exists: () => Effect.fail(fileSystemCause), makeDirectory: () => Effect.void, }), }), ), );}); 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 NodePath from "@effect/platform-node/NodePath";
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 PlatformError from "effect/PlatformError";
import { ChildProcessSpawner } from "effect/unstable/process";
import { GitCommandError, SourceControlProviderError } from "@t3tools/contracts";
import * as 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.SourceControlProvider["Service"]> = {},
): SourceControlProvider.SourceControlProvider["Service"] {
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.SourceControlProvider["Service"];
readonly git?: Partial<GitVcsDriver.GitVcsDriver["Service"]>;
readonly fileSystem?: FileSystem.FileSystem;
}) {
const serviceLayer = 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(),
input.fileSystem ? "/tmp/t3-source-control-repos" : { prefix: "t3-source-control-repos-" },
),
),
);
return input.fileSystem
? serviceLayer.pipe(
Layer.provide(Layer.succeed(FileSystem.FileSystem, input.fileSystem)),
Layer.provideMerge(NodePath.layer),
)
: serviceLayer.pipe(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("preserves provider failures without deriving the repository message from them", () => {
const providerCause = new SourceControlProviderError({
provider: "github",
operation: "getRepositoryCloneUrls",
cwd: "/workspace",
repository: "octocat/t3code",
detail: "credential token abc123 was rejected",
});
const provider = makeProvider({
getRepositoryCloneUrls: () => Effect.fail(providerCause),
});
return Effect.gen(function* () {
const service = yield* SourceControlRepositoryService.SourceControlRepositoryService;
const error = yield* Effect.flip(
service.lookupRepository({
provider: "github",
repository: "octocat/t3code",
cwd: "/workspace",
}),
);
assert.strictEqual(error.provider, "github");
assert.strictEqual(error.operation, "lookupRepository");
assert.strictEqual(error.detail, "The source control operation could not be completed.");
assert.strictEqual(
error.message,
"Source control repository operation lookupRepository failed for github: The source control operation could not be completed.",
);
assert.strictEqual(error.cause, providerCause);
}).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("preserves destination probe failures instead of treating them as missing paths", () => {
const fileSystemCause = PlatformError.systemError({
_tag: "PermissionDenied",
module: "FileSystem",
method: "exists",
pathOrDescriptor: "/restricted/t3code",
});
return Effect.gen(function* () {
const service = yield* SourceControlRepositoryService.SourceControlRepositoryService;
const error = yield* Effect.flip(
service.cloneRepository({
remoteUrl: CLONE_URLS.sshUrl,
destinationPath: "/restricted/t3code",
}),
);
assert.strictEqual(error.provider, "unknown");
assert.strictEqual(error.operation, "cloneRepository");
assert.strictEqual(error.cause, fileSystemCause);
}).pipe(
Effect.provide(
makeLayer({
fileSystem: FileSystem.makeNoop({
exists: () => Effect.fail(fileSystemCause),
makeDirectory: () => Effect.void,
}),
}),
),
);
});
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,
};
}),
},
}),
),
);
});