import simpleGit, { SimpleGit, SimpleGitOptions } from 'simple-git'; import { PROJECT_SRC_PATH } from './config'; import UserConfig from './userConfig'; const util = require('util'); const exec = util.promisify(require('child_process').exec); const DEFAULT_REMOTE = 'origin'; const DEFAULT_BRANCH = 'master'; export default class GitMission { private git: SimpleGit; constructor(private userConfig: UserConfig) { const options: Partial<SimpleGitOptions> = { baseDir: PROJECT_SRC_PATH, binary: 'git', maxConcurrentProcesses: 2, }; this.git = simpleGit(options); } async setupSshAgent() { const { err, stderr, stdout } = await exec(`eval "$(ssh-agent -s)" && ssh-keyscan -p ${this.userConfig.getGiteaSshPort()} -H ${this.userConfig.getGiteaHost()} >> ~/.ssh/known_hosts`); console.log(stdout); if (err) { console.error(stderr); throw new Error(err); } } get author() { return this.userConfig.getUsername(); } async init() { try { console.log('Setup ssh agent'); await this.setupSshAgent(); console.log('Init Git mission..'); const remote = await this.readRemote(); if (remote === DEFAULT_REMOTE) { return Promise.resolve(this); } const remotePath = this.getRemotePath(); await this.git.init(); await this.git.addRemote(DEFAULT_REMOTE, remotePath); await this.git.addConfig('user.email', this.userConfig.getCurrentUserDetails().email, false, "system"); await this.git.addConfig('user.name', `${this.userConfig.getCurrentUserDetails().lastName} ${this.userConfig.getCurrentUserDetails().firstName}`, false, "system"); return Promise.resolve(this); } catch (e) { console.error(e); return Promise.reject(e); } } private getRemotePath() { return `ssh://git@${this.userConfig.getGiteaHost()}:${this.userConfig.getGiteaSshPort()}/${this.userConfig.getRemoteGitUsername()}/${this.userConfig.getMissionId()}`; } async readRemote() { try { return (await this.git.remote([]) || '').replace(/(\r\n|\n|\r)/gm, ''); } catch (e) { // ignore it, maybe the git repo does not exist } return ''; } fetch() { return this.git.fetch(DEFAULT_REMOTE); } pull() { return this.git.pull(DEFAULT_REMOTE, DEFAULT_BRANCH, { '--rebase': 'true' }); } addAll() { return this.git.add('.'); } commit(message) { return this.git.commit(message); } push() { return this.git.push(DEFAULT_REMOTE, DEFAULT_BRANCH); } async isRemoteRepoExist() { try { const remotes = await this.git.listRemote(); return remotes.length !== 0; } catch { // error, Gitea throws Gitea: Unauthorized when not found return false; } } }