import { spawn } from "node:child_process";
import type { ServiceMethodFactory } from "@ethicdevs/react-monolith";
import type { Repository } from "@prisma/client";
import type { CreateRepositoryDTO, RepositoryServiceDeps } from "./types";
const makeCreateRepository: ServiceMethodFactory<
RepositoryServiceDeps,
[CreateRepositoryDTO],
Promise<Repository>
> = ({ request }) => {
return async ({ parentOrgSlug, repoSlug, repoData, repoInitFlags }) => {
const {
orgRepositoriesDir,
withBaseReadmeFile: _,
withLicenseFile: __,
} = repoInitFlags;
const parentOrg = await request.prisma.organization.findUnique({
where: {
slug: parentOrgSlug,
},
});
if (parentOrg == null) {
throw new Error(
`Could not find the parent organization to create new repository in.`
);
}
console.log(
`[..] creating repository "${parentOrg.slug}/${repoSlug}" in database`
);
const newRepo = await request.prisma.repository.create({
data: {
...repoData,
organizationId: parentOrg.id,
slug: repoSlug,
},
});
console.log(
`[ok] created repository in database with id "${newRepo.id}" and slug "${parentOrg.slug}/${newRepo.slug}"!`
);
console.log(
`[..] creating repository folder with "git init --bare --shared=group" in org directory:`,
orgRepositoriesDir
);
const gitInitBareRepoProcess = spawn(
"git",
["init", "--bare", "--shared=group", `${newRepo.slug}.git`],
{ cwd: orgRepositoriesDir.toString() }
);
const gitInitBareRepoResult = await new Promise<string>(
(resolve, reject) => {
let buffer = [] as string[];
gitInitBareRepoProcess.stdout.on("data", (data) => {
console.log("stdout::data:", data);
buffer.push(data);
});
gitInitBareRepoProcess.stderr.on("data", (data) => {
reject(new Error(Buffer.from(data).toString("utf-8")));
});
gitInitBareRepoProcess.stdout.on("close", () => {
resolve(buffer.join(""));
});
}
);
console.log(
`[ok] finished execution of "git init --bare --shared=group" with result:\n\t`,
gitInitBareRepoResult
);
return newRepo;
};
};
export default makeCreateRepository;