feat(repository): add service methods "getRepositoryBranches" and "getRepositoryTags"@@ -0,0 +1,63 @@
+// std
+import { existsSync } from "node:fs";
+import { spawn } from "node:child_process";
+// 1st-party
+import { ServiceMethodFactory } from "@ethicdevs/react-monolith";
+// generated via script[generate:prisma]
+import type { Repository } from "@prisma/client";
+// app
+import { Env } from "../../env";
+// service
+import { RepositoryServiceDeps } from "./types";
+
+const makeGetRepositoryBranches: ServiceMethodFactory<
+ RepositoryServiceDeps,
+ [Repository],
+ Promise<string[]>
+> = ({ request }) => {
+ return async (repo) => {
+ const parentOrg = await request.prisma.organization.findUnique({
+ where: {
+ id: repo.organizationId,
+ },
+ });
+
+ if (parentOrg == null) {
+ throw new Error(
+ `Could not find the parent organization for project "${repo.slug}".`
+ );
+ }
+
+ try {
+ const repoPath = `${Env.GIT_REPOSITORIES_ROOT}/${parentOrg.slug}/${repo.slug}.git`;
+ if (existsSync(repoPath) === false) {
+ throw new Error(
+ `Could not find a valid git repository at: ${repoPath}`
+ );
+ }
+
+ const gitBranchProcess = spawn("git", ["branch", "-a"], {
+ cwd: repoPath,
+ });
+
+ const gitBranchResult = await new Promise<string>((resolve, reject) => {
+ let buffer = [] as string[];
+ gitBranchProcess.stdout.on("data", (data) => buffer.push(data));
+ gitBranchProcess.stderr.on("data", (data) => {
+ reject(new Error(Buffer.from(data).toString("utf-8")));
+ });
+ gitBranchProcess.stdout.on("close", () => {
+ resolve(buffer.join(""));
+ });
+ });
+
+ return gitBranchResult
+ .split("\n")
+ .map((branch) => branch.trim().replace(/^\* /i, ""));
+ } catch (_) {
+ return [];
+ }
+ };
+};
+
+export default makeGetRepositoryBranches;
@@ -0,0 +1,63 @@
+// std
+import { existsSync } from "node:fs";
+import { spawn } from "node:child_process";
+// 1st-party
+import { ServiceMethodFactory } from "@ethicdevs/react-monolith";
+// generated via script[generate:prisma]
+import type { Repository } from "@prisma/client";
+// app
+import { Env } from "../../env";
+// service
+import { RepositoryServiceDeps } from "./types";
+
+const makeGetRepositoryTags: ServiceMethodFactory<
+ RepositoryServiceDeps,
+ [Repository],
+ Promise<string[]>
+> = ({ request }) => {
+ return async (repo) => {
+ const parentOrg = await request.prisma.organization.findUnique({
+ where: {
+ id: repo.organizationId,
+ },
+ });
+
+ if (parentOrg == null) {
+ throw new Error(
+ `Could not find the parent organization for project "${repo.slug}".`
+ );
+ }
+
+ try {
+ const repoPath = `${Env.GIT_REPOSITORIES_ROOT}/${parentOrg.slug}/${repo.slug}.git`;
+ if (existsSync(repoPath) === false) {
+ throw new Error(
+ `Could not find a valid git repository at: ${repoPath}`
+ );
+ }
+
+ const gitTagProcess = spawn("git", ["tag", "--sort=taggerdate"], {
+ cwd: repoPath,
+ });
+
+ const gitTagResult = await new Promise<string>((resolve, reject) => {
+ let buffer = [] as string[];
+ gitTagProcess.stdout.on("data", (data) => buffer.push(data));
+ gitTagProcess.stderr.on("data", (data) => {
+ reject(new Error(Buffer.from(data).toString("utf-8")));
+ });
+ gitTagProcess.stdout.on("close", () => {
+ resolve(buffer.join(""));
+ });
+ });
+
+ return gitTagResult
+ .split("\n")
+ .map((branch) => branch.trim().replace(/^\* /i, ""));
+ } catch (_) {
+ return [];
+ }
+ };
+};
+
+export default makeGetRepositoryTags;
@@ -5,6 +5,7 @@ import type { RepositoryServiceAPI, RepositoryServiceDeps } from "./types";
// service methods
import { default as makeCreateRepository } from "./createRepository";
import { default as makeGetRepository } from "./getRepository";
+import { default as makeGetRepositoryBranches } from "./getRepositoryBranches";
import { default as makeGetRepositoryCommitLog } from "./getRepositoryCommitLog";
import { default as makeGetRepositoryExploreCollection } from "./getRepositoryExploreCollection";
import { default as makeGetRepositoryFileContent } from "./getRepositoryFileContent";
@@ -14,6 +15,7 @@ import { default as makeGetRepositoryHead } from "./getRepositoryHead";
import { default as makeGetRepositoryHTTPCloneUrl } from "./getRepositoryHTTPCloneUrl";
import { default as makeGetRepositorySSHCloneUrl } from "./getRepositorySSHCloneUrl";
import { default as makeGetRepositoryRefDiff } from "./getRepositoryRefDiff";
+import { default as makeGetRepositoryTags } from "./getRepositoryTags";
import { default as makeIsFileInRepositoryPath } from "./isFileInRepositoryPath";
export const makeRepositoryService = makeService<
@@ -22,6 +24,7 @@ export const makeRepositoryService = makeService<
>({
createRepository: makeCreateRepository,
getRepository: makeGetRepository,
+ getRepositoryBranches: makeGetRepositoryBranches,
getRepositoryCommitLog: makeGetRepositoryCommitLog,
getRepositoryExploreCollection: makeGetRepositoryExploreCollection,
getRepositoryFileContent: makeGetRepositoryFileContent,
@@ -31,5 +34,6 @@ export const makeRepositoryService = makeService<
getRepositoryHTTPCloneUrl: makeGetRepositoryHTTPCloneUrl,
getRepositorySSHCloneUrl: makeGetRepositorySSHCloneUrl,
getRepositoryRefDiff: makeGetRepositoryRefDiff,
+ getRepositoryTags: makeGetRepositoryTags,
isFileInRepositoryPath: makeIsFileInRepositoryPath,
});
@@ -33,6 +33,7 @@ export interface CreateRepositoryDTO {
export interface RepositoryServiceAPI extends ServiceApiContract {
createRepository(dto: CreateRepositoryDTO): Promise<Repository>;
getRepository(orgSlug: string, repoSlug: string): Promise<Repository | null>;
+ getRepositoryBranches(repository: Repository): Promise<string[]>;
getRepositoryCommitLog(
repository: Repository,
path?: string,
@@ -68,6 +69,7 @@ export interface RepositoryServiceAPI extends ServiceApiContract {
refA: string,
refB?: string
): Promise<RepositoryFileDiff[]>;
+ getRepositoryTags(repository: Repository): Promise<string[]>;
isFileInRepositoryPath(
repository: Repository,
path: string,