@yuki-no/plugin-sdk
Version:
A GitHub Action that tracks changes between repositories. It creates GitHub issues based on commits from a head repository, making it ideal for documentation translation projects.
65 lines (64 loc) • 2.47 kB
JavaScript
import { createTempFilePath } from '../utils/common';
import { log } from '../utils/log';
import fs from 'node:fs';
import path from 'node:path';
import shell from 'shelljs';
export class Git {
config;
constructor(config) {
this.config = config;
log('I', 'Git[[Construct]] :: Git instance created');
if (config.withClone) {
this.clone();
}
}
#dirName;
get dirName() {
if (this.#dirName) {
return this.#dirName;
}
this.#dirName = fs.mkdtempSync(createTempFilePath(`cloned-by-yuki-no__${this.config.repoSpec.name}__`));
return this.#dirName;
}
exec(command) {
shell.cd(this.dirName);
const result = shell.exec(`git ${command}`);
if (result.code !== 0) {
throw new GitCommandError(command, result.code, result.stderr, result.stdout);
}
return result.stdout.trim();
}
clone() {
const parentDirName = path.resolve(this.dirName, '../');
const baseName = path.basename(this.dirName);
log('I', `Git.clone :: Cloning repository: ${parentDirName}/${baseName}`);
shell.cd(parentDirName);
if (fs.existsSync(baseName)) {
fs.rmSync(baseName, { force: true, recursive: true });
}
const authorizedRepoUrl = createAuthorizedRepoUrl(this.repoUrl, this.config);
// Execute exec directly only here since repoDir doesn't exist yet
shell.exec(`git clone ${authorizedRepoUrl} ${baseName}`);
this.exec(`config user.name "${this.config.userName}"`);
this.exec(`config user.email "${this.config.email}"`);
log('S', `Git.clone :: Repository clone completed with '${this.config.userName}' and '${this.config.email}' / ${baseName}`);
}
get repoUrl() {
return `https://github.com/${this.config.repoSpec.owner}/${this.config.repoSpec.name}`;
}
}
const createAuthorizedRepoUrl = (repoUrl, config) => repoUrl.replace('https://', `https://${config.userName}:${config.accessToken}@`);
export class GitCommandError extends Error {
command;
exitCode;
stderr;
stdout;
constructor(command, exitCode, stderr, stdout) {
super(`Git command failed: git ${command}\nExit code: ${exitCode}\nError: ${stderr}`);
this.command = command;
this.exitCode = exitCode;
this.stderr = stderr;
this.stdout = stdout;
this.name = 'GitCommandError';
}
}