project setup

This commit is contained in:
Andrea Lamparelli 2022-12-06 18:10:30 +01:00
commit 05d156a5b0
39 changed files with 14823 additions and 0 deletions

View file

@ -0,0 +1,102 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const logger_service_factory_1 = __importDefault(require("../../service/logger/logger-service-factory"));
const simple_git_1 = __importDefault(require("simple-git"));
const fs_1 = __importDefault(require("fs"));
/**
* Command line git commands executor service
*/
class GitCLIService {
constructor() {
this.logger = logger_service_factory_1.default.getLogger();
}
/**
* Return a pre-configured SimpleGit instance able to execute commands from current
* directory or the provided one
* @param cwd [optional] current working directory
* @returns {SimpleGit}
*/
git(cwd) {
const gitConfig = { ...(cwd ? { baseDir: cwd } : {}) };
return (0, simple_git_1.default)(gitConfig).addConfig("user.name", "Github").addConfig("user.email", "noreply@github.com");
}
/**
* Return the git version
* @returns {Promise<string | undefined>}
*/
async version() {
const rawOutput = await this.git().raw("version");
const match = rawOutput.match(/(\d+\.\d+(\.\d+)?)/);
return match ? match[1] : undefined;
}
/**
* Clone a git repository
* @param from url or path from which the repository should be cloned from
* @param to location at which the repository should be cloned at
* @param branch branch which should be cloned
*/
async clone(from, to, branch) {
this.logger.info(`Cloning repository ${from}..`);
if (!fs_1.default.existsSync(to)) {
await this.git().clone(from, to, ["--quiet", "--shallow-submodules", "--no-tags", "--branch", branch]);
}
else {
this.logger.warn(`Folder ${to} already exist. Won't clone`);
}
}
/**
* Create a new branch starting from the current one and checkout in it
* @param cwd repository in which createBranch should be performed
* @param newBranch new branch name
*/
async createLocalBranch(cwd, newBranch) {
this.logger.info(`Creating branch ${newBranch}..`);
await this.git(cwd).checkoutLocalBranch(newBranch);
}
/**
* Add a new remote to the current repository
* @param cwd repository in which addRemote should be performed
* @param remote remote git link
* @param remoteName [optional] name of the remote, by default 'fork' is used
*/
async addRemote(cwd, remote, remoteName = "fork") {
this.logger.info(`Adding new remote ${remote}..`);
await this.git(cwd).addRemote(remoteName, remote);
}
/**
* Git fetch from a particular branch
* @param cwd repository in which fetch should be performed
* @param branch fetch from the given branch
* @param remote [optional] the remote to fetch, by default origin
*/
async fetch(cwd, branch, remote = "origin") {
await this.git(cwd).fetch(remote, branch, ["--quiet"]);
}
/**
* Get cherry-pick a specific sha
* @param cwd repository in which the sha should be cherry picked to
* @param sha commit sha
*/
async cherryPick(cwd, sha) {
this.logger.info(`Cherry picking ${sha}..`);
await this.git(cwd).raw(["cherry-pick", "--strategy=recursive", "-X", "theirs", sha]);
}
/**
* Push a branch to a remote
* @param cwd repository in which the push should be performed
* @param branch branch to be pushed
* @param remote [optional] remote to which the branch should be pushed to, by default 'origin'
*/
async push(cwd, branch, remote = "origin", force = false) {
this.logger.info(`Pushing ${branch} to ${remote}..`);
const options = ["--quiet"];
if (force) {
options.push("--force-with-lease");
}
await this.git(cwd).push(remote, branch, options);
}
}
exports.default = GitCLIService;

View file

@ -0,0 +1,36 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const git_types_1 = require("../../service/git/git.types");
const github_service_1 = __importDefault(require("../../service/git/github/github-service"));
/**
* Singleton git service factory class
*/
class GitServiceFactory {
static getService() {
if (!GitServiceFactory.instance) {
throw new Error("You must call `init` method first!");
}
return GitServiceFactory.instance;
}
/**
* Initialize the singleton git management service
* @param type git management service type
* @param auth authentication, like github token
*/
static init(type, auth) {
if (GitServiceFactory.instance) {
throw new Error("Git service already initialized!");
}
switch (type) {
case git_types_1.GitServiceType.GITHUB:
GitServiceFactory.instance = new github_service_1.default(auth);
break;
default:
throw new Error(`Invalid git service type received: ${type}`);
}
}
}
exports.default = GitServiceFactory;

View file

@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

View file

@ -0,0 +1,7 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.GitServiceType = void 0;
var GitServiceType;
(function (GitServiceType) {
GitServiceType["GITHUB"] = "github";
})(GitServiceType = exports.GitServiceType || (exports.GitServiceType = {}));

View file

@ -0,0 +1,18 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
class GitHubMapper {
mapPullRequest(pr) {
return {
url: pr.url,
title: pr.title,
body: pr.body,
patchUrl: pr.patch_url,
state: pr.state,
reviewers: pr.requested_reviewers.filter(r => "login" in r).map((r => r?.login)),
sourceRepo: pr.head.repo.full_name,
targetRepo: pr.base.repo.full_name,
commits: [pr.merge_commit_sha]
};
}
}
exports.default = GitHubMapper;

View file

@ -0,0 +1,30 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const github_mapper_1 = __importDefault(require("../../../service/git/github/github-mapper"));
const octokit_factory_1 = __importDefault(require("../../../service/git/github/octokit-factory"));
class GitHubService {
constructor(token) {
this.octokit = octokit_factory_1.default.getOctokit(token);
this.mapper = new github_mapper_1.default();
}
// READ
async getPullRequest(owner, repo, prNumber) {
const { data } = await this.octokit.rest.pulls.get({
owner: owner,
repo: repo,
pull_number: prNumber
});
return this.mapper.mapPullRequest(data);
}
// WRITE
// eslint-disable-next-line @typescript-eslint/no-unused-vars
createPullRequest(owner, repo, head, base, title, body, reviewers) {
// throw new Error("Method not implemented.");
// TODO implement
return Promise.resolve();
}
}
exports.default = GitHubService;

View file

@ -0,0 +1,24 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const logger_service_factory_1 = __importDefault(require("../../../service/logger/logger-service-factory"));
const rest_1 = require("@octokit/rest");
/**
* Singleton factory class for {Octokit} instance
*/
class OctokitFactory {
static getOctokit(token) {
if (!OctokitFactory.octokit) {
OctokitFactory.logger.info("Creating octokit instance..");
OctokitFactory.octokit = new rest_1.Octokit({
auth: token,
userAgent: "lampajr/backporting"
});
}
return OctokitFactory.octokit;
}
}
exports.default = OctokitFactory;
OctokitFactory.logger = logger_service_factory_1.default.getLogger();

View file

@ -0,0 +1,27 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const logger_1 = __importDefault(require("../../service/logger/logger"));
class ConsoleLoggerService {
constructor() {
this.logger = new logger_1.default();
}
trace(message) {
this.logger.log("[TRACE]", message);
}
debug(message) {
this.logger.log("[DEBUG]", message);
}
info(message) {
this.logger.log("[INFO]", message);
}
warn(message) {
this.logger.log("[WARN]", message);
}
error(message) {
this.logger.log("[ERROR]", message);
}
}
exports.default = ConsoleLoggerService;

View file

@ -0,0 +1,18 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const console_logger_service_1 = __importDefault(require("../../service/logger/console-logger-service"));
/**
* Singleton factory class
*/
class LoggerServiceFactory {
static getLogger() {
if (!LoggerServiceFactory.instance) {
LoggerServiceFactory.instance = new console_logger_service_1.default();
}
return LoggerServiceFactory.instance;
}
}
exports.default = LoggerServiceFactory;

View file

@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

View file

@ -0,0 +1,15 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/**
* Common logger class based on the console.log functionality
*/
class Logger {
log(prefix, ...str) {
// eslint-disable-next-line no-console
console.log.apply(console, [prefix, ...str]);
}
emptyLine() {
this.log("", "");
}
}
exports.default = Logger;