import {ChildProcess, spawn} from 'child_process'; import * as fs from 'fs/promises'; export interface GitService { create(cwd: string): Promise delete(cwd: string): Promise advertiseReceivePackRefs(cwd: string): Promise advertiseUploadPackRefs(cwd: string): Promise receivePack(cwd: string): Promise uploadPack(cwd: string): Promise } export class GitServiceImpl implements GitService { private static isWindows() { return /^win/.test(process.platform); } async create(cwd: string): Promise { await fs.mkdir(cwd, { recursive: true }); return spawn('git', ['init', '--bare'], { cwd }); } async delete(cwd: string): Promise { await fs.rm(cwd, { recursive: true, force: true, }); } async advertiseReceivePackRefs(cwd: string): Promise { const command = GitServiceImpl.isWindows() ? 'git' : 'git-receive-pack'; const commonArgs = ['--stateless-rpc', '--advertise-refs', cwd]; const args = GitServiceImpl.isWindows() ? ['receive-pack', ...commonArgs] : commonArgs; return spawn(command, args); } async advertiseUploadPackRefs(cwd: string): Promise { const command = GitServiceImpl.isWindows() ? 'git' : 'git-upload-pack'; const commonArgs = ['--stateless-rpc', '--advertise-refs', cwd]; const args = GitServiceImpl.isWindows() ? ['upload-pack', ...commonArgs] : commonArgs; return spawn(command, args); } async receivePack(cwd: string): Promise { const command = GitServiceImpl.isWindows() ? 'git' : 'git-receive-pack'; const commonArgs = ['--stateless-rpc', cwd]; const args = GitServiceImpl.isWindows() ? ['receive-pack', ...commonArgs] : commonArgs; return spawn(command, args); } async uploadPack(cwd: string): Promise { const command = GitServiceImpl.isWindows() ? 'git' : 'git-upload-pack'; const commonArgs = ['--stateless-rpc', cwd]; const args = GitServiceImpl.isWindows() ? ['upload-pack', ...commonArgs] : commonArgs; return spawn(command, args); } }